Class PWAIcons

java.lang.Object
com.iizix.pwa.PWAIcons

public final class PWAIcons extends Object
The icons of an installable application (PWA-DESIGN.md 3.3; orders CC-PWA-V5B-MANIFEST and CC-PUSH-PWA-PAGES Set I, rulings PX-1, PD-1, PD-2, PD-4, PI-3): served under /app/<appID>/ by the application directory, which calls build(Sources) once when the server loads the application, and written into the application's PWA folder by the Designer when the PWA page is applied (ruling PD-2, missing()).
The files, and where each lives in the PWA folder <module>/assets/PWA/ (PD-1)
Served asFolder fileSizeUse
icon-192.png, icon-512.pngicons/192.png, icons/512.png192, 512manifest purpose any and the page's PNG rel=icon links: the master scaled, transparency kept
icon-192-maskable.png, icon-512-maskable.pngicons/android/maskable-192.png, maskable-512.png192, 512manifest purpose maskable: opaque, the content inside the safe circle Android crops to
icon-192-monochrome.png, icon-512-monochrome.pngicons/android/monochrome-192.png, monochrome-512.png192, 512manifest purpose monochrome: the shape as alpha, one colour (Android themed icons)
apple-touch-icon.pngicons/ios/180.png180the page's <link rel="apple-touch-icon">: opaque (iOS shows transparency as black)

Where a file comes from, in this order, per file (rulings PD-1, PD-4, PI-3):

  1. the designer's file in the PWA folder, as it is (PWAIcons.Origin.DESIGNER): it always wins;
  2. the image the .iiziPWA names for that kind (iconMaskable, iconMonochrome, iconApple), scaled to the size (PWAIcons.Origin.REFERENCE);
  3. the application's iiziRun icon set under <module>/assets/iiziRun/icons/: the squares for any, the Android adaptive foreground on its bgcolor.xml for maskable and monochrome, ios/180.png for Apple (PWAIcons.Origin.IIZIRUN);
  4. generation from the master icon (PWAIcons.Origin.GENERATED).

Generation (PI-3): transparent margins are trimmed before scaling; the background of a maskable or Apple icon is the image's own edge colour when its border pixels are one opaque colour, else the App's iconBG, else its themeColor, else DEFAULT_BACKGROUND (never white by default); the content is fitted inside the safe circle (diameter SAFE_ZONE of the side), not the whole square scaled to 80 %; the monochrome variant takes its alpha from the content (its own alpha, or what differs from the edge colour) in one colour. An Apple icon from an opaque source is the source full bleed, as iOS expects (its mask rounds the corners); from a source with transparency it is fitted like a maskable icon.

iiziRun's icon set (order CC-PWA-ICONS-IIZIRUN, ruling I-D-1): the same master also gives the files iiziRun's set under IIZIRUN_ICONS lacks, exactly the files the runtime builder checks and the Cordova configuration names (iiziRunRequired(Map)), with the same rules per platform: the squares and the Android icons are the master scaled (purpose any, transparency kept), the Android adaptive foreground layers hold the content inside the launcher's safe zone (ADAPTIVE_SAFE_ZONE) on transparency with the background colour in bgcolor.xml, the iOS icons are the master full bleed on the background, opaque. A file the set already has is never replaced (iiziRunMissing(byte[],Map,Color)); the Designer writes the rest when the PWA page is applied, and the iiziRun setup wizard when a module is set up (iiziRunMissingUnder(File,byte[],byte[],Color), the set read from its directory).

Pure: bytes in, PNG bytes out, nothing cached, nothing written. The same sources give the same bytes, which the directory stamp relies on. Scaling is CachedImage.scale(int,int,String). An instance is immutable; get(String) hands out copies.

Author:
Christopher Mindus
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static enum 
    Where a file came from.
    static final record 
    What the icons are built from.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final double
    The share of an Android adaptive foreground layer's side its safe zone takes: the circle of 66 dp diameter in the 108 dp layer, which no launcher mask crops.
    static final String
    The 180 px icon for iOS and iPadOS.
    static final Color
    The background of a maskable or Apple icon when the image has no edge colour and the App has neither an opaque iconBG nor an opaque themeColor: --iz-bg of the default family (IIZI), light, the manifest's default background_color - never white.
    static final String
    The PWA folder of a module, relative to its assets directory: "PWA" (ruling PD-1).
    static final Map<String,String>
    The files by served name, each mapped to its path in the PWA folder relative to the assets directory, in the order of the table in the class description.
    static final String
    The screenshots folder, relative to the assets directory: "PWA/screenshots" (ruling PM-2).
    static final String
    The 192 px icon, purpose any.
    static final String
    The 192 px icon, purpose maskable.
    static final String
    The 192 px icon, purpose monochrome.
    static final String
    The 512 px icon, purpose any.
    static final String
    The 512 px icon, purpose maskable.
    static final String
    The 512 px icon, purpose monochrome.
    static final String
    The accent colour a generated bgcolor.xml carries beside the background: the file becomes the Android project's res/values/colors.xml (CodeModifier), and BIGACE's and icu's hand-made files carry this colour, the one CodeModifier gives FirebaseX as ANDROID_ICON_ACCENT.
    static final String
    iiziRun's Android adaptive icon folder: its presence makes the runtime builder use adaptive icons (RuntimeBuilderSettings, CodeModifier).
    static final String
    iiziRun's Android adaptive background colour file (<color name="background">#RRGGBB</color>).
    static final String
    iiziRun's largest Android adaptive foreground layer (256 px, transparent), the source of the maskable and monochrome icons when the designer has none.
    static final String
    The iiziRun icon set of a module, relative to its assets directory: "iiziRun/icons" (PD-4).
    static final String
    iiziRun's 180 px iOS icon, the Apple icon when the designer has none.
    static final String
    iiziRun's Android splash screen icon, one transparent pixel: the Cordova configuration CodeModifier writes names it (AndroidWindowSplashScreenAnimatedIcon) for every Android build, although the runtime builder does not check it.
    static final String
    iiziRun's 192 px square, the source of ICON_192 when the designer has none.
    static final String
    iiziRun's 512 px square, the source of ICON_512 when the designer has none.
    static final int
    The smallest side of the master icon: 512 (ruling PX-1).
    static final String
    The media type of every file.
    static final int
    The colour of a monochrome icon: its alpha is the shape, the colour is the platform's.
    static final double
    The share of a maskable icon's side the safe circle takes: 80 %, its diameter.
  • Method Summary

    Modifier and Type
    Method
    Description
    static PWAIcons
    Builds the icons of an application from its sources, in the order the class description gives: the designer's folder file, the named image, the iiziRun icon set, generation from the master.
    static String
    checkMaster(byte[] data)
    Checks the master icon (ruling PX-1): a PNG, square, at least MASTER_MIN_SIZE px.
    static String
    Checks a master icon file before anything is created from it (the iiziRun setup dialog's own check, ruling W-D-3): the file is read and its bytes checked as checkMaster(byte[]) does.
    static PWAIcons
    generate(byte[] master, Color fallback)
    Generates every icon from a master icon alone, on a given background when the image has no edge colour: the shape the tests and the Designer's preview use.
    byte[]
    get(String fileName)
    Gets a copy of a file.
    Gets the background the generated maskable and Apple icons were drawn on.
    static Color
    Picks the App's background for the maskable and Apple icons when an image has no edge colour: the App's iconBG, else its themeColor, else null for DEFAULT_BACKGROUND.
    Gets the names of the files, in the order of the table in the class description.
    getOrigin(String fileName)
    Gets where a file came from.
    static boolean
    hasTransparency(byte[] data)
    Checks whether an image has a pixel that is not fully opaque (the platform rule for a maskable or Apple icon: Android fills the mask with the icon, iOS shows transparency as black).
    static Map<String,byte[]>
    iiziRunMissing(byte[] master, Map<String,byte[]> assets, Color fallback)
    Generates the files iiziRun's icon set lacks from the master icon: every path of iiziRunRequired(Map) the assets do not hold - a file the set has is never replaced.
    static Map<String,byte[]>
    iiziRunMissingUnder(File icons, byte[] master, byte[] ios, Color fallback)
    Generates the files iiziRun's icon set under a directory lacks, as the iiziRun setup wizard needs them: the set is read from the directory and its sub-folders, the missing files are iiziRunMissing(byte[],Map,Color)'s, and the iOS icons may come from a second, opaque master (the wizard's opaque icon file).
    static List<String>
    iiziRunRequired(Map<String,byte[]> assets)
    Gets the files of iiziRun's icon set the runtime builder checks and the Cordova configuration names, by path relative to the assets directory, in the builder's order, each once: the squares (RuntimeBuilderSettings.ICONS_COMMON); the Android icons (RuntimeBuilderSettings.ICONS_ANDROID_STANDARD under android/) and IIZIRUN_NODOT; the adaptive foreground layers (f<size>.png of RuntimeBuilderSettings.ICONS_ANDROID_ADAPTIVE_SIZE under IIZIRUN_ADAPTIVE) with bgcolor.xml, or with the background layers b<size>.png when the folder already has one of them and no bgcolor.xml (the builder's other form); the iOS icons (RuntimeBuilderSettings.ICONS_IOS under ios/).
    static boolean
    isPNG(byte[] data)
    Checks whether bytes start with the PNG signature.
    Map<String,byte[]>
    Gets the files the PWA folder lacks: every file not of PWAIcons.Origin.DESIGNER, by its path in the folder relative to the assets directory.
    static GColor
    opaque(ModuleApp app, GColor c, String scheme)
    Gets a colour of an App when it is an opaque literal, a referenced colour (%...: a palette colour of the module, or a platform role) resolved first through the App's tree for a scheme, by the one algorithm the server and the Designer use (ColorResolver; CC-FIX-NAMED-COLOR-UNRESOLVED - a reference counted as no colour before, while the Designer's App page showed it resolved).
  • Field Details

    • ICON_192

      public static final String ICON_192
      The 192 px icon, purpose any.
      See Also:
    • ICON_512

      public static final String ICON_512
      The 512 px icon, purpose any.
      See Also:
    • ICON_192_MASKABLE

      public static final String ICON_192_MASKABLE
      The 192 px icon, purpose maskable.
      See Also:
    • ICON_512_MASKABLE

      public static final String ICON_512_MASKABLE
      The 512 px icon, purpose maskable.
      See Also:
    • ICON_192_MONOCHROME

      public static final String ICON_192_MONOCHROME
      The 192 px icon, purpose monochrome.
      See Also:
    • ICON_512_MONOCHROME

      public static final String ICON_512_MONOCHROME
      The 512 px icon, purpose monochrome.
      See Also:
    • APPLE_TOUCH_ICON

      public static final String APPLE_TOUCH_ICON
      The 180 px icon for iOS and iPadOS.
      See Also:
    • FOLDER

      public static final String FOLDER
      The PWA folder of a module, relative to its assets directory: "PWA" (ruling PD-1).
      See Also:
    • FOLDER_SCREENSHOTS

      public static final String FOLDER_SCREENSHOTS
      The screenshots folder, relative to the assets directory: "PWA/screenshots" (ruling PM-2).
      See Also:
    • IIZIRUN_ICONS

      public static final String IIZIRUN_ICONS
      The iiziRun icon set of a module, relative to its assets directory: "iiziRun/icons" (PD-4).
      See Also:
    • IIZIRUN_SQUARE_192

      public static final String IIZIRUN_SQUARE_192
      iiziRun's 192 px square, the source of ICON_192 when the designer has none.
      See Also:
    • IIZIRUN_SQUARE_512

      public static final String IIZIRUN_SQUARE_512
      iiziRun's 512 px square, the source of ICON_512 when the designer has none.
      See Also:
    • IIZIRUN_ADAPTIVE_FOREGROUND

      public static final String IIZIRUN_ADAPTIVE_FOREGROUND
      iiziRun's largest Android adaptive foreground layer (256 px, transparent), the source of the maskable and monochrome icons when the designer has none.
      See Also:
    • IIZIRUN_ADAPTIVE_BGCOLOR

      public static final String IIZIRUN_ADAPTIVE_BGCOLOR
      iiziRun's Android adaptive background colour file (<color name="background">#RRGGBB</color>).
      See Also:
    • IIZIRUN_IOS_180

      public static final String IIZIRUN_IOS_180
      iiziRun's 180 px iOS icon, the Apple icon when the designer has none.
      See Also:
    • IIZIRUN_ADAPTIVE

      public static final String IIZIRUN_ADAPTIVE
      iiziRun's Android adaptive icon folder: its presence makes the runtime builder use adaptive icons (RuntimeBuilderSettings, CodeModifier).
      See Also:
    • IIZIRUN_NODOT

      public static final String IIZIRUN_NODOT
      iiziRun's Android splash screen icon, one transparent pixel: the Cordova configuration CodeModifier writes names it (AndroidWindowSplashScreenAnimatedIcon) for every Android build, although the runtime builder does not check it.
      See Also:
    • ADAPTIVE_SAFE_ZONE

      public static final double ADAPTIVE_SAFE_ZONE
      The share of an Android adaptive foreground layer's side its safe zone takes: the circle of 66 dp diameter in the 108 dp layer, which no launcher mask crops.
      See Also:
    • IIZIRUN_ACCENT

      public static final String IIZIRUN_ACCENT
      The accent colour a generated bgcolor.xml carries beside the background: the file becomes the Android project's res/values/colors.xml (CodeModifier), and BIGACE's and icu's hand-made files carry this colour, the one CodeModifier gives FirebaseX as ANDROID_ICON_ACCENT.
      See Also:
    • FOLDER_FILES

      public static final Map<String,String> FOLDER_FILES
      The files by served name, each mapped to its path in the PWA folder relative to the assets directory, in the order of the table in the class description.
    • MASTER_MIN_SIZE

      public static final int MASTER_MIN_SIZE
      The smallest side of the master icon: 512 (ruling PX-1).
      See Also:
    • SAFE_ZONE

      public static final double SAFE_ZONE
      The share of a maskable icon's side the safe circle takes: 80 %, its diameter.
      See Also:
    • DEFAULT_BACKGROUND

      public static final Color DEFAULT_BACKGROUND
      The background of a maskable or Apple icon when the image has no edge colour and the App has neither an opaque iconBG nor an opaque themeColor: --iz-bg of the default family (IIZI), light, the manifest's default background_color - never white.
    • MONOCHROME_RGB

      public static final int MONOCHROME_RGB
      The colour of a monochrome icon: its alpha is the shape, the colour is the platform's.
      See Also:
    • MEDIA_TYPE

      public static final String MEDIA_TYPE
      The media type of every file.
      See Also:
  • Method Details

    • build

      public static PWAIcons build(PWAIcons.Sources sources) throws IOException
      Builds the icons of an application from its sources, in the order the class description gives: the designer's folder file, the named image, the iiziRun icon set, generation from the master. A file no source can give is left out (an application without a master and without the folder's files has no icons at all).
      Parameters:
      sources - The sources.
      Returns:
      The icons, possibly without a single file.
      Throws:
      IOException - If the master is given but is not a square PNG of at least 512 px, or if a named image cannot be read: the text names the problem, never a byte of the image.
    • generate

      public static PWAIcons generate(byte[] master, Color fallback) throws IOException
      Generates every icon from a master icon alone, on a given background when the image has no edge colour: the shape the tests and the Designer's preview use.
      Parameters:
      master - The PNG bytes of the master icon.
      fallback - The background when the image has no edge colour, null for the default.
      Returns:
      The icons.
      Throws:
      IOException - If the master is not a square PNG of at least 512 px.
    • checkMaster

      public static String checkMaster(byte[] data)
      Checks the master icon (ruling PX-1): a PNG, square, at least MASTER_MIN_SIZE px.
      Parameters:
      data - The bytes.
      Returns:
      null when the master is accepted, else the problem as a phrase that completes "The master icon ...": "is not a PNG file", "is not square (width=.., height=..)", "is smaller than 512 x 512 (width=..)".
    • checkMasterFile

      public static String checkMasterFile(File file)
      Checks a master icon file before anything is created from it (the iiziRun setup dialog's own check, ruling W-D-3): the file is read and its bytes checked as checkMaster(byte[]) does. Nothing is written. (Its own name: an overload would make checkMaster(null) ambiguous.)
      Parameters:
      file - The file.
      Returns:
      null when the master is accepted, else the problem as a phrase that completes "The icon file ...": the phrases of checkMaster(byte[]), or "cannot be read (..)" when the file cannot be read.
    • isPNG

      public static boolean isPNG(byte[] data)
      Checks whether bytes start with the PNG signature.
      Parameters:
      data - The bytes.
      Returns:
      true for a PNG file.
    • hasTransparency

      public static boolean hasTransparency(byte[] data)
      Checks whether an image has a pixel that is not fully opaque (the platform rule for a maskable or Apple icon: Android fills the mask with the icon, iOS shows transparency as black).
      Parameters:
      data - The PNG bytes.
      Returns:
      true when a pixel is not opaque; false for an opaque image, or for bytes that are not an image.
    • getBackground

      public static Color getBackground(ModuleApp app)
      Picks the App's background for the maskable and Apple icons when an image has no edge colour: the App's iconBG, else its themeColor, else null for DEFAULT_BACKGROUND. A colour counts only when it is an opaque literal, or a reference that resolves to one for the light scheme (opaque(ModuleApp,GColor,String)).
      Parameters:
      app - The App, or null.
      Returns:
      The colour, or null for the default.
    • opaque

      public static GColor opaque(ModuleApp app, GColor c, String scheme)
      Gets a colour of an App when it is an opaque literal, a referenced colour (%...: a palette colour of the module, or a platform role) resolved first through the App's tree for a scheme, by the one algorithm the server and the Designer use (ColorResolver; CC-FIX-NAMED-COLOR-UNRESOLVED - a reference counted as no colour before, while the Designer's App page showed it resolved).
      Parameters:
      app - The App the colour belongs to: the tree its reference is resolved in.
      c - The colour, or null.
      scheme - The scheme a reference is resolved for, PaletteColor.SCHEME_LIGHT or PaletteColor.SCHEME_DARK.
      Returns:
      The colour, or null when absent, inherited, a reference that does not resolve to a literal, or not opaque.
    • iiziRunRequired

      public static List<String> iiziRunRequired(Map<String,byte[]> assets)
      Gets the files of iiziRun's icon set the runtime builder checks and the Cordova configuration names, by path relative to the assets directory, in the builder's order, each once: the squares (RuntimeBuilderSettings.ICONS_COMMON); the Android icons (RuntimeBuilderSettings.ICONS_ANDROID_STANDARD under android/) and IIZIRUN_NODOT; the adaptive foreground layers (f<size>.png of RuntimeBuilderSettings.ICONS_ANDROID_ADAPTIVE_SIZE under IIZIRUN_ADAPTIVE) with bgcolor.xml, or with the background layers b<size>.png when the folder already has one of them and no bgcolor.xml (the builder's other form); the iOS icons (RuntimeBuilderSettings.ICONS_IOS under ios/).

      The adaptive files are left out when the set has Android icons of the designer's and not a single adaptive file: the builder then uses those icons alone, and an adaptive layer added beside them would replace them on every launcher since Android 8.

      Parameters:
      assets - The module's asset files by path relative to the assets directory with '/' separators, those under IIZIRUN_ICONS at least; null for none.
      Returns:
      The paths.
    • iiziRunMissing

      public static Map<String,byte[]> iiziRunMissing(byte[] master, Map<String,byte[]> assets, Color fallback) throws IOException
      Generates the files iiziRun's icon set lacks from the master icon: every path of iiziRunRequired(Map) the assets do not hold - a file the set has is never replaced. The squares and the Android icons are the master scaled, transparency kept; the adaptive foreground layers are the content (the master's own alpha, or what differs from its edge colour) trimmed and fitted inside ADAPTIVE_SAFE_ZONE on transparency; the background is the image's edge colour, else the fallback, else DEFAULT_BACKGROUND, written as bgcolor.xml (or as opaque b<size>.png layers); the iOS icons are the master scaled to the whole square and drawn on that background, without an alpha channel; nodot.png is one transparent pixel.
      Parameters:
      master - The PNG bytes of the master icon (square, at least 512).
      assets - The module's asset files by path relative to the assets directory with '/' separators, those under IIZIRUN_ICONS at least; null for none.
      fallback - The App's background when the master has no edge colour (getBackground(ModuleApp)), null for the default.
      Returns:
      The missing files, path relative to the assets directory to bytes, in the order of iiziRunRequired(Map); empty when the set is complete.
      Throws:
      IOException - If the master is not a square PNG of at least 512 px: the text names the problem.
    • iiziRunMissingUnder

      public static Map<String,byte[]> iiziRunMissingUnder(File icons, byte[] master, byte[] ios, Color fallback) throws IOException
      Generates the files iiziRun's icon set under a directory lacks, as the iiziRun setup wizard needs them: the set is read from the directory and its sub-folders, the missing files are iiziRunMissing(byte[],Map,Color)'s, and the iOS icons may come from a second, opaque master (the wizard's opaque icon file). A file the directory has is never generated, whatever its bytes.
      Parameters:
      icons - The set's directory (<module>/assets/iiziRun/icons), possibly absent; null for an empty set.
      master - The PNG bytes of the master icon (square, at least 512): the squares, the Android icons and the adaptive layers, and the iOS icons when ios is null.
      ios - The PNG bytes of the master of the iOS icons (square, at least 512), or null for master.
      fallback - The App's background when a master has no edge colour (getBackground(ModuleApp)), null for the default.
      Returns:
      The missing files by path relative to icons with '/' separators (512.png, android/adaptive/f256.png, ios/180.png) to bytes, in the order of iiziRunRequired(Map); empty when the set is complete.
      Throws:
      IOException - If a master is not a square PNG of at least 512 px (the text names the problem), or a file of the set cannot be read.
    • getFileNames

      public Set<String> getFileNames()
      Gets the names of the files, in the order of the table in the class description.
      Returns:
      The served names.
    • get

      public byte[] get(String fileName)
      Gets a copy of a file.
      Parameters:
      fileName - The served name, e.g. ICON_192.
      Returns:
      The PNG bytes, or null for a name this instance does not hold.
    • getOrigin

      public PWAIcons.Origin getOrigin(String fileName)
      Gets where a file came from.
      Parameters:
      fileName - The served name.
      Returns:
      The origin, or null for a name this instance does not hold.
    • missing

      public Map<String,byte[]> missing()
      Gets the files the PWA folder lacks: every file not of PWAIcons.Origin.DESIGNER, by its path in the folder relative to the assets directory. The Designer writes them when the PWA page is applied (ruling PD-2), never over a designer's file.
      Returns:
      The missing files, path to PNG bytes (copies), in the order of the table.
    • getBackground

      public Color getBackground()
      Gets the background the generated maskable and Apple icons were drawn on.
      Returns:
      The opaque colour.