# Class SurfaceRasterizer

java.lang.Object
com.codename1.surfaces.SurfaceRasterizer

public final class SurfaceRasterizer extends Object

A shared software renderer for desktop ports (the JavaSE simulator, the native Windows and Linux ports): draws a parsed surface descriptor node into a mutable Codename One `Image` using only `Graphics` primitives -- no `Container`/`Label` components and no theme dependence, so the output looks the same on every desktop surface. Must run on the EDT (it creates images and measures fonts).

The input is the wire format produced by `SurfaceSerializer` parsed back with `com.codename1.io.JSONParser` -- numbers may arrive as `Double` or `Long`, both are handled. Alongside the pixels the rasterizer returns the absolute hit rectangles of every node carrying an `action`, plus the epoch time when a re-render is due for time-driven content (countdowns, clocks, date-interval progress).

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static class`
  `SurfaceRasterizer.ActionRect`
  The absolute bounds of a node that carries a tap action, in pixels of the rasterized image.
  `static class`
  `SurfaceRasterizer.Result`
  The output of a rasterization pass: pixels, action hit rectangles and the next re-render deadline.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static Map<String,Object>`
  `currentEntry(Map<String,Object> timelineDoc, long now)`
  Returns the timeline entry whose date most recently passed, or the first entry when none passed yet, or null for an entry-less document.
  `static String`
  `formatDynamicText(String style, long dateMillis, long now)`
  Formats a dynamic-text value the way the OS-native views would show it.
  `static Map<String,Object>`
  `layoutForSize(Map<String,Object> timelineDoc, String sizeName)`
  Picks the layout of a timeline document for a size name (`small` / `medium` / `large` / `lockscreen` / the `watch*` complication families): the explicit per-size layout when present, else a family-specific substitute, else the `default` layout, else null.
  `static long`
  `nextEntryFlip(Map<String,Object> timelineDoc, long now)`
  Returns the epoch millis of the next entry flip after `now`, or 0 when no future entry exists.
  `static SurfaceRasterizer.Result`
  `rasterize(Map<String,Object> node, Map<String,Object> state, Map<String,byte[]> images, int width, int height, boolean dark, long now)`
  Rasterizes a descriptor node into a transparent image of the requested size.

  ### Methods inherited from class Object

  `clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Method Details

  - ### rasterize

    public static SurfaceRasterizer.Result rasterize(Map<String,Object> node, Map<String,Object> state, Map<String,byte[]> images, int width, int height, boolean dark, long now)

    Rasterizes a descriptor node into a transparent image of the requested size. Must run on the EDT.

    ###### Parameters

    - `node`: a parsed descriptor node map as produced by the serializer and parsed back with `com.codename1.io.JSONParser`
    - `state`: the current entry's state map, may be null
    - `images`: PNG blobs keyed by wire name, may be null
    - `width`: target width in pixels
    - `height`: target height in pixels
    - `dark`: true to resolve dark-mode colors
    - `now`: the current epoch millis used for dynamic text and interval progress

    ###### Returns

    the rasterization result

  - ### currentEntry

    public static Map<String,Object> currentEntry(Map<String,Object> timelineDoc, long now)

    Returns the timeline entry whose date most recently passed, or the first entry when none passed yet, or null for an entry-less document.

    ###### Parameters

    - `timelineDoc`: a parsed timeline JSON document
    - `now`: the current epoch millis

    ###### Returns

    the active entry map (`date`, `state`), or null

  - ### nextEntryFlip

    public static long nextEntryFlip(Map<String,Object> timelineDoc, long now)

    Returns the epoch millis of the next entry flip after `now`, or 0 when no future entry exists.

    ###### Parameters

    - `timelineDoc`: a parsed timeline JSON document
    - `now`: the current epoch millis

    ###### Returns

    the next flip time, or 0

  - ### layoutForSize

    public static Map<String,Object> layoutForSize(Map<String,Object> timelineDoc, String sizeName)

    Picks the layout of a timeline document for a size name (`small` / `medium` / `large` / `lockscreen` / the `watch*` complication families): the explicit per-size layout when present, else a family-specific substitute, else the `default` layout, else null.

    Two substitutions, matching what the platform renderers do so a preview and a device agree. `watchCorner` falls back to `watchCircular`, because a corner complication is round and Wear OS has no corner slot at all; `watchRectangular` falls back to `lockscreen`, which is the same WidgetKit family on Apple.

    ###### Parameters

    - `timelineDoc`: a parsed timeline JSON document
    - `sizeName`: the wire-format size name

    ###### Returns

    the layout's root node map, or null

  - ### formatDynamicText

    public static String formatDynamicText(String style, long dateMillis, long now)

    Formats a dynamic-text value the way the OS-native views would show it.

    Public because a surface that cannot tick natively needs the text form: a Wear complication slot takes a string, and a Tile freezes its value between timeline flips. Both go through this rather than formatting for themselves, so a countdown reads the same on a watch face as in the simulator preview and on a home screen.

    ###### Parameters

    - `style`: the wire style name (`timerDown`, `timerUp`, `time`, `date`, `relative`)
    - `dateMillis`: the target epoch millis
    - `now`: the current epoch millis

    ###### Returns

    the formatted value