From 199d7389178abc9de3918387e579511051b40dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Thu, 9 Jul 2026 12:07:39 +0200 Subject: [PATCH] Bug 2048531 - Improve selection contrast in dark mode On some OSes, the current approach of using `Highlight`/`HighlightText` colors to draw selected text doesn't work when the OS is set to dark mode, as we revert the `color-scheme` to `light` to compute them (because PDFs are normally in light mode) but that does not affect the `HighlightText` color (which depends not on the `color-scheme` but on the `currentColor`). Other than forcing the `color-scheme` to `light`, set the `color` to `black` and use the `backgroud-color` to compute the `HighlightText` color instead. In OSes where `HighlightText` is theme-dependent this will result in the OS-provided text color, while in OSes where it is `currentColor`-dependent it will be based on the default color for light themes (i.e. black). --- src/display/filter_factory.js | 37 +++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/display/filter_factory.js b/src/display/filter_factory.js index 430cb697e..0819f8117 100644 --- a/src/display/filter_factory.js +++ b/src/display/filter_factory.js @@ -259,7 +259,7 @@ class DOMFilterFactory extends BaseFilterFactory { fgColor = Util.makeHexColor(...fgRGB); const bgRGB = this.#getRGB(bgColor); bgColor = Util.makeHexColor(...bgRGB); - this.#defs.style.color = ""; + this.#resetDefsColor(); if ( (fgColor === "#000000" && bgColor === "#ffffff") || @@ -507,7 +507,7 @@ class DOMFilterFactory extends BaseFilterFactory { newFgRGB, ]; } - this.#defs.style.color = ""; + this.#resetDefsColor(); // Now we can create the filters to highlight some canvas parts. // The colors in the pdf will almost be Canvas and CanvasText, hence we @@ -635,13 +635,8 @@ class DOMFilterFactory extends BaseFilterFactory { this.#appendFeFunc(feComponentTransfer, "feFuncA", aTable); } - #getRGB(color) { - this.#defs.style.color = color; - return getRGB(getComputedStyle(this.#defs).getPropertyValue("color")); - } - /** - * Get the RGBA channels of a color. + * Get the RGB channels of a color. * * @param {string} color * Color in any valid CSS format (such as `x` in `color: x`). @@ -650,9 +645,31 @@ class DOMFilterFactory extends BaseFilterFactory { * the RGB channels are in the range `[0, 255]`; * the alpha channel is in the range `[0, 1]`. */ + #getRGB(color) { + // Some colors on some OSes (e.g. HighlightText in Firefox on macOS) + // are affected by the current text color. Ensure consistent behavior by + // setting it to CanvasText. + this.#defs.style.color = "CanvasText"; + this.#defs.style.backgroundColor = color; + return getRGB( + getComputedStyle(this.#defs).getPropertyValue("background-color") + ); + } + #getRGBA(color) { - this.#defs.style.color = color; - return getRGBA(getComputedStyle(this.#defs).getPropertyValue("color")); + // Some colors on some OSes (e.g. HighlightText in Firefox on macOS) + // are affected by the current text color. Ensure consistent behavior by + // setting it to CanvasText. + this.#defs.style.color = "CanvasText"; + this.#defs.style.backgroundColor = color; + return getRGBA( + getComputedStyle(this.#defs).getPropertyValue("background-color") + ); + } + + #resetDefsColor() { + this.#defs.style.color = ""; + this.#defs.style.backgroundColor = ""; } /**