Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross-browser shield text #1010

Merged
merged 19 commits into from
Jan 12, 2024
Merged

Cross-browser shield text #1010

merged 19 commits into from
Jan 12, 2024

Conversation

ZeLonewolf
Copy link
Member

@ZeLonewolf ZeLonewolf commented Dec 19, 2023

Fixes #625

This PR fixes differences between chrome and webkit by using fudge factors.

It also fixes several "I don't know how this even worked before" bugs in the banner layout code, and does some related typescript cleanup in the affected routines.

They are not pixel-perfect between browsers but they're very close. Tested on Ubuntu.

Webkit
image

Chrome
image

Firefox
image

@ZeLonewolf ZeLonewolf marked this pull request as ready for review December 19, 2023 04:35
top: r.options.bannerPadding,
top: 0,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed because the padding is accomplished by placing a gap between successive layouts, not by buffering the layout itself.

bannerIndex * r.px(r.options.bannerHeight - r.options.bannerPadding)
bannerIndex * r.px(r.options.bannerHeight + r.options.bannerPadding)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even sure how this code worked with this bug.

Comment on lines -175 to +201
var textWidth = metrics.width;
var textHeight = metrics.actualBoundingBoxDescent;
let textWidth: number =
Math.abs(metrics.actualBoundingBoxLeft) +
Math.abs(metrics.actualBoundingBoxRight);
let textHeight: number =
Math.abs(metrics.actualBoundingBoxDescent) +
Math.abs(metrics.actualBoundingBoxAscent);

var availHeight = bounds.height - padTop - padBot;
var availWidth = bounds.width - padLeft - padRight;
//Adjust for excess descender text height across browsers
textHeight *= 0.9;

var xBaseline = padLeft + availWidth / 2;
//Adjust for excess text height measured in Webkit engine specifically
if (isRunningInWebKit()) {
textHeight *= 0.54;
}

let availHeight: number = bounds.height - padTop - padBot;
let availWidth: number = bounds.width - padLeft - padRight;

let xBaseline: number = padLeft + availWidth / 2;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the main fix. We check both ascent/descent and left/right to get height/width, and then we make empirical adjustments to account for how the different browsers actually handle these fonts.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me wonder if WebKit is reporting the full line height as the computer text height.

Comment on lines -185 to +210
let textConstraint = textLayoutFunc(
{ height: availHeight, width: availWidth },
{ height: textHeight, width: textWidth },
let spaceAvail: Dimension = { height: availHeight, width: availWidth };
let measuredTextBounds: Dimension = { height: textHeight, width: textWidth };

let textConstraint: TextTransform = textLayoutFunc(
spaceAvail,
measuredTextBounds,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a nicety to add typescript typing and make it clear what's happening.

Comment on lines +221 to 222
ctx.textAlign = "left";
ctx.textBaseline = "top";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

top/left makes the positioning math a bit easier and more consistent.

@zekefarwell
Copy link
Collaborator

zekefarwell commented Dec 19, 2023

I tested this out on Mac OS 13, Windows 11, iOS 17, and Android 14. Looks quite consistent across all the browsers I tested! Examples of the interstate shield only for a focused comparison:

Windows-Chrome
Chrome on Windows

Mac-Chrome
Chrome on Mac

Android-Chrome
Chrome on Android

Mac-Safari
Safari on Mac

iOS-Safari
Safari on iOS

Windows-FF
Firefox on Windows

Mac-FF
Firefox on Mac

Android-FF
Firefox on Android

Definitely some vertical padding adjustment needed for this and other shields, but that can probably be a follow up PR. Another issue I'm seeing is Chrome on Windows getting the wide shield blank for 2 digit refs. On the plus side, Safari and Firefox on Windows get the narrow shield blank for 111.

@ZeLonewolf
Copy link
Member Author

Definitely some vertical padding adjustment needed for this and other shields, but that can probably be a follow up PR. Another issue I'm seeing is Chrome on Windows getting the wide shield blank for 2 digit refs. On the plus side, Safari and Firefox on Windows get the narrow shield blank for 111.

It looks like that only happens for the slightly wider 2-digit numbers, so I suspect I can just micro-adjust that threshold and achieve the intended effect.

@ZeLonewolf
Copy link
Member Author

Reducing the threshold from 12 to 11.8 seems to be enough for the right 2-digit to 3-digit transition on Windows/Chrome.

@ZeLonewolf ZeLonewolf requested review from claysmalley and zekefarwell and removed request for claysmalley December 20, 2023 02:03
@claysmalley claysmalley added enhancement New feature or request shield-generator Issues specific to the shield library labels Dec 20, 2023
@zekefarwell
Copy link
Collaborator

zekefarwell commented Dec 21, 2023

Reducing the threshold from 12 to 11.8 seems to be enough for the right 2-digit to 3-digit transition on Windows/Chrome

Looks like it. I can no longer reproduce. 👍

I noticed a couple of regressions that it may may be nice to resolve before merging this. The banner text is larger on this branch than on main. Also in some cases the banner text size changes between the narrow and wide variants of a certain shield.

banner-text-PR-1010

This PR

banner-text-main

Main branch

Some shields have a thicker top border on this branch that isn't present on main. I'm only seeing this issue on (some) bannered shields so it may be related to the banner text somehow.

thick-border-PR-1010

This PR

thick-border-main

Main Branch

@claysmalley
Copy link
Member

Some shields have a thicker top border on this branch that isn't present on main. I'm only seeing this issue on (some) bannered shields so it may be related to the banner text somehow.

This appears to be affecting shields generated by draw functions. SVG shields look okay.

@claysmalley claysmalley removed the enhancement New feature or request label Dec 21, 2023
@claysmalley claysmalley added the bug Something isn't working label Dec 21, 2023
@ZeLonewolf
Copy link
Member Author

ZeLonewolf commented Dec 22, 2023

755117b fixes the weirdness we were seeing with some shields. I simplified the code that draws shields when banners are present and removed an extra draw that wasn't supposed to be there.

Copy link
Member

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks better than before in MobileSafari:

Safari

Comment on lines -175 to +201
var textWidth = metrics.width;
var textHeight = metrics.actualBoundingBoxDescent;
let textWidth: number =
Math.abs(metrics.actualBoundingBoxLeft) +
Math.abs(metrics.actualBoundingBoxRight);
let textHeight: number =
Math.abs(metrics.actualBoundingBoxDescent) +
Math.abs(metrics.actualBoundingBoxAscent);

var availHeight = bounds.height - padTop - padBot;
var availWidth = bounds.width - padLeft - padRight;
//Adjust for excess descender text height across browsers
textHeight *= 0.9;

var xBaseline = padLeft + availWidth / 2;
//Adjust for excess text height measured in Webkit engine specifically
if (isRunningInWebKit()) {
textHeight *= 0.54;
}

let availHeight: number = bounds.height - padTop - padBot;
let availWidth: number = bounds.width - padLeft - padRight;

let xBaseline: number = padLeft + availWidth / 2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me wonder if WebKit is reporting the full line height as the computer text height.

@ZeLonewolf ZeLonewolf merged commit 71c9d4c into main Jan 12, 2024
6 checks passed
@ZeLonewolf ZeLonewolf deleted the zlw-shield-text-sizing branch January 12, 2024 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working shield-generator Issues specific to the shield library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Shield labels don't fit properly with Safari
4 participants