refactor(web): partial font-size logic rework

This commit is contained in:
jahorton 2021-07-14 14:54:54 +07:00
parent 0992909831
commit 4dc09ce9b9
5 changed files with 62 additions and 33 deletions

View file

@ -1,29 +1,42 @@
namespace com.keyman.osk {
export interface LengthStyle {
val: number,
absolute: boolean
absolute: boolean,
special?: 'em' | 'rem';
};
export class ParsedLengthStyle implements LengthStyle {
public readonly val: number;
public readonly absolute: boolean;
public readonly special: 'em' | 'rem';
public constructor(style: LengthStyle | string) {
if(typeof style == 'string') {
const parsed = ParsedLengthStyle.parseLengthStyle(style);
this.val = parsed.val;
this.absolute = parsed.absolute;
if(parsed.special) {
this.special = parsed.special;
}
} else {
this.val = style.val;
this.absolute = style.absolute;
if(style.special) {
this.special = style.special;
}
}
}
public get styleString(): string {
if(this.absolute) {
return this.val + 'px';
} else if(this.special) {
// Only 'em' and 'rem' are allowed, and both may be treated similarly.
// Both relate to font sizes, though the path to the reference element
// differs between them.
return this.val + this.special;
} else {
return this.absolute + '%';
return (this.val * 100) + '%';
}
}
@ -46,25 +59,31 @@ namespace com.keyman.osk {
return new ParsedLengthStyle({val: val, absolute: false});
}
private static parseLengthStyle(spec: string): {val: number, absolute: boolean} {
private static parseLengthStyle(spec: string): LengthStyle {
var val: number;
if(spec.indexOf('px') != -1) {
val = parseFloat(spec.substr(0, spec.indexOf('px')));
val = parseFloat(spec);
return {val: val, absolute: true};
} else if(spec.indexOf('pt') != -1) {
// 16 px ~= 12 pt.
// Reference: https://kyleschaeffer.com/css-font-size-em-vs-px-vs-pt-vs-percent
val = parseFloat(spec.substr(0, spec.indexOf('pt')));
val = parseFloat(spec);
return {val: (4 * val / 3), absolute: true};
} else if(spec.indexOf('%') != -1) {
val = parseFloat(spec.substr(0, spec.indexOf('%')));
val = parseFloat(spec);
return {val: val/100, absolute: false};
} else if(!isNaN(val = Number(spec))) {
// Note: this one is NOT natively handled by browsers!
// We'll treat it as if it were 'pt', since that's likely the user's
// most familiar font size unit.
return {val: (4 * val / 3), absolute: true};
} else if(spec.indexOf('rem') != -1) {
val = parseFloat(spec);
return {val: val, absolute: false, special: 'rem'};
} else if(spec.indexOf('em') != -1) {
val = parseFloat(spec);
return {val: val, absolute: false, special: 'em'};
} else {
// Cannot parse.
console.error("Could not properly parse specified length style info: '" + spec + "'.");

View file

@ -352,10 +352,10 @@ namespace com.keyman.osk {
objectUnits(vkbd: VisualKeyboard): string {
// Returns a unit string corresponding to how the width for each key is specified.
if(vkbd.device.formFactor == 'desktop' || vkbd.isStatic) {
return '%';
} else {
if(vkbd.usesFixedScaling) {
return 'px';
} else {
return '%';
}
}

View file

@ -155,25 +155,14 @@ namespace com.keyman.osk {
// Set scaling for mobile devices here.
if(device.touchable) {
var fontScale: number = 1;
if(device.formFactor == 'phone') {
fontScale = 1.6 * (keymanweb.isEmbedded ? 0.65 : 0.6) * 1.2; // Combines original scaling factor with one previously applied to the layer group.
} else {
// The following is a *temporary* fix for small format tablets, e.g. PendoPad
var pixelRatio = 1;
if(device.OS == 'Android' && 'devicePixelRatio' in window) {
pixelRatio = window.devicePixelRatio;
}
if(device.OS == 'Android' && device.formFactor == 'tablet' && this.getHeight() < 300 * pixelRatio) {
fontScale *= 1.2;
} else {
fontScale *= 2; //'2.5em';
}
}
let fontScale = this.defaultFontSize(device, keymanweb.isEmbedded);
// Finalize the font size parameter.
s.fontSize = fontScale + 'em';
if(fontScale.absolute) {
s.fontSize = fontScale.styleString;
} else {
s.fontSize = fontScale.val + 'em';
}
}
if(this.vkbd) {
@ -631,6 +620,32 @@ namespace com.keyman.osk {
return width;
}
public defaultFontSize(device: Device, isEmbedded: boolean): ParsedLengthStyle {
if(device.touchable) {
var fontScale: number = 1;
if(device.formFactor == 'phone') {
fontScale = 1.6 * (isEmbedded ? 0.65 : 0.6) * 1.2; // Combines original scaling factor with one previously applied to the layer group.
} else {
// The following is a *temporary* fix for small format tablets, e.g. PendoPad
var pixelRatio = 1;
if(device.OS == 'Android' && 'devicePixelRatio' in window) {
pixelRatio = window.devicePixelRatio;
}
if(device.OS == 'Android' && device.formFactor == 'tablet' && this.getHeight() < 300 * pixelRatio) {
fontScale *= 1.2;
} else {
fontScale *= 2; //'2.5em';
}
}
// Finalize the font size parameter.
return ParsedLengthStyle.forScalar(fontScale);
} else {
return this.computedHeight ? ParsedLengthStyle.inPixels(this.computedHeight / 8) : undefined;
}
}
/**
* Allow UI to update OSK position and properties
*

View file

@ -13,11 +13,6 @@ namespace com.keyman.osk {
}
}
if(fs.indexOf('em') != -1) {
const val = parseFloat(fs);
return ParsedLengthStyle.forScalar(val);
} else {
return new ParsedLengthStyle(fs);
}
return new ParsedLengthStyle(fs);
}
}

View file

@ -204,7 +204,7 @@ namespace com.keyman.osk {
* based scaling.
*/
public get usesFixedScaling(): boolean {
return this.device.touchable;
return this.device.touchable && !this.isStatic;
}
/**