text metrics are not a uniform multiple of the engine's own grid
Check id text-metrics-uniform-scale
What an ordinary browser yields
Either every width lands on the 1/512 grid, or the off-grid widths are not explained by any single common factor. One factor fitting all of them is the thing being looked for.
What a detector infers
This is the sub-pixel grid check asked one question deeper. That check reports THAT widths have left Blink's 1/512-pixel grid; this one asks what SHAPE the deviation has, which turns out to separate the possible causes cleanly. Because the engine quantises advance widths onto the grid, the nearest grid point to a measured width IS the true width — so dividing each measurement by its own recovered grid point yields the factor by which that string was altered. Three causes, three signatures. Per-glyph noise scatters those factors. A different font or font version moves widths from one grid point to another and leaves them ON the grid, so the factors stay at exactly 1. But a single multiplier applied to the number after the text engine has finished returns the SAME factor for every string — for a single "A", for a twenty-character run of the same letter, for mixed alphanumerics — because it never looked at the glyphs at all. Fourteen strings means thirteen independent constraints on one constant, and satisfying all of them to the last representable bit of a double is not something a coincidence does. Measured on a shipping stealth browser: fourteen of fourteen strings off-grid, every ratio agreeing to within one unit in the last place, with the constant redrawn on each launch. The same product's Worker returned widths exactly on the grid, which independently confirms that the recovered grid points were the true values and that only the page's realm was multiplied. The recovery has a deliberate limit: it holds while the scale is small enough that a shifted width stays nearest its own grid point, and a coarser farble scatters the ratios and makes this check report nothing rather than guess.
How to resolve it
The engine emits widths already quantised on the grid, so a factor shared by every string can only have been applied after it finished. This row is deliberately not scored as a contradiction, because a privacy build that farbles canvas text metrics per session produces precisely this shape and that is a legitimate thing to want. If metrics must vary between sites, vary them inside the shaper so the results stay quantised; a scale applied to the returned number is recoverable regardless of how small it is — the factor measured here was under three parts per million and reconstructed exactly. Worth knowing for anyone weighing that severity: stock Brave 150 was measured against this row on both a real HTTPS origin and on localhost and did NOT trip it — it farbles canvas but leaves text metrics alone — so the unscored treatment is a deliberate margin rather than a response to any observed false positive. Chrome 150, Edge 150 and Firefox 151 were measured clean too, the last of them N/A as the Blink-grid gate requires.
Read in the wild by
CloakBrowser (measured)
Every one of fourteen strings off the grid by an identical factor, on all three launches measured, with the factor redrawn per session — under three parts per million each time, and therefore invisible to any check that only asks whether a width looks reasonable. The product's Worker returned the exact grid values in the same sessions, so the main thread's numbers were the engine's own output multiplied on the way out.
14/14 strings off-grid on 3/3 launches; factors 0.999997293617128, 1.000002932966041 and 0.999997197243199, each shared across all fourteen strings with a spread of 0 to 2.2e-16 (one ULP). Stock Chrome on the same machine: 0/14 off-grid, every ratio exactly 1, spread exactly 0.
CloakBrowser (measured)Every attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Render & GPU
- one WebGL clear reads back as exactly one colour
webgl-readback-flat-uniformA single glClear writes one colour into every pixel of the framebuffer, so reading that framebuffer back must yield exactly one colour. - a WebGL framebuffer reads back the same through readPixels and toDataURL
webgl-readpixels-vs-todataurlreadPixels and toDataURL both read the drawing buffer of one WebGL canvas, and PNG is lossless, so decoding the data URL has to reproduce… - WebGL and WebGPU agree on whether this device clears uniformly
webgl-webgpu-readback-agreeOne clear, two GPU APIs, one adapter. WebGL paints a flat colour and reads it back with readPixels; WebGPU renders the same clear into a… - canvas measureText widths on the 1/512 sub-pixel grid
measuretext-gridChrome's 2D text metrics are quantised: advance widths are computed in fixed-point and land on a dyadic 1/512-pixel grid. - N copies of a glyph measure exactly N times one copy
text-advance-additivityThe advance width of N copies of a single glyph is exactly N times the advance of one copy. - ink extent and advance width grow by the same step
text-ink-extent-vs-advanceTextMetrics reports two numbers produced by different parts of the engine. width is the sum of the glyph advances the shaper accumulated… - main-thread metrics === Worker metrics
worker-vs-mainThe same five strings are measured at 12px Arial twice: once on a main-thread 2D canvas, and once inside a dedicated Worker on an… - getBoundingClientRect === Range client rects
bcr-vs-rangeTwo independent APIs are pointed at the same laid-out text: an absolutely-positioned div containing "WWWWWiiiii" is measured with…
Clearcote is a browser built for fingerprint coherence
It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.
This audit takes no position on how Clearcote scores on Render & GPU checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.
See the other checks in Render & GPU — the family text-metrics-uniform-scale belongs to.