Skip to content

Commit 6809168

Browse files
committed
feat: text-metrics
1 parent cba9823 commit 6809168

4 files changed

Lines changed: 30 additions & 14 deletions

File tree

src/collection/dimensions/bounds.mjs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { assignBoundingBox, expandBoundingBoxSides, clearBoundingBox, expandBou
33
import {defaults, endsWith, getPrefixedProperty, hashIntsArray, memoize} from '../../util/index.mjs';
44

55
let fn, elesfn;
6+
const BBOX_MARGIN_ERROR = 2;
67

78
fn = elesfn = {};
89

@@ -291,7 +292,8 @@ let updateBoundsFromLabel = function( bounds, ele, prefix ){
291292
let borderWidth = ele.pstyle( 'text-border-width' ).pfValue;
292293
let halfBorderWidth = borderWidth / 2;
293294
let padding = ele.pstyle( 'text-background-padding' ).pfValue;
294-
let marginOfError = 2; // expand to work around browser dimension inaccuracies
295+
let marginOfErrorX = BBOX_MARGIN_ERROR; // expand to work around browser dimension inaccuracies
296+
let marginOfErrorY = BBOX_MARGIN_ERROR; // expand to work around browser dimension inaccuracies
295297

296298
let lh = labelHeight;
297299
let lw = labelWidth;
@@ -341,10 +343,10 @@ let updateBoundsFromLabel = function( bounds, ele, prefix ){
341343
}
342344

343345
// shift by margin and expand by outline and border
344-
let leftPad = marginX - Math.max( outlineWidth, halfBorderWidth ) - padding - marginOfError;
345-
let rightPad = marginX + Math.max( outlineWidth, halfBorderWidth ) + padding + marginOfError;
346-
let topPad = marginY - Math.max( outlineWidth, halfBorderWidth ) - padding - marginOfError;
347-
let botPad = marginY + Math.max( outlineWidth, halfBorderWidth ) + padding + marginOfError;
346+
let leftPad = marginX - Math.max( outlineWidth, halfBorderWidth ) - padding - marginOfErrorX;
347+
let rightPad = marginX + Math.max( outlineWidth, halfBorderWidth ) + padding + marginOfErrorX;
348+
let topPad = marginY - Math.max( outlineWidth, halfBorderWidth ) - padding - marginOfErrorY;
349+
let botPad = marginY + Math.max( outlineWidth, halfBorderWidth ) + padding + marginOfErrorY;
348350

349351
lx1 += leftPad;
350352
lx2 += rightPad;

src/extensions/renderer/base/coord-ele-math/labels.mjs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,14 +312,14 @@ BRp.applyPrefixedLabelDimensions = function( ele, prefix ){
312312

313313
let labelDims = this.calculateLabelDimensions( ele, text );
314314
let lineHeight = ele.pstyle('line-height').pfValue;
315+
let size = ele.pstyle('font-size').pfValue;
315316
let textWrap = ele.pstyle('text-wrap').strValue;
316317
let lines = util.getPrefixedProperty( _p.rscratch, 'labelWrapCachedLines', prefix ) || [];
317318
let numLines = textWrap !== 'wrap' ? 1 : Math.max(lines.length, 1);
318-
let normPerLineHeight = labelDims.height / numLines;
319-
let labelLineHeight = normPerLineHeight * lineHeight;
319+
let labelLineHeight = size * lineHeight;
320320

321321
let width = labelDims.width;
322-
let height = labelDims.height + (numLines - 1) * (lineHeight - 1) * normPerLineHeight;
322+
let height = labelDims.height + (numLines - 1) * (lineHeight - 1) * size;
323323

324324
util.setPrefixedProperty( _p.rstyle, 'labelWidth', prefix, width );
325325
util.setPrefixedProperty( _p.rscratch, 'labelWidth', prefix, width );
@@ -328,6 +328,7 @@ BRp.applyPrefixedLabelDimensions = function( ele, prefix ){
328328
util.setPrefixedProperty( _p.rscratch, 'labelHeight', prefix, height );
329329

330330
util.setPrefixedProperty( _p.rscratch, 'labelLineHeight', prefix, labelLineHeight );
331+
util.setPrefixedProperty( _p.rscratch, 'labelActualDescent', prefix, labelDims.labelActualDescent );
331332
};
332333

333334
BRp.getLabelText = function( ele, prefix ){
@@ -509,23 +510,34 @@ BRp.calculateLabelDimensions = function( ele, text ){
509510
let width = 0;
510511
let height = 0;
511512
let lines = text.split('\n');
513+
let lineCount = lines.length;
514+
let labelActualDescent = 0;
515+
let labelActualAscent = 0;
512516

513-
for( let i = 0; i < lines.length; i++ ){
517+
for( let i = 0; i < lineCount; i++ ){
514518
let line = lines[i];
515519
let metrics = c2d.measureText(line);
516520
let w = Math.ceil(metrics.width);
517521
let h = size;
522+
if (i === 0) {
523+
labelActualAscent = Number.isFinite(metrics.actualBoundingBoxAscent) ? metrics.actualBoundingBoxAscent : size;
524+
}
525+
if (i === lineCount - 1) {
526+
labelActualDescent = Number.isFinite(metrics.actualBoundingBoxDescent) ? metrics.actualBoundingBoxDescent : 0;
527+
}
518528

519529
width = Math.max(w, width);
520530
height += h;
521531
}
522-
532+
height -= size - labelActualAscent - labelActualDescent;
523533
width += padding;
524534
height += padding;
525535

526536
return {
527537
width,
528-
height
538+
height,
539+
labelActualAscent,
540+
labelActualDescent
529541
};
530542
};
531543

src/extensions/renderer/canvas/drawing-label-text.mjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ CRp.drawElementText = function( context, ele, shiftToOriginWithBb, force, prefix
3939
let justification = r.getLabelJustification(ele);
4040

4141
context.textAlign = justification;
42-
context.textBaseline = 'bottom';
42+
context.textBaseline = 'alphabetic';
4343
} else {
4444
let badLine = ele.element()._private.rscratch.badLine;
4545
let label = ele.pstyle( 'label' );
@@ -198,6 +198,7 @@ CRp.drawText = function( context, ele, prefix, applyRotation = true, useEleOpaci
198198
let pdash = prefix ? prefix + '-' : '';
199199
let textW = util.getPrefixedProperty( rscratch, 'labelWidth', prefix );
200200
let textH = util.getPrefixedProperty( rscratch, 'labelHeight', prefix );
201+
let labelActualDescent = util.getPrefixedProperty( rscratch, 'labelActualDescent', prefix );
201202
let marginX = ele.pstyle( pdash + 'text-margin-x' ).pfValue;
202203
let marginY = ele.pstyle( pdash + 'text-margin-y' ).pfValue;
203204

@@ -335,7 +336,8 @@ CRp.drawText = function( context, ele, prefix, applyRotation = true, useEleOpaci
335336
if( lineWidth > 0 ){
336337
context.lineWidth = lineWidth;
337338
}
338-
339+
340+
textY -= labelActualDescent;
339341
if( ele.pstyle( 'text-wrap' ).value === 'wrap' ){
340342
let lines = util.getPrefixedProperty( rscratch, 'labelWrapCachedLines', prefix );
341343
let lineHeight = util.getPrefixedProperty( rscratch, 'labelLineHeight', prefix );

src/style/properties.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ const styfn = {};
217217
{ name: 'text-overflow-wrap', type: t.textOverflowWrap, triggersBounds: diff.any },
218218
{ name: 'text-max-width', type: t.size, triggersBounds: diff.any },
219219
{ name: 'text-outline-width', type: t.size, triggersBounds: diff.any },
220-
{ name: 'line-height', type: t.positiveNumber, triggersBounds: diff.any }
220+
{ name: 'line-height', type: t.positiveNumber, triggersBounds: diff.any },
221221
];
222222

223223
let commonLabel = [

0 commit comments

Comments
 (0)