Skip to content

[App quality] Make zoom-to-physical-size correct per display and calibratable #157

Description

@mberrys

Part of #155.

Problem

The product is named for a magnifier and the vision doc commits it to being "exact about geometry". The zoom-to-physical-size mapping is not exact, and on the multi-monitor setups that print shops actually use it is wrong.

Pdf4QtLibWidgets/sources/pdfdrawspacecontroller.cpp:554-570:

QScreen* primaryScreen = QGuiApplication::primaryScreen();
QSizeF physicalSize = primaryScreen->physicalSize();
QSizeF pixelSize    = primaryScreen->size();
m_pixelPerMM = pixelSize.width() / physicalSize.width();

Three defects follow:

  1. Always the primary screen. The scale factor is derived from primaryScreen() regardless of which display the window is on. A laptop panel plus an external 4K monitor — the standard studio setup — gives a wrong millimetre-per-pixel ratio on the secondary display, and nothing recalculates when the window is dragged between screens. "100%" is then not 100% and a hairline measured on screen is not the hairline on press.
  2. physicalSize() is EDID-reported and frequently wrong. Monitors misreport, projectors and VMs report nothing useful, and remote sessions synthesise values. There is no operator calibration path (Acrobat exposes one; a print tool needs one).
  3. Only the primary screen's width is usedphysicalSize.height() and non-square pixel aspect are ignored.

Separately, Pdf4QtLibGui/main.cpp:33 sets Qt::AA_DisableHighDpiScaling, which no other entry point does. Whatever that surface is for, it renders at 1× on a high-DPI display while the shipped Editor does not — an inconsistency that should be resolved rather than left in the tree.

Scope

  1. Derive the pixel-per-millimetre ratio from the screen the window is currently on (QWidget::screen()), and recalculate on QWindow::screenChanged and on QScreen::physicalDotsPerInchChanged.
  2. Add an operator display calibration: a settings surface where the user matches an on-screen ruler to a physical one, persisted per display (keyed by screen name/serial), overriding the EDID-derived value when set.
  3. Show the effective source of the current scale — reported by display, or calibrated by operator — wherever "actual size" is claimed, so an operator can tell whether to trust it.
  4. Handle non-square pixel aspect, or state explicitly that it is unsupported and detect it.
  5. Resolve AA_DisableHighDpiScaling in Pdf4QtLibGui/main.cpp: remove it, or document why that surface differs.
  6. Confirm the QPainter renderer path (pdfdrawwidget.cpp:848-853) reaches device-pixel resolution on fractional scale factors. The Blend2D path handles device pixel ratio explicitly (pdfdrawwidget.cpp:819-830); the QPainter path does not, and the two should be verified to produce the same measured output.

Acceptance criteria

  • Dragging a window between displays with different DPI updates the scale factor, and a 100 mm object measures 100 mm on both, within the calibration tolerance.
  • With calibration set, "actual size" matches a physical ruler within 0.5 mm over 100 mm on the calibrated display.
  • Calibration persists per display and survives disconnect/reconnect of an external monitor.
  • The Blend2D and QPainter engines produce the same measured page geometry at the same zoom on the same display.
  • No entry point disables high-DPI scaling without a recorded reason.

Test strategy

  • Unit: scale-factor computation against synthetic QScreen geometries, including a two-screen configuration where primary and current differ, and a screen reporting zero physical size.
  • Integration: render a known-size fixture at 100% and assert the pixel extent equals the expected physical extent for a given DPI.
  • Manual, on the named reference device: physical-ruler check on primary and secondary displays, before and after calibration.

Dependencies

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions