Skip to content

Commit

Permalink
signed distance field font rendering
Browse files Browse the repository at this point in the history
fixes #19

this requires https://github.com/mapbox/fontserver as a backend as it
relies on glyph images embedded into the tiles
  • Loading branch information
kkaefer committed Oct 16, 2013
1 parent cd85284 commit e1a7bba
Show file tree
Hide file tree
Showing 23 changed files with 1,544 additions and 39,843 deletions.
38,922 changes: 0 additions & 38,922 deletions ArialUnicode.json

This file was deleted.

137 changes: 98 additions & 39 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,34 @@
<script src="js/mrucache.js"></script>
<script src="js/protobuf.js"></script>
<script src="js/glutil.js"></script>
<script src="js/linegeometry.js"></script>
<!-- <script src="js/geometry.js"></script> -->
<script src="js/fillbuffer.js"></script>
<script src="js/vertexbuffer.js"></script>
<script src="js/tile.js"></script>
<script src="js/rastertile.js"></script>
<script src="js/transform.js"></script>
<script src="js/parse_style.js"></script>
<script src="js/style.js"></script>
<script src="js/font.js"></script>
<script src="js/binpack.js"></script>
<script src="js/coordinate.js"></script>
<script src="js/interaction.js"></script>
<script src="js/debug_text.js"></script>
<script src="js/dispatcher.js"></script>
<script src="js/labelcanvas.js"></script>
<script src="js/labeltexture.js"></script>
<!-- <script src="js/labelcanvas.js"></script> -->
<!-- <script src="js/labeltexture.js"></script> -->
<script src="js/imagesprite.js"></script>
<script src="js/glyphatlas.js"></script>
<script src="js/glyphvertexbuffer.js"></script>
<script src="js/map.js"></script>
<script src="js/layer.js"></script>
<script src="js/painter.js"></script>
<script src="js/site.js"></script>

<!-- these are the previous shaders -->
<script id="debug-vertex" type="x-shader/x-vertex">
precision mediump float;

attribute vec2 a_pos;

uniform float u_pointsize;
Expand Down Expand Up @@ -119,58 +125,57 @@

<!-- these are the point shaders -->
<script id="point-vertex" type="x-shader/x-vertex">
precision mediump float;
precision mediump float;

#define scale 63.0
#define root2 1.42
#define scale 63.0
#define root2 1.42

uniform mat4 u_posmatrix;
uniform vec2 u_size;
uniform vec2 u_tpos;
uniform vec2 u_tsize;
uniform mat2 u_rotationmatrix;
uniform mat4 u_posmatrix;
uniform vec2 u_size;
uniform vec2 u_tpos;
uniform vec2 u_tsize;
uniform mat2 u_rotationmatrix;

attribute vec2 a_pos;
attribute vec2 a_slope;
varying mat2 v_rotationmatrix;
attribute vec2 a_pos;
attribute vec2 a_slope;
varying mat2 v_rotationmatrix;

void main(void) {
void main(void) {

gl_Position = u_posmatrix * vec4(floor(a_pos/2.0), 0, 1);
gl_PointSize = u_size.x * root2;
gl_Position = u_posmatrix * vec4(floor(a_pos/2.0), 0, 1);
gl_PointSize = u_size.x * root2;

float angle = atan(a_slope.y, a_slope.x);
float angle = atan(a_slope.y, a_slope.x);

v_rotationmatrix = mat2(
cos(angle), -sin(angle),
sin(angle), cos(angle)
) * u_rotationmatrix;
}
v_rotationmatrix = mat2(
cos(angle), -sin(angle),
sin(angle), cos(angle)
) * u_rotationmatrix;
}

</script>
<script id="point-fragment" type="x-shader/x-fragment">
#define root2 1.42
precision mediump float;

uniform sampler2D u_image;
uniform vec2 u_size;
uniform vec2 u_tpos;
uniform vec2 u_tsize;
#define root2 1.42
precision mediump float;

varying vec2 imageCoords;
varying mat2 v_rotationmatrix;
uniform sampler2D u_image;
uniform vec2 u_size;
uniform vec2 u_tpos;
uniform vec2 u_tsize;

void main(void) {
varying vec2 imageCoords;
varying mat2 v_rotationmatrix;

vec2 pos = v_rotationmatrix * (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5;
vec2 imageCoord = (u_tpos + u_size * pos)/ u_tsize;
void main(void) {

float inbounds = step(0.0, pos.x) * step(0.0, pos.y) *
(1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y));
vec2 pos = v_rotationmatrix * (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5;
vec2 imageCoord = (u_tpos + u_size * pos)/ u_tsize;

gl_FragColor = texture2D(u_image, imageCoord) * inbounds;
}
float inbounds = step(0.0, pos.x) * step(0.0, pos.y) *
(1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y));

gl_FragColor = texture2D(u_image, imageCoord) * inbounds;
}
</script>

<!-- these are the shaders for rendering from a framebuffer -->
Expand Down Expand Up @@ -205,6 +210,8 @@

<!-- these are the shaders for rendering filled areas -->
<script id="area-vertex" type="x-shader/x-vertex">
precision mediump float;

attribute vec2 a_pos;

uniform mat4 u_posmatrix;
Expand Down Expand Up @@ -331,6 +338,8 @@

<!-- these are the shaders for rendering labels -->
<script id="label-vertex" type="x-shader/x-vertex">
precision mediump float;

attribute vec2 a_pos;
attribute vec2 a_offset;
attribute vec2 a_tex;
Expand Down Expand Up @@ -361,6 +370,56 @@
}
</script>

<script id="sdf-vertex" type="x-shader/x-vertex">
precision mediump float;

attribute vec2 a_pos;
attribute vec2 a_offset;
attribute vec2 a_tex;
// TODO: optimize this so we store less data
attribute float a_angle;

// posmatrix is for the vertex position, exmatrix is for rotating and projecting
// the extrusion vector.
uniform mat4 u_posmatrix;
uniform mat4 u_exmatrix;
uniform float u_angle;

uniform vec2 u_texsize;

varying vec2 v_tex;


const float PI_2 = 3.14159268 / 2.0;

void main() {
float rev = 1.0;
if (abs(a_angle + u_angle) > PI_2) rev = -1.0;

gl_Position = u_posmatrix * vec4(a_pos, 0, 1) + rev * u_exmatrix * vec4(a_offset / 64.0, 0, 0);
v_tex = a_tex * 4.0 / u_texsize;
}
</script>



<script id="sdf-fragment" type="x-shader/x-fragment">
precision mediump float;

uniform sampler2D u_texture;
uniform vec4 u_color;
uniform float u_buffer;
uniform float u_gamma;

varying vec2 v_tex;

void main() {
float dist = texture2D(u_texture, v_tex).r;
float alpha = smoothstep(u_buffer - u_gamma, u_buffer + u_gamma, dist);
gl_FragColor = vec4(u_color.rgb, alpha * u_color.a);
// gl_FragColor = vec4(0, 0, 0, 1);
}
</script>
</head>
<body>

Expand Down
53 changes: 53 additions & 0 deletions js/binpack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
function BinPack(width, height) {
this.width = width;
this.height = height;
this.free = [{ x: 0, y: 0, w: width, h: height }];
this.index = {};
}

BinPack.prototype.release = function(rect) {
this.free.push({ x: rect.x, y: rect.y, w: width, h: height });
// TODO: Try to merge with neighboring segments?
};

BinPack.prototype.allocate = function(width, height) {
// Find the smallest free rect angle
var rect = { x: Infinity, y: Infinity, w: Infinity, h: Infinity };
var smallest = -1;
for (var i = 0; i < this.free.length; i++) {
var ref = this.free[i];
if (width <= ref.w && height <= ref.h && ref.y <= rect.y && ref.x <= rect.x) {
rect = ref;
smallest = i;
}
}

if (smallest < 0) {
// There's no space left for this char.
return { x: -1, y: -1 };
} else {
this.free.splice(smallest, 1);

// Shorter/Longer Axis Split Rule (SAS)
// http://clb.demon.fi/files/RectangleBinPack.pdf p. 15
// Ignore the dimension of R and just split long the shorter dimension
// See Also: http://www.cs.princeton.edu/~chazelle/pubs/blbinpacking.pdf
if (rect.w < rect.h) {
// split horizontally
// +--+---+
// |__|___| <-- b1
// +------+ <-- b2
if (rect.w > width) this.free.push({ x: rect.x + width, y: rect.y, w: rect.w - width, h: height });
if (rect.h > height) this.free.push({ x: rect.x, y: rect.y + height, w: rect.w, h: rect.h - height });
} else {
// split vertically
// +--+---+
// |__| | <-- b1
// +--|---+ <-- b2
if (rect.w > width) this.free.push({ x: rect.x + width, y: rect.y, w: rect.w - width, h: rect.h });
if (rect.h > height) this.free.push({ x: rect.x, y: rect.y + height, w: width, h: rect.h - height });
}

return { x: rect.x, y: rect.y, w: width, h: height };
}
};
Loading

0 comments on commit e1a7bba

Please sign in to comment.