User:Jgottula/hydradark.css

/* NOTE: MediaWiki concatenates [user common.css + user hydradark.css] *      and then puts a element in in the initial HTML document *      (so any modifications made here should be instantaneous, unlike user JS) */

/* basically all of my user tweaks from here got integrated into the site css without even having to ask... sweet! */

/* TODO: alpha is slightly too low for top-of-page tabs that lack .selected */ /* TODO: additionally, dropdown menus (e.g. the More menu, div#p-cactions / .vectorMenu) should probably be same alpha as .selected tabs */

/* apply 'image-rendering: pixelated;' to JUST the background-image (making it less mushy/ugly) * while avoiding unintended auto-inheritance to everything else */ html { /* we actually have to put the property up here so it happens "before" the 'body' rule's background-image property */ image-rendering: pixelated; /* TODO: consider putting in fallbacks similar to the '#content img:not(.no-pixel)' rule * (or maybe don't; see long, disgusting explanation below) */ } html > :not(body), body > * { /* and then here, we "reset" the property back to normal for everything other than ; at least in theory */ image-rendering: auto; /* this is VERY wrong (ignores user-agent styles, among myriad other things) */ } /* if this were to be applied to the actual site CSS, less hacky methods could be used: * 1. just put the 'image-rendering: pixelated' property (and any compat properties too... ugh) into the '.page-' rules themselves (for background images for which it makes sense) *   (actually come to think of it, maybe make one big rule for '.page-, .page-, [...], .page-' so that this shit doesn't have to be duplicated in every damn block... *     as long as that actually works correctly and does indeed apply the 'image-rendering' property "before" the 'background-image' property, which I'm not 100% sure about) * 2. also put it into the 'body' rule right alongside the background-image property for all the non-specialized-background pages (if appropriate for the image, again) * 3. then, probably just put a 'body > *' rule that does 'image-rendering: auto' to "reset" things as reasonably as possible (doesn't respect stuff like user agent defaults but who gives a shit) */

/* make it easier to see the background, just for the moment... */ /*div#content { visibility: hidden !important; }*/

/* NOTE: Chromium [blink/skia] details:

[GENERATED] third_party/blink/renderer/core/css_value_keywords.h	enum class CSSValidID { kAuto                  = 405, kOptimizeSpeed         = 630, kOptimizeQuality       = 667, kPixelated             = 668, kWebkitOptimizeContrast = 669, }; // (irrelevant values omitted) [GENERATED] third_party/blink/renderer/core/style/computed_style_base_constants.h	enum class EImageRendering : unsigned { kAuto                  = 0, kOptimizespeed         = 1, kOptimizequality       = 2, kPixelated             = 3, kWebkitOptimizeContrast = 4, }; [GENERATED] third_party/blink/renderer/core/style/computed_style_initial_values.h	static EImageRendering ComputedStyleInitialValues::InitialImageRendering { return EImageRendering::kAuto; } [GENERATED] third_party/blink/renderer/core/css/css_value_id_mappings_generated.h	template <> inline EImageRendering cssValueIDToPlatformEnumGenerated(CSSValueID v) { ... }	inline CSSValueID platformEnumToCSSValueIDGenerated(EImageRendering v) { ... } third_party/blink/renderer/platform/graphics/graphics_types.h	enum InterpolationQuality { kInterpolationNone   = kNone_SkFilterQuality, kInterpolationLow    = kLow_SkFilterQuality, kInterpolationMedium = kMedium_SkFilterQuality, #if defined(WTF_USE_LOW_QUALITY_IMAGE_INTERPOLATION) kInterpolationDefault = kInterpolationLow, #else kInterpolationDefault = kInterpolationMedium, #endif }; third_party/blink/renderer/core/style/computed_style.cc	InterpolationQuality ComputedStyle::GetInterpolationQuality const { if (ImageRendering == EImageRendering::kPixelated)             return kInterpolationNone; if (ImageRendering == EImageRendering::kWebkitOptimizeContrast) return kInterpolationLow; return kInterpolationDefault; }

third_party/skia/include/core/SkFilterQuality.h	enum SkFilterQuality { kNone_SkFilterQuality  = 0,    //!< nearest-neighbor; fastest but lowest quality kLow_SkFilterQuality   = 1,    //!< bilerp kMedium_SkFilterQuality = 2,   //!< bilerp + mipmaps; good for down-scaling kHigh_SkFilterQuality  = 3,    //!< bicubic resampling; slowest but good quality }; third_party/skia/include/core/SkSamplingOptions.h + third_party/skia/src/image/SkImage.cpp enum class SkFilterMode { kNearest,  // single sample point (nearest neighbor) kLinear,   // interporate between 2x2 sample points (bilinear interpolation) };	enum class SkMipmapMode { kNone,     // ignore mipmap levels, sample from the "base" kNearest,  // sample from the nearest level kLinear,   // interpolate between the two nearest levels };	struct SkCubicResampler { float B, C;		// Historic default for kHigh_SkFilterQuality static constexpr SkCubicResampler Mitchell { return {1/3.0f, 1/3.0f}; } static constexpr SkCubicResampler CatmullRom { return {0.0f, 1/2.0f}; } };	struct SK_API SkSamplingOptions { const bool            useCubic = false; const SkCubicResampler cubic   = {0, 0}; const SkFilterMode    filter   = SkFilterMode::kNearest; const SkMipmapMode    mipmap   = SkMipmapMode::kNone; enum MediumBehavior { kMedium_asMipmapNearest,   // historic cpu behavior kMedium_asMipmapLinear,    // historic gpu behavior };		        SkSamplingOptions(SkFilterMode fm, SkMipmapMode mm) : useCubic(false), filter(fm), mipmap(mm)                  {} explicit SkSamplingOptions(SkFilterMode fm)                 : useCubic(false), filter(fm), mipmap(SkMipmapMode::kNone) {} explicit SkSamplingOptions(const SkCubicResampler& c)       : useCubic(true),  cubic(c)                                {}

explicit SkSamplingOptions(SkFilterQuality fq, MediumBehavior behavior = kMedium_asMipmapNearest) {			switch (fq) { case SkFilterQuality::kHigh_SkFilterQuality: *this = SkSamplingOptions(SkCubicResampler{1/3.0f, 1/3.0f}); break; case SkFilterQuality::kMedium_SkFilterQuality: *this = SkSamplingOptions(SkFilterMode::kLinear, behavior == kMedium_asMipmapNearest ? SkMipmapMode::kNearest : SkMipmapMode::kLinear); break; case SkFilterQuality::kLow_SkFilterQuality: *this = SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone); break; case SkFilterQuality::kNone_SkFilterQuality: *this = SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone); break; }		}	};

okay, so, after a couple hours looking through the Chromium source code base, the short version is basically that you're fucked: - your five choices are actually two (or debatably three-ish) choices - and those choices are nearest-neighbor and bilinear and why is it so, you ask? because fuck you, that's why. Google hates you personally.

CSS string => EImageRendering => InterpolationQuality => SkFilterQuality => SkSamplingOptions

=
================================================================================  'auto'                      => kAuto                   => kInterpolationDefault => kMedium_SkFilterQuality => bilinear filtering with mipmaps 'pixelated'                => kPixelated              => kInterpolationNone    => kNone_SkFilterQuality   => nearest neighbor ^! '-webkit-optimize-contrast' => kWebkitOptimizeContrast => kInterpolationLow    => kLow_SkFilterQuality    => bilinear filtering @ 'crisp-edges' @ 'high-quality' @ 'smooth'
 * 1) ! 'optimizespeed'            => kOptimizespeed          => kInterpolationDefault => kMedium_SkFilterQuality => bilinear filtering with mipmaps
 * 2) ! 'optimizequality'          => kOptimizequality        => kInterpolationDefault => kMedium_SkFilterQuality => bilinear filtering with mipmaps

LEGEND: ^ non-standard vendor-specific property (everybody loves those!) @ exists in the standard but Chromium hasn't bothered to implement it ! doesn't actually do what the standard says it should do (sometimes flagrantly so)
 * 1) deprecated and should probably go away

('initial' is equivalent to 'auto') ('crisp-edges' should exist; Chromium effectively uses '-webkit-optimize-contrast' as an alias for it but doesn't support 'crisp-edges' itself; oh yeah and the whole point of 'crisp-edges' is to specifically use a NON-SMOOTH algorithm like nearest neighbor or a smart pixel-art scaler, but Chromium does bilinear because fuck you) ('high-quality' should exist; Chromium doesn't bother implementing it) ('smooth'      should exist; Chromium doesn't bother implementing it) ('optimizespeed'  is deprecated and should act as an alias for 'pixelated'; Chromium treats it as an alias for 'auto', even though 'pixelated' is supported) ('optimizequality' is deprecated and should act as an alias for   'smooth'; Chromium treats it as an alias for 'auto', probably because 'smooth' isn't supported)

so basically your actual options are 'auto'                     = bilinear 'pixelated'                = nearest neighbor '-webkit-optimize-contrast' = bilinear except a bit shittier (for that super-authentic "crisp edges" effect)

oh god what a clusterfuck. oh yeah and apparently it looks like Chromium never *actually* uses bicubic filtering via kHigh_SkFilterQuality, except maybe in special cases, because... reasons?

SkFilterQuality => SkSamplingOptions

=
======================= kNone_SkFilterQuality  => [nearest neighbor]       !useCubic, SkFilterMode::kNearest, skMipmapMode::kNone kLow_SkFilterQuality   => [bilinear,  no mipmaps]  !useCubic, SkFilterMode::kLinear,  skMipmapMode::kNone kMedium_SkFilterQuality => [bilinear, with mipmaps] !useCubic, SkFilterMode::kLinear, skMipmapMode::kNearest // <-- iff kMedium_asMipmapNearest kMedium_SkFilterQuality => [bilinear, with mipmaps] !useCubic, SkFilterMode::kLinear, skMipmapMode::Linear   // <-- iff kMedium_asMipmapLinear kHigh_SkFilterQuality  => [bicubic, Mitchell]       useCubic, SkCubicResampler{1/3.0f, 1/3.0f}

why the fuck does this stupid MediumBehavior bullshit exist in Skia? why oh why oh why