diff --git a/web/source/osk/lengthStyle.ts b/web/source/osk/lengthStyle.ts index 732b6f3745..16c5c5a790 100644 --- a/web/source/osk/lengthStyle.ts +++ b/web/source/osk/lengthStyle.ts @@ -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 + "'."); diff --git a/web/source/osk/oskKey.ts b/web/source/osk/oskKey.ts index 71cad5132e..c547629018 100644 --- a/web/source/osk/oskKey.ts +++ b/web/source/osk/oskKey.ts @@ -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 '%'; } } diff --git a/web/source/osk/oskManager.ts b/web/source/osk/oskManager.ts index 8b0c2c2a69..97f21e5a38 100644 --- a/web/source/osk/oskManager.ts +++ b/web/source/osk/oskManager.ts @@ -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 * diff --git a/web/source/osk/utils.ts b/web/source/osk/utils.ts index 2fc82be848..1e3a622eff 100644 --- a/web/source/osk/utils.ts +++ b/web/source/osk/utils.ts @@ -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); } } \ No newline at end of file diff --git a/web/source/osk/visualKeyboard.ts b/web/source/osk/visualKeyboard.ts index ff63400d46..07ebcc6b8c 100644 --- a/web/source/osk/visualKeyboard.ts +++ b/web/source/osk/visualKeyboard.ts @@ -204,7 +204,7 @@ namespace com.keyman.osk { * based scaling. */ public get usesFixedScaling(): boolean { - return this.device.touchable; + return this.device.touchable && !this.isStatic; } /**