Class UnitType

java.lang.Object
com.iizix.prop.gunit.internal.UnitType

public final class UnitType extends Object
The 29 unit types of a GUnit formula: their names, their numbering, whether they are axis-dependent, and the construction of the scale table that the evaluator indexes.

Everything is a postfix scale. Every unit, percentages included, is exactly one operation: multiply the value on top of the evaluation stack by a scalar. There is no unit system in the evaluator, only a stack machine and a double [] scale table indexed by the UT_* constants. px is 1.0, pt is dpi/72, em is the font size, % is axisParentDimension/100, and so on.

Only TWO of the 29 units are axis-dependent, UT_PC and UT_DLG. The scale table can therefore be built once per element with fillCommon(IScaleProvider,double[]) and have just those two slots swapped between the X pass and the Y pass with fillAxis(IScaleProvider,double[],int). One parsed program serves both axes.

The unit numbering 1 to 19 is unchanged from the original GUnit implementation and is part of the wire format; units 20 to 29 are new. The name array is ONE-BASED, i.e. getName(UT_PX) rather than TYPES[UT_PX-1].

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 size of a scale table, i.e.
    static final int
    The number of unit types, i.e.
    static final int
    The component's own computed CSS max-height in pixels, chmax.
    static final int
    The component's own computed CSS min-height in pixels, chmin.
    static final int
    The component's own computed CSS max-width in pixels, cwmax.
    static final int
    The component's own computed CSS min-width in pixels, cwmin.
    static final int
    Dialog units, dlg.
    static final int
    THE DEVICE PIXEL RATIO ITSELF, dpr: 1, 1.25, 1.5, 2, 3.
    static final int
    ONE PHYSICAL DEVICE PIXEL expressed in CSS pixels, dpx, i.e.
    static final int
    The font size of the element's own font, em.
    static final int
    The x-height of the element's own font, ex.
    static final int
    The safe-area inset on the BOTTOM, nb.
    static final int
    The notch cutout bounding-box HEIGHT in SCREEN space, nh.
    static final int
    The safe-area inset on the LEFT, nl.
    static final int
    The safe-area inset on the RIGHT, nr.
    static final int
    The safe-area inset on the TOP, nt.
    static final int
    The notch cutout bounding-box WIDTH in SCREEN space, nw.
    static final int
    The offset along the top or bottom edge to the LEFT side of the notch, nx.
    static final int
    The offset along the left or right edge to the TOP of the notch, ny.
    static final int
    Percent of the parent along the axis being calculated, %.
    static final int
    Percent of the parent HEIGHT, %h.
    static final int
    Percent of the LARGER of the parent's width and height, %max.
    static final int
    Percent of the SMALLER of the parent's width and height, %min.
    static final int
    Percent of the parent WIDTH, %w.
    static final int
    Points, pt, i.e.
    static final int
    Pixels, px.
    static final int
    The ROOT element font size, rem.
    static final int
    Percent of the viewport height, vh.
    static final int
    Percent of the larger viewport dimension, vmax.
    static final int
    Percent of the smaller viewport dimension, vmin.
    static final int
    Percent of the viewport width, vw.
  • Method Summary

    Modifier and Type
    Method
    Description
    static double[]
    Convenience method building a complete scale table for one axis in a single call.
    static double[]
    Allocates an empty scale table of the correct size.
    static void
    fillAxis(IScaleProvider p, double[] scales, int axis)
    Fills the two axis-DEPENDENT slots of the scale table, UT_PC and UT_DLG.
    static void
    fillCommon(IScaleProvider p, double[] scales)
    Fills every axis-INDEPENDENT slot of the scale table.
    static int
    Looks a unit name up, case insensitively.
    static String
    getName(int ut)
    Gets the name of a unit type.
    static boolean
    Checks if the unit type is axis-dependent, i.e.
    static String
    Suggests a unit name for a misspelling, for the "did you mean" part of an error message.
  • Field Details

    • 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
      Pixels, px. The identity scale of 1.0; the emitter emits no scale opcode for it, and it is the implicit unit of a bare number.
      See Also:
    • UT_PT

      public static final int UT_PT
      Points, pt, i.e. 1/72 inch.
      See Also:
    • UT_EM

      public static final int UT_EM
      The font size of the element's own font, em. Per-element.
      See Also:
    • UT_EX

      public static final int UT_EX
      The x-height of the element's own font, ex. Per-element.
      See Also:
    • UT_DLG

      public static final int UT_DLG
      Dialog units, dlg. Axis-dependent, and per-element since it depends on the element's own font. Windows dialog units use a different base unit AND a different divisor per axis: horizontal px = dlu*baseUnitX/4, vertical px = dlu*baseUnitY/8.
      See Also:
    • UT_PC

      public static final int UT_PC
      Percent of the parent along the axis being calculated, %. Axis-dependent.
      See Also:
    • UT_PCW

      public static final int UT_PCW
      Percent of the parent WIDTH, %w. Axis-independent, so it is usable on the Y axis to obtain an X-relative value.
      See Also:
    • UT_PCH

      public static final int UT_PCH
      Percent of the parent HEIGHT, %h. Axis-independent, the mirror of UT_PCW.
      See Also:
    • UT_PCMIN

      public static final int UT_PCMIN
      Percent of the SMALLER of the parent's width and height, %min. Axis-independent: the same value on the X pass and the Y pass.
      See Also:
    • UT_PCMAX

      public static final int UT_PCMAX
      Percent of the LARGER of the parent's width and height, %max. Axis-independent.
      See Also:
    • UT_VW

      public static final int UT_VW
      Percent of the viewport width, vw.
      See Also:
    • UT_VH

      public static final int UT_VH
      Percent of the viewport height, vh.
      See Also:
    • UT_VMIN

      public static final int UT_VMIN
      Percent of the smaller viewport dimension, vmin.
      See Also:
    • UT_VMAX

      public static final int UT_VMAX
      Percent of the larger viewport dimension, vmax.
      See Also:
    • UT_NL

      public static final int UT_NL
      The safe-area inset on the LEFT, nl.
      See Also:
    • UT_NR

      public static final int UT_NR
      The safe-area inset on the RIGHT, nr.
      See Also:
    • UT_NW

      public static final int UT_NW
      The notch cutout bounding-box WIDTH in SCREEN space, nw.

      The meaning of this unit is restated. It is the screen-space width of the cutout, not "the maximum of the left and right insets" as the original javadoc said. Because nw and UT_NH describe the bounding box in screen space, they swap as the device rotates under the cutout: a 40x10 notch in portrait becomes 10x40 in landscape, and a formula author never has to branch on orientation.

      In landscape the two descriptions coincide, since the inset perpendicular to the edge IS the cutout extent along the screen's horizontal; that is why the previous definition worked in practice. In portrait the width has no data source on the web platform and resolves to whatever the IScaleProvider reports, which is 0 unless a measured value has been supplied.

      See Also:
    • UT_NT

      public static final int UT_NT
      The safe-area inset on the TOP, nt.
      See Also:
    • UT_NB

      public static final int UT_NB
      The safe-area inset on the BOTTOM, nb. Note that in portrait on an iPhone X or later this is the home-indicator inset, around 34px, and NOT zero.
      See Also:
    • UT_CWMIN

      public static final int UT_CWMIN
      The component's own computed CSS min-width in pixels, cwmin.

      Naming. %min, %max, %w and %h all measure the PARENT; these four measure the COMPONENT. Naming them %wmin and so on would put two different subjects under one prefix, so that %w and %wmin would read as a family while meaning different things. The c prefix marks the subject.

      See Also:
    • UT_CWMAX

      public static final int UT_CWMAX
      The component's own computed CSS max-width in pixels, cwmax. See UT_CWMIN for the naming.
      See Also:
    • UT_CHMIN

      public static final int UT_CHMIN
      The component's own computed CSS min-height in pixels, chmin. See UT_CWMIN for the naming.
      See Also:
    • UT_CHMAX

      public static final int UT_CHMAX
      The component's own computed CSS max-height in pixels, chmax. See UT_CWMIN for the naming.
      See Also:
    • UT_REM

      public static final int UT_REM
      The ROOT element font size, rem. Real CSS and universally supported; UT_EM covers the element's own font, nothing else was root-relative.
      See Also:
    • UT_DPX

      public static final int UT_DPX
      ONE PHYSICAL DEVICE PIXEL expressed in CSS pixels, dpx, i.e. 1/devicePixelRatio. A LENGTH.

      0.333px on a 3x display and 0.25px at 4x, so on a 4x device 4dpx is exactly 1px. Non-integer ratios are the common case, since Windows display scaling gives 1.25, 1.5, 1.75 and 2.5, and they work normally: 1dpx at 1.25 is 0.8px.

      Two caveats. First, browsers re-round hairlines: for border-width, outline-width, column-rule-width and outline-offset the computed length is rounded to an integer number of device pixels, so a dpx-derived value landing in one of those four properties gets the browser's rounding applied on top of ours. Width, height, margin and padding pass through untouched. Second, devicePixelRatio is not constant for the life of a page: it changes on browser zoom and when a window moves between displays of different density, with NO resize event, so the client must refill this slot from a matchMedia('(resolution: Ndppx)') change listener.

      Neither dpx nor UT_DPR is a CSS unit. CSS has no <length> unit for a physical device pixel; dppx exists but is a <resolution> unit valid only inside media queries. This is no different from dlg, %w or nl in that the browser only ever receives the evaluated px value.

      See Also:
    • UT_DPR

      public static final int UT_DPR
      THE DEVICE PIXEL RATIO ITSELF, dpr: 1, 1.25, 1.5, 2, 3.

      This unit is unlike every other one. Every other unit is a measurement that stands alone. dpr is a bare MULTIPLIER, NOT A LENGTH: 1dpr by itself resolves to an arbitrary pixel count, 3px on a 3x display, and is not a meaningful size. It is only useful multiplied by something else, e.g. 16px*1dpr which gives 48px there. It is intended for density-aware sizing.

      dpr and UT_DPX are exact reciprocals, so 1dpx*1dpr is exactly 1px in IEEE double even at 3x, since (1.0/3.0)*3.0==1.0. They can therefore cancel silently in a formula.

      Do not confuse the IIZI unit dpr with the JavaScript variable window.devicePixelRatio. They are the same quantity at different layers: the unit is what a designer writes in a formula, the variable is what fills the scale table.

      See Also:
    • UT_NH

      public static final int UT_NH
      The notch cutout bounding-box HEIGHT in SCREEN space, nh. Pairs with UT_NW; see there for the screen-space rotation behaviour.
      See Also:
    • UT_NX

      public static final int UT_NX
      The offset along the top or bottom edge to the LEFT side of the notch, nx. Used mainly in portrait and zero in landscape.

      EDGE, not centre. nx is the left edge, nx+nw the right edge, and the centre is nx+nw/2 when wanted. Centre-based offsets would make the common case pay a -nw/2 tax, and edge is consistent with nl, nr, nt and nb and with every platform API, all of which return rectangles. A useful expression worth knowing rather than adding a unit for: the gap to the right of the notch in portrait is 100%w-(1nx+1nw).

      See Also:
    • UT_NY

      public static final int UT_NY
      The offset along the left or right edge to the TOP of the notch, ny. Used mainly in landscape and zero in portrait. See UT_NX for the edge-not-centre decision.
      See Also:
    • UNIT_COUNT

      public static final int UNIT_COUNT
      The number of unit types, i.e. the largest legal UT_* value.
      See Also:
    • SCALE_TABLE_SIZE

      public static final int SCALE_TABLE_SIZE
      The size of a scale table, i.e. UNIT_COUNT+1 since the table is indexed one-based by the UT_* constants and slot 0 is unused.
      See Also:
  • Method Details

    • getName

      public static String getName(int ut)
      Gets the name of a unit type.
      Parameters:
      ut - The unit type, 1 to UNIT_COUNT.
      Returns:
      The unit name, e.g. "%w".
      Throws:
      IllegalArgumentException - If the unit type is out of range.
    • fromName

      public static int fromName(String name)
      Looks a unit name up, case insensitively.
      Parameters:
      name - The candidate unit name, exactly as written in the source.
      Returns:
      The unit type 1 to UNIT_COUNT, or -1 if the name is not a unit.
    • suggest

      public static String suggest(String name)
      Suggests a unit name for a misspelling, for the "did you mean" part of an error message. A suggestion is only offered when the edit distance is exactly one AND the match is unique, so that the suggestion is never a guess between two candidates.
      Parameters:
      name - The unknown unit name as written in the source.
      Returns:
      The suggested unit name, or null when there is no unique edit-distance-one match.
    • isAxisDependent

      public static boolean isAxisDependent(int ut)
      Checks if the unit type is axis-dependent, i.e. resolves differently on the X pass and the Y pass. Exactly two units are: UT_PC and UT_DLG.
      Parameters:
      ut - The unit type.
      Returns:
      true if the slot must be refilled per axis, false otherwise.
    • createScaleTable

      public static double[] createScaleTable()
      Allocates an empty scale table of the correct size.
      Returns:
      A new double [] of SCALE_TABLE_SIZE entries.
    • fillCommon

      public static void fillCommon(IScaleProvider p, double[] scales)
      Fills every axis-INDEPENDENT slot of the scale table. Call this once per element, then call fillAxis(IScaleProvider,double[],int) once per axis pass.
      Parameters:
      p - The value provider.
      scales - The scale table to fill, of SCALE_TABLE_SIZE entries.
    • fillAxis

      public static void fillAxis(IScaleProvider p, double[] scales, int axis)
      Fills the two axis-DEPENDENT slots of the scale table, UT_PC and UT_DLG. Call once per axis pass after fillCommon(IScaleProvider, double[]).
      Parameters:
      p - The value provider.
      scales - The scale table, of SCALE_TABLE_SIZE entries.
      axis - AXIS_X or AXIS_Y.
    • buildScaleTable

      public static double[] buildScaleTable(IScaleProvider p, int axis)
      Convenience method building a complete scale table for one axis in a single call. Prefer fillCommon(IScaleProvider, double[]) plus fillAxis(IScaleProvider, double[], int) when both axes are evaluated for the same element, which is the normal layout case.
      Parameters:
      p - The value provider.
      axis - AXIS_X or AXIS_Y.
      Returns:
      The filled scale table.