tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cs_line_decoration.glsl (5861B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2  * License, v. 2.0. If a copy of the MPL was not distributed with this
      3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include shared
      6 
      7 #define LINE_STYLE_SOLID        0
      8 #define LINE_STYLE_DOTTED       1
      9 #define LINE_STYLE_DASHED       2
     10 #define LINE_STYLE_WAVY         3
     11 
     12 // Fragment position in the coordinate system used for positioning decorations.
     13 // To keep the code independent of whether the line is horizontal or vertical,
     14 // vLocalPos.x is always parallel, and .y always perpendicular, to the line
     15 // being decorated.
     16 varying highp vec2 vLocalPos;
     17 
     18 // Line style. Packed in to a vector to work around bug 1630356.
     19 flat varying mediump ivec2 vStyle;
     20 
     21 flat varying mediump vec4 vParams;
     22 
     23 #ifdef WR_VERTEX_SHADER
     24 
     25 // The size of the mask tile we're rendering, in pixels.
     26 PER_INSTANCE in vec4 aTaskRect;
     27 
     28 // The size of the mask tile. aLocalSize.x is always horizontal and .y vertical,
     29 // regardless of the line's orientation. The size is chosen by
     30 // prim_store::line_dec::get_line_decoration_sizes.
     31 PER_INSTANCE in vec2 aLocalSize;
     32 
     33 // A LINE_STYLE_* value, indicating what sort of line to draw.
     34 PER_INSTANCE in int aStyle;
     35 
     36 // 0.0 for a horizontal line, 1.0 for a vertical line.
     37 PER_INSTANCE in float aAxisSelect;
     38 
     39 // The thickness of the wavy line itself, not the amplitude of the waves (i.e.,
     40 // the thickness of the final decorated line).
     41 PER_INSTANCE in float aWavyLineThickness;
     42 
     43 void main(void) {
     44     vec2 size = mix(aLocalSize, aLocalSize.yx, aAxisSelect);
     45     vStyle.x = aStyle;
     46 
     47     switch (vStyle.x) {
     48         case LINE_STYLE_SOLID: {
     49             break;
     50         }
     51         case LINE_STYLE_DASHED: {
     52             vParams = vec4(size.x,          // period
     53                            0.5 * size.x,    // dash length
     54                            0.0,
     55                            0.0);
     56             break;
     57         }
     58         case LINE_STYLE_DOTTED: {
     59             float diameter = size.y;
     60             float period = diameter * 2.0;
     61             float center_line = 0.5 * size.y;
     62             vParams = vec4(period,
     63                            diameter / 2.0, // radius
     64                            center_line,
     65                            0.0);
     66             break;
     67         }
     68         case LINE_STYLE_WAVY: {
     69             // This logic copied from gecko to get the same results
     70             float line_thickness = max(aWavyLineThickness, 1.0);
     71             // Difference in height between peaks and troughs
     72             // (and since slopes are 45 degrees, the length of each slope)
     73             float slope_length = size.y - line_thickness;
     74             // Length of flat runs
     75             float flat_length = max((line_thickness - 1.0) * 2.0, 1.0);
     76 
     77             vParams = vec4(line_thickness / 2.0,
     78                            slope_length,
     79                            flat_length,
     80                            size.y);
     81             break;
     82         }
     83         default:
     84             vParams = vec4(0.0);
     85     }
     86 
     87     vLocalPos = mix(aPosition.xy, aPosition.yx, aAxisSelect) * size;
     88 
     89     gl_Position = uTransform * vec4(mix(aTaskRect.xy, aTaskRect.zw, aPosition.xy), 0.0, 1.0);
     90 }
     91 #endif
     92 
     93 #ifdef WR_FRAGMENT_SHADER
     94 
     95 #define MAGIC_WAVY_LINE_AA_SNAP         0.5
     96 
     97 void main(void) {
     98     // Find the appropriate distance to apply the step over.
     99     vec2 pos = vLocalPos;
    100     float aa_range = compute_aa_range(pos);
    101     float alpha = 1.0;
    102 
    103     switch (vStyle.x) {
    104         case LINE_STYLE_SOLID: {
    105             break;
    106         }
    107         case LINE_STYLE_DASHED: {
    108             // Calculate dash alpha (on/off) based on dash length
    109             alpha = step(floor(pos.x + 0.5), vParams.y);
    110             break;
    111         }
    112         case LINE_STYLE_DOTTED: {
    113             // Get the dot alpha
    114             vec2 dot_relative_pos = pos - vParams.yz;
    115             float dot_distance = length(dot_relative_pos) - vParams.y;
    116             alpha = distance_aa(aa_range, dot_distance);
    117             break;
    118         }
    119         case LINE_STYLE_WAVY: {
    120             float half_line_thickness = vParams.x;
    121             float slope_length = vParams.y;
    122             float flat_length = vParams.z;
    123             float vertical_bounds = vParams.w;
    124             // Our pattern is just two slopes and two flats
    125             float half_period = slope_length + flat_length;
    126 
    127             float mid_height = vertical_bounds / 2.0;
    128             float peak_offset = mid_height - half_line_thickness;
    129             // Flip the wave every half period
    130             float flip = -2.0 * (step(mod(pos.x, 2.0 * half_period), half_period) - 0.5);
    131             // float flip = -1.0;
    132             peak_offset *= flip;
    133             float peak_height = mid_height + peak_offset;
    134 
    135             // Convert pos to a local position within one half period
    136             pos.x = mod(pos.x, half_period);
    137 
    138             // Compute signed distance to the 3 lines that make up an arc
    139             float dist1 = distance_to_line(vec2(0.0, peak_height),
    140                                            vec2(1.0, -flip),
    141                                            pos);
    142             float dist2 = distance_to_line(vec2(0.0, peak_height),
    143                                            vec2(0, -flip),
    144                                            pos);
    145             float dist3 = distance_to_line(vec2(flat_length, peak_height),
    146                                            vec2(-1.0, -flip),
    147                                            pos);
    148             float dist = abs(max(max(dist1, dist2), dist3));
    149 
    150             // Apply AA based on the thickness of the wave
    151             alpha = distance_aa(aa_range, dist - half_line_thickness);
    152 
    153             // Disable AA for thin lines
    154             if (half_line_thickness <= 1.0) {
    155                 alpha = 1.0 - step(alpha, MAGIC_WAVY_LINE_AA_SNAP);
    156             }
    157 
    158             break;
    159         }
    160         default: break;
    161     }
    162 
    163     oFragColor = vec4(alpha);
    164 }
    165 #endif