Skip to content

Unicode rendering is incorrectly scaled by min / max #77

@joshka

Description

@joshka

The documentation for Renderer::min_dimensions states:

Sets the minimum total image size in pixels, including the quiet zone if applicable. The renderer will try to find the dimension as small as possible, such that each module in the QR code has uniform size (no distortion).

For instance, a version 1 QR code has 19 modules across including the quiet zone. If we request an image of size ≥200×200, we get that each module’s size should be 11×11, so the actual image size will be 209×209.

Renderer::max_dimensions states:

Sets the maximum total image size in pixels, including the quiet zone if applicable. The renderer will try to find the dimension as large as possible, such that each module in the QR code has uniform size (no distortion).

For instance, a version 1 QR code has 19 modules across including the quiet zone. If we request an image of size ≤200×200, we get that each module’s size should be 10×10, so the actual image size will be 190×190.

The module size is at least 1×1, so if the restriction is too small, the final image can be larger than the input.

When rendering using the unicode approach, the behavior is to treat each string character as 2 blocks arranged vertically. This is fine and expected because most terminals render characters with approximately a 1x2 ratio. What's unexpected is that the scaling distorts the modules so that they are scaled only in one dimension. E.g. rendering QrCode::new("") without a quiet zone with min_dimensions that is 21x12 gives:

███████  ██ █ ███████
█     █    ██ █     █
█ ███ █ ███ █ █ ███ █
█ ███ █ █     █ ███ █
█ ███ █ ██  █ █ ███ █
█     █ ████  █     █
███████ █ █ █ ███████
        ██           
█ █████  ███  █████  
   █ █ █  █████  █ █ 
      ████  █ ██     

It should give:

██████████████    ████
██          ██        
██  ██████  ██  ██████
██  ██████  ██  ██    
██  ██████  ██  ████  
██          ██  ██████
██████████████  ██  ██
████  
██  ██████████    ████
██  ██  ██    ██
████████  
██████        ████  ██

See https://github.com/joshka/tui-widgets/blob/main/tui-qrcode/src/lib.rs#L504 for some unit tests that show the problem visually when using this as a Ratatui widget.

An expected fix for this would be to ensure that the width and height will be clamped to the max / min (depending on the function) of each other and the aspect ratio remains square-ish. There was an unresolved comment in the initial PR that introduced this at #42 (comment) (cc @cab404)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions