aboutsummaryrefslogtreecommitdiff
path: root/alacritty/res/rect.f.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/res/rect.f.glsl')
-rw-r--r--alacritty/res/rect.f.glsl127
1 files changed, 101 insertions, 26 deletions
diff --git a/alacritty/res/rect.f.glsl b/alacritty/res/rect.f.glsl
index ab1d9dcd..9af76ae4 100644
--- a/alacritty/res/rect.f.glsl
+++ b/alacritty/res/rect.f.glsl
@@ -9,46 +9,121 @@ flat in vec4 color;
out vec4 FragColor;
-uniform int isUndercurl;
+uniform int rectKind;
uniform float cellWidth;
uniform float cellHeight;
uniform float paddingY;
uniform float paddingX;
-uniform float undercurlThickness;
+uniform float underlinePosition;
+uniform float underlineThickness;
+
uniform float undercurlPosition;
+#define UNDERCURL 1
+#define DOTTED 2
+#define DASHED 3
+
#define PI 3.1415926538
-void main()
-{
- if (isUndercurl == 0) {
- FragColor = color;
- return;
- }
+vec4 draw_undercurl(int x, int y) {
+ // We use `undercurlPosition` as an amplitude, since it's half of the descent
+ // value.
+ float undercurl =
+ -1. * undercurlPosition / 2. * cos(float(x) * 2 * PI / cellWidth) +
+ cellHeight - undercurlPosition;
- int x = int(gl_FragCoord.x - paddingX) % int(cellWidth);
- int y = int(gl_FragCoord.y - paddingY) % int(cellHeight);
+ float undercurlTop = undercurl + max((underlineThickness - 1), 0);
+ float undercurlBottom = undercurl - max((underlineThickness - 1), 0);
- // We use `undercurlPosition` as amplitude, since it's half of the descent
- // value.
- float undercurl = -1. * undercurlPosition / 2.
- * cos(float(x) * 2 * PI / float(cellWidth))
- + cellHeight - undercurlPosition;
+ // Compute resulted alpha based on distance from `gl_FragCoord.y` to the
+ // cosine curve.
+ float alpha = 1.;
+ if (y > undercurlTop || y < undercurlBottom) {
+ alpha = 1. - min(abs(undercurlTop - y), abs(undercurlBottom - y));
+ }
- // We subtract one, since curve is already 1px thick.
- float undercurl_top = undercurl + max((undercurlThickness - 1), 0);
- float undercurl_bottom = undercurl - max((undercurlThickness - 1), 0);
+ // The result is an alpha mask on a rect, which leaves only curve opaque.
+ return vec4(color.rgb, alpha);
+}
+// When the dot size increases we can use AA to make spacing look even and the
+// dots rounded.
+vec4 draw_dotted_aliased(float x, float y) {
+ int dotNumber = int(x / underlineThickness);
- // Compute resulted alpha based on distance from `gl_FragCoord.y` to the
- // cosine curve.
- float alpha = 1.;
- if (y > undercurl_top || y < undercurl_bottom) {
- alpha = 1. - min(abs(undercurl_top - y), abs(undercurl_bottom - y));
- }
+ float radius = underlineThickness / 2.;
+ float centerY = cellHeight - underlinePosition;
+
+ float leftCenter = (dotNumber - dotNumber % 2) * underlineThickness + radius;
+ float rightCenter = leftCenter + 2 * underlineThickness;
+
+ float distanceLeft = sqrt(pow(x - leftCenter, 2) + pow(y - centerY, 2));
+ float distanceRight = sqrt(pow(x - rightCenter, 2) + pow(y - centerY, 2));
+
+ float alpha = max(1 - (min(distanceLeft, distanceRight) - radius), 0);
+ return vec4(color.rgb, alpha);
+}
+
+/// Draw dotted line when dot is just a single pixel.
+vec4 draw_dotted(int x, int y) {
+ int cellEven = 0;
+
+ // Since the size of the dot and its gap combined is 2px we should ensure that
+ // spacing will be even. If the cellWidth is even it'll work since we start
+ // with dot and end with gap. However if cellWidth is odd, the cell will start
+ // and end with a dot, creating a dash. To resolve this issue, we invert the
+ // pattern every two cells.
+ if (int(cellWidth) % 2 != 0) {
+ cellEven = int((gl_FragCoord.x - paddingX) / cellWidth) % 2;
+ }
- // The result is an alpha mask on a rect, which leaves only curve opaque.
- FragColor = vec4(color.xyz, alpha);
+ // Since we use the entire descent area for dotted underlines, we limit its
+ // height to a single pixel so we don't draw bars instead of dots.
+ float alpha = 1. - abs(round(cellHeight - underlinePosition) - y);
+ if (x % 2 != cellEven) {
+ alpha = 0;
+ }
+
+ return vec4(color.rgb, alpha);
+}
+
+vec4 draw_dashed(int x) {
+ // Since dashes of adjacent cells connect with each other our dash length is
+ // half of the desired total length.
+ int halfDashLen = int(cellWidth) / 4;
+
+ float alpha = 1.;
+
+ // Check if `x` coordinate is where we should draw gap.
+ if (x > halfDashLen && x < cellWidth - halfDashLen - 1) {
+ alpha = 0.;
+ }
+
+ return vec4(color.rgb, alpha);
+}
+
+void main() {
+ int x = int(gl_FragCoord.x - paddingX) % int(cellWidth);
+ int y = int(gl_FragCoord.y - paddingY) % int(cellHeight);
+
+ switch (rectKind) {
+ case UNDERCURL:
+ FragColor = draw_undercurl(x, y);
+ break;
+ case DOTTED:
+ if (underlineThickness < 2) {
+ FragColor = draw_dotted(x, y);
+ } else {
+ FragColor = draw_dotted_aliased(x, y);
+ }
+ break;
+ case DASHED:
+ FragColor = draw_dashed(x);
+ break;
+ default:
+ FragColor = color;
+ break;
+ }
}