Class GUnit

java.lang.Object
com.iizix.prop.GUnit
All Implemented Interfaces:
Cloneable

public class GUnit extends Object implements Cloneable
This is a data holder class for a unit "px" for pixels, "dlg" for dialog, "em" for the size of the current font, "ex" for the size of the "x" character of the current font, "pt" for point size (1/72 of an inch), and "%" for percent of the parent component size.

Dialog units use font metrics as: 1/4 maximum character width, 1/8 maximum character height (+ external & internal leadings). This is a heritage from the Windows.

Two different unit types exist: integer values and decimal values. The type "px" only supports integer values. Integer values can range from -536870911 (-0x1FFFFFFF) to 536870911 (0x1FFFFFFF). Decimal values can be from -536870911.ddddddd (-0x1FFFFFFF.ddddddd) to 536870911.ddddddd (0x1FFFFFFF.ddddddd) where "ddddddd" is the decimal part with a maximum of 7 digits. A unit can be a combination of several other units, e.g. "90%-10px+1pt". This type is called FORMULA.

This class supersedes the Nashorn-based GUnit and differs from it in one structural way: NO STRING IS EVER EVALUATED AS CODE. The predecessor is preserved, unbuilt, at com.iizix.core/unused-saved/GUnit.java--using-Nashorn; references to "the previous GUnit" below mean that file. It validates a formula with a hand-written character scanner and then evaluates it by handing a string to a JavaScript engine, on the server through javax.script and on the client through eval(). Here a formula is compiled once, by the lexer and recursive-descent parser in com.iizix.prop.gunit, into a Formula: an opcode array plus its constants. That array is what is transported and what both sides walk.

Consequences worth knowing:

  • The stored text of a formula is a DISPLAY ARTEFACT, regenerated from the opcodes by Formula.toSource(). Nothing parses a stored string at runtime.
  • Errors carry an exact offset and length into the original source string, which the old pre-substitution approach could not do because replacing every unit name with a single control character shifted every position after the first unit.
  • The grammar gains min(a,b,...), max(a,b,...) and clamp(min,preferred,max), and ten new units: cwmin, cwmax, chmin, chmax, rem, dpx, dpr, nh, nx and ny. See UnitType for each of them.
  • Java and JavaScript can no longer disagree about a literal. 010 was 10 to the Java validator and, in a sloppy-mode browser context, legacy octal 8 to the client.
Author:
Christopher Mindus
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    Axis constant for a horizontal, i.e.
    static final int
    Axis constant for a vertical, i.e.
    static final int
    The default number of decimals a formula result is rounded to.
    static final GUnit
    An empty "NONE" unit, i.e.
    static final int
    The unit type size of the component's own computed CSS "max-height" in pixels or "chmax" for short.
    static final int
    The unit type size of the component's own computed CSS "min-height" in pixels or "chmin" for short.
    static final int
    The unit type size of the component's own computed CSS "max-width" in pixels or "cwmax" for short.
    static final int
    The unit type size of the component's own computed CSS "min-width" in pixels or "cwmin" for short.
    static final int
    The unit type "dialog" or "dlg" for short.
    static final int
    The DEVICE PIXEL RATIO itself or "dpr" for short.
    static final int
    The unit type size of ONE PHYSICAL DEVICE PIXEL in CSS pixels or "dpx" for short, i.e.
    static final int
    The unit type size of the current font or "em" for short.
    static final int
    The unit type size of the "x" character of current font or "ex" for short.
    static final int
    The unit type for complex values with a formula.
    static final int
    The unit type size of the notch BOTTOM side safe size in pixels or "nb" for short.
    static final int
    The unit type size of the notch cutout bounding-box HEIGHT in SCREEN space in pixels or "nh" for short.
    static final int
    The unit type size of the notch LEFT side safe size in pixels or "nl" for short.
    static final int
    The unit type size of the notch RIGHT side safe size in pixels or "nr" for short.
    static final int
    The unit type size of the notch TOP side safe size in pixels or "nt" for short.
    static final int
    The unit type size of the notch cutout bounding-box WIDTH in SCREEN space in pixels or "nw" for short.
    static final int
    The unit type offset along the top or bottom edge to the LEFT side of the notch or "nx" for short.
    static final int
    The unit type offset along the left or right edge to the TOP of the notch or "ny" for short.
    static final int
    The unit type size for percentage of parent or "%" for short.
    static final int
    The unit type size for percentage of parent height or "%h" for short.
    static final int
    The unit type size for maximum size of percentage of parent width and height or "%max" for short.
    static final int
    The unit type size for minimum size of percentage of parent width and height or "%min" for short.
    static final int
    The unit type size for percentage of parent width or "%w" for short.
    static final int
    The unit type in points, i.e.
    static final int
    The unit type "pixels" or "px" for short.
    static final int
    The unit type size of the ROOT element font or "rem" for short.
    static final int
    The unit type size special value string, set as the formula.
    static final int
    The unit type size for percentage of viewport height or "vh" for short.
    static final int
    The unit type size for maximum size of percentage of viewport width and height or "vmax" for short.
    static final int
    The unit type size for minimum size of percentage of viewport width and height or "vmin" for short.
    static final int
    The unit type size for percentage of viewport width or "vw" for short.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Creates a unit object to 0 (zero) in pixels.
    GUnit(double value, int unit)
    Creates a unit object with the specified value in pixels.
    GUnit(int value)
    Creates a unit object with the specified value in pixels.
    Creates a unit object from a transaction.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Appends the unit object to a transaction.
    Clones this instance.
    static GUnit
    createCSSGUnit(String value, String... specialValues)
    Creates a GUnit object from a String.
    static GUnit
    createGUnit(String expr0, String... specialValues)
    Creates a GUnit object from a String.
    boolean
    equals(GUnit unit)
    Checks if two unit objects are equal.
    boolean
    Checks if two unit objects are equal.
    double
    evalDouble(IScaleProvider scales, int axis)
    Evaluates the formula and returns the raw, unrounded pixel value.
    int
    evalInt(IScaleProvider scales, int axis)
    Evaluates the formula and rounds the result to a whole pixel.
    double
    evalRounded(IScaleProvider scales, int axis)
    Evaluates the formula and rounds the result to DEFAULT_DECIMALS decimals.
    double
    evalRounded(IScaleProvider scales, int axis, int decimals)
    Evaluates the formula and rounds the result to a given number of decimals.
    double
    evalSnapped(IScaleProvider scales, int axis)
    Evaluates the formula and snaps the result to the DEVICE PIXEL GRID.
    double
    evaluate(double[] scaleTable)
    Evaluates the compiled formula against a prepared scale table.
    Gets the unit as a CSS value.
    Gets the compiled program of a UT_FORMULA unit.
    Gets the formula as normalised source text, generated from the opcode array.
    double
    getPixelValue(UIComp comp, boolean isHorz)
    Calculates the unit into a pixel value using the font information.
    Gets the String representation of the bounds as "value type".
    int
    Gets the type of the unit (0-29), one of the values: UT_PX (pixel), UT_DLG (dialog), UT_EM ("em"), UT_EX ("ex"), UT_PT (point), UT_PC (percent), UT_PCW (percentage of parent width), UT_PCH (percentage of parent height), UT_PCMIN (minimum size of percentage of parent width and height), UT_PCMAX (maximum size of percentage of parent width and height), UT_VW (percentage of viewport width), UT_VH (percentage of viewport height), UT_VMIN (size for minimum size of percentage of viewport width and height), UT_VMAX (size for maximum size of percentage of viewport width and height), UT_NL (size of the notch LEFT side safe size in pixels), UT_NR (size of the notch RIGHT side safe size in pixels), UT_NW (notch cutout bounding-box WIDTH in screen space, in pixels), UT_NT (size of the notch TOP side safe size in pixels), UT_NB (size of the notch BOTTOM side safe size in pixels), UT_CWMIN (the component's own computed CSS "min-width"), UT_CWMAX (the component's own computed CSS "max-width"), UT_CHMIN (the component's own computed CSS "min-height"), UT_CHMAX (the component's own computed CSS "max-height"), UT_REM (the root element font size), UT_DPX (one physical device pixel in CSS pixels), UT_DPR (the device pixel ratio itself, a multiplier and not a length), UT_NH (notch cutout bounding-box HEIGHT in screen space, in pixels), UT_NX (offset along the top or bottom edge to the LEFT side of the notch), UT_NY (offset along the left or right edge to the TOP of the notch), UT_FORMULA (formula) or UT_VALUE (special value).
    double
    Returns the double value for the unit.
    int
    Returns the hash code of this unit.
    boolean
    Returns if this value is dependent on the container size, i.e.
    boolean
    Checks if the unit is "locked" from user change in the GUI design editor.
    boolean
    Checks if this is a valid CSS pure unit, e.g.
    boolean
    Checks if the unit is zero.
    protected String
    Returns the parameter string representing the state of this event.
    void
    setLocked(boolean on)
    Sets the lock state of the unit.
    Simplifies the formula by folding constant subexpressions.
    Returns a string representation of this class instance.
    Validates an expression formula by evaluating it against a neutral scale table, i.e.
    static void
    validateCSSGUnit(GUnit unit, String... specialValues)
    Validates a GUnit object.

    Methods inherited from class Object

    finalize, getClass, notify, notifyAll, wait, wait, wait
  • Field Details

    • NONE

      public static final GUnit NONE
      An empty "NONE" unit, i.e. "0px".
    • AXIS_X

      public static final int AXIS_X
      Axis constant for a horizontal, i.e. X, evaluation pass.
      See Also:
    • AXIS_Y

      public static final int AXIS_Y
      Axis constant for a vertical, i.e. Y, evaluation pass.
      See Also:
    • UT_PX

      public static final int UT_PX
      The unit type "pixels" or "px" for short. Only integer values are allowed.
      See Also:
    • UT_PT

      public static final int UT_PT
      The unit type in points, i.e. 1/72 inch or "pt" for short. Decimals are allowed.
      See Also:
    • UT_EM

      public static final int UT_EM
      The unit type size of the current font or "em" for short. Decimals are allowed.
      See Also:
    • UT_EX

      public static final int UT_EX
      The unit type size of the "x" character of current font or "ex" for short. Decimals are allowed.
      See Also:
    • UT_DLG

      public static final int UT_DLG
      The unit type "dialog" or "dlg" for short. Decimals are allowed.
      See Also:
    • UT_PC

      public static final int UT_PC
      The unit type size for percentage of parent or "%" for short. Decimals are allowed.
      See Also:
    • UT_PCW

      public static final int UT_PCW
      The unit type size for percentage of parent width or "%w" for short. Decimals are allowed.
      See Also:
    • UT_PCH

      public static final int UT_PCH
      The unit type size for percentage of parent height or "%h" for short. Decimals are allowed.
      See Also:
    • UT_PCMIN

      public static final int UT_PCMIN
      The unit type size for minimum size of percentage of parent width and height or "%min" for short. Decimals are allowed.
      See Also:
    • UT_PCMAX

      public static final int UT_PCMAX
      The unit type size for maximum size of percentage of parent width and height or "%max" for short. Decimals are allowed.
      See Also:
    • UT_VW

      public static final int UT_VW
      The unit type size for percentage of viewport width or "vw" for short. Decimals are allowed.
      See Also:
    • UT_VH

      public static final int UT_VH
      The unit type size for percentage of viewport height or "vh" for short. Decimals are allowed.
      See Also:
    • UT_VMIN

      public static final int UT_VMIN
      The unit type size for minimum size of percentage of viewport width and height or "vmin" for short. Decimals are allowed.
      See Also:
    • UT_VMAX

      public static final int UT_VMAX
      The unit type size for maximum size of percentage of viewport width and height or "vmax" for short. Decimals are allowed.
      See Also:
    • UT_NL

      public static final int UT_NL
      The unit type size of the notch LEFT side safe size in pixels or "nl" for short. Decimals are allowed.
      See Also:
    • UT_NR

      public static final int UT_NR
      The unit type size of the notch RIGHT side safe size in pixels or "nr" for short. Decimals are allowed.
      See Also:
    • UT_NW

      public static final int UT_NW
      The unit type size of the notch cutout bounding-box WIDTH in SCREEN space in pixels or "nw" for short. Decimals are allowed.

      Note that this is NOT "the maximum of the left and right insets" as the original previous GUnit's javadoc said; see UnitType.UT_NW.

      See Also:
    • UT_NT

      public static final int UT_NT
      The unit type size of the notch TOP side safe size in pixels or "nt" for short. Decimals are allowed.
      See Also:
    • UT_NB

      public static final int UT_NB
      The unit type size of the notch BOTTOM side safe size in pixels or "nb" for short. Decimals are allowed.
      See Also:
    • UT_CWMIN

      public static final int UT_CWMIN
      The unit type size of the component's own computed CSS "min-width" in pixels or "cwmin" for short. Decimals are allowed. See UnitType.UT_CWMIN for the naming.
      See Also:
    • UT_CWMAX

      public static final int UT_CWMAX
      The unit type size of the component's own computed CSS "max-width" in pixels or "cwmax" for short. Decimals are allowed.
      See Also:
    • UT_CHMIN

      public static final int UT_CHMIN
      The unit type size of the component's own computed CSS "min-height" in pixels or "chmin" for short. Decimals are allowed.
      See Also:
    • UT_CHMAX

      public static final int UT_CHMAX
      The unit type size of the component's own computed CSS "max-height" in pixels or "chmax" for short. Decimals are allowed.
      See Also:
    • UT_REM

      public static final int UT_REM
      The unit type size of the ROOT element font or "rem" for short. Decimals are allowed.
      See Also:
    • UT_DPX

      public static final int UT_DPX
      The unit type size of ONE PHYSICAL DEVICE PIXEL in CSS pixels or "dpx" for short, i.e. 1/devicePixelRatio. Decimals are allowed. See UnitType.UT_DPX.
      See Also:
    • UT_DPR

      public static final int UT_DPR
      The DEVICE PIXEL RATIO itself or "dpr" for short. Decimals are allowed.

      This unit is unlike every other one: it is a bare MULTIPLIER and not a length. See UnitType.UT_DPR.

      See Also:
    • UT_NH

      public static final int UT_NH
      The unit type size of the notch cutout bounding-box HEIGHT in SCREEN space in pixels or "nh" for short. Decimals are allowed.
      See Also:
    • UT_NX

      public static final int UT_NX
      The unit type offset along the top or bottom edge to the LEFT side of the notch or "nx" for short. Decimals are allowed. Edge, not centre; see UnitType.UT_NX.
      See Also:
    • UT_NY

      public static final int UT_NY
      The unit type offset along the left or right edge to the TOP of the notch or "ny" for short. Decimals are allowed. Edge, not centre; see UnitType.UT_NY.
      See Also:
    • UT_FORMULA

      public static final int UT_FORMULA
      The unit type for complex values with a formula.
      See Also:
    • UT_VALUE

      public static final int UT_VALUE
      The unit type size special value string, set as the formula.
      See Also:
    • DEFAULT_DECIMALS

      public static final int DEFAULT_DECIMALS
      The default number of decimals a formula result is rounded to.
      See Also:
  • Constructor Details

    • GUnit

      public GUnit()
      Creates a unit object to 0 (zero) in pixels.
    • GUnit

      public GUnit(int value)
      Creates a unit object with the specified value in pixels.
      Parameters:
      value - The value.
      Throws:
      IllegalArgumentException - if the value is not in range of -0x1FFFFFFF to 0x1FFFFFFF.
    • GUnit

      public GUnit(double value, int unit)
      Creates a unit object with the specified value in pixels.
      Parameters:
      value - The value.
      unit - The unit UT_* (excluding UT_FORMULA and UT_VALUE).
      Throws:
      IllegalArgumentException - For invalid value range.
    • GUnit

      public GUnit(ReadTransaction trans)
      Creates a unit object from a transaction.

      The UT_FORMULA branch reads the opcode array rather than a string: an unsigned instruction count so the reader can preallocate, then one unsigned byte per instruction, with the constant triple inline after each CONST. The datatype tagging of the transaction is deliberately left on, since it is the mechanism that makes a desync fail loudly rather than silently.

      Parameters:
      trans - The transaction.
  • Method Details

    • createGUnit

      public static GUnit createGUnit(String expr0, String... specialValues) throws GUnitException
      Creates a GUnit object from a String. The String must be in the formats:
       - [+|-] nnn [unit]
       - [+|-] nnn[.ddd] [unit]
       - a formula built from numbers, unit suffixes, the operators "+-*/", parentheses
         and the functions min(), max() and clamp()
      

      A value that is a single number with at most one unit suffix and an optional sign becomes a simple unit, exactly as before; anything else becomes a UT_FORMULA.

      Parameters:
      expr0 - The expression string.
      specialValues - Accepted special values.
      Returns:
      GUnit the created unit.
      Throws:
      GUnitException - The error message. The instance is a FormulaException carrying the offset and length of the error in expr0, so a caller wanting to place a caret can test for that subclass.
    • createCSSGUnit

      public static GUnit createCSSGUnit(String value, String... specialValues) throws GUnitException
      Creates a GUnit object from a String. The String must be in the formats:
       - [+|-] nnn [unit]
       - [+|-] nnn[.ddd] [unit]
      

      All formats except "pixel" supports decimals ([.ddd] above).

      Formulas are not supported. The following units are supported:

      • px: pixel,
      • pt: point,
      • em: width of "M",
      • ex: width of "x",
      • %: percentage width of parent,
      • vw: viewport width,
      • vh: viewport height,
      • rem: root element font size.
      Parameters:
      value - The value string.
      specialValues - Accepted special values.
      Returns:
      GUnit the created unit.
      Throws:
      GUnitException - The error message.
    • validateCSSGUnit

      public static void validateCSSGUnit(GUnit unit, String... specialValues) throws GUnitException
      Validates a GUnit object.

      Formulas are not supported. The following units are supported:

      • px: pixel,
      • pt: point,
      • em: width of "M",
      • ex: width of "x",
      • %: percentage width of parent,
      • vw: viewport width,
      • vh: viewport height,
      • rem: root element font size.
      Parameters:
      unit - The unit as CSS value.
      specialValues - Accepted special values.
      Throws:
      GUnitException - The error message.
    • getType

      public int getType()
      Gets the type of the unit (0-29), one of the values:
      • UT_PX (pixel),
      • UT_DLG (dialog),
      • UT_EM ("em"),
      • UT_EX ("ex"),
      • UT_PT (point),
      • UT_PC (percent),
      • UT_PCW (percentage of parent width),
      • UT_PCH (percentage of parent height),
      • UT_PCMIN (minimum size of percentage of parent width and height),
      • UT_PCMAX (maximum size of percentage of parent width and height),
      • UT_VW (percentage of viewport width),
      • UT_VH (percentage of viewport height),
      • UT_VMIN (size for minimum size of percentage of viewport width and height),
      • UT_VMAX (size for maximum size of percentage of viewport width and height),
      • UT_NL (size of the notch LEFT side safe size in pixels),
      • UT_NR (size of the notch RIGHT side safe size in pixels),
      • UT_NW (notch cutout bounding-box WIDTH in screen space, in pixels),
      • UT_NT (size of the notch TOP side safe size in pixels),
      • UT_NB (size of the notch BOTTOM side safe size in pixels),
      • UT_CWMIN (the component's own computed CSS "min-width"),
      • UT_CWMAX (the component's own computed CSS "max-width"),
      • UT_CHMIN (the component's own computed CSS "min-height"),
      • UT_CHMAX (the component's own computed CSS "max-height"),
      • UT_REM (the root element font size),
      • UT_DPX (one physical device pixel in CSS pixels),
      • UT_DPR (the device pixel ratio itself, a multiplier and not a length),
      • UT_NH (notch cutout bounding-box HEIGHT in screen space, in pixels),
      • UT_NX (offset along the top or bottom edge to the LEFT side of the notch),
      • UT_NY (offset along the left or right edge to the TOP of the notch),
      • UT_FORMULA (formula) or
      • UT_VALUE (special value).
      Returns:
      The unit type.
    • getFormula

      public Formula getFormula()
      Gets the compiled program of a UT_FORMULA unit.
      Returns:
      The compiled formula, or null when this is not a UT_FORMULA.
    • getFormulaSource

      public String getFormulaSource()
      Gets the formula as normalised source text, generated from the opcode array.

      This is a DISPLAY ARTEFACT, not the text the author typed: spacing is normalised and only precedence- and associativity-required parentheses are emitted. Nothing may parse this string at runtime.

      Parenthesis minimisation is not an optimisation pass and costs nothing to leave on: the opcode array holds no parentheses to begin with, so every call regenerates the minimum set from the tree. ((((1%+(((2em+3ex)/2))))+10)/3) comes back as (1% + (2em + 3ex) / 2 + 10) / 3 -- six pairs down to two, both load-bearing.

      Deliberately distinct from toString(), which keeps the behaviour the previous GUnit always had.

      Returns:
      The formula source, or null if this unit is not a formula.
    • simplifyFormula

      public GUnit simplifyFormula() throws GUnitException
      Simplifies the formula by folding constant subexpressions.

      7+(1+(2*3)) becomes 14. Folding stops at a SCALE, so 10%+5 is already minimal: 10% is not known until evaluation.

      Parenthesis minimisation is NOT part of this: it happens on every getFormulaSource() call, because the opcode array contains no parentheses to begin with. Only constant folding discards something the developer wrote, which is why only folding is an explicit action. It must never run automatically -- a developer may have written 2*3 because it is 2 columns by 3 rows and intends to edit it, and regenerating the display text through a folder would silently eat that.

      The result is still a UT_FORMULA even when it has folded to a single constant. It is deliberately not collapsed to a simple unit: a simple pixel value may not carry decimals, so simplifying 1.5+1 would have to throw rather than return the 2.5 it just computed.

      The previous GUnit was immutable and GUnit stays that way, so this returns a new instance rather than folding in place. A property value is very likely shared and cached across the property tree, and a mutating simplify in one editor would change an instance another component is holding.

      Returns:
      A new simplified GUnit, or this when the formula is already minimal and nothing changed. The caller's test is an identity comparison, if ( simplified!=gu ).
      Throws:
      GUnitException - If this unit is not a formula.
    • isLocked

      public boolean isLocked()
      Checks if the unit is "locked" from user change in the GUI design editor.
      Returns:
      The lock flag.
    • setLocked

      public void setLocked(boolean on)
      Sets the lock state of the unit.
      Parameters:
      on - The lock flag.
    • getString

      public String getString()
      Gets the String representation of the bounds as "value type".
      Returns:
      A string in the form of value type.
    • isZero

      public boolean isZero()
      Checks if the unit is zero.
      Returns:
      true if the value is zero when not a UT_FORMULA or UT_VALUE string such as "fixed", false otherwise.
    • equals

      public boolean equals(Object o)
      Checks if two unit objects are equal.
      Overrides:
      equals in class Object
      Parameters:
      o - another unit object. If null, the units are not equal.
      Returns:
      true if the object has the same type and value.
    • equals

      public boolean equals(GUnit unit)
      Checks if two unit objects are equal.

      Two formulas are equal when they are the same PROGRAM, i.e. identical opcodes and constants, rather than when their text happens to match. The text is regenerated from the opcodes so the two are equivalent, but comparing the program says what is meant.

      Parameters:
      unit - another size object. If null, the sizes are not equal.
      Returns:
      true if the object has the same type and value.
    • hashCode

      public int hashCode()
      Returns the hash code of this unit.
      Overrides:
      hashCode in class Object
      Returns:
      The hash code.
    • clone

      public GUnit clone()
      Clones this instance.
      Overrides:
      clone in class Object
      Returns:
      As cloned instance of GUnit.
    • paramString

      protected String paramString()
      Returns the parameter string representing the state of this event. This string is useful for debugging. Super-classes adds extra information to the string by preceding it with a comma followed by the extra information.

      For a UT_FORMULA the text is REGENERATED from the opcodes, with normalised spacing. It is a display artefact; nothing parses it back at runtime.

      Returns:
      the parameter string of this unit object.
    • getValue

      public double getValue()
      Returns the double value for the unit.
      Returns:
      The value for every simple unit type, or Double.NaN for UT_FORMULA and UT_VALUE.
    • toString

      public String toString()
      Returns a string representation of this class instance.
      Overrides:
      toString in class Object
      Returns:
      A string representation of this class instance.
    • getCSSValue

      public String getCSSValue()
      Gets the unit as a CSS value. Formula and percent is NOT accepted and returns null along with a warning logging.
      Returns:
      The CSS value, or null if it's a UT_FORMULA.
    • append

      public void append(SendTransaction trans)
      Appends the unit object to a transaction.

      Only the UT_FORMULA branch differs from the previous GUnit: it writes the opcode array rather than a control-character string. UT_VALUE still writes a string and a simple value still writes the signed integer, the decimal digit count and, when there are decimals, the decimal part. A formula's constants reuse that same triple, which is both smaller than a text number for fractions and already readable by the client.

      Parameters:
      trans - The transaction.
    • validate

      public String validate() throws GUnitException
      Validates an expression formula by evaluating it against a neutral scale table, i.e. one where every unit resolves to 1.0 except the reciprocal pair dpx and dpr.

      Parsing IS validation now, so by the time an instance exists the formula is known to be well formed; this method remains as a smoke test that evaluation terminates and produces a number, and as the value the Designer shows.

      Returns:
      The evaluated value as a string, or null when this is not a UT_FORMULA.
      Throws:
      GUnitException - For validation errors.
    • evalDouble

      public double evalDouble(IScaleProvider scales, int axis)
      Evaluates the formula and returns the raw, unrounded pixel value.

      This overload builds a scale table on every call. When both axes are evaluated for the same element, which is the normal layout case, build the table once with UnitType.fillCommon(IScaleProvider,double[]), swap the two axis-dependent slots with UnitType.fillAxis(IScaleProvider,double[],int) and call evaluate(double[]) instead.

      Parameters:
      scales - The value provider.
      axis - AXIS_X or AXIS_Y.
      Returns:
      The value, or Double.NaN when this is not a UT_FORMULA.
    • evalRounded

      public double evalRounded(IScaleProvider scales, int axis)
      Evaluates the formula and rounds the result to DEFAULT_DECIMALS decimals.
      Parameters:
      scales - The value provider.
      axis - AXIS_X or AXIS_Y.
      Returns:
      The rounded value.
    • evalRounded

      public double evalRounded(IScaleProvider scales, int axis, int decimals)
      Evaluates the formula and rounds the result to a given number of decimals.
      Parameters:
      scales - The value provider.
      axis - AXIS_X or AXIS_Y.
      decimals - The number of decimals, 0 to 7.
      Returns:
      The rounded value.
      Throws:
      IllegalArgumentException - If the decimal count is out of range.
    • evalInt

      public int evalInt(IScaleProvider scales, int axis)
      Evaluates the formula and rounds the result to a whole pixel.
      Parameters:
      scales - The value provider.
      axis - AXIS_X or AXIS_Y.
      Returns:
      The value as an integer number of CSS pixels.
    • evalSnapped

      public double evalSnapped(IScaleProvider scales, int axis)
      Evaluates the formula and snaps the result to the DEVICE PIXEL GRID.

      Snapping is a DIFFERENT operation from decimal rounding: three decimals preserves precision through the arithmetic, snapping aligns the final result to hardware. If both are wanted, snapping goes last. At a device pixel ratio of 2 this permits 0.5px positions, which are exact device pixels, giving twice the positional resolution of integer rounding and letting a 1dpx border land on exactly one physical pixel.

      Callers should snap cumulative OFFSETS and derive each size as the difference, i.e. size[i] = snap(pos[i+1]) - snap(pos[i]). Rounding each item's size independently accumulates error, so item edges stop meeting exactly and a bordered list gets a 1px gap here and an overlap there. Edges then meet by construction, and individual items differing by a pixel is invisible where misaligned borders are not.

      Parameters:
      scales - The value provider.
      axis - AXIS_X or AXIS_Y.
      Returns:
      The snapped value.
    • evaluate

      public double evaluate(double[] scaleTable)
      Evaluates the compiled formula against a prepared scale table. THE EVALUATOR.

      A loop over a switch and a fixed stack. The stack never grows and is never indexed out of bounds, because the parser computes the peak depth of the program at compile time and rejects anything above Formula.MAX_STACK_DEPTH; the depth grows with parenthesis nesting only, never with argument count, since variadic min() and max() are folded pairwise.

      MIN2 and MAX2 are a plain compare rather than Math.min/Math.max: faster, and it avoids having to replicate JavaScript's -0 and NaN rules exactly in Java. The consequence is that a NaN as the right operand loses the comparison and is discarded rather than propagating. A non-finite result is clamped to 0 once, at the end, so NaN never escapes either way.

      Parameters:
      scaleTable - The scale table, see UnitType.
      Returns:
      The value, or Double.NaN when this is not a UT_FORMULA.
    • getPixelValue

      public double getPixelValue(UIComp comp, boolean isHorz)
      Calculates the unit into a pixel value using the font information.

      A unit typed alone resolves exactly as the same unit inside a formula. Every unit except the four font units reads the SAME IScaleProvider the UT_FORMULA branch uses, through providerScale(IScaleProvider,int,int), so 100% and 100%+0px return the same number, and so do 100cwmax and 100cwmax+0px. Only the ONE getter for the unit in question is called; no scale table is built, because this runs per layout. The font units are not routed there because they already agree by identity: both paths read the same comp.getFontInfo().

      The notch values are therefore no longer hardcoded to zero as they are in the previous GUnit. They still evaluate to zero in the Designer, but because the provider has nothing to report there rather than because this method says so.

      BEHAVIOUR CHANGE against the previous GUnit, 2026-08-17, and it is a visible one. The nine percent and viewport units used to read UIComp.getPixelWidth()/getPixelHeight() here and return NaN when the container declared nothing, while a formula read UIComp.getApproximateSize() -- a hardcoded Size(300,200) on a plain container. Both now take the two-level chain in

      invalid reference
      UICompScaleProvider#containerDimension(UIContainer,boolean)
      . Two consequences:
      • Every existing FORMULA using a percent or viewport unit changes value, from a constant-based number to one derived from the container's real declared size.
      • A SIMPLE percent unit no longer yields NaN when the container declares no size; it falls back like everything else. UIComp.getPixelWidth() maps that NaN to -1, so a component declaring 100% under an undeclared parent used to report "no width" and now reports a number. -1 consequently narrows to its literal meaning: no layout, or no unit declared at all.
      Parameters:
      comp - The component.
      isHorz - Flag indicating this is a horizontal value (significant only for % or DLG).
      Returns:
      The pixel value, or Double.NaN if the expression is invalid.
      Throws:
      IllegalStateException - If this is called outside of the Designer.
    • isPureCSS

      public boolean isPureCSS()
      Checks if this is a valid CSS pure unit, e.g. not DLG, Formula.
      Returns:
      true if it's a pure CSS unit, false if it is a calculated value and cannot be used in CSS declarations.
    • isContainerDependent

      public boolean isContainerDependent()
      Returns if this value is dependent on the container size, i.e. value is a percent value or a formula containing percent.

      Behaviour change against the previous GUnit, deliberate. It tests the formula with the anchored regular expression ^[\x06-\x0A]+$, which requires the ENTIRE formula to consist of percent markers and therefore answers false for every formula that also contains a number, i.e. for every real formula. Here the question asked is the one the javadoc always described: does the program use any percent unit.

      Returns:
      true if the value is container dependent, i.e. a Percent value, or if it is a formula that contains a percent value. false is returned if the value is not dependent of the container.