diff --git a/packages/ui/resolution/ResolutionDecorator.js b/packages/ui/resolution/ResolutionDecorator.js
index ee2854e85a..461dc94ddf 100644
--- a/packages/ui/resolution/ResolutionDecorator.js
+++ b/packages/ui/resolution/ResolutionDecorator.js
@@ -9,7 +9,15 @@ import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import hoc from '@enact/core/hoc';
-import {init, config as riConfig, defineScreenTypes, getResolutionClasses} from './resolution';
+import {
+ init,
+ calculateFontSize,
+ config as riConfig,
+ defineScreenTypes,
+ getResolutionClasses,
+ updateBaseFontSize,
+ updateScreenScale
+} from './resolution';
/**
* Default config for `ResolutionDecorator`.
@@ -97,13 +105,29 @@ const ResolutionDecorator = hoc(defaultConfig, (config, Wrapped) => {
static displayName = 'ResolutionDecorator';
static propTypes = /** @lends ui/resolution.ResolutionDecorator.prototype */ {
- className: PropTypes.string
+ className: PropTypes.string,
+
+ /**
+ * Screen Scale value for the large screen mode.
+ * Use this value to set the scale of the base font.
+ * This is the value that will be multiplied by pxPerRem, which is determined by the resolution.
+ *
+ * @type {Number}
+ * @default 1
+ * @public
+ */
+ screenScale: PropTypes.number
+ };
+
+ static defaultProps = {
+ screenScale: 1
};
constructor (props) {
super(props);
riConfig.intermediateScreenHandling = config.intermediateScreenHandling;
riConfig.matchSmallerScreenType = config.matchSmallerScreenType;
+ updateScreenScale(this.props.screenScale);
init({measurementNode: (typeof window !== 'undefined' && window)});
this.state = {
resolutionClasses: ''
@@ -116,6 +140,10 @@ const ResolutionDecorator = hoc(defaultConfig, (config, Wrapped) => {
this.rootNode = ReactDOM.findDOMNode(this);
}
+ componentDidUpdate (prevProps) {
+ if (prevProps.screenScale !== this.props.screenScale) updateBaseFontSize(calculateFontSize());
+ }
+
componentWillUnmount () {
if (config.dynamic) window.removeEventListener('resize', this.handleResize);
}
@@ -145,11 +173,17 @@ const ResolutionDecorator = hoc(defaultConfig, (config, Wrapped) => {
}
render () {
+ const {...rest} = this.props;
+
+ delete rest.screenScale;
+
+ if (this.props.screenScale) updateScreenScale(this.props.screenScale);
+
// Check if the classes are different from our previous classes
let classes = getResolutionClasses();
if (this.props.className) classes += (classes ? ' ' : '') + this.props.className;
- return ;
+ return ;
}
};
});
diff --git a/packages/ui/resolution/resolution.js b/packages/ui/resolution/resolution.js
index 4028498a1b..447ade288f 100644
--- a/packages/ui/resolution/resolution.js
+++ b/packages/ui/resolution/resolution.js
@@ -1,6 +1,7 @@
let baseScreen,
orientation,
riRatio,
+ screenScale = 1,
screenType,
workspaceBounds = {
width: (typeof window === 'object') ? window.innerWidth : 1920,
@@ -201,11 +202,11 @@ function calculateFontSize (type) {
let size;
if (orientation === 'portrait' && config.orientationHandling === 'scale') {
- size = scrObj.height / scrObj.width * scrObj.pxPerRem;
+ size = scrObj.height / (scrObj.width * scrObj.pxPerRem * screenScale);
} else {
- size = scrObj.pxPerRem;
+ size = scrObj.pxPerRem * screenScale;
if (orientation === 'landscape' && shouldScaleFontSize) {
- size = parseInt(workspaceBounds.height * scrObj.pxPerRem / scrObj.height);
+ size = parseInt(workspaceBounds.height * scrObj.pxPerRem * screenScale / scrObj.height);
}
}
return size + 'px';
@@ -224,6 +225,17 @@ function updateBaseFontSize (size) {
}
}
+/**
+ * @function
+ * @memberof ui/resolution
+ * @param {Number} screenScaleValue A value that adjusts the screen scaling.
+ * @returns {undefined}
+ * @private
+ */
+function updateScreenScale (screenScaleValue) {
+ screenScale = screenScaleValue;
+}
+
/**
* Returns the CSS classes for the given `type`.
*
@@ -332,7 +344,7 @@ function getAspectRatioName (type) {
* @public
*/
function scale (px) {
- return (riRatio || getRiRatio()) * px;
+ return (riRatio || getRiRatio()) * px * screenScale;
}
/**
@@ -366,7 +378,7 @@ function unit (pixels, toUnit) {
if (typeof pixels === 'string' && pixels.substr(-2) === 'px') pixels = parseInt(pixels.substr(0, pixels.length - 2));
if (typeof pixels !== 'number') return;
- return (pixels / unitToPixelFactors[toUnit]) + '' + toUnit;
+ return (pixels / (screenScale * unitToPixelFactors[toUnit])) + '' + toUnit;
}
/**
@@ -494,5 +506,8 @@ export {
scaleToRem,
selectSrc,
unit,
- unitToPixelFactors
+ unitToPixelFactors,
+ updateBaseFontSize,
+ updateScreenScale,
+ updateWorkspaceBounds
};
diff --git a/packages/ui/resolution/tests/ResolutionDecorator-specs.js b/packages/ui/resolution/tests/ResolutionDecorator-specs.js
index 99e46d0284..8fa8fcb745 100644
--- a/packages/ui/resolution/tests/ResolutionDecorator-specs.js
+++ b/packages/ui/resolution/tests/ResolutionDecorator-specs.js
@@ -1,6 +1,7 @@
import '@testing-library/jest-dom';
import {render, screen} from '@testing-library/react';
+import {updateBaseFontSize, calculateFontSize} from '../resolution';
import ResolutionDecorator from '../ResolutionDecorator';
describe('ResolutionDecorator Specs', () => {
@@ -28,6 +29,23 @@ describe('ResolutionDecorator Specs', () => {
expect(div).toHaveClass('enact-res-mhd');
});
+ test('should change the base font size when screenScale prop changed', () => {
+ const before = 1;
+
+ const Component = ResolutionDecorator('div');
+ const {rerender} = render();
+ const after = 2;
+ rerender(
+
+ );
+
+ updateBaseFontSize(calculateFontSize());
+ const value = document.documentElement.style.fontSize;
+ const expected = '72px';
+
+ expect(value).toBe(expected);
+ });
+
test.skip('should update the resolution when the screen is resized', function () {
// TODO: write a test
});
diff --git a/packages/ui/resolution/tests/resolution-specs.js b/packages/ui/resolution/tests/resolution-specs.js
index 4ac795c450..4d5b90ddb2 100644
--- a/packages/ui/resolution/tests/resolution-specs.js
+++ b/packages/ui/resolution/tests/resolution-specs.js
@@ -3,8 +3,10 @@ import {
config,
defineScreenTypes,
getScreenType,
+ getScreenTypeObject,
scale,
- unit
+ unit,
+ updateWorkspaceBounds
} from '../resolution.js';
describe('Resolution Specs', () => {
@@ -272,6 +274,41 @@ describe('Resolution Specs', () => {
expect(actualHD).toBe(expectedHD);
});
+ test('should calculate font size when orientation is landscape and shouldScaleFontSize value is true', () => {
+ config.intermediateScreenHandling = 'scale';
+ config.matchSmallerScreenType = true;
+
+ window.innerWidth = 1920;
+ window.innerHeight = 1080;
+
+ // update workspaceBounds
+ updateWorkspaceBounds(window);
+ // update orientation
+ getScreenType();
+ const size = calculateFontSize();
+ const expected = '18px';
+
+ expect(size).toBe(expected);
+
+ // clear window inner size
+ window.innerWidth = 640;
+ window.innerHeight = 480;
+ });
+
+ test('should calculate font size when orientation is portrait and config.orientationHandling is scale', () => {
+ config.orientationHandling = 'scale';
+ const fhdPortrait = {width: 1080, height: 1920};
+ getScreenType(fhdPortrait);
+
+ const size = calculateFontSize();
+ const scrObj = getScreenTypeObject();
+ const screenScale = 1;
+ const expected = scrObj.height / (scrObj.width * scrObj.pxPerRem * screenScale) + 'px';
+
+ expect(size).toBe(expected);
+
+ });
+
// NOTE: Currently tough to test selectSrc because it relies on a global variable for screenType
test.skip('should select source for the current screen type', function () {