summaryrefslogtreecommitdiff
path: root/data/shaders/path-stroke-frag.glsl
blob: 9682c8fec6ab04961a0c220edfbba0ab9944db5e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// -*- mode: c -*-

#ifdef GLSL330
out vec4 fragColor;
#else
#define fragColor gl_FragColor
#endif

#ifdef GLSL120
varying vec2 fragTex;
varying float fragStrokeLength;
#else
in vec2 fragTex;
in float fragStrokeLength;
#endif

uniform vec4 color;
uniform float feather;
uniform int strokeClosed;
uniform float strokeWidth;
uniform int strokeCap;
uniform int strokeMiterStyle;
uniform float strokeMiterLimit;

float infinity = 1.0 / 0.0;

void main(void) {
  if (color.a <= 0.0) {
    discard;
  }

  float hw = strokeWidth / 2.0;
  float u = fragTex.x;
  float v = fragTex.y;
  float dx;
  float dy;
  float d;

  // Stroke caps.
  if (u < 0 || u > fragStrokeLength) {
    if (u < 0) {
      dx = abs(u);
    } else {
      dx = u - fragStrokeLength;
    }
    dy = abs(v);

    if (strokeCap == 0) { // none
      d = infinity;
    } else if (strokeCap == 1) { // butt
      d = max(dx + hw - 2 * feather, dy);
    } else if (strokeCap == 2) { // square
      d = max(dx, dy);
    } else if (strokeCap == 3) { // round
      d = sqrt(dx * dx + dy * dy);
    } else if (strokeCap == 4) { // triangle out
      d = dx + dy;
    } else if (strokeCap == 5) { // triangle in
      d = max(dy, hw - feather + dx - dy);
    }
    // Stroke inner/join
  } else {
    d = abs(v);
  }

  if(d <= hw) {
    fragColor = color;
  } else {
    vec4 c = vec4(color.rgb, color.a * (1.0 - ((d - hw) / feather)));

    if (c.a <= 0.0) {
      discard;
    }

    fragColor = c;
  }
}