Merge pull request #7632 from Snuffleupagus/more-efficient-expandTextDivs

[EnhanceTextSelection] Make `expandTextDivs` more efficient by updating all styles at once instead of piecewise
This commit is contained in:
Tim van der Meij 2016-09-15 16:01:07 +02:00 committed by GitHub
commit 26da2d57ce

View File

@ -59,14 +59,20 @@ var renderTextLayer = (function renderTextLayerClosure() {
return !NonWhitespaceRegexp.test(str); return !NonWhitespaceRegexp.test(str);
} }
// Text layers may contain many thousand div's, and using `styleBuf` avoids
// creating many intermediate strings when building their 'style' properties.
var styleBuf = ['left: ', 0, 'px; top: ', 0, 'px; font-size: ', 0,
'px; font-family: ', '', ';'];
function appendText(task, geom, styles) { function appendText(task, geom, styles) {
// Initialize all used properties to keep the caches monomorphic. // Initialize all used properties to keep the caches monomorphic.
var textDiv = document.createElement('div'); var textDiv = document.createElement('div');
var textDivProperties = { var textDivProperties = {
style: null,
angle: 0, angle: 0,
canvasWidth: 0, canvasWidth: 0,
isWhitespace: false, isWhitespace: false,
originalTransform: '', originalTransform: null,
paddingBottom: 0, paddingBottom: 0,
paddingLeft: 0, paddingLeft: 0,
paddingRight: 0, paddingRight: 0,
@ -104,10 +110,12 @@ var renderTextLayer = (function renderTextLayerClosure() {
left = tx[4] + (fontAscent * Math.sin(angle)); left = tx[4] + (fontAscent * Math.sin(angle));
top = tx[5] - (fontAscent * Math.cos(angle)); top = tx[5] - (fontAscent * Math.cos(angle));
} }
textDiv.style.left = left + 'px'; styleBuf[1] = left;
textDiv.style.top = top + 'px'; styleBuf[3] = top;
textDiv.style.fontSize = fontHeight + 'px'; styleBuf[5] = fontHeight;
textDiv.style.fontFamily = style.fontFamily; styleBuf[7] = style.fontFamily;
textDivProperties.style = styleBuf.join('');
textDiv.setAttribute('style', textDivProperties.style);
textDiv.textContent = geom.str; textDiv.textContent = geom.str;
// |fontName| is only used by the Font Inspector. This test will succeed // |fontName| is only used by the Font Inspector. This test will succeed
@ -517,7 +525,6 @@ var renderTextLayer = (function renderTextLayerClosure() {
this._renderTimer = null; this._renderTimer = null;
this._bounds = []; this._bounds = [];
this._enhanceTextSelection = !!enhanceTextSelection; this._enhanceTextSelection = !!enhanceTextSelection;
this._expanded = false;
} }
TextLayerRenderTask.prototype = { TextLayerRenderTask.prototype = {
get promise() { get promise() {
@ -555,18 +562,20 @@ var renderTextLayer = (function renderTextLayerClosure() {
if (!this._enhanceTextSelection || !this._renderingDone) { if (!this._enhanceTextSelection || !this._renderingDone) {
return; return;
} }
if (!this._expanded) { if (this._bounds !== null) {
expand(this); expand(this);
this._expanded = true; this._bounds = null;
this._bounds.length = 0;
} }
for (var i = 0, ii = this._textDivs.length; i < ii; i++) { for (var i = 0, ii = this._textDivs.length; i < ii; i++) {
var div = this._textDivs[i]; var div = this._textDivs[i];
var divProperties = this._textDivProperties.get(div); var divProperties = this._textDivProperties.get(div);
if (divProperties.isWhitespace) {
continue;
}
if (expandDivs) { if (expandDivs) {
var transform = ''; var transform = '', padding = '';
if (divProperties.scale !== 1) { if (divProperties.scale !== 1) {
transform = 'scaleX(' + divProperties.scale + ')'; transform = 'scaleX(' + divProperties.scale + ')';
@ -575,21 +584,26 @@ var renderTextLayer = (function renderTextLayerClosure() {
transform = 'rotate(' + divProperties.angle + 'deg) ' + transform; transform = 'rotate(' + divProperties.angle + 'deg) ' + transform;
} }
if (divProperties.paddingLeft !== 0) { if (divProperties.paddingLeft !== 0) {
div.style.paddingLeft = padding += ' padding-left: ' +
(divProperties.paddingLeft / divProperties.scale) + 'px'; (divProperties.paddingLeft / divProperties.scale) + 'px;';
transform += ' translateX(' + transform += ' translateX(' +
(-divProperties.paddingLeft / divProperties.scale) + 'px)'; (-divProperties.paddingLeft / divProperties.scale) + 'px)';
} }
if (divProperties.paddingTop !== 0) { if (divProperties.paddingTop !== 0) {
div.style.paddingTop = divProperties.paddingTop + 'px'; padding += ' padding-top: ' + divProperties.paddingTop + 'px;';
transform += ' translateY(' + (-divProperties.paddingTop) + 'px)'; transform += ' translateY(' + (-divProperties.paddingTop) + 'px)';
} }
if (divProperties.paddingRight !== 0) { if (divProperties.paddingRight !== 0) {
div.style.paddingRight = padding += ' padding-right: ' +
(divProperties.paddingRight / divProperties.scale) + 'px'; (divProperties.paddingRight / divProperties.scale) + 'px;';
} }
if (divProperties.paddingBottom !== 0) { if (divProperties.paddingBottom !== 0) {
div.style.paddingBottom = divProperties.paddingBottom + 'px'; padding += ' padding-bottom: ' +
divProperties.paddingBottom + 'px;';
}
if (padding !== '') {
div.setAttribute('style', divProperties.style + padding);
} }
if (transform !== '') { if (transform !== '') {
CustomStyle.setProp('transform', div, transform); CustomStyle.setProp('transform', div, transform);
@ -597,7 +611,7 @@ var renderTextLayer = (function renderTextLayerClosure() {
} else { } else {
div.style.padding = 0; div.style.padding = 0;
CustomStyle.setProp('transform', div, CustomStyle.setProp('transform', div,
divProperties.originalTransform); divProperties.originalTransform || '');
} }
} }
}, },