Affichage de texte

/* text.c */

/* affichage de texte */

#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>

GC      gc; 
Display *display; 
int     screen; 
Window  win, root, wbidon; 
unsigned long white_pixel, black_pixel; 
Font police;
XFontStruct *police_attrib;
int larg_win, haut_win, bidon;
char *lignes[] = {"1ere ligne", "seconde", "3eme", "quatrieme ligne",
		  "5eme tres tres tres longue ligne", "derniere" };
void affiche();
 
main() { 
  display = XOpenDisplay ("");
  gc = DefaultGC (display, screen); 
  screen = DefaultScreen (display); 
  root = RootWindow (display, screen); 
  white_pixel = WhitePixel (display, screen); 
  black_pixel = BlackPixel (display, screen); 
  police = XLoadFont (display,
     "-adobe-times-medium-i-normal--10-100-75-75-p-52-iso8859-1");
  police_attrib = XQueryFont (display, police) ;
  XSetFont (display, gc, police);
  larg_win = haut_win = 80 ;
  win = XCreateSimpleWindow (display, root, 0, 0, larg_win, haut_win, 2, 
			     black_pixel, white_pixel); 
  XSelectInput (display, win, ExposureMask | StructureNotifyMask); 
  XStoreName (display, win, "text"); 
  XMapWindow (display, win); 
      
  for (;;) { 
    XEvent ev;
 
    XNextEvent (display, &ev); 
    switch (ev.type) { 
    case Expose : 
      affiche();
      break; 
    case ConfigureNotify :
      XGetGeometry (display, win, &wbidon, &bidon, &bidon,
		    &larg_win, &haut_win, &bidon, &bidon);
      affiche();
      break; 
    default : 
      break;            
    } 
  } 
} 

void affiche() {
  XCharStruct xcs_bidon;
  int i, y_utilise, base, text_haut, text_bas;
  y_utilise = 0;
  for (i=0; i<6; ++i) {
    XTextExtents(police_attrib, lignes[i], strlen(lignes[i]), &bidon,
		 &text_haut, &text_bas, &xcs_bidon);
    base = y_utilise + 2 + text_haut ;
    if (XTextWidth(police_attrib, lignes[i], strlen(lignes[i])) + 4
	<= larg_win)
      XDrawString (display, win, gc, 2, base, lignes[i], strlen(lignes[i]));  
    y_utilise = base + text_bas ;
  }
}

Execution :

Modifiez la géométrie de la fenêtre et regardez le texte se re-afficher.

Fonctionnement de ce programme :

Principe de "dessin" des caractères : Les caractères sont écrits sur une ligne de base commençant au point défini par XDrawString. La partie au dessus de cette ligne est la tête de caractère, en dessous la queue. La largeur totale, cad la distance entre les débuts de 2 caractères consécutifs, peut être fixe ou proportionelle. Les caractères étant dessinés, certains caractères ascii ne produisent aucun dessin (ni autre effet) dont LF le passage à la ligne.

Après avoir charger une fonte avec XLoadFont, le programme obtient les caractéristiques de cette fonte avec XQueryFont.
XTextExtents fournit (dans la structure XCharStruct) la hauteur maximale de tête de tous les caractères d'un texte ainsi que la hauteur maximale des queues de lettres. Ceci permet de calculer la hauteur d'une ligne.
XTextWidth calcule la largeur de la ligne en pixel.

La liste des polices (font), leurs caractéristiques, s'obtiennent par plusieures commandes :

xfonfsel pour sélectionner une fonte, xlsfonts pour obtenir la liste des fontes, et xfd pour afficher les caractères et leurs caractèristiques d'une fonte.

Exercice text2.c :

Même programme que text.c, mais un peu plus dur. Il faudra afficher un texte assez long d'environ 80 caractères dans une petite fenêtre en passant automatiquement à la ligne. Peu importe que les mots soient coupés. Il serait plus joli que la dernière ligne affichable (la fenêtre n'étant pas forcément assez haute) ne soit pas tronquée.
Enfin, les boutons de la souris sélectionneront une police proportionnelle ou une fixe.

programme suivant index général fonctions de la XLib événements types dans XLib