Move drawText along line to executor

This commit is contained in:
Guillaume Beraudo
2018-11-14 18:20:38 +01:00
parent 0ece0fb002
commit c0df61468f
2 changed files with 35 additions and 33 deletions
+31 -7
View File
@@ -22,7 +22,7 @@ import {
import {createCanvasContext2D} from '../../dom.js'; import {createCanvasContext2D} from '../../dom.js';
import {labelCache, defaultTextAlign, measureTextHeight, measureTextWidths} from '../canvas.js'; import {labelCache, defaultTextAlign, measureTextHeight, measureTextWidth, measureTextWidths} from '../canvas.js';
/** /**
@@ -206,6 +206,14 @@ class CanvasInstructionsExecutor {
* @type {!Object<string, import("../canvas.js").TextState>} * @type {!Object<string, import("../canvas.js").TextState>}
*/ */
this.textStates = {}; this.textStates = {};
// Adaptations
/**
* @private
* @type {Object<string, Object<string, number>>}
*/
this.widths_ = {};
} }
@@ -697,19 +705,35 @@ class CanvasInstructionsExecutor {
const overflow = /** @type {number} */ (instruction[5]); const overflow = /** @type {number} */ (instruction[5]);
const fillKey = /** @type {string} */ (instruction[6]); const fillKey = /** @type {string} */ (instruction[6]);
const maxAngle = /** @type {number} */ (instruction[7]); const maxAngle = /** @type {number} */ (instruction[7]);
const measure = /** @type {function(string):number} */ (instruction[8]); const measurePixelRatio = /** @type {number} */ (instruction[8]);
const offsetY = /** @type {number} */ (instruction[9]); const offsetY = /** @type {number} */ (instruction[9]);
const strokeKey = /** @type {string} */ (instruction[10]); const strokeKey = /** @type {string} */ (instruction[10]);
const strokeWidth = /** @type {number} */ (instruction[11]); const strokeWidth = /** @type {number} */ (instruction[11]);
const text = /** @type {string} */ (instruction[12]); const text = /** @type {string} */ (instruction[12]);
const textKey = /** @type {string} */ (instruction[13]); const textKey = /** @type {string} */ (instruction[13]);
const textScale = /** @type {number} */ (instruction[14]); const pixelRatioScale = /** @type {number} */ (instruction[14]);
const textState = this.textStates[textKey];
const font = textState.font;
const textScale = textState.scale;
let widths = this.widths_[font];
if (!widths) {
this.widths_[font] = widths = {};
}
const measure = function(text) {
let width = widths[text];
if (!width) {
width = widths[text] = measureTextWidth(font, text);
}
return width * textScale * measurePixelRatio;
};
const pathLength = lineStringLength(pixelCoordinates, begin, end, 2); const pathLength = lineStringLength(pixelCoordinates, begin, end, 2);
const textLength = measure(text); const textLength = measure(text);
if (overflow || textLength <= pathLength) { if (overflow || textLength <= pathLength) {
/** @type {import("./TextBuilder.js").default} */ const textReplay = this;
const textReplay = /** @type {?} */ (this);
const textAlign = textReplay.textStates[textKey].textAlign; const textAlign = textReplay.textStates[textKey].textAlign;
const startM = (pathLength - textLength) * TEXT_ALIGN[textAlign]; const startM = (pathLength - textLength) * TEXT_ALIGN[textAlign];
const parts = drawTextOnPath( const parts = drawTextOnPath(
@@ -726,7 +750,7 @@ class CanvasInstructionsExecutor {
this.replayImage_(context, this.replayImage_(context,
/** @type {number} */ (part[0]), /** @type {number} */ (part[1]), label, /** @type {number} */ (part[0]), /** @type {number} */ (part[1]), label,
anchorX, anchorY, declutterGroup, label.height, 1, 0, 0, anchorX, anchorY, declutterGroup, label.height, 1, 0, 0,
/** @type {number} */ (part[3]), textScale, false, label.width, /** @type {number} */ (part[3]), pixelRatioScale, false, label.width,
defaultPadding, null, null); defaultPadding, null, null);
} }
} }
@@ -740,7 +764,7 @@ class CanvasInstructionsExecutor {
this.replayImage_(context, this.replayImage_(context,
/** @type {number} */ (part[0]), /** @type {number} */ (part[1]), label, /** @type {number} */ (part[0]), /** @type {number} */ (part[1]), label,
anchorX, anchorY, declutterGroup, label.height, 1, 0, 0, anchorX, anchorY, declutterGroup, label.height, 1, 0, 0,
/** @type {number} */ (part[3]), textScale, false, label.width, /** @type {number} */ (part[3]), pixelRatioScale, false, label.width,
defaultPadding, null, null); defaultPadding, null, null);
} }
} }
+4 -26
View File
@@ -8,7 +8,7 @@ import {intersects} from '../../extent.js';
import {matchingChunk} from '../../geom/flat/straightchunk.js'; import {matchingChunk} from '../../geom/flat/straightchunk.js';
import GeometryType from '../../geom/GeometryType.js'; import GeometryType from '../../geom/GeometryType.js';
import {CANVAS_LINE_DASH} from '../../has.js'; import {CANVAS_LINE_DASH} from '../../has.js';
import {labelCache, measureTextWidth, measureTextWidths, defaultTextAlign, measureTextHeight, defaultPadding, defaultLineCap, defaultLineDashOffset, defaultLineDash, defaultLineJoin, defaultFillStyle, checkFont, defaultFont, defaultLineWidth, defaultMiterLimit, defaultStrokeStyle, defaultTextBaseline} from '../canvas.js'; import {labelCache, measureTextWidths, defaultTextAlign, measureTextHeight, defaultPadding, defaultLineCap, defaultLineDashOffset, defaultLineDash, defaultLineJoin, defaultFillStyle, checkFont, defaultFont, defaultLineWidth, defaultMiterLimit, defaultStrokeStyle, defaultTextBaseline} from '../canvas.js';
import CanvasInstruction from './Instruction.js'; import CanvasInstruction from './Instruction.js';
import CanvasInstructionsBuilder from './InstructionsBuilder.js'; import CanvasInstructionsBuilder from './InstructionsBuilder.js';
import {TEXT_ALIGN} from '../replay.js'; import {TEXT_ALIGN} from '../replay.js';
@@ -119,12 +119,6 @@ class CanvasTextBuilder extends CanvasInstructionsBuilder {
*/ */
this.strokeKey_ = ''; this.strokeKey_ = '';
/**
* @private
* @type {Object<string, Object<string, number>>}
*/
this.widths_ = {};
labelCache.prune(); labelCache.prune();
} }
@@ -409,35 +403,19 @@ class CanvasTextBuilder extends CanvasInstructionsBuilder {
const offsetY = this.textOffsetY_ * pixelRatio; const offsetY = this.textOffsetY_ * pixelRatio;
const text = this.text_; const text = this.text_;
const font = textState.font;
const textScale = textState.scale; const textScale = textState.scale;
const strokeWidth = strokeState ? strokeState.lineWidth * textScale / 2 : 0; const strokeWidth = strokeState ? strokeState.lineWidth * textScale / 2 : 0;
let widths = this.widths_[font];
if (!widths) {
this.widths_[font] = widths = {};
}
this.instructions.push([CanvasInstruction.DRAW_CHARS, this.instructions.push([CanvasInstruction.DRAW_CHARS,
begin, end, baseline, declutterGroup, begin, end, baseline, declutterGroup,
textState.overflow, fillKey, textState.maxAngle, textState.overflow, fillKey, textState.maxAngle,
function(text) { pixelRatio,
let width = widths[text];
if (!width) {
width = widths[text] = measureTextWidth(font, text);
}
return width * textScale * pixelRatio;
},
offsetY, strokeKey, strokeWidth * pixelRatio, text, textKey, 1 offsetY, strokeKey, strokeWidth * pixelRatio, text, textKey, 1
]); ]);
this.hitDetectionInstructions.push([CanvasInstruction.DRAW_CHARS, this.hitDetectionInstructions.push([CanvasInstruction.DRAW_CHARS,
begin, end, baseline, declutterGroup, begin, end, baseline, declutterGroup,
textState.overflow, fillKey, textState.maxAngle, textState.overflow, fillKey, textState.maxAngle,
function(text) { 1,
let width = widths[text];
if (!width) {
width = widths[text] = measureTextWidth(font, text);
}
return width * textScale;
},
offsetY, strokeKey, strokeWidth, text, textKey, 1 / pixelRatio offsetY, strokeKey, strokeWidth, text, textKey, 1 / pixelRatio
]); ]);
} }