• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

excaliburjs / Excalibur / 14804036802

02 May 2025 09:58PM UTC coverage: 5.927% (-83.4%) from 89.28%
14804036802

Pull #3404

github

web-flow
Merge 5c103d7f8 into 0f2ccaeb2
Pull Request #3404: feat: added Graph module to Math

234 of 8383 branches covered (2.79%)

229 of 246 new or added lines in 1 file covered. (93.09%)

13145 existing lines in 208 files now uncovered.

934 of 15759 relevant lines covered (5.93%)

4.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/engine/Graphics/Text.ts
1
import { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';
2
import { BoundingBox } from '../Collision/BoundingBox';
3
import { SpriteFont } from './SpriteFont';
4
import { Graphic, GraphicOptions } from './Graphic';
5
import { Color } from '../Color';
6
import { Font } from './Font';
7

8
export interface TextOptions {
9
  /**
10
   * Text to draw
11
   */
12
  text: string;
13

14
  /**
15
   * Optionally override the font color, currently unsupported by SpriteFont
16
   */
17
  color?: Color;
18

19
  /**
20
   * Optionally specify a font, if none specified a default font is used (System sans-serif 10 pixel)
21
   */
22
  font?: Font | SpriteFont;
23

24
  /**
25
   * Optionally specify a maximum width in pixels for our text, and wrap to the next line if needed.
26
   */
27
  maxWidth?: number;
28
}
29

30
/**
31
 * Represent Text graphics in excalibur
32
 *
33
 * Useful for in game labels, ui, or overlays
34
 */
35
export class Text extends Graphic {
36
  public color?: Color;
37
  public maxWidth?: number;
38
  constructor(options: TextOptions & GraphicOptions) {
UNCOV
39
    super(options);
×
40
    // This order is important font, color, then text
UNCOV
41
    this.font = options.font ?? new Font();
×
UNCOV
42
    this.color = options.color ?? this.color;
×
UNCOV
43
    this.text = options.text;
×
UNCOV
44
    this.maxWidth = options.maxWidth;
×
45
  }
46

47
  public clone(): Text {
UNCOV
48
    return new Text({
×
49
      text: this.text.slice(),
50
      color: this.color?.clone() ?? Color.Black,
×
51
      font: this.font.clone(),
52
      maxWidth: this.maxWidth
53
    });
54
  }
55

UNCOV
56
  private _text: string = '';
×
57
  public get text() {
UNCOV
58
    return this._text;
×
59
  }
60

61
  public set text(value: string) {
UNCOV
62
    this._text = value;
×
UNCOV
63
    this._calculateDimension();
×
64
  }
65

66
  private _font!: Font | SpriteFont;
67
  public get font(): Font | SpriteFont {
UNCOV
68
    return this._font;
×
69
  }
70
  public set font(font: Font | SpriteFont) {
UNCOV
71
    this._font = font;
×
72
  }
73

UNCOV
74
  private _textWidth: number = 0;
×
75

76
  public get width() {
UNCOV
77
    if (this._textWidth === 0) {
×
78
      this._calculateDimension();
×
79
    }
UNCOV
80
    return this._textWidth * this.scale.x;
×
81
  }
82

UNCOV
83
  private _textHeight: number = 0;
×
84
  public get height() {
UNCOV
85
    if (this._textHeight === 0) {
×
86
      this._calculateDimension();
×
87
    }
UNCOV
88
    return this._textHeight * this.scale.y;
×
89
  }
90

91
  private _calculateDimension() {
UNCOV
92
    const { width, height } = this.font.measureText(this._text, this.maxWidth);
×
UNCOV
93
    this._textWidth = width;
×
UNCOV
94
    this._textHeight = height;
×
95
  }
96

97
  public get localBounds(): BoundingBox {
UNCOV
98
    return this.font.measureText(this._text, this.maxWidth).scale(this.scale);
×
99
  }
100

101
  protected override _rotate(_ex: ExcaliburGraphicsContext) {
102
    // None this is delegated to font
103
    // This override erases the default behavior
104
  }
105

106
  protected override _flip(_ex: ExcaliburGraphicsContext) {
107
    // None this is delegated to font
108
    // This override erases the default behavior
109
  }
110

111
  protected override _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number): void {
UNCOV
112
    if (this.isStale() || this.font.isStale()) {
×
UNCOV
113
      this.font.flipHorizontal = this.flipHorizontal;
×
UNCOV
114
      this.font.flipVertical = this.flipVertical;
×
UNCOV
115
      this.font.rotation = this.rotation;
×
UNCOV
116
      this.font.origin = this.origin;
×
UNCOV
117
      this.font.opacity = this.opacity;
×
118
    }
UNCOV
119
    this.font.tint = this.tint;
×
UNCOV
120
    super._preDraw(ex, x, y);
×
121
  }
122

123
  protected override _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number) {
UNCOV
124
    let color = Color.Black;
×
UNCOV
125
    if (this.font instanceof Font) {
×
UNCOV
126
      color = this.color ?? this.font.color;
×
127
    }
128

UNCOV
129
    const { width, height } = this.font.measureText(this._text, this.maxWidth);
×
UNCOV
130
    this._textWidth = width;
×
UNCOV
131
    this._textHeight = height;
×
132

UNCOV
133
    this.font.render(ex, this._text, color, x, y, this.maxWidth);
×
134

UNCOV
135
    if (this.font.showDebug) {
×
136
      ex.debug.drawRect(x - width, y - height, width * 2, height * 2);
×
137
      if (this.maxWidth != null) {
×
138
        ex.debug.drawRect(x, y, this.maxWidth, this.height, {
×
139
          color: Color.Yellow
140
        });
141
      }
142
    }
143
  }
144
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc