Closed Bug 1319870 Opened 8 years ago Closed 8 years ago

HiDPI (dppx > 1.1) scales -moz-image-region incorrectly

Categories

(Core :: Layout, defect)

defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: jaws, Unassigned)

References

Details

Attachments

(1 file)

STR:
In about:config set layout.devPixelsPerPx is 1.5 (ensure HiDPI rendering)
Save the attached SVG file locally
Open the browser toolbox's Inspector
Select the Home button on the toolbar (#home-button)
On the right-side, switch to the Computed View
See that the button has a computed width of 32x28
Switch to the Rules view
Add the following two rules to the 'element' selector:
  list-style-image: url(<path-to-locally-saved-svg-file>);
  -moz-image-region: rect(0, 18px, 18px, 0);
Hover your mouse over the #home-button in the Tree view to invalidate the rendering
Switch to the Computed View

Expected results:
The width of the button should still be 32x28

Actual results:
The width of the button is 31.333x28
Attached image 1f923.svg
Daniel, do you know who could help look in to this? This showed up in the new Theme work we're doing in bug 1306671.
Component: WebExtensions: General → Layout
Flags: needinfo?(dholbert)
Product: Toolkit → Core
A few notes:
 - For me (on Linux), the button is shown as 30px tall (not 28px tall).  My results do match yours for the width, though (32 and then 31.3333).
 - To trigger this behavior, technically you don't need to bother downloading the SVG or setting "list-style-image".  Just the "-moz-image-region: rect(0, 18px, 18px, 0)" style on is own is sufficient to trigger the 31.3333 value.
 - On my machine, this seems to happen for *any* fractional HiDPI setting, but not for any whole-number HiDPI settings:
  layout.devPixelsPerPx  Reported width
  =====================  ==============
                  unset  32
                  1.25   31.6
                  1.5    31.3333
                  2      32
                  2.9    31.4
                  3      32
                  3.1    31.9
Thank you, I can confirm that I am running with 150% display scaling. The 30px tall vs 28px tall is just a minor difference in the theme between Linux and Windows I believe.
OK -- so these styles are actually correct (i.e. they're accurate representations of the width).

The problem here is actually here -- we've got this border around the image inside of the button:
>   border: 1px solid transparent;
https://dxr.mozilla.org/mozilla-central/rev/0ddfec7126ec503b54df9c4b7c3b988906f6c882/browser/themes/linux/browser.css#373-380

We pixel-snap borders to display pixels, so this border ends up being a fractional number of CSS pixels in width.  This means the button (which shrinkwraps its contents, including this border around the image) also ends up being a fractional number of CSS pixels wide.

If we can get rid of that border, the problem should go away.
Flags: needinfo?(dholbert)
This border only presents a problem if you explicitly add the styling:
  -moz-image-region: rect(0, 18px, 18px, 0);

...because otherwise, you get our native HiDPI settings, which e.g. for me includes:
   -moz-image-region: rect(0, 252px, 36px, 216px);

...and that is a wider image (36px wide) which (combined with the fractional border) surpasses a separate "max-width: 32px" declaration.  So that "max-width"/large-image-region combination is why we end up with 32px in Nightly right now, when you have fractional HiDPI settings.
So basically, what's going on here is:
  * The button gets sized to image-region + image-padding + image-border.
  * There's 12px of horizontal padding (6px on each side), and 2px of horizontal border (1px on each side)
  * So, you'd rightly expect that with an 18px-wide image, you'd end up with 18px + 12px + 2px = 32px wide image.

  * BUT: the 2px of border gets pixel-snapped -- so it's not actually 2 CSS pixels wide.  It's 2/3 of a CSS pixel wide, which is 1 dev pixel wide.  So really, our button is 18px + 12px + 2/3px + 2/3px = 31.3333 CSS pixels wide.

  * If you use a larger -moz-image-region (as we do in current Nightly with a "@min-resolution: 1.1dppx" media query), then we end up instead with 36px + 12px + 2/3px + 2/3px = 49.3333px.  But that gets clamped by "max-width" to exactly 32px.  So that's why you only see this problem if you provide a -moz-image-region of 18px wide or smaller. Anything larger will push the button-width over 32px and get clamped.
So this is INVALID as a gecko bug, I think.  (To the extent that there's a problem here, it's that borders are device-pixel-snapped, and that's not something that's likely to change because it's important for nice crisp rendering.)

Please let me know if anything here doesn't make sense.
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → INVALID
Thanks, this is a great explanation! I filed bug 1320077 for us to use HiDPI sizes with -moz-image-region when > 1.1dppx so that WebExtension themes match the implementation behavior of our default theme.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: