Skip to content

Commit 091a4b8

Browse files
authored
Merge pull request #1382 from AaronDavidNewman/chord-symbol-width
Consider existing modifiers when calculating chord symbol width
2 parents 590d5c2 + 1cbcbc7 commit 091a4b8

File tree

9 files changed

+316
-144
lines changed

9 files changed

+316
-144
lines changed

src/annotation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export class Annotation extends Modifier {
9797
maxLeftGlyphWidth = Math.max(glyphWidth, maxLeftGlyphWidth);
9898
leftWidth = Math.max(leftWidth, textWidth) + Annotation.minAnnotationPadding;
9999
} else if (annotation.horizontalJustification === AnnotationHorizontalJustify.RIGHT) {
100-
maxRightGlyphWidth = Math.max(glyphWidth, maxLeftGlyphWidth);
100+
maxRightGlyphWidth = Math.max(glyphWidth, maxRightGlyphWidth);
101101
rightWidth = Math.max(rightWidth, textWidth);
102102
} else {
103103
leftWidth = Math.max(leftWidth, textWidth / 2) + Annotation.minAnnotationPadding;

src/chordsymbol.ts

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ import { Font, FontInfo, FontStyle, FontWeight } from './font';
1313
import { Glyph } from './glyph';
1414
import { Modifier } from './modifier';
1515
import { ModifierContextState } from './modifiercontext';
16+
import { Note } from './note';
1617
import { StemmableNote } from './stemmablenote';
1718
import { Tables } from './tables';
1819
import { TextFormatter } from './textformatter';
19-
import { Category } from './typeguard';
20+
import { Category, isStemmableNote } from './typeguard';
2021
import { log } from './util';
2122

2223
// To enable logging for this class. Set `Vex.Flow.ChordSymbol.DEBUG` to `true`.
@@ -247,6 +248,10 @@ export class ChordSymbol extends Modifier {
247248
return block.symbolModifier !== undefined && block.symbolModifier === SymbolModifiers.SUBSCRIPT;
248249
}
249250

251+
static get minPadding(): number {
252+
const musicFont = Tables.currentMusicFont();
253+
return musicFont.lookupMetric('glyphs.noteHead.minPadding');
254+
}
250255
/**
251256
* Estimate the width of the whole chord symbol, based on the sum of the widths of the individual blocks.
252257
* Estimate how many lines above/below the staff we need.
@@ -256,12 +261,17 @@ export class ChordSymbol extends Modifier {
256261

257262
let width = 0;
258263
let nonSuperWidth = 0;
259-
const reportedWidths = [];
264+
let leftWidth = 0;
265+
let rightWidth = 0;
266+
let maxLeftGlyphWidth = 0;
267+
let maxRightGlyphWidth = 0;
260268

261269
for (const symbol of symbols) {
262270
const fontSize = Font.convertSizeToPointValue(symbol.textFont?.size);
263271
const fontAdj = Font.scaleSize(fontSize, 0.05);
264272
const glyphAdj = fontAdj * 2;
273+
const note: Note = symbol.checkAttachedNote();
274+
let symbolWidth = 0;
265275
let lineSpaces = 1;
266276
let vAlign = false;
267277

@@ -323,6 +333,7 @@ export class ChordSymbol extends Modifier {
323333
}
324334
block.vAlign = vAlign;
325335
width += block.width;
336+
symbolWidth = width;
326337
}
327338

328339
// make kerning adjustments after computing super/subscripts
@@ -336,17 +347,31 @@ export class ChordSymbol extends Modifier {
336347
symbol.setTextLine(state.text_line + 1);
337348
state.text_line += lineSpaces + 1;
338349
}
339-
if (symbol.getReportWidth()) {
340-
reportedWidths.push(width);
341-
} else {
342-
reportedWidths.push(0);
350+
if (symbol.getReportWidth() && isStemmableNote(note)) {
351+
const glyphWidth = note.getGlyph().getWidth();
352+
if (symbol.getHorizontal() === ChordSymbolHorizontalJustify.LEFT) {
353+
maxLeftGlyphWidth = Math.max(glyphWidth, maxLeftGlyphWidth);
354+
leftWidth = Math.max(leftWidth, symbolWidth) + ChordSymbol.minPadding;
355+
} else if (symbol.getHorizontal() === ChordSymbolHorizontalJustify.RIGHT) {
356+
maxRightGlyphWidth = Math.max(glyphWidth, maxRightGlyphWidth);
357+
rightWidth = Math.max(rightWidth, symbolWidth);
358+
} else {
359+
leftWidth = Math.max(leftWidth, symbolWidth / 2) + ChordSymbol.minPadding;
360+
rightWidth = Math.max(rightWidth, symbolWidth / 2);
361+
maxLeftGlyphWidth = Math.max(glyphWidth / 2, maxLeftGlyphWidth);
362+
maxRightGlyphWidth = Math.max(glyphWidth / 2, maxRightGlyphWidth);
363+
}
343364
}
365+
width = 0; // reset symbol width
344366
}
367+
const rightOverlap = Math.min(
368+
Math.max(rightWidth - maxRightGlyphWidth, 0),
369+
Math.max(rightWidth - state.right_shift, 0)
370+
);
371+
const leftOverlap = Math.min(Math.max(leftWidth - maxLeftGlyphWidth, 0), Math.max(leftWidth - state.left_shift, 0));
345372

346-
width = reportedWidths.reduce((a, b) => a + b, 0);
347-
348-
state.left_shift += width / 2;
349-
state.right_shift += width / 2;
373+
state.left_shift += leftOverlap;
374+
state.right_shift += rightOverlap;
350375
return true;
351376
}
352377

src/factory.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { ModifierContext } from './modifiercontext';
2525
import { MultiMeasureRest, MultimeasureRestRenderOptions } from './multimeasurerest';
2626
import { Note, NoteStruct } from './note';
2727
import { NoteSubGroup } from './notesubgroup';
28+
import { Ornament } from './ornament';
2829
import { PedalMarking } from './pedalmarking';
2930
import { RenderContext } from './rendercontext';
3031
import { Renderer } from './renderer';
@@ -403,6 +404,31 @@ export class Factory {
403404
return articulation;
404405
}
405406

407+
Ornament(
408+
type: string,
409+
params?: { position?: string | number; upperAccidental?: string; lowerAccidental?: string; delayed?: boolean }
410+
) {
411+
const options = {
412+
type,
413+
position: 0,
414+
accidental: '',
415+
...params,
416+
};
417+
const ornament = new Ornament(type);
418+
ornament.setPosition(options.position);
419+
if (options.upperAccidental) {
420+
ornament.setUpperAccidental(options.upperAccidental);
421+
}
422+
if (options.lowerAccidental) {
423+
ornament.setLowerAccidental(options.lowerAccidental);
424+
}
425+
if (typeof options.delayed !== 'undefined') {
426+
ornament.setDelayed(options.delayed);
427+
}
428+
ornament.setContext(this.context);
429+
return ornament;
430+
}
431+
406432
TextDynamics(params?: { text?: string; duration?: string; dots?: number; line?: number }): TextDynamics {
407433
const p = {
408434
text: 'p',

src/fonts/bravura_metrics.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -459,21 +459,21 @@ export const BravuraMetrics = {
459459
xOffset: -12,
460460
yOffset: 0,
461461
stemUpYOffset: 0,
462-
reportedWidth: 10,
462+
reportedWidth: 20,
463463
},
464464
brassDoitMedium: {
465465
scale: 1.0,
466466
xOffset: 16,
467467
yOffset: 0,
468468
stemUpYOffset: 0,
469-
reportedWidth: 15,
469+
reportedWidth: 22,
470470
},
471471
brassFallLipShort: {
472472
scale: 1.0,
473473
xOffset: 16,
474474
yOffset: 0,
475475
stemUpYOffset: 0,
476-
reportedWidth: 5,
476+
reportedWidth: 15,
477477
},
478478
brassLiftMedium: {
479479
scale: 1.0,
@@ -513,22 +513,22 @@ export const BravuraMetrics = {
513513
brassFlip: {
514514
scale: 1.0,
515515
xOffset: 10,
516-
yOffset: -4,
517-
stemUpYOffset: 0,
518-
reportedWidth: 5,
516+
yOffset: 0,
517+
stemUpYOffset: 7,
518+
reportedWidth: 10,
519519
},
520520
brassJazzTurn: {
521521
scale: 1.0,
522-
xOffset: 6,
523-
yOffset: -4,
524-
stemUpYOffset: 0,
525-
reportedWidth: 5,
522+
xOffset: 0,
523+
yOffset: 0,
524+
stemUpYOffset: 8,
525+
reportedWidth: 31,
526526
},
527527
brassSmear: {
528528
scale: 1.0,
529529
xOffset: 10,
530-
yOffset: -4,
531-
stemUpYOffset: 0,
530+
yOffset: 0,
531+
stemUpYOffset: 8,
532532
reportedWidth: 5,
533533
},
534534
},

src/fonts/gonville_metrics.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -356,21 +356,21 @@ export const GonvilleMetrics = {
356356
xOffset: -12,
357357
yOffset: 0,
358358
stemUpYOffset: 0,
359-
reportedWidth: 10,
359+
reportedWidth: 15,
360360
},
361361
brassDoitMedium: {
362362
scale: 1.0,
363363
xOffset: 16,
364364
yOffset: 0,
365365
stemUpYOffset: 0,
366-
reportedWidth: 5,
366+
reportedWidth: 22,
367367
},
368368
brassFallLipShort: {
369369
scale: 1.0,
370370
xOffset: 17,
371371
yOffset: 0,
372372
stemUpYOffset: 0,
373-
reportedWidth: 5,
373+
reportedWidth: 15,
374374
},
375375
brassLiftMedium: {
376376
scale: 1.0,
@@ -411,21 +411,21 @@ export const GonvilleMetrics = {
411411
scale: 1.0,
412412
xOffset: 10,
413413
yOffset: -4,
414-
stemUpYOffset: 0,
414+
stemUpYOffset: 7,
415415
reportedWidth: 5,
416416
},
417417
brassJazzTurn: {
418418
scale: 1.0,
419-
xOffset: 6,
419+
xOffset: 3,
420420
yOffset: -4,
421-
stemUpYOffset: 0,
422-
reportedWidth: 5,
421+
stemUpYOffset: 10,
422+
reportedWidth: 28,
423423
},
424424
brassSmear: {
425425
scale: 1.0,
426426
xOffset: 10,
427427
yOffset: -4,
428-
stemUpYOffset: 0,
428+
stemUpYOffset: 9,
429429
reportedWidth: 5,
430430
},
431431
},

src/fonts/petaluma_metrics.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -487,28 +487,28 @@ export const PetalumaMetrics = {
487487
xOffset: -12,
488488
yOffset: 0,
489489
stemUpYOffset: 0,
490-
reportedWidth: 10,
490+
reportedWidth: 15,
491491
},
492492
brassDoitMedium: {
493493
scale: 1.0,
494494
xOffset: 16,
495495
yOffset: 0,
496496
stemUpYOffset: 0,
497-
reportedWidth: 5,
497+
reportedWidth: 19,
498498
},
499499
brassFallLipShort: {
500500
scale: 1.0,
501501
xOffset: 16,
502502
yOffset: 0,
503503
stemUpYOffset: 0,
504-
reportedWidth: 5,
504+
reportedWidth: 19,
505505
},
506506
brassLiftMedium: {
507507
scale: 1.0,
508508
xOffset: 16,
509509
yOffset: 5,
510510
stemUpYOffset: 0,
511-
reportedWidth: 5,
511+
reportedWidth: 15,
512512
},
513513
brassFallRoughMedium: {
514514
scale: 1.0,
@@ -542,21 +542,21 @@ export const PetalumaMetrics = {
542542
scale: 1.0,
543543
xOffset: 10,
544544
yOffset: -4,
545-
stemUpYOffset: 0,
545+
stemUpYOffset: 7,
546546
reportedWidth: 5,
547547
},
548548
brassJazzTurn: {
549549
scale: 1.0,
550550
xOffset: 6,
551551
yOffset: -4,
552-
stemUpYOffset: 0,
553-
reportedWidth: 5,
552+
stemUpYOffset: 5,
553+
reportedWidth: 30,
554554
},
555555
brassSmear: {
556556
scale: 1.0,
557557
xOffset: 10,
558558
yOffset: -4,
559-
stemUpYOffset: 0,
559+
stemUpYOffset: 5,
560560
reportedWidth: 5,
561561
},
562562
},

src/ornament.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ export class Ornament extends Modifier {
3232
static get CATEGORY(): string {
3333
return Category.Ornament;
3434
}
35+
static get minPadding(): number {
36+
const musicFont = Tables.currentMusicFont();
37+
return musicFont.lookupMetric('glyphs.noteHead.minPadding');
38+
}
3539

3640
protected ornament: {
3741
code: string;
@@ -74,8 +78,8 @@ export class Ornament extends Modifier {
7478
}
7579
if (ornament.reportedWidth && ornament.x_shift < 0) {
7680
left_shift += ornament.reportedWidth;
77-
} else if (ornament.reportedWidth && ornament.x_shift > 0) {
78-
right_shift += ornament.reportedWidth;
81+
} else if (ornament.reportedWidth && ornament.x_shift >= 0) {
82+
right_shift += ornament.reportedWidth + Ornament.minPadding;
7983
} else {
8084
width = Math.max(ornament.getWidth(), width);
8185
}

0 commit comments

Comments
 (0)