N copies of a glyph measure exactly N times one copy
Check id text-advance-additivity
What an ordinary browser yields
Every repeated-glyph measurement equals the single-glyph measurement times the repeat count, exactly, with no residue.
What a detector infers
The advance width of N copies of a single glyph is exactly N times the advance of one copy. An advance is a per-glyph quantity that the shaper adds up, so repeating one glyph multiplies its width and nothing else happens — there is no reference value anywhere in this, only the browser's own arithmetic held against itself. That is what makes it the most countermeasure-resistant of the text rows. The other three are defeated by the same two moves: round the modified width back onto the sub-pixel grid, which satisfies the grid check, and apply the identical modification inside workers, which satisfies the cross-realm check. Additivity survives both, because it never compares a measurement against an expectation — it compares two measurements the same browser has just produced. It also separates the styles of modification precisely, which is worth understanding before reading a verdict here. A single multiplicative scale applied to every measurement PASSES this row, because scaling both sides preserves the proportion; that case belongs to the uniform-scale row next door. What breaks it is noise applied per string or per call, and a scale that has been rounded back onto the grid, because then the rounding residue depends on the length and no longer cancels. This row therefore ships with no sighting attached, deliberately: the stealth browser measured for this page applies a uniform scale, which additivity cannot see and the neighbouring rows catch instead. It is here for the modification styles those rows cannot reach. Measured exact — worst difference of zero — on Chrome 150, Brave 150, Firefox 151 and that stealth browser, across 12px and 16px Arial, monospace and Times New Roman, six glyphs and five repeat counts. Holding on Gecko as well as Blink is what allows it to run with no engine gate, unlike the dyadic-grid row, which is a Blink-specific property and has to decline elsewhere. One implementation detail carries weight: the repeat counts are powers of two, so multiplying a width by N is a pure exponent shift on a dyadic value and the arithmetic inside the check cannot introduce rounding of its own.
How to resolve it
Nothing to fix if this passes, and it passes on every browser measured here. If it fails, the width returned for a string was adjusted per measurement rather than derived once per glyph and summed — which is what per-string noise does, and what a scale rounded back onto the sub-pixel grid does once the string is long enough for the residue to show. The general lesson for anyone building text-metric protection is that the proportions between a browser's own measurements are much harder to keep consistent than the individual values are, and a page can check those proportions without knowing what any correct value would be.
Nearby checks in Render & GPU
- 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. - text metrics are not a uniform multiple of the engine's own grid
text-metrics-uniform-scaleThis 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… - 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… - clientWidth and offsetWidth equal the box the element itself reports
layout-box-arithmeticclientWidth and offsetWidth are not opinions the browser offers — CSSOM defines them as arithmetic over values the same element hands you…
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-advance-additivity belongs to.