barmalei / zebkit

JavaScript library that follows easy OOP concept, provides HTML5 Canvas based Rich UI and includes Java to JavaScript converter tool
Apache License 2.0
931 stars 177 forks source link

ui.Lable and grid cells and captions alignment is changed in latest chrome #175

Open vasu-vvp opened 5 years ago

vasu-vvp commented 5 years ago

In latest update of google chrome alignment of labels, grid cells and captions is changed. How to fix this ? Latest Google chrome version image

Take a look at example available on zebkit.org.

image

almercier commented 5 years ago

@barmalei I have seen this in Firefox forever now. We have since added code in our copy of zebra.js StringRender paint() method that explicitly checks for FF and shifts the text down 3 pixels. Did something change and now that is required for google chrome as well? Any idea why that is required or what caused this? This is causing our entire application to look really strange.

Some examples with a centered label in a panel, plus text centered in a zebra.ui.Button

updated Chrome (left) x Safari (right). Notice labels are slightly above center of their containers. screen shot 2018-12-18 at 2 49 26 pm screen shot 2018-12-18 at 2 50 00 pm

This is also noticeable on all examples on the zebkit.org website

almercier commented 5 years ago

@barmalei @vasu-vvp See this chromium bug report. This is what caused this issue. https://bugs.chromium.org/p/chromium/issues/detail?id=607053 It seems like chrome fixed the "TOP" textBaseline to correctly paint text at the top based on the font size in fillText, while it appears as though zebra/zebkit is relying on that issue to happen.

I have a simple jsfiddle that demonstrates this easily. You can test by running it on a new and old version of chrome, or a new version of chrome and safari/edge/IE. https://jsfiddle.net/Mercieral/hyrgqkox/23/ You will notice the text is rendered at the true top on FF/New Chrome, and shifted ~3 pixels down on any other browsers (older chrome, safari, edge, etc)

barmalei commented 5 years ago

Thanks. Probably you are right, Chrome starts applying correct text alignment for fillText(...) method + "top" base line alignment. The problem Safari and IE still have the bug :) I have just added fast fix that switches zebkit to "middle" text base line usage instead of "top" (actually zebkit did it for FF). It seems "middle" works for all browsers.

vasu-vvp commented 5 years ago

@barmalei, Still the labels are not at the center. I have tested it latest updated code of zebkit in my application. Also take a look at the top captions of grid on zebkit.org

image

vasu-vvp commented 5 years ago

@almercier , "shifting 3 pixels down" does not works as expected when we increase font size. For the now I have fixed this by shifting ( font height - font ascent ) in my custom renderer

almercier commented 5 years ago

@vasu-vvp Yes, I am seeing that while playing around with font sizes now.

FYI @barmalei : Here's one option (bit of a hack) to dynamically determine if a shift is needed or not, rather than relying on browser and browser version. I wanted to use CanvasRenderingContext2D.measureText() "textMetrics" which would be much cleaner but the needed properties are experimental and not globally supported ☹️

// Create a canvas with a simple 40px "T" character to test 
let canvas = document.createElement('canvas');
canvas.width = "10";
canvas.height = "20";
let g = canvas.getContext('2d');
g.textBaseline = "top";
g.font = "40px Arial";
g.fillText("T", 0, 0);

// Get Image Data and parse down the center to find distance to first black pixel.
let imgData = g.getImageData(0, 0, canvas.width, canvas.height);
let gap = 0;
for (let i = Math.round(canvas.width / 2) * 4; i < imgData.data.length; i = i + (canvas.width * 4)) {
    gap += 1;
  if (imgData.data[i+3] > 200) {
    // found a black(ish) pixel, stop calculating
    break;
  }
}

// Add the label detailing the findings.
// NOTE: gap should be around 3px for fixed browsers, and around 8px for unfixed browsers
let label = document.createElement('h1');
label.innerText = `Top gap is ${gap} pixels...\n\n ${(gap > 5) ? 'Issue not fixed yet: Do not apply any shifts' : 'Issue was fixed: Needs shifted!'}`
document.body.appendChild(label);
barmalei commented 5 years ago

@vasu-vvp I would say switching zebkit to "middle" text base line works slightly differently in various browsers, but more or less correctly in general. Take the screenshots below that demonstrate usage "middle" alignment:

Latest chrome (71.0.3578.98): image

FireFox: image

Safari: image

To better see how vertical alignment works you should increase height of grid cells/header rows and use text that contains character with none-zero descent (for instance "g", "y", etc).

One more option to fix the problem that probably can work better (because of more unified browsers support) is using "bottom" base text alignment. I have uploaded the variants as zebkit sandbox version http://zebkit.org/ver/sandbox/zebkit.js, it seems it works like prev. version of chrome.

Could anybody try the sandbox fix ?

vasu-vvp commented 5 years ago

Tested with http://zebkit.org/ver/sandbox/zebkit.js It seems to be in centre in when tested with the grid. But values are not exactly in centre of the cell. We can observe the exact difference when tested with the labels and drop downs. Value are slightly moved to down and are not in exact centre position in Google chrome, Where as on firefox this moved to bottom completely.

barmalei commented 5 years ago

@vasu-vvp Not clear, in my case everything is ok in chrome. Could you comment it with screen shot example ?