New mum tools
This commit is contained in:
parent
dfec02ebcb
commit
9a98ce5e43
6
Makefile
6
Makefile
|
@ -200,6 +200,9 @@ endif
|
||||||
all: $(NAME)
|
all: $(NAME)
|
||||||
cp -f $(NAME) $(APP)$(EXT)
|
cp -f $(NAME) $(APP)$(EXT)
|
||||||
|
|
||||||
|
$(APP): $(NAME)
|
||||||
|
cp -f $(NAME) $(APP)
|
||||||
|
|
||||||
$(NAME): $(OBJS) $(DEPS)
|
$(NAME): $(OBJS) $(DEPS)
|
||||||
@echo Linking $(NAME)
|
@echo Linking $(NAME)
|
||||||
$(CROSS)$(LD) $^ $(CPPFLAGS) $(LDFLAGS) -L. $(LDPATHS) $(LDLIBS) -o $@
|
$(CROSS)$(LD) $^ $(CPPFLAGS) $(LDFLAGS) -L. $(LDPATHS) $(LDLIBS) -o $@
|
||||||
|
@ -282,6 +285,9 @@ clean:
|
||||||
docs: doc/prosperon.org
|
docs: doc/prosperon.org
|
||||||
make -C doc
|
make -C doc
|
||||||
mv doc/html .
|
mv doc/html .
|
||||||
|
|
||||||
|
api: $(APP)
|
||||||
|
./prosperon run 'for (var i in globalThis) say(i)' | xargs -I {} ./prosperon api {} > docs/api/{}.md
|
||||||
|
|
||||||
TAGINC != find . -name "*.[chj]"
|
TAGINC != find . -name "*.[chj]"
|
||||||
tags: $(TAGINC)
|
tags: $(TAGINC)
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
# spline
|
|
||||||
#### catmull()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### bezier()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
# vector
|
|
||||||
#### dot()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### project()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### inflate()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -241,24 +241,9 @@ function use(file, env = {}, script) {
|
||||||
use.cache = {};
|
use.cache = {};
|
||||||
|
|
||||||
global.check_registers = function (obj) {
|
global.check_registers = function (obj) {
|
||||||
if (typeof obj.update === "function")
|
for (var reg in Register.registries)
|
||||||
obj.timers.push(Register.update.register(obj.update.bind(obj)));
|
if (typeof obj[reg] === 'function')
|
||||||
|
obj.timers.push(Register.registries[reg].register(obj[reg].bind(obj)));
|
||||||
if (typeof obj.physupdate === "function")
|
|
||||||
obj.timers.push(Register.physupdate.register(obj.physupdate.bind(obj)));
|
|
||||||
|
|
||||||
if (typeof obj.draw === "function")
|
|
||||||
obj.timers.push(Register.draw.register(obj.draw.bind(obj), obj));
|
|
||||||
|
|
||||||
if (typeof obj.debug === "function")
|
|
||||||
obj.timers.push(Register.debug.register(obj.debug.bind(obj)));
|
|
||||||
|
|
||||||
if (typeof obj.gui === "function")
|
|
||||||
obj.timers.push(Register.gui.register(obj.gui.bind(obj)));
|
|
||||||
|
|
||||||
if (typeof obj.screengui === "function")
|
|
||||||
obj.timers.push(Register.screengui.register(obj.screengui.bind(obj)));
|
|
||||||
|
|
||||||
for (var k in obj) {
|
for (var k in obj) {
|
||||||
if (!k.startswith("on_")) continue;
|
if (!k.startswith("on_")) continue;
|
||||||
var signal = k.fromfirst("on_");
|
var signal = k.fromfirst("on_");
|
||||||
|
@ -363,11 +348,7 @@ function process() {
|
||||||
}
|
}
|
||||||
var st = profile.now();
|
var st = profile.now();
|
||||||
prosperon.window_render(window.size);
|
prosperon.window_render(window.size);
|
||||||
prosperon.draw();
|
prosperon.render();
|
||||||
prosperon.debug();
|
|
||||||
prosperon.gui();
|
|
||||||
prosperon.screengui();
|
|
||||||
prosperon.hookend?.();
|
|
||||||
profile.addreport(profcache, "render frame", st);
|
profile.addreport(profcache, "render frame", st);
|
||||||
frames.push(profile.secs(profile.now() - startframe));
|
frames.push(profile.secs(profile.now() - startframe));
|
||||||
if (frames.length > 20) frames.shift();
|
if (frames.length > 20) frames.shift();
|
||||||
|
@ -558,7 +539,7 @@ which returns a function that, when invoked, cancels the registry.
|
||||||
var Register = {
|
var Register = {
|
||||||
registries: [],
|
registries: [],
|
||||||
|
|
||||||
add_cb(name) {
|
add_cb(name, e_event = false) {
|
||||||
var n = {};
|
var n = {};
|
||||||
var fns = [];
|
var fns = [];
|
||||||
|
|
||||||
|
@ -579,19 +560,19 @@ var Register = {
|
||||||
};
|
};
|
||||||
|
|
||||||
Register[name] = n;
|
Register[name] = n;
|
||||||
Register.registries.push(n);
|
Register.registries[name] = n;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Register.add_cb("appupdate");
|
Register.add_cb("appupdate", true);
|
||||||
Register.add_cb("update").doc = "Called once per frame.";
|
Register.add_cb("update", true).doc = "Called once per frame.";
|
||||||
Register.add_cb("physupdate");
|
Register.add_cb("physupdate", true);
|
||||||
Register.add_cb("gui");
|
Register.add_cb("gui", true);
|
||||||
Register.add_cb("debug");
|
Register.add_cb("hud", true);
|
||||||
Register.add_cb("draw");
|
Register.add_cb("debug", true);
|
||||||
Register.add_cb("screengui");
|
Register.add_cb("draw", true);
|
||||||
|
|
||||||
var Event = {
|
var Event = {
|
||||||
events: {},
|
events: {},
|
||||||
|
@ -643,8 +624,7 @@ function world_start() {
|
||||||
|
|
||||||
global.mixin("scripts/physics");
|
global.mixin("scripts/physics");
|
||||||
global.mixin("scripts/widget");
|
global.mixin("scripts/widget");
|
||||||
|
global.mixin("scripts/mum");
|
||||||
globalThis.mum = app.spawn("scripts/mum");
|
|
||||||
|
|
||||||
window.title = `Prosperon v${prosperon.version}`;
|
window.title = `Prosperon v${prosperon.version}`;
|
||||||
window.size = [500, 500];
|
window.size = [500, 500];
|
||||||
|
|
|
@ -164,16 +164,6 @@ Mum.button = Mum.text._int.extend({
|
||||||
action() { console.warn("Button has no action."); },
|
action() { console.warn("Button has no action."); },
|
||||||
});
|
});
|
||||||
|
|
||||||
var mumcam = {};
|
|
||||||
mumcam.transform = os.make_transform();
|
|
||||||
mumcam.ortho = true;
|
|
||||||
mumcam.near = 0;
|
|
||||||
mumcam.far = 1000;
|
|
||||||
mumcam.transform.pos = [100,100,-100];
|
|
||||||
mumcam.app = true;
|
|
||||||
|
|
||||||
var textssbo = render.text_ssbo();
|
|
||||||
|
|
||||||
Mum.window = Mum.extend({
|
Mum.window = Mum.extend({
|
||||||
start() {
|
start() {
|
||||||
this.wh = [this.width, this.height];
|
this.wh = [this.width, this.height];
|
||||||
|
@ -190,10 +180,7 @@ Mum.window = Mum.extend({
|
||||||
if (item.hide) return;
|
if (item.hide) return;
|
||||||
item.draw(pos.slice(),this);
|
item.draw(pos.slice(),this);
|
||||||
}, this);
|
}, this);
|
||||||
render.set_camera(mumcam);
|
|
||||||
render.setpipeline(render.textshader.pipe);
|
|
||||||
render.shader_apply_material(render.textshader);
|
|
||||||
var bind = render.sg_bind(render.textshader, shape.quad, {text:render.font.texture}, textssbo);
|
|
||||||
bind.inst = render.flushtext();
|
bind.inst = render.flushtext();
|
||||||
render.spdraw(bind);
|
render.spdraw(bind);
|
||||||
gui.scissor_win();
|
gui.scissor_win();
|
||||||
|
@ -243,12 +230,13 @@ Mum.column = Mum.extend({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
Mum.debug_colors = {
|
Mum.debug_colors = {
|
||||||
bounds: Color.red.slice(),
|
bounds: Color.red.slice(),
|
||||||
margin: Color.blue.slice(),
|
margin: Color.blue.slice(),
|
||||||
padding: Color.green.slice()
|
padding: Color.green.slice()
|
||||||
};
|
};*/
|
||||||
|
|
||||||
Object.values(Mum.debug_colors).forEach(function(v) { v.a = 100; });
|
//Object.values(Mum.debug_colors).forEach(function(v) { v.a = 100; });
|
||||||
|
|
||||||
return { Mum };
|
//return { Mum };
|
||||||
|
|
116
scripts/mum.js
116
scripts/mum.js
|
@ -1,21 +1,107 @@
|
||||||
|
globalThis.mum = {};
|
||||||
var panel;
|
var panel;
|
||||||
|
|
||||||
self.screengui = function()
|
mum.base = {
|
||||||
{
|
padding:[0,0], /* Each element inset with this padding on all sides */
|
||||||
if (panel) panel.gui();
|
offset:[0,0],
|
||||||
|
pos: [0,0],
|
||||||
|
font: "fonts/c64.ttf",
|
||||||
|
selectable: false,
|
||||||
|
selected: false,
|
||||||
|
font_size: 16,
|
||||||
|
text_align: "left", /* left, center, right */
|
||||||
|
scale: 1,
|
||||||
|
angle: 0,
|
||||||
|
anchor: [0,1],
|
||||||
|
background_image: null,
|
||||||
|
hovered: {},
|
||||||
|
text_shadow: {
|
||||||
|
pos: [0,0],
|
||||||
|
color: Color.white,
|
||||||
|
},
|
||||||
|
text_outline: 1, /* outline in pixels */
|
||||||
|
color: Color.white,
|
||||||
|
margin: [0,0], /* Distance between elements for things like columns */
|
||||||
|
width: null,
|
||||||
|
height: null,
|
||||||
|
max_width: Infinity,
|
||||||
|
max_height: Infinity,
|
||||||
|
image_repeat: false,
|
||||||
|
image_repeat_offset: [0,0],
|
||||||
|
debug: false, /* set to true to draw debug boxes */
|
||||||
|
hide: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.prompt = function(msg = "prompt", value = "", list = [], cb = function() {})
|
var post = function() {};
|
||||||
|
var posts = [];
|
||||||
|
|
||||||
|
var context = mum.base;
|
||||||
|
var contexts = [];
|
||||||
|
|
||||||
|
var cursor = [0,0];
|
||||||
|
|
||||||
|
var end = function()
|
||||||
{
|
{
|
||||||
console.info(`creating popup`);
|
post();
|
||||||
panel = Object.create(listpanel);
|
context = contexts.pop();
|
||||||
panel.title = msg;
|
if (!context) context = mum.base;
|
||||||
panel.value = value;
|
}
|
||||||
panel.allassets = list;
|
|
||||||
panel.action = function() {
|
var listpost = function()
|
||||||
cb(panel.value);
|
{
|
||||||
panel = undefined;
|
var height = 0;
|
||||||
}
|
if (context.height) height += context.height;
|
||||||
panel.start();
|
else height += (context.bb.t - context.bb.b);
|
||||||
player[0].control(panel);
|
cursor.y -= height;
|
||||||
|
cursor.y -= context.padding.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pre = function(data)
|
||||||
|
{
|
||||||
|
if (data.hide || context.hide) return true;
|
||||||
|
data.__proto__ = context;
|
||||||
|
contexts.push(context);
|
||||||
|
context = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
mum.list = function(fn, data = {})
|
||||||
|
{
|
||||||
|
if (pre(data)) return;
|
||||||
|
|
||||||
|
cursor = context.pos;
|
||||||
|
cursor = cursor.add(context.offset);
|
||||||
|
posts.push(post);
|
||||||
|
post = listpost;
|
||||||
|
|
||||||
|
fn();
|
||||||
|
post = posts.pop();
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
|
||||||
|
mum.image = function(path, data = {})
|
||||||
|
{
|
||||||
|
if (pre(data)) return;
|
||||||
|
|
||||||
|
var tex = game.texture(path);
|
||||||
|
context.bb = render.image(tex, cursor, context.size);
|
||||||
|
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
|
||||||
|
mum.button = function(str, data = {padding:[4,4]})
|
||||||
|
{
|
||||||
|
if (pre(data)) return;
|
||||||
|
var bb = render.text(str, cursor.add(context.padding), context.size, context.color);
|
||||||
|
render.rectangle([bb.l-context.padding.x, bb.b-context.padding.y], [bb.r+context.padding.y, bb.t+context.padding.y], Color.black);
|
||||||
|
context.bb = bb;
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
|
||||||
|
mum.label = function(str, data = {})
|
||||||
|
{
|
||||||
|
if (pre(data)) return;
|
||||||
|
render.set_font(data.font, data.font_size);
|
||||||
|
context.bb = render.text(str, cursor, context.size, context.color);
|
||||||
|
|
||||||
|
end();
|
||||||
}
|
}
|
|
@ -361,11 +361,13 @@ render.device.doc = `Device resolutions given as [x,y,inches diagonal].`;
|
||||||
var textshader;
|
var textshader;
|
||||||
var circleshader;
|
var circleshader;
|
||||||
var polyshader;
|
var polyshader;
|
||||||
|
var slice9shader;
|
||||||
|
|
||||||
render.init = function() {
|
render.init = function() {
|
||||||
textshader = render.make_shader("shaders/text_base.cg");
|
textshader = render.make_shader("shaders/text_base.cg");
|
||||||
render.spriteshader = render.make_shader("shaders/sprite.cg");
|
render.spriteshader = render.make_shader("shaders/sprite.cg");
|
||||||
render.postshader = render.make_shader("shaders/simplepost.cg");
|
render.postshader = render.make_shader("shaders/simplepost.cg");
|
||||||
|
slice9shader = render.make_shader("shaders/9slice.cg");
|
||||||
circleshader = render.make_shader("shaders/circle.cg");
|
circleshader = render.make_shader("shaders/circle.cg");
|
||||||
polyshader = render.make_shader("shaders/poly.cg");
|
polyshader = render.make_shader("shaders/poly.cg");
|
||||||
|
|
||||||
|
@ -498,20 +500,27 @@ render.window = function(pos, wh, color) {
|
||||||
};
|
};
|
||||||
|
|
||||||
render.text = function(str, pos, size = 1, color = Color.white, wrap = -1, anchor = [0,1], cursor = -1) {
|
render.text = function(str, pos, size = 1, color = Color.white, wrap = -1, anchor = [0,1], cursor = -1) {
|
||||||
|
|
||||||
var bb = render.text_size(str, size, wrap);
|
var bb = render.text_size(str, size, wrap);
|
||||||
var w = bb.r*2;
|
var w = (bb.r - bb.l);
|
||||||
var h = bb.t*2;
|
var h = (bb.t - bb.b);
|
||||||
|
|
||||||
//render.text draws with an anchor on top left corner
|
//render.text draws with an anchor on top left corner
|
||||||
var p = pos.slice();
|
var p = pos.slice();
|
||||||
|
bb.r += pos.x;
|
||||||
|
bb.l += pos.x;
|
||||||
|
bb.t += pos.y;
|
||||||
|
bb.b += pos.y;
|
||||||
|
gui.text(str, p, size, color, wrap, cursor);
|
||||||
|
return bb;
|
||||||
|
|
||||||
p.x -= w * anchor.x;
|
p.x -= w * anchor.x;
|
||||||
bb.r += (w*anchor.x);
|
bb.r += (w*anchor.x);
|
||||||
bb.l += (w*anchor.x);
|
bb.l += (w*anchor.x);
|
||||||
p.y += h * (1 - anchor.y);
|
p.y += h * (1 - anchor.y);
|
||||||
bb.t += h*(1-anchor.y);
|
bb.t += h*(1-anchor.y);
|
||||||
bb.b += h*(1-anchor.y);
|
bb.b += h*(1-anchor.y);
|
||||||
gui.text(str, p, size, color, wrap, cursor);
|
|
||||||
|
|
||||||
return bb;
|
return bb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -528,12 +537,49 @@ render.image = function(tex, pos, scale = 1, rotation = 0, color = Color.white,
|
||||||
var bind = render.sg_bind(render.spriteshader, shape.quad, {diffuse:tex});
|
var bind = render.sg_bind(render.spriteshader, shape.quad, {diffuse:tex});
|
||||||
bind.inst = 1;
|
bind.inst = 1;
|
||||||
render.spdraw(bind);
|
render.spdraw(bind);
|
||||||
|
|
||||||
|
var bb = {};
|
||||||
|
bb.b = pos.y;
|
||||||
|
bb.l = pos.x;
|
||||||
|
bb.t = pos.y + tex.height*scale;
|
||||||
|
bb.r = pos.x + tex.width*scale;
|
||||||
|
return bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
render.slice9 = function(tex, pos, bb, scale = 1, color = Color.white)
|
||||||
|
{
|
||||||
|
var t = os.make_transform();
|
||||||
|
t.pos = pos;
|
||||||
|
t.scale = [scale,scale,scale];
|
||||||
|
render.setpipeline(render.slice9.pipe);
|
||||||
|
render.setunim4(0, render.slice9.vs.unimap.model.slot, t);
|
||||||
|
render.shader_apply_material(render.slice9, {
|
||||||
|
shade: color
|
||||||
|
});
|
||||||
|
var bind = render.sg_bind(render.slice9, shape.quad, {diffuse:tex});
|
||||||
|
bind.inst = 1;
|
||||||
|
render.spdraw(bind);
|
||||||
|
}
|
||||||
|
|
||||||
|
var textssbo = render.text_ssbo();
|
||||||
|
|
||||||
|
render.flush_text = function()
|
||||||
|
{
|
||||||
|
if (!render.textshader) return;
|
||||||
|
render.setpipeline(render.textshader.pipe);
|
||||||
|
render.shader_apply_material(render.textshader);
|
||||||
|
var textbind = render.sg_bind(render.textshader, shape.quad, {text:render.font.texture}, textssbo);
|
||||||
|
textbind.inst = render.flushtext();
|
||||||
|
render.spdraw(textbind);
|
||||||
}
|
}
|
||||||
|
|
||||||
render.fontcache = {};
|
render.fontcache = {};
|
||||||
render.set_font = function(path, size) {
|
render.set_font = function(path, size) {
|
||||||
var fontstr = `${path}-${size}`;
|
var fontstr = `${path}-${size}`;
|
||||||
|
if (render.font && render.fontcache[fontstr] === render.font) return;
|
||||||
if (!render.fontcache[fontstr]) render.fontcache[fontstr] = os.make_font(path, size);
|
if (!render.fontcache[fontstr]) render.fontcache[fontstr] = os.make_font(path, size);
|
||||||
|
|
||||||
|
render.flush_text();
|
||||||
|
|
||||||
gui.font_set(render.fontcache[fontstr]);
|
gui.font_set(render.fontcache[fontstr]);
|
||||||
render.font = render.fontcache[fontstr];
|
render.font = render.fontcache[fontstr];
|
||||||
|
|
41
shaders/9slice.cg
Normal file
41
shaders/9slice.cg
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
@block vert
|
||||||
|
uniform vec4 rect;
|
||||||
|
uniform vec2 diffuse_size;
|
||||||
|
void vert()
|
||||||
|
{
|
||||||
|
pos *= vec3(diffuse_size*rect.zw, 1);
|
||||||
|
uv = (uv*rect.zw)+rect.xy;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@block frag
|
||||||
|
uniform vec4 border;
|
||||||
|
// borders in pixels, x = left, y = bottom, z = right, w = top
|
||||||
|
#define B vec4(10., 20., 30., 20.)
|
||||||
|
|
||||||
|
vec2 uv9slice(vec2 uv, vec2 s, vec4 b)
|
||||||
|
{
|
||||||
|
vec2 t = clamp((s * uv - b.xy) / (s - b.xy - b.zw), 0., 1.);
|
||||||
|
return mix(uv * s, 1. - s * (1. - uv), t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void frag()
|
||||||
|
{
|
||||||
|
vec2 uv = fragCoord/iResolution.xy;
|
||||||
|
vec2 ts = vec2(textureSize(iChannel0, 0));
|
||||||
|
// scaling factor
|
||||||
|
// probably available as uniform irl
|
||||||
|
vec2 s = iResolution.xy / ts;
|
||||||
|
|
||||||
|
// border by texture size, shouldn't be > .5
|
||||||
|
// probably available as uniform irl
|
||||||
|
vec4 b = min(B / ts.xyxy, vec4(.499));
|
||||||
|
uv = uv9slice(uv, s, b);
|
||||||
|
|
||||||
|
vec3 col = vec3(texture(iChannel0, uv).x);
|
||||||
|
|
||||||
|
fragColor = vec4(col,1.0);
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
#include <base.cg>
|
|
@ -1,4 +1,5 @@
|
||||||
#depth off
|
#depth off
|
||||||
|
#blend mix
|
||||||
|
|
||||||
@vs vs
|
@vs vs
|
||||||
in vec2 a_pos;
|
in vec2 a_pos;
|
||||||
|
@ -53,8 +54,8 @@ sampler smp;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
float lettera = texture(sampler2D(text,smp),fuv).r;
|
float lettera = texture(sampler2D(text,smp),fuv).r;
|
||||||
if (lettera < 0.1f) discard;
|
|
||||||
frag();
|
frag();
|
||||||
|
color.a = lettera;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
@block vert
|
@block vert
|
||||||
uniform vec4 emissive;
|
|
||||||
uniform vec4 rect;
|
uniform vec4 rect;
|
||||||
uniform vec2 diffuse_size;
|
uniform vec2 diffuse_size;
|
||||||
void vert()
|
void vert()
|
||||||
|
|
|
@ -80,7 +80,7 @@ struct sFont *MakeSDFFont(const char *fontfile, int height)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sFont *MakeFont(const char *fontfile, int height) {
|
struct sFont *MakeFont(const char *fontfile, int height) {
|
||||||
int packsize = 1024;
|
int packsize = 2048;
|
||||||
|
|
||||||
struct sFont *newfont = calloc(1, sizeof(struct sFont));
|
struct sFont *newfont = calloc(1, sizeof(struct sFont));
|
||||||
newfont->height = height;
|
newfont->height = height;
|
||||||
|
@ -106,11 +106,16 @@ struct sFont *MakeFont(const char *fontfile, int height) {
|
||||||
if (!stbtt_InitFont(&fontinfo, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0))) {
|
if (!stbtt_InitFont(&fontinfo, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0))) {
|
||||||
YughError("Failed to make font %s", fontfile);
|
YughError("Failed to make font %s", fontfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ascent, descent, linegap;
|
||||||
|
|
||||||
stbtt_GetFontVMetrics(&fontinfo, &newfont->ascent, &newfont->descent, &newfont->linegap);
|
stbtt_GetFontVMetrics(&fontinfo, &ascent, &descent, &linegap);
|
||||||
//newfont->emscale = stbtt_ScaleForMappingEmToPixels(&fontinfo, 16);
|
float emscale = stbtt_ScaleForPixelHeight(&fontinfo, height);
|
||||||
newfont->emscale = stbtt_ScaleForPixelHeight(&fontinfo, height);
|
newfont->ascent = ascent*emscale;
|
||||||
newfont->linegap = (newfont->ascent - newfont->descent) * newfont->emscale*1.5;
|
newfont->descent = descent*emscale;
|
||||||
|
newfont->linegap = linegap*emscale;
|
||||||
|
newfont->linegap = ((newfont->ascent - newfont->descent) - newfont->linegap);
|
||||||
|
printf("newfont : %g, %g, %g\n", newfont->ascent, newfont->descent, newfont->linegap);
|
||||||
|
|
||||||
newfont->texture = malloc(sizeof(texture));
|
newfont->texture = malloc(sizeof(texture));
|
||||||
newfont->texture->id = sg_make_image(&(sg_image_desc){
|
newfont->texture->id = sg_make_image(&(sg_image_desc){
|
||||||
|
@ -137,12 +142,9 @@ struct sFont *MakeFont(const char *fontfile, int height) {
|
||||||
r.y = (glyph.y0) / (float)packsize;
|
r.y = (glyph.y0) / (float)packsize;
|
||||||
r.h = (glyph.y1-glyph.y0) / (float)packsize;
|
r.h = (glyph.y1-glyph.y0) / (float)packsize;
|
||||||
|
|
||||||
stbtt_GetCodepointHMetrics(&fontinfo, c, &newfont->Characters[c].Advance, &newfont->Characters[c].leftbearing);
|
|
||||||
newfont->Characters[c].leftbearing *= newfont->emscale;
|
|
||||||
|
|
||||||
newfont->Characters[c].Advance = glyph.xadvance; /* x distance from this char to the next */
|
newfont->Characters[c].Advance = glyph.xadvance; /* x distance from this char to the next */
|
||||||
newfont->Characters[c].Size[0] = glyph.x1 - glyph.x0;
|
newfont->Characters[c].Size[0] = (glyph.x1 - glyph.x0);
|
||||||
newfont->Characters[c].Size[1] = glyph.y1 - glyph.y0;
|
newfont->Characters[c].Size[1] = (glyph.y1 - glyph.y0);
|
||||||
newfont->Characters[c].Bearing[0] = glyph.xoff;
|
newfont->Characters[c].Bearing[0] = glyph.xoff;
|
||||||
newfont->Characters[c].Bearing[1] = glyph.yoff2;
|
newfont->Characters[c].Bearing[1] = glyph.yoff2;
|
||||||
newfont->Characters[c].rect = r;
|
newfont->Characters[c].rect = r;
|
||||||
|
@ -202,8 +204,6 @@ void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgb
|
||||||
|
|
||||||
struct text_vert vert;
|
struct text_vert vert;
|
||||||
|
|
||||||
float lsize = 1.0 / 1024.0;
|
|
||||||
|
|
||||||
vert.pos.x = cursor.X + c.Bearing[0] * scale;
|
vert.pos.x = cursor.X + c.Bearing[0] * scale;
|
||||||
vert.pos.y = cursor.Y - c.Bearing[1] * scale;
|
vert.pos.y = cursor.Y - c.Bearing[1] * scale;
|
||||||
vert.wh.x = c.Size[0] * scale;
|
vert.wh.x = c.Size[0] * scale;
|
||||||
|
@ -290,7 +290,12 @@ struct boundingbox text_bb(const char *text, float scale, float lw, float tracki
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cwh2bb((HMM_Vec2){0,0}, (HMM_Vec2){cursor.X,use_font->linegap-cursor.Y});
|
return (struct boundingbox){
|
||||||
|
.b = cursor.Y + use_font->descent,
|
||||||
|
.t = cursor.Y + use_font->ascent,
|
||||||
|
.l = 0,
|
||||||
|
.r = cursor.X
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_caret(int caret, int l, HMM_Vec2 pos, float scale, struct rgba color)
|
void check_caret(int caret, int l, HMM_Vec2 pos, float scale, struct rgba color)
|
||||||
|
|
|
@ -22,10 +22,9 @@ struct Character {
|
||||||
struct sFont {
|
struct sFont {
|
||||||
uint32_t fontTexture;
|
uint32_t fontTexture;
|
||||||
uint32_t height; /* in pixels */
|
uint32_t height; /* in pixels */
|
||||||
int ascent;
|
float ascent;
|
||||||
int descent;
|
float descent;
|
||||||
int linegap;
|
float linegap;
|
||||||
float emscale;
|
|
||||||
struct Character Characters[256];
|
struct Character Characters[256];
|
||||||
sg_image texID;
|
sg_image texID;
|
||||||
texture *texture;
|
texture *texture;
|
||||||
|
|
|
@ -617,7 +617,6 @@ int point2segindex(HMM_Vec2 p, HMM_Vec2 *segs, double slop) {
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JSC_GETSET(warp_gravity, strength, number)
|
JSC_GETSET(warp_gravity, strength, number)
|
||||||
JSC_GETSET(warp_gravity, decay, number)
|
JSC_GETSET(warp_gravity, decay, number)
|
||||||
JSC_GETSET(warp_gravity, spherical, boolean)
|
JSC_GETSET(warp_gravity, spherical, boolean)
|
||||||
|
|
Loading…
Reference in a new issue