User:Jgottula/fandomdesktop.css

From Dead Cells Wiki
Jump to navigation Jump to search

In other languages: Español • Polski • Русский • Українська


CSS and Javascript changes must comply with the wiki design rules.


Note: After saving, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Clear the cache in Tools → Preferences
/* NOTE: MediaWiki concatenates [user common.css + user hydradark.css]
 *       and then puts a <link> element in <head> 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 <body> 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 <body>; 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-<PageName>' rules themselves (for background images for which it makes sense)
 *    (actually come to think of it, maybe make one big rule for '.page-<PageName1>, .page-<PageName2>, [...], .page-<PageNameN>' 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
#! 'optimizespeed'             => kOptimizespeed          => kInterpolationDefault => kMedium_SkFilterQuality => bilinear filtering with mipmaps
#! 'optimizequality'           => kOptimizequality        => 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'

LEGEND:
^ non-standard vendor-specific property (everybody loves those!)
# deprecated and should probably go away
@ 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)

('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

*/