rendry-io · Schema

TextFit

What the finished render MEASURED for one text layer. Every number is in DSL layout coordinates.

CompanyImage RenderingPDF GenerationTemplate EngineAPIAI Integration

Properties

Name Type Description
id string The measured layer's own id. This is why text_fit is a list: the entry names its layer, the list does not
plate object Present only for an assembled text plate
rotation_origin object Present for ordinary raster text with rotation or flips; native document text uses its own placement
raster_top integer Where the raster image put the top of the text block under vertical_align center or bottom, in whole pixels below the layer's y; absent for top alignment, no box height, a plate, and PDF or HTML outpu
size integer The size that was asked for
fitted_size integer The size auto_fit settled on; equal to size when nothing shrank
text_w integer Width of the rendered text mask
text_h integer Height of the rendered text mask
box_w integer Declared layer width; 0 means unconstrained
box_h integer Declared layer height; 0 means unconstrained
lines integer Lines after wrapping, not only explicit newlines
wraps array Where the render broke the text for width: the rune offset, in the text as drawn (variables substituted, list markers and soft hyphens in place, rich_text ** pairs removed), at which each line begins
kept_spaces array Visible-rune offsets of whitespace replaced with non-breaking spaces by keep_last_words. Shares the wraps coordinate system; absent when no spaces changed. The editor applies these exact substitutions
mask_x integer mask_text placement inside a shape or image
mask_y integer
mask_w integer
mask_h integer
ink_top integer Mask offset from the logical text box; a diagnostic, not an alignment source — Pango bounds can include empty rows
ink_left integer
fit_group string The layer's fit_group name, present only for a member of one
size_alone integer The size this member would have taken fitted BY ITSELF, before the group levelled. Present only for a member of a fit_group; a layer in no group reports fitted_size and nothing more
fit_group_size integer The size the group settled on — the smallest size_alone among its members. A member whose own min_size is above it keeps min_size, so fitted_size can exceed fit_group_size. Present only for a member o
origin object
list_paragraphs array Native list geometry on the wraps rune coordinate system; includes blank/trailing paragraphs. Absent for ordinary non-list text.
logical_h integer Native logical block height for lists and clip_lines, including blank lines and fallback-font metrics; absent legacy measurements keep existing line-step behavior.
clip_end integer Exclusive rune endpoint in the final parsed/formatted source, present only when clip_lines removed a suffix. Zero keeps a leading blank line. Slice already parsed styled content before applying wraps/
lines_cut integer Number of complete native lines removed by clip_lines after full-source fitting. lines is the retained count. Absent when no lines were cut.
View JSON Schema on GitHub

JSON Schema

rendry-io-text-fit-schema.json Raw ↑
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/rendry-io/json-schema/rendry-io-text-fit-schema.json",
  "title": "TextFit",
  "description": "What the finished render MEASURED for one text layer. Every number is in DSL layout coordinates.",
  "x-generated": "2026-10-31",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/rendry-io-openapi.json#/components/schemas/TextFit",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "The measured layer's own id. This is why text_fit is a list: the entry names its layer, the list does not"
    },
    "plate": {
      "$ref": "#/$defs/TextPlateFit",
      "description": "Present only for an assembled text plate"
    },
    "rotation_origin": {
      "$ref": "#/$defs/TextRotationOrigin",
      "description": "Present for ordinary raster text with rotation or flips; native document text uses its own placement"
    },
    "raster_top": {
      "type": "integer",
      "description": "Where the raster image put the top of the text block under vertical_align center or bottom, in whole pixels below the layer's y; absent for top alignment, no box height, a plate, and PDF or HTML output"
    },
    "size": {
      "type": "integer",
      "description": "The size that was asked for"
    },
    "fitted_size": {
      "type": "integer",
      "description": "The size auto_fit settled on; equal to size when nothing shrank"
    },
    "text_w": {
      "type": "integer",
      "description": "Width of the rendered text mask"
    },
    "text_h": {
      "type": "integer",
      "description": "Height of the rendered text mask"
    },
    "box_w": {
      "type": "integer",
      "description": "Declared layer width; 0 means unconstrained"
    },
    "box_h": {
      "type": "integer",
      "description": "Declared layer height; 0 means unconstrained"
    },
    "lines": {
      "type": "integer",
      "description": "Lines after wrapping, not only explicit newlines"
    },
    "wraps": {
      "type": "array",
      "items": {
        "type": "integer"
      },
      "description": "Where the render broke the text for width: the rune offset, in the text as drawn (variables substituted, list markers and soft hyphens in place, rich_text ** pairs removed), at which each line begins because the line before it was full. A line an explicit newline starts is not listed; absent when nothing wrapped. The editor draws its lines at these offsets"
    },
    "kept_spaces": {
      "type": "array",
      "items": {
        "type": "integer"
      },
      "description": "Visible-rune offsets of whitespace replaced with non-breaking spaces by keep_last_words. Shares the wraps coordinate system; absent when no spaces changed. The editor applies these exact substitutions before painting."
    },
    "mask_x": {
      "type": "integer",
      "description": "mask_text placement inside a shape or image"
    },
    "mask_y": {
      "type": "integer"
    },
    "mask_w": {
      "type": "integer"
    },
    "mask_h": {
      "type": "integer"
    },
    "ink_top": {
      "type": "integer",
      "description": "Mask offset from the logical text box; a diagnostic, not an alignment source — Pango bounds can include empty rows"
    },
    "ink_left": {
      "type": "integer"
    },
    "fit_group": {
      "type": "string",
      "description": "The layer's fit_group name, present only for a member of one"
    },
    "size_alone": {
      "type": "integer",
      "description": "The size this member would have taken fitted BY ITSELF, before the group levelled. Present only for a member of a fit_group; a layer in no group reports fitted_size and nothing more"
    },
    "fit_group_size": {
      "type": "integer",
      "description": "The size the group settled on — the smallest size_alone among its members. A member whose own min_size is above it keeps min_size, so fitted_size can exceed fit_group_size. Present only for a member of a fit_group"
    },
    "origin": {
      "$ref": "#/$defs/TextDiagnosticOrigin"
    },
    "list_paragraphs": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/ListParagraph"
      },
      "description": "Native list geometry on the wraps rune coordinate system; includes blank/trailing paragraphs. Absent for ordinary non-list text."
    },
    "logical_h": {
      "type": "integer",
      "minimum": 1,
      "maximum": 2097151,
      "description": "Native logical block height for lists and clip_lines, including blank lines and fallback-font metrics; absent legacy measurements keep existing line-step behavior."
    },
    "clip_end": {
      "type": "integer",
      "minimum": 0,
      "description": "Exclusive rune endpoint in the final parsed/formatted source, present only when clip_lines removed a suffix. Zero keeps a leading blank line. Slice already parsed styled content before applying wraps/list_paragraphs; this is server observation, never authored DSL."
    },
    "lines_cut": {
      "type": "integer",
      "minimum": 0,
      "description": "Number of complete native lines removed by clip_lines after full-source fitting. lines is the retained count. Absent when no lines were cut."
    }
  },
  "$defs": {
    "ListParagraph": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "rune_offset",
        "prefix_runes",
        "reserve_px",
        "continued",
        "rtl"
      ],
      "properties": {
        "rune_offset": {
          "type": "integer",
          "minimum": 0,
          "description": "Paragraph start in the same final parsed rune stream as wraps, including blank paragraphs."
        },
        "prefix_runes": {
          "type": "integer",
          "minimum": 0,
          "description": "Drawn marker/indent prefix length; zero for a midparagraph flow continuation."
        },
        "reserve_px": {
          "type": "number",
          "description": "Native physical continuation reserve in layout pixels: positive left, negative right, zero centered or unconstrained. Never infer RTL from this sign."
        },
        "continued": {
          "type": "boolean",
          "description": "Keeps an earlier paragraph marker reserve without drawing that marker again."
        },
        "rtl": {
          "type": "boolean",
          "description": "Original native resolved paragraph direction, including empty and continued paragraphs."
        }
      },
      "description": "Measured list paragraph geometry. Bind it and wraps to unchanged render inputs; ordinary non-list text omits this array. Literal list newlines normalize CRLF/CR to LF before formatting."
    },
    "TextDiagnosticOrigin": {
      "type": "object",
      "properties": {
        "key": {
          "type": "string",
          "description": "Server-created prepared structural identity; independent of generated cell IDs."
        },
        "layer_id": {
          "type": "string",
          "description": "Safe authored layer identifier; values and paths are excluded."
        },
        "table": {
          "type": "boolean"
        },
        "master": {
          "type": "boolean"
        },
        "page": {
          "type": "integer",
          "description": "Final page, 1-based."
        },
        "row": {
          "type": "integer",
          "description": "Original body row, 1-based; header and footer row zero."
        },
        "column": {
          "type": "integer",
          "description": "Column, 1-based."
        },
        "header": {
          "type": "boolean"
        },
        "master_kind": {
          "type": "string",
          "enum": [
            "first",
            "even"
          ],
          "description": "Present for replacement-master origins in diagnostics v2; keys use master_first/N or master_even/N. Default-only diagnostics remain v1."
        },
        "footer": {
          "type": "boolean",
          "description": "True for the final table footer; row is zero and header is false."
        }
      }
    },
    "TextPlateFit": {
      "type": "object",
      "description": "Actual unrotated text plate assembly in DSL pixels, before effects and output scaling. Text coordinates identify the logical text box, not tight glyph bounds.",
      "required": [
        "x",
        "y",
        "width",
        "height",
        "text_x",
        "text_y",
        "text_width"
      ],
      "properties": {
        "x": {
          "type": "integer",
          "description": "Plate left relative to the layer origin"
        },
        "y": {
          "type": "integer",
          "description": "Plate top relative to the layer origin"
        },
        "width": {
          "type": "integer",
          "description": "Assembled plate width after minimum size and circle sizing"
        },
        "height": {
          "type": "integer",
          "description": "Assembled plate height after minimum size and circle sizing"
        },
        "text_x": {
          "type": "integer",
          "description": "Logical text origin inside the plate, including stroke and bearing placement"
        },
        "text_y": {
          "type": "integer",
          "description": "Logical text origin inside the plate"
        },
        "text_width": {
          "type": "integer",
          "description": "Resolved advance or constrained wrap width"
        }
      }
    },
    "TextRotationOrigin": {
      "type": "object",
      "description": "Actual pre-transform assembly center of ordinary raster text relative to the layer origin, in DSL pixels. Half-pixel centers are preserved.",
      "required": [
        "x",
        "y"
      ],
      "properties": {
        "x": {
          "type": "number"
        },
        "y": {
          "type": "number"
        }
      }
    }
  }
}

Work with this as data

Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for schemas

4 MCP tools reach this
  • find_json_schemasBrowse and filter every JSON Schema in the catalog.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/rendry-io-text-fit"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.