> For the complete documentation index, see [llms.txt](https://docs.quickclient.cc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.quickclient.cc/en/ui/render-2d.md).

# 2D render

Drawing a HUD on top of the game with Render2D.

Everything a script draws on top of the game goes through `Render2D`: your own HUD, a timer panel, a list of targets in the corner of the screen.

It is passed as the argument of `onRender2D(Render2D)` and is only valid for that frame. Do not store it in a field: in the next frame its methods throw `IllegalStateException`. The same set of methods is available to `Custom` settings through `Canvas.render()`.

Coordinates are in Quick interface units, with zero in the top left corner. Colors are written as `0xAARRGGBB`. If the alpha is `0`, there is nothing to draw and the call is skipped. It is best to take colors from the theme with `themeColor(token)`, so the script looks like part of Quick in any theme.

```java
@Override
public void onRender2D(Render2D render) {
    float w = render.textWidth("sf_rounded_semibold", "Hello", 7f, 0f) + 12f;
    render.drawClientRect(10f, 10f, w, 16f, 4f, render.themeColor("rect"));
    render.drawText("sf_rounded_semibold", "Hello", 16f, 14f, 7f, 0f, render.themeColor("hudText"));
    render.drawItem("totem_of_undying", 16f + w, 8f, 16f, 3);
}
```

How it works:

* First the width of the label is measured and padding is added on both sides.
* A rounded panel in the theme color is drawn under the text, then the label on top of it.
* A totem with the number 3 is shown to the right of the panel.

## Shapes

| Method                                                               | Description                                                      |
| -------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `drawClientRect(x, y, w, h, round, color)`                           | rounded rectangle; with `round = 0` the corners are square       |
| `drawClientGradientRect(x, y, w, h, r1, r2, r3, r4, c1, c2, c3, c4)` | separate radius and color for each corner                        |
| `drawClientOutline(x, y, w, h, round, smooth, c1, c2, c3, c4)`       | outline with a gradient across the corners                       |
| `drawBlur(x, y, w, h, round, smooth, radius, alpha)`                 | blurs the background under the rectangle                         |
| `drawBlur(x, y, w, h, round, smooth, radius, alpha, color)`          | blur with a colored backing                                      |
| `drawTexture(id, x, y, w, h, color)`                                 | whole texture; `id` is a path in `resources/` or a full game id  |
| `drawTexture(id, sampler, x, y, w, h, color)`                        | with a sampler: `NEAREST` or `LINEAR` + `CLAMP` or `REPEAT`      |
| `drawTexture(id, x, y, w, h, u, v, uWidth, vHeight, color)`          | part of a texture by UV, in fractions from 0 to 1                |
| `drawTexture(id, x, y, w, h, u, v, uWidth, vHeight, round, color)`   | part of a texture with rounded corners                           |
| `drawImage(path, x, y, w, h, color)`                                 | image from `resources/`, works the same as `drawTexture`         |
| `shader(shader, x, y, w, h, color)`                                  | rectangle with your own shader, see [Shaders](/en/ui/shaders.md) |
| `shader(shader, x, y, w, h, color, first, second)`                   | the same with two parameters, the shader gets them in `UV2`      |
| `drawQuad(…)`, `drawMesh(…)`                                         | low level drawing, see [Your own geometry](/en/ui/gpu.md)        |

If a texture has the color `-1`, it is drawn as is, without tinting. `Render2D.ITEM_SIZE = 16` equals the side of an inventory slot.

## Items

Item icons are not drawn right away. Quick collects them until the end of the frame and draws them in one batch on top of everything drawn earlier. Otherwise a semi-transparent panel would end up on top and the item would look faded.

| Method                                           | Description                                          |
| ------------------------------------------------ | ---------------------------------------------------- |
| `drawItem(item, x, y)`                           | icon of an item from a snapshot, the size of a slot  |
| `drawItem(item, x, y, size)`                     | the same with a custom size                          |
| `drawItem(item, x, y, size, decorations)`        | with count and durability bar, like in the inventory |
| `drawItem(id, x, y)`, `drawItem(id, x, y, size)` | by string id                                         |
| `drawItem(id, x, y, size, count)`                | with a count number                                  |

All of them return a `boolean`: whether the icon was queued for this frame.

## Text

`fonts()` returns the list of Quick fonts. `sf_rounded_bold`, `sf_rounded_semibold` and `sf_rounded_medium` are built in, and you can add your own with `fonts().register(...)`. How to do that is described on the [Styled text](/en/ui/text.md) page.

| Method                                                                                    | Type    | Description                                                                      |
| ----------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------- |
| `drawText(font, text, x, y, size, thickness, color)`                                      | `float` | a string; returns the position of its right edge                                 |
| `drawText(font, Text, x, y, size, thickness)`                                             | `float` | styled text, colors come from the text itself                                    |
| `drawText(font, Text, x, y, size, thickness, color)`                                      | `float` | styled text; `color` applies to parts without their own color                    |
| `drawTextFaded(font, text, x, y, size, thickness, color, maxWidth, fade)`                 | `void`  | a string that fades out toward the right edge                                    |
| `drawTextGradient(font, key, text, x, y, size, thickness, color, from, to, power, speed)` | `void`  | moving gradient; `key` is a stable key so the animation does not reset           |
| `drawClientText(text, x, y, size, color)`                                                 | `void`  | text in the default Quick font                                                   |
| `drawClientGradientText(text, x, y, size, color1, color2)`                                | `void`  | gradient from left to right                                                      |
| `textWidth(font, text, size, thickness)`                                                  | `float` | width of a string                                                                |
| `textWidth(font, Text, size, thickness)`                                                  | `float` | width of styled text                                                             |
| `textWidth(text, size)`, `textHeight(size)`                                               | `float` | the same for the default Quick font                                              |
| `textHeight(font, size)`                                                                  | `float` | font size                                                                        |
| `lineHeight(font, size)`                                                                  | `float` | full line height, from the top of tall letters to the bottom of letters like "y" |
| `baseline(font, size)`                                                                    | `float` | distance from `y` to the baseline                                                |
| `descender(font, size)`                                                                   | `float` | how far letters like "y" and "p" go below the baseline                           |

`thickness` sets the spacing between letters, usually from -0.1 to 0.2. Measure text width once and keep it, there is no need to recalculate it every frame.

## Coordinate system and clipping

| Method                              | Description                                                                                                           |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `push()`, `pop()`                   | save the coordinate system and restore it; Quick pops any unclosed `push` at the end of the frame                     |
| `translate(x, y)`                   | move the origin                                                                                                       |
| `scale(x, y)`                       | scale relative to the origin                                                                                          |
| `scale(scale, originX, originY)`    | scale relative to a point                                                                                             |
| `rotate(degrees)`                   | clockwise rotation around the origin                                                                                  |
| `rotate(degrees, originX, originY)` | rotation around a point                                                                                               |
| `scissor(x, y, w, h)`               | everything drawn after this is clipped to the frame; clips can be nested, but each one needs its own `clearScissor()` |
| `clearScissor()`                    | remove the last clip                                                                                                  |
| `newLayer()`                        | start a new layer: everything after it goes on top of what is already drawn                                           |

## Screen and theme

| Method                            | Type    | Description                                                                                                                     |
| --------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `screenWidth()`, `screenHeight()` | `int`   | screen size in interface units                                                                                                  |
| `delta()`                         | `float` | fraction of the tick elapsed by this frame                                                                                      |
| `themeColor(token)`               | `int`   | theme color: `basic`, `basic2`, `main`, `text`, `hudText`, `headerText`, `inactiveText`, `rect`, `outline`, `field`, `switcher` |
| `fade(index)`                     | `int`   | color of the moving theme gradient; `index` is the phase shift in degrees, 0, 90, 180 and 270 give the four corners             |

Interface units and window pixels differ by a factor of `control().guiScale()`. Cursor coordinates from `keys().mouseX()` are in pixels, so divide them by the scale before use.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.quickclient.cc/en/ui/render-2d.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
