Les plans supplémentaires en Java et en JavaScript

Jean-François Perrot

  1. La contradiction
  2. La technique
  3. Mise en œuvre

  1. La contradiction

    Quand on sort du BMP, le numéro Unicode vu comme un entier ne peut plus se loger dans 16 bits.
    Un conflit se produit alors entre
    1. la position de principe, pour qui la taille de l'entier est sans importance,
      par exemple, les entités HTML restent valables :
      • Le caractère gotique 𐌰, U+10330, est fidèlement désigné par l'entité 𐌰 : 𐌰
      • Le caractère nôm 𤾓, U+024F93, est fidèlement désigné par l'entité 𤾓 : 𤾓
    2.  
    3. la réalité de nombreuses implémentations pour lesquelles l'unité de compte est de 16 bits.

      • ainsi, en JavaScript, sans que ce soit documenté, les méthodes de l'"objet" String sont "calées" sur 16 bits
        • la fonction charCodeAt(i) renvoie un entier sur 16 bits
        • la fonction length() renvoie le nombre de blocs de 16 bits et non pas le nombre de caractères !

      • alors qu'en Java les chose sont dites explicitement, grâce au type char qui occupe exactement 16 bits :
        • la méthode length() renvoie le nombre de chars, dont le nombre de blocs de 16 bits
        • la méthode charAt(i) renvoie un char - mais il ne faut pas la confondre avec...
        • la méthode codePointAt(i) qui renvoie un entier, à savoir le n° Unicode (sans limitation)
          du caractère... mais au fait, que signifie l'index i ?
  2. La technique

    Pour surmonter cette contradiction, la représentation UTF-16 acquiert droit de cité :

    chaque numéro Unicode qui dépasse FFFF est assorti de sa représentation comme un couple de nombres sur 16 bits
    (surrogate pair)
    1. le premier appartenant à la plage U+D800 à U+DBFF (demi-zone haute d’indirection, alias high-surrogate)
    2. le second appartenant à la plage U+DC00 à U+DFFF (demi-zone basse d’indirection, alias low-surrogate)
    C'est sous cette forme qu'il conviendra de l'écrire dans les constantes de chaînes, tant en Java qu'en JavaScript.
    Cette décomposition est donnée par les logiciels d'exploration d'Unicode.

    Exemples :
    Il suffit alors d'admettre que les caractères des plans supplémentaires apparaissent aux yeux de Java et de  JavaScript comme
    des couples de caractères spéciaux, qu'il faut manipuler ensemble.

    Plus précisément, nous sommes à présent en mesure de comprendre la spécification de la méthode codePointAt(i) 
    donnée par la JavaDoc de la classe String :

    If the char value specified at the given index is in the high-surrogate range, the following index is less than the length of this String,
    and the char value at the following index is in the low-surrogate range, then the supplementary code point corresponding to this surrogate pair is returned.
    Otherwise, the char value at the given index is returned.


  3. Mise en œuvre