#version 330 core

// SDF TrueType font fragment shader (see Verso::SdfFont / verso.truetype).
//
// This is a TEMPLATE. verso.truetype loads it and, when the JSON supplies "fillShader",
// "outlineShader" or "visibilityShader", replaces the body between the matching //BEGIN_* and
// //END_* markers with the user's function. A user snippet is just a GLSL function with the same
// signature; it may use any of the uniforms declared above the markers, plus iTime / iResolution.

in vec2 ex_Uv;      // atlas UV for this glyph
in vec2 ex_TextUv;  // 0..1 across the whole text block

out vec4 fragColor;

uniform sampler2D uSdf;
uniform float alpha;
uniform int uStyle;          // 0 = fill, 1 = outline only, 2 = fill + outline
uniform float uWeight;       // 0.5 nominal; > 0.5 bolder, < 0.5 thinner
uniform float uOutlineWidth; // outline band width in SDF units (0..0.5)
uniform vec4 uFillColor;
uniform vec4 uOutlineColor;
uniform float iTime;
uniform vec2 iResolution;

//BEGIN_FILL
// Colour of the glyph interior. Override by supplying a "fillShader" file that redefines this
// function. Available: uv (atlas), textUv (0..1 across the block), sdf (0..1, 0.5 = edge).
vec4 fillShader(vec2 uv, vec2 textUv, float sdf) {
	return uFillColor;
}
//END_FILL

//BEGIN_OUTLINE
// Colour of the outline band. Override with an "outlineShader" file.
vec4 outlineShader(vec2 uv, vec2 textUv, float sdf) {
	return uOutlineColor;
}
//END_OUTLINE

//BEGIN_VISIBILITY
// Per-fragment visibility mask 0..1 (<= 0 hides the fragment). Override with a "visibilityShader"
// file to reveal / dissolve / wipe which parts of the text are drawn over time.
float visibilityShader(vec2 uv, vec2 textUv) {
	return 1.0;
}
//END_VISIBILITY

void main() {
	float sdf = texture(uSdf, ex_Uv).r;    // 0..1, 0.5 = glyph edge
	float aa = fwidth(sdf);
	float fillT = 0.5 - (uWeight - 0.5);    // higher weight -> lower threshold -> fatter
	float outlineT = fillT - uOutlineWidth;

	float fill = smoothstep(fillT - aa, fillT + aa, sdf);
	float outer = smoothstep(outlineT - aa, outlineT + aa, sdf); // glyph + outline band
	float band = clamp(outer - fill, 0.0, 1.0);

	vec4 fillC = fillShader(ex_Uv, ex_TextUv, sdf);
	vec4 outC = outlineShader(ex_Uv, ex_TextUv, sdf);

	vec4 col;
	float cover;
	if (uStyle == 1) {          // outline only
		col = outC;
		cover = band;
	} else if (uStyle == 2) {   // fill + outline
		col = mix(outC, fillC, fill);
		cover = outer;
	} else {                    // fill
		col = fillC;
		cover = fill;
	}

	float vis = clamp(visibilityShader(ex_Uv, ex_TextUv), 0.0, 1.0);
	float a = cover * col.a * alpha * vis;
	if (a <= 0.0) {
		discard;
	}
	fragColor = vec4(col.rgb, a);
}
