Description générale des chemins d'images

Un chemin décrivant une image peut être le chemin d'accès à un fichier sur le disque (relatif ou absolu), ce qui permet de charger ce fichier directement. Mais on peut également préciser un certain nombre d'actions particulières pour créer l'image ex-nihilo, ou pour transformer celle chargée depuis le fichier. Ces actions sont à préciser avec un « # », suivi du nom de l'action, suivi d'un éventuel paramètre (entre parenthèses s'il est présent), suivi éventuellement d'un signe « : » si la fonction s'applique sur un autre chemin. Par exemple, « #tint(sepia):/chemin/vers/photo » va charger une photo et la teindre en sépia, ou « #icon(image-missing) » va chercher l'icône « image-missing » dans le thème actuel.

Si le chemin demandé ne commence ni par « # » ni par « / » et ne correspond pas à un fichier sur le disque, on va tenter de l'interprêter autrement. Les chemins « CLIPBOARD », « PRIMARY » et « SECONDARY », de même que les chemins débutant par « _ » et ne contenant que des caractères alphabétiques non-accentués majuscules en plus des éventuels autres « _ » sont considérés comme des identifiants de sélection X (sur le display actif), l'image est donc lue depuis le presse-papier correspondant. Sinon, on tentera d'écrire le texte sur fond transparent.

Le module d'images possède un attribut « prefix », qui vaut par défaut une chaîne vide. Il est possible que le programme appelant, par exemple d'après un paramètre de configuration, modifie cette variable pour ajouter une ou plusieurs fonctions à ce préfixe pour appliquer systématiquement une transformation donnée à toutes les images chargées.

Transformations possibles sur les images

#file(mode):chemin permet de charger le fichier dont le chemin est fourni. C'est cette fonction qui est implicitement appelée quand un chemin vers un fichier est donné, mais l'appeler explicitement permet d'en changer les paramètres. Par défaut, trois valeurs sont reconnues : « render » pour afficher l'image si elle est chargeable directement, « texte » pour générer une miniature présentant le contenu texte du fichier, et « mime » pour afficher une icône correspondant au type mime. On peut désactiver l'une ou l'autre de ces options en ne mettant que les deux autres paramètres.

Cette fonction renvoie en fait sur les différents chargeurs d'image fournis, qui dépendent eux-mêmes beaucoup des bibliothèques disponibles (PIL et GDK supportent beaucoup de formats d'images différents. Cairo ne gère de base que le PNG, mais j'y ai ajouté une fonction lisant du XPM, fonction qui est présente aussi pour générer des array).

#icon(name) permet de charger une icône depuis le thème actif (qui peut être modifié par le contexte, voir ci-dessous). Plusieurs noms d'icônes peuvent être spécifiés, et on utilisera le premier correspondant à une image du thème.

En pratique, la fonction de base du module utilise xdg.IconTheme pour chercher le fichier correspondant au nom d'icône, et passer ensuite le relai à la fonction file. Cependant, GTK fournit également le mécanisme pour faire ce travail, ce qui permet donc de charger directement un pixbuf sans passer par cette étape si besoin.

#clip(mode):sélection permet de récupérer une image depuis une sélection X, comme le presse-papier. Le fonctionnement est assez similaire à #file, mais avec quelques adaptations dues au fait qu'une sélection peut contenir plusieurs types de contenus différents (le mode « mime » n'est donc pas disponible, car on ne saurait pas forcément quel type mime afficher).

TODO : cette fonction sera à compléter une fois que les « trucs » correspondant aux sélections seront recodés. Il faut aussi que je revoie ce qui est faisable avec GDK à ce niveau (si on est limité au $DISPLAY de l'environnement ou pas).

#thing(chemin) charge le « truc » dont le chemin est indiqué, et lui demande comment tracer son icône. Si le contexte ne précise pas d'états en particulier, les états actuels du « truc » en question sont utilisés. Si le contexte ne précise aucune taille, on utilisera 48 par défaut. Il s'agit d'une simple fonction de remplacement de texte, qui ne dépend d'aucune bibliothèque.

#empty crée simplement une image vide (c'est-à-dire dont tous les pixels sont entièrement transparents) à la taille demandée (1×1 par défaut). Elle est disponible pour la plupart des formats sans dépendance à une bibliothèque en particulier.

#shared(id):chemin permet de charger une image préalablement partagée d'après l'id indiqué. Si cette id n'a pas été préalablement partagée, le reste du chemin est utilisé à la place.

La méthode share du module principal, prenant en paramètre l'id à utiliser et le chemin qui y correspond, se charge de partager le chemin en question. Afin d'être accessible à toutes les applications actives (et de rester pour plus tard), les chemins partagés sont inscrits dans le fichier $TARGETSHM/icons. Indiquer None comme chemin d'accès lors de l'appel à cette fonction permet de retirer l'identifiant de la liste des partages.

#size(taille): permet d'enregistrer une taille à utiliser dans le contexte, en pixels. Son paramètre peut être soit un entier seul pour une image carrée, soit deux entiers, largeur puis hauteur. Il s'agit d'une simple modification de contexte, qui ne dépend d'aucune bibliothèque.

#scale(taille): va modifier la taille de l'image chargée. Son paramètre doit renseigner deux fractions (« X/Y », où X et Y sont des nombres entiers. Si le / n'est pas présent, on considérera « X/1 »), par lesquelles sera multipliée la taille actuelle. Si une seule de ces fractions est indiquée, on considérera qu'elle s'applique à la fois pour la hauteur et pour la largeur.

Si le contexte contient déjà une taille à utiliser, on se contentera de modifier cette taille avant le chargement de l'image, donc d'influer uniquement sur ce contexte, pour éviter les opérations inutiles. Dans le cas contraire, on retaillera l'image après son chargement. Cette fonction nécessite la présence d'au moins bibliothèque, que ce soit PIL, Cairo ou GDK.

#theme(nom): et #mode(nom): permettent d'influer sur le chargement d'icônes. La première change le nom du thème d'icônes qui sera utilisée. La seconde bascule de mode de chargement, avec quatre valeurs possibles : « classic » charge des images habituelles depuis le thème actif, « symbolic » préfère des images symboliques à la dernière mode de GTK, « unicode » tente de remplacer les icônes par des caractères Unicode ressemblants tracés sur fond transparent, et enfin « custom » (par défaut) permet d'utiliser certaines icônes spéciales (voir ci-dessous). Il s'agit de simples fonctions de modification de contexte, qui ne dépend d'aucune bibliothèque.

#states(états): place dans le contexte un certain nombre d'états. Ils seront utilisés pour chager une icône depuis un « truc », ainsi que pour certaines icônes spéciales. Il s'agit d'une simple fonction de remplacement de texte, qui ne dépend d'aucune bibliothèque.

#grounds(couleurs): permet de référencer certaines couleurs dans le contexte. L'idée est que la première servira de premier plan (foreground) et la dernière d'arrière-plan (background), mais il peut n'y en avoir qu'une ou y en avoir plus que deux sans problème. Elles seront utilisées pour un certain nombre de traitements d'images précisés ci-dessous. Il s'agit d'une simple fonction de changement de contexte, qui ne dépend d'aucune bibliothèque.

#brush(taille): change la taille du pinceau utilisé pour certains dessins, voir ci-dessous. Il s'agit d'une simple fonction de changement de contexte, qui ne dépend d'aucune bibliothèque.

#canvas(marges): permet de délimiter un cadre de travail à l'intérieur de l'image. Les marges indiquées (haut, droite, bas, gauche si elles sont quatre, haut et bas, droite et gauche si elles ne sont que deux, et tous les côtés s'il n'y en a qu'une) peuvent être un nombre de pixels absolu ou une fraction multipliant la taille de l'image. Cette information sera utilisée pour tracer du texte sur l'image, ainsi que pour la fonction #stencil ci-dessous. Il s'agit d'une simple fonction de changement de contexte, qui ne dépend d'aucune bibliothèque.

#cache(valeur): est tout simplement ignorée. Elle est en fait utilisée pour permettre aux logiciels de ne pas recharger sans cesse les images : si le contenu d'un fichier ou l'icône d'une fenêtre ont changé, le « truc » correspondant ajoutera cette fonction avec une valeur différente dans ses chemins d'images. De cette manière, tant que le chemin reste identique, il est inutile de re-charger l'image. Cette fonction ne dépend évidemment d'aucune bibliothèque.

#rotate: permet de faire pivoter une image. Appelée sans paramètre, elle fait faire un demi-tour à l'image. Appelée avec un paramètre indiquant une direction (« #rotate(cw): » pour clockwise, donc le sens des aiguilles d'une montre, ou « #rotate(cc): » pour counter-clockwise, donc le sens trigonométrique), elle effectuera un quart de tour dans la direction demandée.

En pratique, la fonction effectuant réellement le travail est #turn:, implémentée actuellement par GDK, mais dont il existe aussi une version « à la main ». En effet, une limitation de la bibliothèque fait qu'une fonction peut soit modifier le contexte (et renvoyer vers une autre), soit agir sur une image, mais pas les deux en même temps. La fonction #rotate: va donc simplement renvoyer vers #turn:, mais après avoir si besoin modifié le contexte pour inverser la taille qui y est éventuellement renseignée (remplaçant (w,h) par (h,w)), afin d'éviter les erreurs ultérieures.

#flip(direction): inverse le sens de l'image, en mettant le haut en bas et le bas en haut si le paramètre fourni vaut « v » ou vrai, ou en mettant la droite à gauche et la gauche à droite si le paramètre vaut « h » ou faux. Idem, actuellement implémentée par GDK et « à la main ».

#tint(couleur): va modifier la teinte générale de l'image, donc recolorer tout son contenu, à la couleur demandée, en conservant les mêmes valeurs. Elle est actuellement implémentée en passant par GDK ou en passant par Cairo.

#sepia: est un alias plus rapide pour « #tint(sepia): ». Il s'agit d'une simple fonction de remplacement de texte, qui ne dépend d'aucune bibliothèque.

#greyshade: ou #grayshade: permet de convertir une image en nuances de gris. Il peut s'agir d'une simple fonction de remplacement de texte, renvoyant sur « #tint(black): » qui a environ le même effet, mais des fonctions spécifiques sont implémentées en passant par GDK et « à la main ».

#random(détails) va générer une image dont la couleur de chaque pixel est tirée aléatoirement. Le paramètre indique la couleur minimale et maximale pour chacune des composantes de couleur. Si deux nombres sont indiquées, on considère que c'est la spécification pour le canal alpha, les autres canaux étant tirés entre 0 et 255. Si six nombres sont proposés, on considère que ce sont pour les composantes rouge, verte et bleue, et le canal alpha est fixé à son niveau maximal (opaque). Les huit nombres peuvent bien sûr être proposés d'un coup. La seule implémentation actuelle de cette méthode ne dépend d'aucune bibliothèque et génère un array.

#overlay(chemin2):chemin1 va charger deux images et superposer la seconde (celle correspondant au paramètre, chemin2) sur la première (celle correspondant à chemin1). Combiné aux fonction de retaillage ci-dessous, cela permet d'ajouter des symboles sur les images.

La plupart des bibliothèques ont permi d'implémenter une méthode overlay depuis leur propre format d'image. Il est également possible, si les deux bibliothèques concernées sont présentes, de combiner deux pixbufs pour donner une surface. Une implémentation « à la main » permet de générer un array depuis à peu près tous les formats d'entrée, pour n'importe laquelle des deux images, d'où le fait que cette fonction soit présente en de nombreux exemplaires.

#shape(chemin2):chemin1 va également combiner deux images, mais en utilisant la « forme » (le canal alpha) de l'une et la « texture » (les trois composantes de couleur) de l'autre, pour donner une image hybride.

Comme pour overlay, un array peut être généré pour n'importe quels formats d'entrée, offrant beaucoup de possibilités. Des fonctions équivalentes ont également pu être implémentés avec PIL et avec Cairo (cette dernière pouvant également gérer les pixbufs si GDK est présent, mais il n'y a pas de fonction pour ça en utilisant uniquement GDK).

#noise(détails): cette fonction combine les trois précédentes. « #noise(détails):chemin » peut ainsi être traduit par « #shape(chemin):#overlay(#random(détails)):chemin » : on va donc ajouter des pixels aléatoires sur une image, mais seulement sur les pixels qui ne sont pas transparents.

Une fonction de base permet effectivement de remplacer le chemin de cette manière. C'est cependant une façon particulièrement énergivore de le faire, puisqu'il faut charger deux fois (séparément) l'image de base. Une fonction dédiée permet d'éviter ce problème en modifiant directement une image existante pour générer un array. Il n'y a donc de toute façon de dépendance à aucune bibliothèque.

#shuffle(seuil): mélange les pixels de l'image. Le paramètre fourni indique un seuil de transparence à partir duquel effectuer cette opération : s'il est à 0, tous les pixels de l'image sont mélangés, peu importe leur canal alpha. S'il est raisonnablement haut, les pixels transparents ne seront pas déplacés et la forme de l'image restera donc globalement la même. Implémenté actuellement « à la main » (en générant un array).

#resize: permet de retailler l'image à la taille précisée dans le contexte. Sans paramètre, elle va retailler en conservant les proportions initiales de l'image. Avec le paramètre « h », elle va forcer le retaillage horizontal, sans toucher à la taille verticale. Avec le paramètre « v », elle va faire l'inverse. Enfin, on peut préciser deux booléens pour paramétrer plus précisément le comportement.

Cette méthode est fournie en passant par les bibliothèques d'images classiques, PIL, Cairo et GDK. En revanche, je ne connais pas d'algo de retaillage d'image que j'ai pu implémenter « à la main ». C'est une des raisons pour lesquelles il faut au moins une de ces trois bibliothèques pour que le module fonctionne : retailler une image est souvent nécessaire, et ce n'est en l'état pas faisable sans dépendance externe (sans compter la conversion depuis le PNG et les autres formats).

#reframe: est un complément à #resize: dès lors que l'on utilise celle-ci de façon proportionnelle. En effet, si l'image n'avait pas les bonnes proportions au départ, elle ne les aura toujours pas après un appel proportionnel à #resize:. #reframe: règle alors le souci en ajoutant des marges transparentes autour de l'image pour lui donner les bonnes proportions sans affecter le contenu.

Par ailleurs, #reframe: peut également prendre un paramètre, constituté de deux lettres, pour indiquer comment placer ces marges : selon si la première lettre est « t », « c » ou « b », l'image sera verticalement positionnée en haut (top), au centre ou en bas, selon si la deuxième est « r », « c » ou « l », l'image sera horizontalement positionnée à droite (right), au centre ou à gauche (left). Mêmes remarques que pour #resize: concernant ses implémentations.

Note : la fonction « icon » du module d'images ajoute automatiquement le préfixe « #reframe:#resize: » à chaque chemin qu'elle tente de charger, afin de s'assurer que l'icône obtenue sera bien à la taille spécifiée dans tous les cas.

#blur(fraction): Fonction basique de floutage d'une image en utilisant les méthodes précédentes : il s'agit simplement d'appliquer #scale pour réduire fortement la taille de l'image (le paramètre de #blur lui sera transféré tel quel), et #resize pour la ramener à sa taille d'origine, entraînant une perte de détails. Cette fonction ne dépend donc directement d'aucune bibliothèque elle-même, mais indirectement des dépendances de ces autres fonctions.

#gaussian: Fonction de floutage un peu plus élégante, mais aussi beaucoup plus gourmande en ressources que la précédente, qui pour chaque pixel effectue la moyenne des pixels voisins. Implémentation « à la main », indépendante des différentes bibliothèques.

TODO : actuellement, cette fonction floute l'ensemble de l'image. Je me demande si ça ne pourrait pas être une bonne idée de l'adapter pour n'agir (ou de fournir une autre fonction de flou qui n'agisse) que sur une partie de l'image délimintée par un appel préalable à #canvas, permettant ainsi de flouter une partie d'une image en laissant le reste intact.

#negative: inverse la valeur de certains canaux d'une image. Si le paramètre vaut « t »/« tint » (par défaut s'il n'est pas précisé), la couleur est inversée, l'alpha reste inchangé. Le contraire s'il vaut « a »/« alpha ». S'il vaut « b »/« both », l'ensemble est inversé. Implémenté « à la main » et avec PIL.

Note : est-ce que ça pourrait avoir un intérêt d'ajouter des paramètres pour inverser certains canaux de couleurs mais pas les autres, par exemple « red » pour inverser le rouge en laissant le vert et le bleu intacts, ou « magenta » pour inverser le rouge et le bleu en laissant le vert intact ?)

#fade: augmente la transparence d'une image. On peut préciser un paramètre entier indiquant de quel pourcentage l'opacité doit être réduite (il vaut 20 par défaut, indiquer 100 rend évidemment l'image totalement transparente, même si les pixels invisibles conservent dans ce cas l'information de couleur). Implémenté « à la main » et avec GDK.

#bright: Augmente l'intensité des couleurs. Peut par exemple produire un effet de surbrillance sympathique pour l'icône sur laquelle passe actuellement la souris. Implémenté actuellement uniquement en utilisant GDK.

#tiny(position): Combinaison de scale et de reframe, permettant de réduire de moitié la taille (en distances, donc réduire l'aire au quart) d'une image en conservant la même zone de travail. Le paramètre position est passé à reframe, pour déplacer l'image vers un des bords de la zone de travail, ce qui est utile pour ajouter un symbole sur une autre image. Simple modification du chemin, qui ne dépend d'aucune bibliothèque (mais utilise scale et reframe qui, elles, en dépendent).

#small(position): Combinaison de scale et de reframe, permettant de réduire aux deux tiers la taille (en distances) d'une image en conservant la même zone de travail. Le paramètre position est passé à reframe, pour déplacer l'image vers un des bords de la zone de travail, ce qui est utile pour ajouter un symbole sur une autre image. Simple modification du chemin, qui ne dépend d'aucune bibliothèque (mais utilise scale et reframe qui, elles, en dépendent).

#new: Ajoute l'icône « emblem-new » (généralement une étoile), au format #tiny, en haut et à droite de l'image, pour reproduire l'effet intégré de base dans les icônes « document-new » et « folder-new ». Simple modification du chemin.

#ok: Ajoute l'icône « dialog-apply » (généralement une coche ✔), au format #small, en bas et à droite de l'image. Simple modification du chemin.

#ko: Ajoute l'icône « window-close » (généralement une croix ❌), au format #small, en bas et à droite de l'image. Simple modification du chemin.

#working: Ajoute l'icône « gtk-execute » (généralement un symbole d'engrenages), au format #small, en bas et à droite de l'image. Simple modification du chemin.

#warning: Ajoute l'icône « dialog-warning » (généralement un panneau de danger ⚠), au format #small, en bas et au centre de l'image. Simple modification du chemin.

#text(chemin):texte Trace le texte demandé dans l'image, en fonction d'une police de caractères présente dans le contexte. Si un chemin est présent en paramètre, on précharge cette image d'abord et on trace le texte dessus ensuite. Sinon, on trace le texte sur une image vide. Si un #canvas a été précisé préalablement, le texte ne sera affiché que dans cette zone. Si la police de caractères n'a aucune taille précisée, la première ligne de texte occupera toute la hauteur de l'image.

Actuellement, la seule implémentation de cette méthode nécessite Cairo, GDK, Pango et PangoCairo, ce qui fait un peu beaucoup. Tracer du texte sur une image est également faisable avec PIL, mais la dernière fois que j'ai tenté, j'avais des difficultés à ajuster les tailles de polices pour avoir le même rendu des deux côtés. Je vais tenter de profiter de retravailler la partie GDK pour ajuster ça.

Note : la logique utilisée pour les autres fonction voudrait plutôt que l'ordre soit ici « #text(texte):chemin », puisque le chemin va d'abord être chargé comme image de base, puis le texte sera affiché dessus. Cependant, il est ici exceptionnellement inversé car le texte demandé peut contenir des parenthèses et autres caractères qui perturberaient le parsage. Le placer après les : permet donc d'éviter les soucis de syntaxe.

#keymap:texte Affiche le texte demandé sur la moitié haute de l'icône « keyboard » du thème. Prévue pour afficher la disposition actuelle du clavier pour l'icône du « truc » dédié. Simple modification du chemin.

#window(xid): Récupère l'icône actuelle d'une fenêtre X. L'identifiant passé en paramètre doit être le chemin d'accès au « truc » correspondant, donc de la forme « :display/numéro ». Si la fenêtre possède plusieurs icônes, on choisit en fonction de la taille précisée dans le contexte. Cette fonction ne dépend d'aucune bibliothèque graphique, mais utilise le module des « trucs » et la Xlib pour accéder à l'icône des fenêtres.

Note : j'utilisais auparavant la bibliothèque WNCK dans le même objectif, mais celle-ci présentait deux limitations notables : seul le display actif (celui de la variable d'environnement $DISPLAY) était géré, et l'icône ne pouvait être récupérée qu'en 16×16 ou en 32×32, même quand des tailles plus grandes étaient disponibles. J'hésite cependant à remettre ça en place, mais uniquement en guise de fallback si la Xlib n'est pas disponible.

#capture Réalise une capture d'écran d'une fenêtre ou du bureau complet. TODO

#webcam Prend une image à la webcam. Actuellement, la seule implémentation génère un stream en utilisant le programme externe vgrabbj. À voir si une autre bibliothèque fournit le même genre de fonctionnalités.

#widget(type) Trace dans l'image l'apparence usuelle d'un composant graphique (bouton, onglet…), par exemple pour servir de fond à une autre image. Utilise actuellement l'apparence des widgets GTK, mais ça pourrait être intéressant de proposer aussi autre chose. Nécessite donc GTK. Réécriture en cours, détails à suivre.

#circle: Trace un cercle dans l'image (ou sur fond transparent si aucun chemin d'image n'est précisé.) Si le paramètre « fill » est présent, le disque complet sera colorié en utilisant la couleur d'arrière-plan préalablement défini par #grounds (donc la dernière de la liste). Si ce paramètre n'est pas présent, seul le cercle extérieur sera tracé, en utilisant la couleur de premier plan (donc la première de la liste) et la taille de pinceau définie par #brush. Actuellement implémentée uniquement avec cairo.

#clock(heure): Trace les aiguilles d'une horloge (petite et grande aiguille, plus éventuellement une trotteuse) par dessus l'image, à l'heure indiquée dans le paramètre (de la forme « h,m » ou « h,m,s »). Si aucun autre chemin n'est précisé, trace automatiquement un disque pour représenter le cadran. Utilise les couleurs définies par un appel préalable à #grounds, ou s'il n'y en a pas, le noir et le blanc par défaut. La couleur d'arrière-plan est utilisée pour le disque du cadran, celle de premier plan pour le cercle et pour la petite et la grande aiguille. Si une trotteuse est demandée, elle utilisera par défaut la couleur de premier plan/le noir, mais si plus de deux couleurs ont été définies par #grounds, elle utilisera la deuxième de la liste.

En pratique, la fonction #clock fait appel à des fonctions internes, #hour, #minute et éventuellement #second (en plus de #circle pour tracer le cadran le cas échéant). Ces trois méthodes sont rigoureusement identiques, mais avec un pré-traitement des paramètres différent pour obtenir l'aspect des différentes d'aiguilles (l'aiguille des heures est plus courte et sa position se compte entre 0 et 12, les deux autres se comptent entre 0 et 60 mais la trotteuse est plus fine et de taille intermédiaire). Actuellement, ce n'est implémenté qu'avec la bibliothèque cairo.

#dye(couleurs) Remplace les couleurs passées en paramètre par celles préalablement définies par #grounds. Utilisé notamment pour mettre aux bonnes couleurs les icônes symboliques. TODO.

#stencil(couleur): Fonction de coloration particulière, utilisée notamment pour les différentes fonctions ci-dessous. Les pixels complètement transparents restent transparents, pour les autres, on mélange les couleurs comme si on traçait l'image sur un fond uni de la couleur passée en paramètre. Seule la partie préalablement délimitée par #canvas est affecté, le reste gardant sa couleur d'origine. Il s'agit d'un algo « à la main », mais une implémentation utilisant GDK existe également.

#battery(niveau) Image indiquant le niveau actuel d'une batterie. Si #mode a été défini à autre chose que « custom », on tâchera d'utiliser les différentes icônes du thème actif (visiblement, les icônes symboliques offrent davantage de niveau de détail que les icônes classiques. Unicode n'a visiblement pas d'emojis suffisamment détaillés). Dans le cas contraire, on utilisera une image de batterie colorée par #stencil (en vert et rouge par défaut, mais cela peut être modifié par un appel préalable à #grounds). L'image de batterie est par défaut à l'horizontale, elle sera tournée vers le haut en cas de charge et vers le bas en cas de décharge, en fonction des états précisés dans le contexte.

#signal(niveau) Image indiquant la qualité de réception d'un signal radio. Comme pour #battery, on tâchera d'utiliser les icônes du thème actif si #mode a été placé sur autre chose que « custom » (il y a de nouveau pas d'emojis détaillés en Unicode ; en revanche, c'est cette fois le thème classique qui contient plus de détails que le thème symbolique). Dans le cas contraire, on utilisera une image intégrée recolorée par #stencil. Par défaut, la partie gauche de l'image est colorée en fonction de la qualité du signal (du rouge pour 0% au vert pour 100%) et la partie droite n'est pas colorée, mais d'autres couleurs peuvent être spécifiés par #grounds.

#screen(niveau) Image indiquant la luminosité actuelle de l'écran. Comme aucun thème à ma connaissance ne contient d'images dédiées, #mode est ignoré et on utilise toujours une image interne recolorée par #stencil. La couleur par défaut est le jaune (mais elle peut être modifiée par #grounds), et c'est son niveau d'opacité qui déterminera l'intensité de l'image résultante.

#thermal(niveau) Image indiquant la température actuelle d'un capteur interne. Comme aucun thème à ma connaissance ne contient d'images dédiées, #mode est ignoré et on utilise toujours une image interne recolorée par #stencil. Les couleurs par défaut (qui peuvent être modifiées par #grounds) sont le cyan en haut et le cramoisi (« crimson ») en bas. Compte tenu des marges, l'image ne change plus en dessous de 10° et au dessus de 95°.

Note : la fonction #thermal ne fait que générer l'image colorée. L'icône des « trucs » correspondant aux capteurs de température comporte en plus la température en chiffres sur l'image, mais cet effet est obtenu en faisant appel à la fonction #text en complément.

#cpu(niveau) Image indiquant l'état de charge actuel d'un processeur. Comme aucun thème à ma connaissance ne contient d'images dédiées, #mode est ignoré et on utilise toujours une image interne recolorée par #stencil. #grounds est ici ignoré car c'est la teinte utilisée (entre vert pour 0% et rouge pour 100%) qui fournit toute l'information visuelle.

#drive(niveau) Image indiquant l'état actuel de remplissage d'un disque. Comme aucun thème à ma connaissance ne contient d'images dédiées, #mode est ignoré et on utilise toujours une image interne recolorée par #stencil. Par défaut, la partie basse de l'image est colorée en fonction de l'espace occupé (du rouge pour 100% au vert pour 0%) et la partie haute n'est pas colorée, mais d'autres couleurs peuvent être spécifiés par #grounds.

#volume(niveau) Image indiquant le niveau actuel d'une batterie. Si #mode a été défini à autre chose que « custom », on tâchera d'utiliser les différentes icônes du thème actif (unicode, symbolique et classique offrant ici le même niveau (assez faible) de détails). Dans le cas contraire, on utilisera une image intégrée recolorée par #stencil. Par défaut, la partie basse de l'image est colorée en fonction du volume (du rouge pour 100% au vert pour 0%) et la partie haute n'est pas colorée, mais d'autres couleurs peuvent être spécifiés par #grounds. Si l'état « muted » est présent dans le contexte, la couleur par défaut devient cyan et on ajoute l'opération #ko: pour avoir un symbole visuel.

#record(niveau) Alternative à #volume fonctionnant de la même manière, mais utilisant une image de base de micro à la place de l'image de haut-parleur (Unicode ne semble pas contenir d'emojis pour le niveau de sensibilité d'un micro, mais les thèmes d'icônes classiques et symboliques comptent le même niveau de détail que pour #volume).

#media(niveau) Image indiquant la progression actuelle dans l'écoute d'un morceau (il s'agit d'une note de musique qui se décolore peu à peu). Comme aucun thème à ma connaissance ne contient d'images dédiées, #mode est ignoré et on utilise toujours une image interne recolorée par #stencil. Par défaut, la partie basse de l'image est colorée en bleu et la partie haute n'est pas colorée, mais d'autres couleurs peuvent être spécifiés par #grounds.