GraphicalLabel.ts 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import { TextAlignmentEnum } from "../../Common/Enums/TextAlignment";
  2. import { Label } from "../Label";
  3. import { BoundingBox } from "./BoundingBox";
  4. import { Clickable } from "./Clickable";
  5. import { EngravingRules } from "./EngravingRules";
  6. import { MusicSheetCalculator } from "./MusicSheetCalculator";
  7. /**
  8. * The graphical counterpart of a Label
  9. */
  10. export class GraphicalLabel extends Clickable {
  11. private label: Label;
  12. private rules: EngravingRules;
  13. public TextLines: {text: string, xOffset: number, width: number}[];
  14. /**
  15. * Creates a new GraphicalLabel from a Label
  16. * @param label label object containing text
  17. * @param textHeight Height of text
  18. * @param alignment Alignement like left, right, top, ...
  19. * @param parent Parent Bounding Box where the label is attached to
  20. */
  21. constructor(label: Label, textHeight: number, alignment: TextAlignmentEnum, rules: EngravingRules,
  22. parent: BoundingBox = undefined, ) {
  23. super();
  24. this.label = label;
  25. this.boundingBox = new BoundingBox(this, parent);
  26. this.label.fontHeight = textHeight;
  27. this.label.textAlignment = alignment;
  28. this.rules = rules;
  29. }
  30. public get Label(): Label {
  31. return this.label;
  32. }
  33. public toString(): string {
  34. return `${this.label.text} (${this.boundingBox.RelativePosition.x},${this.boundingBox.RelativePosition.y})`;
  35. }
  36. /**
  37. * Calculate GraphicalLabel's Borders according to its Alignment
  38. * Create also the text-lines and their offsets here
  39. */
  40. public setLabelPositionAndShapeBorders(): void {
  41. if (this.Label.text.trim() === "") {
  42. return;
  43. }
  44. this.TextLines = [];
  45. const labelMarginBorderFactor: number = this.rules?.LabelMarginBorderFactor ?? 0.1;
  46. const lines: string[] = this.Label.text.split(/[\n\r]+/g);
  47. const numOfLines: number = lines.length;
  48. let maxWidth: number = 0;
  49. for (let i: number = 0; i < numOfLines; i++) {
  50. const line: string = lines[i].trim();
  51. const widthToHeightRatio: number =
  52. MusicSheetCalculator.TextMeasurer.computeTextWidthToHeightRatio(
  53. line, this.Label.font, this.Label.fontStyle, this.label.fontFamily);
  54. const currWidth: number = this.Label.fontHeight * widthToHeightRatio;
  55. maxWidth = Math.max(maxWidth, currWidth);
  56. // here push only text and width of the text:
  57. this.TextLines.push({text: line, xOffset: 0, width: currWidth});
  58. }
  59. // maxWidth is calculated ->
  60. // now also set the x-offsets:
  61. for (const line of this.TextLines) {
  62. let xOffset: number = 0;
  63. switch (this.Label.textAlignment) {
  64. case TextAlignmentEnum.RightBottom:
  65. case TextAlignmentEnum.RightCenter:
  66. case TextAlignmentEnum.RightTop:
  67. xOffset = maxWidth - line.width;
  68. break;
  69. case TextAlignmentEnum.CenterBottom:
  70. case TextAlignmentEnum.CenterCenter:
  71. case TextAlignmentEnum.CenterTop:
  72. xOffset = (maxWidth - line.width) / 2;
  73. break;
  74. default:
  75. break;
  76. }
  77. line.xOffset = xOffset;
  78. }
  79. const height: number = this.Label.fontHeight * numOfLines;
  80. const bbox: BoundingBox = this.PositionAndShape;
  81. switch (this.Label.textAlignment) {
  82. case TextAlignmentEnum.CenterBottom:
  83. bbox.BorderTop = -height;
  84. bbox.BorderLeft = -maxWidth / 2;
  85. bbox.BorderBottom = 0;
  86. bbox.BorderRight = maxWidth / 2;
  87. break;
  88. case TextAlignmentEnum.CenterCenter:
  89. bbox.BorderTop = -height / 2;
  90. bbox.BorderLeft = -maxWidth / 2;
  91. bbox.BorderBottom = height / 2;
  92. bbox.BorderRight = maxWidth / 2;
  93. break;
  94. case TextAlignmentEnum.CenterTop:
  95. bbox.BorderTop = 0;
  96. bbox.BorderLeft = -maxWidth / 2;
  97. bbox.BorderBottom = height;
  98. bbox.BorderRight = maxWidth / 2;
  99. break;
  100. case TextAlignmentEnum.LeftBottom:
  101. bbox.BorderTop = -height;
  102. bbox.BorderLeft = 0;
  103. bbox.BorderBottom = 0;
  104. bbox.BorderRight = maxWidth;
  105. break;
  106. case TextAlignmentEnum.LeftCenter:
  107. bbox.BorderTop = -height / 2;
  108. bbox.BorderLeft = 0;
  109. bbox.BorderBottom = height / 2;
  110. bbox.BorderRight = maxWidth;
  111. break;
  112. case TextAlignmentEnum.LeftTop:
  113. bbox.BorderTop = 0;
  114. bbox.BorderLeft = 0;
  115. bbox.BorderBottom = height;
  116. bbox.BorderRight = maxWidth;
  117. break;
  118. case TextAlignmentEnum.RightBottom:
  119. bbox.BorderTop = -height;
  120. bbox.BorderLeft = -maxWidth;
  121. bbox.BorderBottom = 0;
  122. bbox.BorderRight = 0;
  123. break;
  124. case TextAlignmentEnum.RightCenter:
  125. bbox.BorderTop = -height / 2;
  126. bbox.BorderLeft = -maxWidth;
  127. bbox.BorderBottom = height / 2;
  128. bbox.BorderRight = 0;
  129. break;
  130. case TextAlignmentEnum.RightTop:
  131. bbox.BorderTop = 0;
  132. bbox.BorderLeft = -maxWidth;
  133. bbox.BorderBottom = height;
  134. bbox.BorderRight = 0;
  135. break;
  136. default:
  137. }
  138. bbox.BorderMarginTop = bbox.BorderTop - height * labelMarginBorderFactor;
  139. bbox.BorderMarginLeft = bbox.BorderLeft - height * labelMarginBorderFactor;
  140. bbox.BorderMarginBottom = bbox.BorderBottom + height * labelMarginBorderFactor;
  141. bbox.BorderMarginRight = bbox.BorderRight + height * labelMarginBorderFactor;
  142. }
  143. }