Skip to main content

Stretchable icons and text backgrounds

Fit point icons to shaped text while preserving fixed corners and edges

Development SDK 0.3.0-dev.87035c71 passes the same public script with 24 checks and 21 actual phases on Linux native, browser main thread and Worker.

The implemented scope includes image stretchX/stretchY/content and textFitWidth/textFitHeight metadata, plus none/width/height/both icon-text-fit modes and four-side padding. Content uses actual shaped font bounds. Real UV patches keep fixed corners and edges. Collision and hit queries use the final accepted icon/text geometry.

Interfaces follow public specifications; the map engine and mesh algorithms are independently implemented. Final frozen contracts define supported parameters and budgets. Unknown values, limits and invalid materials fail while preserving the previous map. This does not imply complete symbol layout, line text, mobile GIS, devices or formal releases.

Probe (await map.sqs.getCapabilities()).commonIconTextFitStretch at runtime; probe the matching SDK before using these properties.

Complete acceptance script uses original 24 × 24 PNG, A-glyph PBF and promoted-ID point MVT fixtures; localhost3305 is an actual local screenshot barrier. Three actual text references are checked against the own PBF glyph bounds. The UV oracle checks fixed 4 px edges and 8 px interior intervals without reusing the new mesh algorithm.

Omitted metadata stays absent; explicit fields return independent deeply frozen copies. Same-size updates change pixels only. Selected fit axes use the shaped glyph-quad union and CSS padding, without extra atlas space or advance-based dimensions. Icon size affects fixed/unfitted regions and offset applies once. TextFit only constrains both; double proportional is height-led, the two documented asymmetric combinations use content-aspect lower bounds and other combinations fit exactly. Existing resource/geometry budgets and atomic asynchronous arrivals remain enforced. GUI/external devices, line text, other complete style/DEM support and formal releases remain incomplete.

Each image allows up to 8 disjoint stretch intervals per axis and 289 texture patches. Text, ordinary icons and patches share budgets of 65,536 quads, 16,384 symbol origins and 1,000,000 collision operations. Each padding side is 0–128 CSS pixels. Dynamic image callbacks are unavailable.

// panel is a 24 × 24 RGBA image.
map.addImage("panel", panel, {
  stretchX: [[4, 20]],
  stretchY: [[4, 20]],
  content: [4, 4, 20, 20]
});
map.addLayer({
  id: "labels", type: "symbol", source: "places",
  layout: {
    "icon-image": "panel", "icon-text-fit": "both",
    "icon-text-fit-padding": [3, 7, 5, 11],
    "text-field": ["get", "name"], "text-size": 24
  }
});