@syncfusion/ej2-documenteditor
Version:
Feature-rich document editor control with built-in support for context menu, options pane and dialogs.
123 lines (122 loc) • 5.88 kB
JavaScript
import { isNullOrUndefined, createElement, updateCSSText } from '@syncfusion/ej2-base';
/**
* Class which performs optimized text measuring logic to find font height.
*/
var Optimized = /** @class */ (function () {
/**
* Constructor to initialize Optimized module.
*
* @param {DocumentHelper} documentHelper - the document helper object.
*/
function Optimized(documentHelper) {
this.documentHelper = documentHelper;
this.optimizedHeightCollection = {};
}
Optimized.prototype.getModuleName = function () {
return 'Optimized';
};
/**
* Construct key based on the character format.
*
* @param {WCharacterFormat} characterFormat - the character format to construct key.
* @returns {string} - the constructed key.
*/
Optimized.prototype.getkeyFromCharFormat = function (characterFormat) {
var formatText = characterFormat.fontFamily.toLocaleLowerCase();
if (characterFormat.bold) {
formatText += ';' + 'bold';
}
if (characterFormat.italic) {
formatText += ';' + 'italic';
}
return formatText;
};
/**
* Method to retrieve font information with optimized text measuring logic.
*
* @param {WCharacterFormat} characterFormat -character format to apply.
* @returns {string} - returns font size information.
*/
Optimized.prototype.getFontInfo = function (characterFormat) {
var iframe = createElement('iframe');
document.body.appendChild(iframe);
var innerHtml = '<!DOCTYPE html>'
+ '<html><head></head>'
+ '<body>'
+ '</body>'
+ '</html>';
var externalFonts = this.documentHelper.owner.externalFonts;
if (externalFonts && externalFonts.length > 0) {
externalFonts.forEach(function (externalFont) {
if (externalFont.src) {
innerHtml += '<style>@font-face {font-family: \'' + externalFont.fontFamily + '\'; src: ' + externalFont.src + '; }</style>';
}
});
}
if (!isNullOrUndefined(iframe.contentDocument)) {
iframe.contentDocument.open();
iframe.contentDocument.write(innerHtml);
iframe.contentDocument.close();
}
var container = document.createElement('div');
var cssText = 'position:absolute;top:-1000px;left:-1000px;opacity:0;font-size:0px;line-height:normal';
updateCSSText(container, cssText);
// constant tested height value for calculating height factor which matches 90% accuracy with GDI+ value.
var maxFontHeight = 288;
var factor = 1.0 / window.devicePixelRatio;
container.style.transform = 'scale(' + factor.toString() + ',' + factor.toString() + ')';
/* eslint-disable-next-line max-len */
container.innerHTML = '';
var baselineReferenceSpan = document.createElement('span');
baselineReferenceSpan.className = 'e-de-font-info';
baselineReferenceSpan.style.cssText = 'font-size: 0; font-family: ' + ("'" + characterFormat.fontFamily + "'") + '; display: inline-block;';
baselineReferenceSpan.textContent = 'm';
var fontMeasurementSpan = document.createElement('span');
fontMeasurementSpan.className = 'e-de-font-info';
fontMeasurementSpan.style.cssText = 'font-size: ' + maxFontHeight + 'pt; ' +
'font-family: ' + ("'" + characterFormat.fontFamily + "'") + '; ' +
(characterFormat.bold ? 'font-weight: bold; ' : '') +
(characterFormat.italic ? 'font-style: italic; ' : '') +
'display: inline-block;';
fontMeasurementSpan.textContent = 'm';
container.appendChild(baselineReferenceSpan);
container.appendChild(fontMeasurementSpan);
iframe.contentDocument.body.appendChild(container);
/* eslint-disable-next-line max-len */
var baseLineFactor = container.firstChild.offsetTop / container.lastChild.offsetHeight;
var heightFactor = parseFloat((container.lastChild.offsetHeight / maxFontHeight).toFixed(2));
document.body.removeChild(iframe);
return { HeightFactor: heightFactor, BaselineFactor: baseLineFactor };
};
/**
* @private
* @param {WCharacterFormat} characterFormat - character format to apply.
* @returns {TextSizeInfo} returns text size information.
*/
Optimized.prototype.getHeightInternal = function (characterFormat) {
var key = this.getkeyFromCharFormat(characterFormat);
//With optimized technique, height and baseline factor will be same for each font-family, hence we maintaining cache for the factors and updating height based on font size.
var isBidi = characterFormat.bidi || characterFormat.complexScript;
if (isNullOrUndefined(this.optimizedHeightCollection["" + key])) {
var fontInfo = this.getFontInfo(characterFormat);
this.optimizedHeightCollection["" + key] = fontInfo;
var fontHeight = fontInfo.HeightFactor * (isBidi ? characterFormat.fontSizeBidi : characterFormat.fontSize);
return { Height: fontHeight, BaselineOffset: fontInfo.BaselineFactor * fontHeight };
}
else {
var fontSizeInfo = this.optimizedHeightCollection["" + key];
var fontHeight = fontSizeInfo.HeightFactor * (isBidi ? characterFormat.fontSizeBidi : characterFormat.fontSize);
return { Height: fontHeight, BaselineOffset: fontSizeInfo.BaselineFactor * fontHeight };
}
};
/**
* @private
* @returns {void}
*/
Optimized.prototype.destroy = function () {
this.documentHelper = undefined;
this.optimizedHeightCollection = undefined;
};
return Optimized;
}());
export { Optimized };