From 474b23344aa9152e392eb456c820552404ffafdb Mon Sep 17 00:00:00 2001 From: David Maciejak Date: Sun, 25 Jan 2026 14:17:52 -0500 Subject: [PATCH] wrlib: change default scaling interpolation to Catmull-Rom This patch is implementing a new default Catmull-Rom filter to resize images. Catmull-Rom is a special case of cubic interpolation with B=0 and C=0.5 (in the Mitchell-Netravali formulation). It provides slighlty sharper results than Mitchell with the same performance. Catmull-Rom is a better choice for a window manager as it prioritizes sharpness, making small elements feel crisp. --- wrlib/context.c | 2 +- wrlib/scale.c | 27 ++++++++++++++++++++++++--- wrlib/wraster.h.in | 3 ++- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/wrlib/context.c b/wrlib/context.c index 73044506..6bc4c85a 100644 --- a/wrlib/context.c +++ b/wrlib/context.c @@ -554,7 +554,7 @@ RContext *RCreateContext(Display * dpy, int screen_number, const RContextAttribu if (!(context->attribs->flags & RC_ScalingFilter)) { context->attribs->flags |= RC_ScalingFilter; - context->attribs->scaling_filter = RMitchellFilter; + context->attribs->scaling_filter = RCatmullRomFilter; } /* get configuration from environment variables */ diff --git a/wrlib/scale.c b/wrlib/scale.c index 93c5172d..da715ea5 100644 --- a/wrlib/scale.c +++ b/wrlib/scale.c @@ -244,8 +244,25 @@ static double Mitchell_filter(double t) return (0.0); } -static double (*filterf)(double) = Mitchell_filter; -static double fwidth = Mitchell_support; +#define CatmullRom_support (2.0) + +static double CatmullRom_filter(double t) +{ + double tt; + + tt = t * t; + if (t < 0) + t = -t; + if (t < 1.0) { + return ((1.5 * t * tt) - (2.5 * tt) + 1.0); + } else if (t < 2.0) { + return ((-0.5 * t * tt) + (2.5 * tt) - (4.0 * t) + 2.0); + } + return (0.0); +} + +static double (*filterf)(double) = CatmullRom_filter; +static double fwidth = CatmullRom_support; void wraster_change_filter(RScalingFilter type) { @@ -270,11 +287,15 @@ void wraster_change_filter(RScalingFilter type) filterf = Lanczos3_filter; fwidth = Lanczos3_support; break; - default: case RMitchellFilter: filterf = Mitchell_filter; fwidth = Mitchell_support; break; + default: + case RCatmullRomFilter: + filterf = CatmullRom_filter; + fwidth = CatmullRom_support; + break; } } diff --git a/wrlib/wraster.h.in b/wrlib/wraster.h.in index 6414455e..e197c8d7 100644 --- a/wrlib/wraster.h.in +++ b/wrlib/wraster.h.in @@ -143,7 +143,8 @@ typedef enum { RBellFilter, RBSplineFilter, RLanczos3Filter, - RMitchellFilter + RMitchellFilter, + RCatmullRomFilter } RScalingFilter;