Skip to content

Commit

Permalink
fix: [#3060] SpriteFont measureText with scale (#3062)
Browse files Browse the repository at this point in the history
Closes #3060

## Changes:

- Adds sandbox test with repro
- Updates spritefont to include scale
  • Loading branch information
eonarheim authored May 15, 2024
1 parent 29fef3b commit 5dcff5d
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 6 deletions.
32 changes: 27 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Breaking Changes

- `ex.Action` now requires a unique `id` property
-

### Deprecated

Expand All @@ -18,27 +18,49 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added

- `actor.oldGlobalPos` returns the globalPosition from the previous frame
- Built in actions now have a unique `id` property
- create development builds of excalibur that bundlers can use in dev mode
- show warning in development when Entity hasn't been added to a scene after a few seconds

### Fixed

- Fixed animation glitch caused by uninitialized state in `ImageRenderer`
- Fixed issue where `ex.Loader.suppressPlayButton = true` did not work. Only using the `ex.Engine({suppressPlayButton: true})` worked
- Fixed issue where `ex.SpriteFont` did not respect scale when measuring text

### Updates

-

### Changed

- `ex.Vector.toAngle()` now returns angles from [0 - 2 PI)

<!--------------------------------- DO NOT EDIT BELOW THIS LINE --------------------------------->
<!--------------------------------- DO NOT EDIT BELOW THIS LINE --------------------------------->
<!--------------------------------- DO NOT EDIT BELOW THIS LINE --------------------------------->

## [v0.29.3]

### Breaking Changes

- `ex.Action` now requires a unique `id` property

### Deprecated

### Added

- Built in actions now have a unique `id` property

### Fixed

- Fixed animation glitch caused by uninitialized state in `ImageRenderer`
- Fixed issue where `ex.Loader.suppressPlayButton = true` did not work. Only using the `ex.Engine({suppressPlayButton: true})` worked

### Updates

-

### Changed

- `ex.Vector.toAngle()` now returns angles from `[0 - 2 PI)`

## [v0.29.2]

### Breaking Changes
Expand Down
Binary file added sandbox/tests/spritefont-measuring/font.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions sandbox/tests/spritefont-measuring/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sprite Font Rendering</title>
</head>
<body>
<script src="../../lib/excalibur.js"></script>
<script src="index.js"></script>
</body>
</html>
46 changes: 46 additions & 0 deletions sandbox/tests/spritefont-measuring/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
class TestFontMeasuringScene extends ex.Scene {
font1: ex.SpriteFont;
font2: ex.SpriteFont;
async onInitialize(game: ex.Engine) {
super.onInitialize(game);
let loader = new ex.DefaultLoader();
let fontImage = new ex.ImageSource('font.png');
loader.addResource(fontImage);
await game.start(loader);

let fontSpriteSheet = ex.SpriteSheet.fromImageSource({
image: fontImage,
grid: { columns: 1, rows: 45, spriteWidth: 10, spriteHeight: 10 }
});

this.font1 = this.createFont(fontSpriteSheet);
this.font2 = this.createFont(fontSpriteSheet);
this.font2.scale = ex.vec(2, 2);
}

createFont(spriteSheet: ex.SpriteSheet) {
return new ex.SpriteFont({
alphabet: '01234567890.- ©][ABCDEFGHIJKLMNOPQRSTUVWXYZ|/',
caseInsensitive: true,
spriteSheet
});
}
onActivate(ctx: ex.SceneActivationContext) {
const text = 'brown fox jumps over the lazy dog';
let m1 = this.font1.measureText(text);
console.log('font 1', m1.dimensions); //330,10, OK
let m2 = this.font2.measureText(text);
console.log('font 2', m2.dimensions); //330,10, should be 660,20
}
}

var engineSpriteFont = new ex.Engine({
width: 600,
height: 600,
pixelArt: true,
scenes: {
start: TestFontMeasuringScene
}
});

engineSpriteFont.start('start');
Binary file added sandbox/tests/spritefont-rendering/font.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions sandbox/tests/spritefont-rendering/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sprite Font Rendering</title>
</head>
<body>
<script src="../../lib/excalibur.js"></script>
<script src="index.js"></script>
</body>
</html>
37 changes: 37 additions & 0 deletions sandbox/tests/spritefont-rendering/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class TestFontScene extends ex.Scene {
async onInitialize(game: ex.Engine) {
super.onInitialize(game);
let loader = new ex.DefaultLoader();
let fontImage = new ex.ImageSource('./font.png');
loader.addResource(fontImage);
await game.start(loader);
let fontSpriteSheet = ex.SpriteSheet.fromImageSource({
image: fontImage,
grid: { columns: 1, rows: 45, spriteWidth: 10, spriteHeight: 10 }
});
let font = new ex.SpriteFont({
alphabet: '01234567890.- ©][ABCDEFGHIJKLMNOPQRSTUVWXYZ|/',
caseInsensitive: true,
spriteSheet: fontSpriteSheet,
scale: ex.vec(4, 4)
});
let lbl = new ex.Label({
pos: ex.vec(10, 10),
anchor: ex.vec(0, 0),
text: '-brown fox jumps \nover the lazy dog',
spriteFont: font
});
this.add(lbl);
}
}

var engineSpriteFont = new ex.Engine({
width: 600,
height: 600,
pixelArt: true,
scenes: {
start: TestFontScene
}
});

engineSpriteFont.start('start');
2 changes: 1 addition & 1 deletion src/engine/Graphics/SpriteFont.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export class SpriteFont extends Graphic implements FontRenderer {
width += sprite.width + this.spacing;
height = Math.max(height, sprite.height);
}
return BoundingBox.fromDimension(width, height * lines.length, Vector.Zero);
return BoundingBox.fromDimension(width * this.scale.x, height * lines.length * this.scale.y, Vector.Zero);
}

protected _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number, maxWidth?: number): void {
Expand Down
39 changes: 39 additions & 0 deletions src/spec/TextSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,45 @@ describe('A Text Graphic', () => {
await expectAsync(canvasElement).toEqualImage('src/spec/images/GraphicsTextSpec/spritefont-text.png');
});

it('can scale a spritefont', async () => {
const spriteFontImage = new ex.ImageSource('src/spec/images/GraphicsTextSpec/spritefont.png');

await spriteFontImage.load();

const spriteFontSheet = ex.SpriteSheet.fromImageSource({
image: spriteFontImage,
grid: {
rows: 3,
columns: 16,
spriteWidth: 16,
spriteHeight: 16
}
});

const spriteFont = new ex.SpriteFont({
alphabet: '0123456789abcdefghijklmnopqrstuvwxyz,!\'&."?- ',
caseInsensitive: true,
spacing: -5,
spriteSheet: spriteFontSheet,
scale: ex.vec(3, 3)
});

const sut = new ex.Text({
text: 'Some Sprite Text!?',
font: spriteFont
});

const canvasElement = document.createElement('canvas');
canvasElement.width = 200;
canvasElement.height = 100;
const ctx = new ex.ExcaliburGraphicsContext2DCanvas({ canvasElement });

ctx.clear();
sut.draw(ctx, 0, 50);
expect(spriteFont.measureText('some test')).toEqual(ex.BoundingBox.fromDimension((16 - 5) * 9 * 3, 16 * 3, ex.vec(0, 0)));
await expectAsync(canvasElement).toEqualImage('src/spec/images/GraphicsTextSpec/spritefont-scaled.png');
});

it('can have a custom lineHeight', async () => {
const spriteFontImage = new ex.ImageSource('src/spec/images/GraphicsTextSpec/spritefont.png');

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 5dcff5d

Please sign in to comment.