Skip to content

Commit

Permalink
Hugely improve dynamic font support, now with autowrap
Browse files Browse the repository at this point in the history
  • Loading branch information
pixelpicosean committed Apr 15, 2020
1 parent fc53b11 commit c55a4c9
Show file tree
Hide file tree
Showing 22 changed files with 282 additions and 106 deletions.
Binary file added assets/font/GROBOLD.ttf
Binary file not shown.
2 changes: 1 addition & 1 deletion assets/meta.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"resource_lookup_skip_list": [
"Elephant"
"GROBOLD"
]
}
17 changes: 12 additions & 5 deletions assets/resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
"1": "monitor",
"2": "alien",
"3": "player",
"5": "Elephant"
"5": "res://font/GROBOLD.ttf"
},
"sub": {
"1": {
"type": "DynamicFont",
"font": "@ext#5",
"size": 20
"size": 25
},
"2": {
"type": "Shader",
Expand Down Expand Up @@ -190,12 +190,12 @@
"anchor_left": 0.5,
"anchor_top": 0.5,
"anchor_right": 0.5,
"margin_bottom": 37,
"margin_bottom": 17,
"margin_left": -106.5,
"margin_top": -28,
"margin_top": -19,
"margin_right": 105.5,
"align": 1,
"text": "GAME OVER",
"text": "GAME OVERg",
"valign": 1,
"font": "@sub#1"
},
Expand All @@ -210,5 +210,12 @@
"margin_right": 239.5
}
]
},
"res://font/GROBOLD.ttf": {
"type": "DynamicFontData",
"filename": "res://font/GROBOLD.ttf",
"family": "GROBOLD",
"ascender": 800,
"descender": -200
}
}
10 changes: 5 additions & 5 deletions assets/scene/demo.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
[ext_resource path="res://image/sprites/monitor.png" type="Texture" id=1]
[ext_resource path="res://image/sprites/alien.png" type="Texture" id=2]
[ext_resource path="res://image/sprites/player.png" type="Texture" id=3]
[ext_resource path="res://font/ELEPHNT.TTF" type="DynamicFontData" id=5]
[ext_resource path="res://font/GROBOLD.ttf" type="DynamicFontData" id=5]

[sub_resource type="DynamicFont" id=1]
size = 20
size = 25
font_data = ExtResource( 5 )

[sub_resource type="Shader" id=2]
Expand Down Expand Up @@ -117,11 +117,11 @@ anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -106.5
margin_top = -28.0
margin_top = -19.0
margin_right = 105.5
margin_bottom = 37.0
margin_bottom = 17.0
custom_fonts/font = SubResource( 1 )
text = "GAME OVER"
text = "GAME OVERg"
align = 1
valign = 1
__meta__ = {
Expand Down
6 changes: 4 additions & 2 deletions fonts.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@font-face {
font-family: 'Elephant';
src: url('media/ELEPHNT.TTF') format(truetype);
font-family: 'GROBOLD';
src: url('media/font/GROBOLD.woff2') format('woff2'),
url('media/font/GROBOLD.woff') format('woff'),
url('media/font/GROBOLD.ttf') format('truetype');
}
Binary file added media/font/ELEPHNT.ttf
Binary file not shown.
Binary file added media/font/ELEPHNT.woff
Binary file not shown.
Binary file added media/font/ELEPHNT.woff2
Binary file not shown.
Binary file added media/font/GROBOLD.ttf
Binary file not shown.
Binary file added media/font/GROBOLD.woff
Binary file not shown.
Binary file added media/font/GROBOLD.woff2
Binary file not shown.
4 changes: 3 additions & 1 deletion src/engine/core/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ export class Engine {

// process resource first
if (res.type !== 'PackedScene') {
normalize_resource_array(res.resource, res.ext || {}, res.sub || {});
if (res.resource) {
normalize_resource_array(res.resource, res.ext || {}, res.sub || {});
}

const ctor = res_class_map[res.type];
if (ctor) {
Expand Down
5 changes: 5 additions & 0 deletions src/engine/drivers/webgl/rasterizer_storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,11 @@ export class RasterizerStorage {
rid.wrap_u = p_flags.wrap_u || WRAP_CLAMP_TO_EDGE;
rid.wrap_v = p_flags.wrap_v || WRAP_CLAMP_TO_EDGE;

if (rid.gl_tex) {
gl.deleteTexture(rid.gl_tex);
rid.gl_tex = null;
}

rid.gl_tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, rid.gl_tex);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, rid.min_filter);
Expand Down
70 changes: 28 additions & 42 deletions src/engine/scene/gui/label.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
VALIGN_BOTTOM,
VALIGN_FILL,
} from "engine/core/math/math_defs";
import { Vector2 } from "engine/core/math/vector2";
import { Vector2, Vector2Like } from "engine/core/math/vector2";
import { Rect2 } from "engine/core/math/rect2";
import { Color } from "engine/core/color";

import { VSG } from "engine/servers/visual/visual_server_globals";
Expand All @@ -25,7 +26,6 @@ import {
NOTIFICATION_RESIZED,
} from "./control";
import { DynamicFont, BitmapFont } from "../resources/font";
import { Rect2 } from "engine/core/math/rect2";

let pos = new Vector2;

Expand Down Expand Up @@ -171,7 +171,8 @@ export class Label extends Control {
const f = this.get_font('font');
if (f.type === 'DynamicFont') {
const font = /** @type {DynamicFont} */(f);
const s = font.get_text_size(this._text);
const width = this._autowrap ? (this.rect_size.x - min_style.x) : this.get_longest_line_width();
const s = font.get_text_size(this._text, width, this.get_constant('line_spacing'));
return size.set(
s.width,
s.height
Expand Down Expand Up @@ -212,42 +213,9 @@ export class Label extends Control {
const text = this._text;
const size = this.rect_size;
const style = this.get_stylebox('normal');
const f = this.get_font('font');
const font_color = this.get_color('font_color');
const line_spacing = this.get_constant('line_spacing');

if (f.type === "DynamicFont") {
const font = /** @type {DynamicFont} */(f);
const texture = font.draw_to_texture(this.canvas_item, this._text, this._align);
switch (this._align) {
case HALIGN_LEFT:
case HALIGN_FILL: {
pos.x = 0;
} break;
case HALIGN_RIGHT: {
pos.x = size.x - texture.get_width();
} break;
case HALIGN_CENTER: {
pos.x = (size.x - texture.get_width()) / 2;
} break;
}
switch (this._valign) {
case VALIGN_TOP:
case VALIGN_FILL: {
pos.y = 0;
} break;
case VALIGN_BOTTOM: {
pos.y = size.y - texture.get_height();
} break;
case VALIGN_CENTER: {
pos.y = (size.y - texture.get_height()) / 2;
} break;
}
texture.draw(this.canvas_item, pos);
return;
}

const font = /** @type {BitmapFont} */(f);
let font = this.get_font('font');

// TODO: draw stylebox

Expand All @@ -268,6 +236,22 @@ export class Label extends Control {
lines_visible = this._max_lines_visible;
}

if (font.type === 'DynamicFont') {
font = /** @type {DynamicFont} */(font);
const texture = font.draw_to_texture(
this.canvas_item,
text,
size,
this._align,
this._valign,
line_spacing,
lines_visible,
this._autowrap ? (size.x - style.get_minimum_size(tmp_vec).x) : this.get_longest_line_width()
);
texture.draw(this.canvas_item, Vector2.ZERO);
return;
}

if (lines_visible > 0) {
switch (this._valign) {
case VALIGN_TOP: {
Expand Down Expand Up @@ -299,7 +283,6 @@ export class Label extends Control {

let line = 0;
let line_to = this._lines_skipped + (lines_visible > 0 ? lines_visible : 1);
let glyph_idx = 0;
while (wc) {
if (line >= line_to) {
break;
Expand Down Expand Up @@ -356,6 +339,7 @@ export class Label extends Control {
y_ofs += (line - this._lines_skipped) * font_h + font.ascent;
y_ofs += vbegin + line * vsep;

font = /** @type {BitmapFont} */(font);
while (from !== to) {
// draw a word
let pos = from.char_pos;
Expand All @@ -379,8 +363,6 @@ export class Label extends Control {
n = n.toUpperCase();
}

glyph_idx++;

const char = font.char_map[c.charCodeAt(0)];

// Update char sprite info
Expand Down Expand Up @@ -419,7 +401,7 @@ export class Label extends Control {
const f = this.get_font('font');
if (f.type === 'DynamicFont') {
let font = /** @type {DynamicFont} */(f);
return font.get_text_size(this._text).width;
return font.get_text_size(this._text, -1, this.get_constant('line_spacing')).width;
}

const font = /** @type {BitmapFont} */(f);
Expand Down Expand Up @@ -506,7 +488,11 @@ export class Label extends Control {
const width = this._autowrap ? (this.rect_size.x - style.get_minimum_size(tmp_vec3).x) : this.get_longest_line_width();
const f = this.get_font('font');

if (f.type === "DynamicFont") return;
if (f.type === "DynamicFont") {
let font = /** @type {DynamicFont} */(f);
this.line_count = font.wrap_lines(text, width).length;
return;
}

const font = /** @type {BitmapFont} */(f);

Expand Down
Loading

0 comments on commit c55a4c9

Please sign in to comment.