diff --git a/src/effect/rounded-corners-effect.ts b/src/effect/rounded-corners-effect.ts index 09a8e1b..f585ea0 100644 --- a/src/effect/rounded-corners-effect.ts +++ b/src/effect/rounded-corners-effect.ts @@ -22,6 +22,7 @@ const { declarations, code } = loadShader ( class Uniforms { bounds = 0 clip_radius = 0 + smoothing = 0 inner_bounds = 0 inner_clip_radius = 0 pixel_step = 0 @@ -54,6 +55,7 @@ export default registerClass ( Effect.uniforms = { bounds: 0, clip_radius: 0, + smoothing: 0, inner_bounds: 0, inner_clip_radius: 0, pixel_step: 0, @@ -123,7 +125,7 @@ export default registerClass ( const border_color = border.color const radius = corners_cfg.border_radius * scale_factor - const { padding } = corners_cfg + const { padding, smoothing } = corners_cfg const bounds = [ outer_bounds.x1 + padding.left * scale_factor, @@ -152,6 +154,7 @@ export default registerClass ( this.set_uniform_float (location.inner_bounds, 4, inner_bounds) this.set_uniform_float (location.pixel_step, 2, pixel_step) this.set_uniform_float (location.border_width, 1, [border_width]) + this.set_uniform_float (location.smoothing, 1, [smoothing]) this.set_uniform_float (location.clip_radius, 1, [radius]) this.set_uniform_float (location.border_color, 4, border_color) this.set_uniform_float (location.inner_clip_radius, 1, [ diff --git a/src/effect/shader/rounded_corners.frag b/src/effect/shader/rounded_corners.frag index 513b8a6..01f17f6 100644 --- a/src/effect/shader/rounded_corners.frag +++ b/src/effect/shader/rounded_corners.frag @@ -4,8 +4,6 @@ // With a litte change to make it works well with windows // The uniforms variables for controls -// varying vec2 vsPos; - uniform vec4 bounds; // x, y: top left; z, w: bottom right uniform float clip_radius; uniform vec4 inner_bounds; @@ -14,58 +12,94 @@ uniform vec2 pixel_step; uniform float skip; uniform float border_width; uniform vec4 border_color; +uniform float smoothing; + + +float circle_bounds(vec2 p, vec2 center, float clip_radius) { + vec2 delta = p - vec2(center.x, center.y); + float dist_squared = dot(delta, delta); + + // Fully outside the circle + float outer_radius = clip_radius + 0.5; + if(dist_squared >= (outer_radius * outer_radius)) + return 0.0; + + // Fully inside the circle + float inner_radius = clip_radius - 0.5; + if(dist_squared <= (inner_radius * inner_radius)) + return 1.0; + + // Only pixels on the edge of the curve need expensive antialiasing + return outer_radius - sqrt(dist_squared); +} + +float squircle_bounds(vec2 p, vec2 center, float clip_radius, float exponent) { + vec2 delta = abs(p - center); + + float pow_dx = pow(delta.x, exponent); + float pow_dy = pow(delta.y, exponent); + + float dist = pow(pow_dx + pow_dy, 1.0 / exponent); + + return clamp(clip_radius - dist + 0.5, 0.0, 1.0); +} -float rounded_rect_coverage(vec2 p, vec4 bounds, float clip_radius) { +float rounded_rect_coverage(vec2 p, vec4 bounds, float clip_radius, float exponent) { // Outside the bounds if(p.x < bounds.x || p.x > bounds.z || p.y < bounds.y || p.y > bounds.w) { return 0.0; } + + vec2 center; + float center_left = bounds.x + clip_radius; float center_right = bounds.z - clip_radius; - float center_x; if(p.x < center_left) - center_x = center_left; + center.x = center_left; else if(p.x > center_right) - center_x = center_right; + center.x = center_right; else return 1.0; // The vast majority of pixels exit early here float center_top = bounds.y + clip_radius; float center_bottom = bounds.w - clip_radius; - float center_y; if(p.y < center_top) - center_y = center_top; + center.y = center_top; else if(p.y > center_bottom) - center_y = center_bottom; + center.y = center_bottom; else return 1.0; + + if(exponent <= 2.0) { + return circle_bounds(p, center, clip_radius); + } else { + return squircle_bounds(p, center, clip_radius, exponent); + } +} - vec2 delta = p - vec2(center_x, center_y); - float dist_squared = dot(delta, delta); +void main() { + if(skip < 1.0) { + + float exponent = smoothing * 10.0 + 2.0; - // Fully outside the circle - float outer_radius = clip_radius + 0.5; - if(dist_squared >= (outer_radius * outer_radius)) - return 0.0; + float radius = clip_radius * 0.5 * exponent; - // Fully inside the circle - float inner_radius = clip_radius - 0.5; - if(dist_squared <= (inner_radius * inner_radius)) - return 1.0; + float max_radius = min(bounds.z - bounds.x, bounds.w - bounds.y) * 0.5; - // Only pixels on the edge of the curve need expensive antialiasing - return outer_radius - sqrt(dist_squared); -} + if(radius > max_radius) { + exponent *= max_radius / radius; + radius = max_radius; + } + + float inner_radius = inner_clip_radius * (radius / clip_radius); -void main() { - if(skip < 1.0) { vec2 texture_coord = cogl_tex_coord0_in.xy / pixel_step; - float outer_alpha = rounded_rect_coverage(texture_coord, bounds, clip_radius); + float outer_alpha = rounded_rect_coverage(texture_coord, bounds, radius, exponent); if(border_width > 0.1) { - float inner_alpha = rounded_rect_coverage(texture_coord, inner_bounds, inner_clip_radius); + float inner_alpha = rounded_rect_coverage(texture_coord, inner_bounds, inner_radius, exponent); float border_alpha = clamp(outer_alpha - inner_alpha, 0.0, 1.0) * cogl_color_out.a; cogl_color_out = mix(cogl_color_out, vec4(border_color.rgb, 1.0), border_alpha * border_color.a); diff --git a/src/manager/rounded-corners-manager.ts b/src/manager/rounded-corners-manager.ts index 01ba4b8..81e7ada 100644 --- a/src/manager/rounded-corners-manager.ts +++ b/src/manager/rounded-corners-manager.ts @@ -249,6 +249,11 @@ export class RoundedCornersManager { } const { left, right, top, bottom } = padding + // Increasing border_radius when smoothing is on + if (this.global_rounded_corners !== null) { + border_radius *= 1.0 + this.global_rounded_corners.smoothing + } + // Sadly, the scale of style of St.Widget may be different between scale // of window if there are two monitor with different scale factor. // - Scale of Style always as same as primary monitor diff --git a/src/preferences/widgets/rounded-corners-item.ts b/src/preferences/widgets/rounded-corners-item.ts index 732242c..3a76b5d 100644 --- a/src/preferences/widgets/rounded-corners-item.ts +++ b/src/preferences/widgets/rounded-corners-item.ts @@ -16,6 +16,7 @@ export default GObject.registerClass ( InternalChildren: [ 'rounded_in_maximized_switch', 'border_radius_scale', + 'smoothing_scale', 'padding_left_scale', 'padding_right_scale', 'padding_top_scale', @@ -28,6 +29,7 @@ export default GObject.registerClass ( class extends Gtk.ListBox { private _rounded_in_maximized_switch !: Gtk.Switch private _border_radius_scale !: Gtk.Scale + private _smoothing_scale !: Gtk.Scale private _padding_left_scale !: Gtk.Scale private _padding_right_scale !: Gtk.Scale private _padding_top_scale !: Gtk.Scale @@ -43,6 +45,7 @@ export default GObject.registerClass ( super._init () this._scales = [ this._border_radius_scale, + this._smoothing_scale, this._padding_bottom_scale, this._padding_left_scale, this._padding_right_scale, @@ -90,6 +93,7 @@ export default GObject.registerClass ( }, keep_rounded_corners: this._rounded_in_maximized_switch.active, border_radius: this._border_radius_scale.get_value (), + smoothing: this._smoothing_scale.get_value (), enabled: true, } } @@ -97,6 +101,7 @@ export default GObject.registerClass ( set cfg (cfg: RoundedCornersCfg) { this._rounded_in_maximized_switch.active = cfg.keep_rounded_corners this._border_radius_scale.set_value (cfg.border_radius) + this._smoothing_scale.set_value (cfg.smoothing) this._padding_left_scale.set_value (cfg.padding.left) this._padding_right_scale.set_value (cfg.padding.right) this._padding_top_scale.set_value (cfg.padding.top) diff --git a/src/preferences/widgets/rounded-corners-item.ui b/src/preferences/widgets/rounded-corners-item.ui index 975eee4..812e876 100644 --- a/src/preferences/widgets/rounded-corners-item.ui +++ b/src/preferences/widgets/rounded-corners-item.ui @@ -37,6 +37,40 @@ + + + Don't Configuration in Custom Page + + + + + center + true + vertical + + + start + Corner Smoothing + + + + + + + true + center + 280 + true + 1 + horizontal + smoothing_ajustment + right + + + + + + @@ -270,6 +304,12 @@ 40 1 1 + + + 0 + 1 + 0.1 + 0.1 0 diff --git a/src/utils/types.ts b/src/utils/types.ts index e656377..00b3e6c 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -17,6 +17,7 @@ export class Padding { export interface RoundedCornersCfg { keep_rounded_corners: boolean border_radius: number + smoothing: number padding: Padding enabled: boolean }