Vous êtes sur la page 1sur 14

Programacin en X Window: Dibujo de grficos

27/06/2013

Previous Next Table of Contents

6. Dibujo de grficos 6.1 Las dos cosas que se deben especificar al dibujar grficos
Para dibujar grficos se deben especificar dos cosas: las primitivas grficas y los atributos grficos. Las primitivas grficas son los objetos fundamentales que se pueden dibujar mediante llamadas a la Xlib. La relacin entre ambas se puede ver en la tabla 6.1:
+-------------------+-------------------------------------+ |Llamada a la Xlib |Primitiva grfica | +-------------------+-------------------------------------+ |XDrawPoint |punto | +-------------------+-------------------------------------+ |XDrawPoints |puntos | +-------------------+-------------------------------------+ |XDrawLine |lnea entre los dos puntos | +-------------------+-------------------------------------+ |XDrawLines |polilnea | +-------------------+-------------------------------------+ |XDrawSegments |segmentos de lnea | +-------------------+-------------------------------------+ |XDrawRectangle |rectngulo | +-------------------+-------------------------------------+ |XDrawRectangles |rectngulos | +-------------------+-------------------------------------+ |XDrawArc |arco de circunferencia | +-------------------+-------------------------------------+ |XDrawArcs |arcos de circunferencia | +-------------------+-------------------------------------+ |XFillRectangle |rectngulo relleno | +-------------------+-------------------------------------+ |XFillRectangles |rectngulos rellenos | +-------------------+-------------------------------------+ |XFillPolygon |polgono relleno | +-------------------+-------------------------------------+ |XFillArc |arco de circunferencia relleno | +-------------------+-------------------------------------+ |XFillArcs |arcos de circunferencia rellenos | +-------------------+-------------------------------------+ |XDrawText | | |XDrawString |texto | |XDrawImageString | | +-------------------+-------------------------------------+ |XDrawText16 | | |XDrawString16 |texto especial (alfabetos no latinos)| |XDrawImageString16 | | +-------------------+-------------------------------------+ Tabla 6.1: primitivas grficas y llamadas a la Xlib

Los atributos grficos son las caractersticas relacionadas con las primitivas grficas, por ejemplo, para la primitiva grfica lnea los atributos grficos son el ancho de la lnea, el color y el estilo con que se debe dibujar.

6.2 Manejo de atributos grficos


Hay dos mtodos de manejar los atributos grficos. El primero consiste en enviar los atributos al servidor al mismo tiempo que las peticiones de dibujo de primitivas. El segundo mtodo consiste en enviar los atributos previamente al servidor, que los almacena, y enviar las peticiones de las primitivas grficas sin volver a enviar los atributos. El segundo mtodo es mucho ms eficiente ya que sobrecarga menos la red.

6.3 Contexto grfico


Un contexto grfico o simplemente, un GC, es el recurso del servidor donde se almacenan los atributos de los grficos. Es necesario al menos un GC para que el servidor acepte peticiones de primitivas grficas por parte del cliente, ya que cada peticin de primitiva grfica debe especificar el identificador del GC que se debe usar. Los GCs se crean y se almacenan en el servidor. Los clientes pueden solicitar la creacin de un GC en el servidor y obtener su identificador, mediante el cual pueden establecer o cambiar los atributos almacenados en el GC.

6.4 Los tres pasos para dibujar grficos


Los tres pasos necesarios para poder dibujar grficos son los siguientes:

http://www.lsi.us.es/cursos/xlib-6.html

1 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

1. Obtener un GC o crearlo. 2. Establecer los atributos del GC apropiadamente. 3. Enviar las peticiones de las primitivas grficas. Para el primer paso hay tres mtodos posibles: 1. Crear un GC y obtener su ID. 2. Copiar sobre un nuevo GC un GC ya creado y obtener su ID. 3. Obtener el ID del GC creado por defecto en el servidor.

6.5 Creacin y establecimiento de atributos de GCs


Se puede crear un GC y especificar los atributos grficos al mismo tiempo. Tambin se pueden cambiar los atributos una vez creado un GC. Un GC puede almacenar 23 atributos grficos. La estructura XGCValues se usa para especificar todos o algunos de los 23 atributos a la hora de crear o cambiar un GC. En la mayora de los casos slo habr que especificar algunos de los 23 atributos, no todos. Para especificar qu valores de atributos se deben tomar como vlidos en la estructura XCGValues se usa una mscara de valores, en la que cada bit del 0 al 22 se corresponde con cada uno de los 23 miembros, de forma que si el bit est a 1 se toma el valor del campo como vlido, y si est a 0 no se tiene en cuenta. Para establecer los valores de la mscara se pueden usar los siguientes smbolos. Si se quiere especificar ms de un cambio se puede hacer mediante la operacion OR. Los smbolos son los siguientes:
#define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define GCFunction GCPlaneMask GCForeground GCBackground GCLineWidth GCLineStyle GCCapStyle GCJoinStyle GCFillStyle GCFillRule GCTile GCStipple GCTileStipXOrigin GCTileStipYOrigin GCFont GCSubwindowMode GCGraphicsExposures GCClipXOrigin GCClipYOrigin GCClipMask GCDashOffset GCDashList GCArcMode (1L<<0) (1L<<1) (1L<<2) (1L<<3) (1L<<4) (1L<<5) (1L<<6) (1L<<7) (1L<<8) (1L<<9) (1L<<10) (1L<<11) (1L<<12) (1L<<13) (1L<<14) (1L<<15) (1L<<16) (1L<<17) (1L<<18) (1L<<19) (1L<<20) (1L<<21) (1L<<22)

La estructura XGCValues est definida como sigue:


typedef struct { int function; unsigned long plane_mask; unsigned long foreground; unsigned long background; int line_width; int line_style; int cap_style; int join_style; int fill_style; int fill_rule; int arc_mode; Pixmap tile; Pixmap stipple; int ts_x_origin; int ts_y_origin; Font font; int subwindow_mode; Bool graphic_exposures; int clip_x_origin; int clip_y_origin; Pixmap clip_mask; int dash_offset; char dashes; } XGCValues; /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* operacin lgica */ mscara de plano */ color de primer plano */ color de fondo */ ancho de linea */ LineSolid, LineOfOffDash, LineDoubleDash */ CapNotLast, CapButt, CapRound, CapProjecting */ JoinMiter, JoinRound, JoinBevel */ FillSolid,FillTiled,FillStippled,FillOpaeueStippled */ EvenOddRule, WindingRule */ ArcChord, ArcPieSlice */ pixmap para operaciones de "tile" */ pixmap para operaciones de "stipple" */ desplazamiento del pixmap en las */ de "tile" y "stipple" */ fuente por defecto para las operaciones de texto */ ClipByChildren, IncludeInferiors */ deben generarse exposiciones ? */ origen de recortado */

/* recorte de mapa de bits */ /* informacin de la linea dashed/patterned */

6.6 Llamadas Xlib: creacin y modificacin de GCs


GC XCreateGC( Display *display, Drawable drw,
http://www.lsi.us.es/cursos/xlib-6.html 2 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

unsigned long mascara, XGCValues *valores ); XChangeGC( Display *display, GC gc, unsigned long mascara, XCGValues *valores );

Mediante XCreateGC se puede crear un GC en el servidor y obtener su ID. Al mismo tiempo se pueden establecer todos o algunos de los 23 atributos grficos del GC usando los argumentos mascara y valores, los cales, si toman los valores 0 y NULL respectivamente, hacen que GC tome los atributos por defecto. Los valores por defecto se pueden ver en la tabla 6.2. Mediante XChangeGC se pueden cambiar todos o algunos de los 23 atributos grficos de un GC especificando los valores de los campos y de mscara adecuados.

6.7 Ejemplo: cdigo


GC gc; XGCValues valores1, valores2; valores1.foreground = color1.pixel; valores1.line_width = 10; /* A */ /* B */ /* C */

gc = XCreateGC( d, w, GCForeground | GCLineWidth, &valores1 ); /* D */ valores2.line_style = LineOnOffDash; valores2.cap_style = CapButt; XChangeGC( d, gc, GCLineStyle | GCCapStyle, &valores2 ); XDrawLine( d, w, gc, 50, 150, 350, 150 ); /* E */ /* F */ /* G */

En A se declara el contexto grfico y en B las estructuras para los atributos grficos. En C y D establecemos los valores de color de fondo y ancho de lnea y creamos el GC con dichos valores. En E y F cambiamos dos atributos del GC creado anteriormente y en G dibujamos una lnea con el GC actual.
+--------------------+--------------------------------------+ | Campo de XCGValues | Valor por defecto | +--------------------+--------------------------------------+ |function |GXcopy | +--------------------+--------------------------------------+ |plane_mask |todo a 1 | +--------------------+--------------------------------------+ |foreground |0 | +--------------------+--------------------------------------+ |background |1 | +--------------------+--------------------------------------+ |line_width |0 | +--------------------+--------------------------------------+ |line_style |LineSolid | +--------------------+--------------------------------------+ |cap_style |CapButt | +--------------------+--------------------------------------+ |join_style |JoinMiter | +--------------------+--------------------------------------+ |fill_style |FillSolid | +--------------------+--------------------------------------+ |fill_rule |EvenOddRule | +--------------------+--------------------------------------+ |arc_mode |ArcPieSlice | +--------------------+--------------------------------------+ |tile |pixmap relleno con el color de fondo | +--------------------+--------------------------------------+ |stipple |pixmap relleno de 1s | +--------------------+--------------------------------------+ |ts_x_origin |0 | +--------------------+--------------------------------------+ |ts_y_origin |0 | +--------------------+--------------------------------------+ |font |depende de la implementacin | +--------------------+--------------------------------------+ |subwindow_mode |ClipByChildren | +--------------------+--------------------------------------+ |graphics_exposures |True | +--------------------+--------------------------------------+ |clip_x_origin |0 | +--------------------+--------------------------------------+ |clip_x_origin |0 | +--------------------+--------------------------------------+ |clip_mask |Ninguno | +--------------------+--------------------------------------+ |dash_offset |0 | +--------------------+--------------------------------------+ |dashes |4 (es decir, la lista [4,4]) | +--------------------+--------------------------------------+ Tabla 6.2: valores por defecto de XGCValues
http://www.lsi.us.es/cursos/xlib-6.html 3 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

6.8 Funciones de conveniencia


Se pueden establecer y cambiar algunos o todos los atributos grficos usando las funciones vistas hasta ahora, es decir, XCreateGC y XChangeGC. Una forma alternativa es usar las funciones de conveniencia, que cambian los atributos individualmente o en pequeos grupos. Estas funciones tienen unos nombres significativos y sencillos de recordar, y por tanto hacen ms fcil el mantenimiento del cdigo. La forma usual de usar estas funciones de conveniencia es crear un GC sin especificar ningn valor, es decir, con los valores por defecto, y a continuacin usar las funciones de conveniencia correspondientes para establecer los valores deseados. La tabla 6.3 muestra la relacin entre los campos de XGCValues y las funciones de conveniencia.
+--------------------+--------------------------------------+ | Campo de XCGValues | Valor por defecto | +--------------------+--------------------------------------+ |function |XSetState, XSetFunction | +--------------------+--------------------------------------+ |plane_mask |XSetState, XSetPlaneMask | +--------------------+--------------------------------------+ |foreground |XSetState, XSetForeground | +--------------------+--------------------------------------+ |background |XSetState, XSetBackground | +--------------------+--------------------------------------+ |line_width |XSetLineAttributes | +--------------------+--------------------------------------+ |line_style |XSetLineAttributes | +--------------------+--------------------------------------+ |cap_style |XSetLineAttributes | +--------------------+--------------------------------------+ |join_style |XSetLineAttributes | +--------------------+--------------------------------------+ |fill_style |XSetArcMode | +--------------------+--------------------------------------+ |fill_rule |XSetFillRule | +--------------------+--------------------------------------+ |arc_mode |XSetArcMode | +--------------------+--------------------------------------+ |tile |XSetTile | +--------------------+--------------------------------------+ |stipple |XSetStipple | +--------------------+--------------------------------------+ |ts_x_origin |XSetTSOrigin | +--------------------+--------------------------------------+ |ts_y_origin |XSetTSOrigin | +--------------------+--------------------------------------+ |font |XSetFont | +--------------------+--------------------------------------+ |subwindow_mode |XSetSubwindowMode | +--------------------+--------------------------------------+ |graphics_exposures |XSetGraphicsExposures | +--------------------+--------------------------------------+ |clip_x_origin |XSetClipOrigin | +--------------------+--------------------------------------+ |clip_x_origin |XSetClipOrigin | +--------------------+--------------------------------------+ |clip_mask |XSetClipMask, XSetClipRectangle | +--------------------+--------------------------------------+ |dash_offset |XSetDashes | +--------------------+--------------------------------------+ |dashes |XSetDashes | +--------------------+--------------------------------------+ Tabla 6.3: campos de XGCValues y funciones de conveniencia

6.9 Ejemplo: cdigo


GC gc; /* A */ gc = XCreateGC( d, w, 0, NULL ); /* B */ XSetForeground( d, gc, color.pixel ); /* C */ XSetLineAttributes( d, gc, 10, LineOffDash, CapButt, JoinRound ); XDrawLine( d, w, gc, 50, 150, 350, 150 ); /* D */

En A declaramos el GC de la forma habitual, sin embargo en B lo creamos sin especificar ningn atributo. A continuacin en C establecemos los valores de fondo y varios de atributos de lnea usando dos funciones de conveniencia. Por ltimo en D dibujamos una lnea de la forma usual.

6.10 Dibujable (Drawable)


http://www.lsi.us.es/cursos/xlib-6.html 4 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

Un dibujable es un recurso en el que se pueden dibujar grficos, es decir, una ventana o un pixmap. Un pixmap es un rea de memoria en la que se pueden almacenar grficos, aunque no son visibles. Los grficos de un pixmap se usan copindolos sobre las ventanas o bien como patrn de relleno.

6.11 Llamadas Xlib: especificacin de colores


XSetForeground( Display *display, GC gc, unsigned long pixel ) XSetBackground( Display *display, GC gc, unsigned long pixel )

XSetForeground
establece el atributo de frente del GC pasado como argumento. El color se frente determina el color de todas las primitivas grficas, aunque hay algunas que tambin tiene partes del color del atributo de fondo.

XSetBackground
establece el atributo de fondo del GC pasado como argumento. El color afecta a parte del color de las siguientes primitivas grficas: lneas discontnuas, patrones con zonas transparentes (stipples) y texto.

6.12 Ejemplo: cdigo


El siguiente programa dibuja dos lneas, una de color verde desde el punto (50,100) al (350,100), y otra de color rojo desde el (50,200) al (350,200).
#include <X11/Xlib.h> #include <X11/Xutil.h> #include <stdio.h> extern unsigned long Color( Display *display, const char *nombreColor ); main() { Display *d; Window w; unsigned long verde, rojo; GC gc; d = XOpenDisplay( NULL ); verde = Color( d, "green" ); rojo = Color( d, "red" ); w = XCreateSimpleWindow( d, DefaultRootWindow( d ), 250, 50, 400, 300, 2, BlackPixel( d, DefaultScreen( d ) ), WhitePixel( d, DefaultScreen( d ) ) ); XMapWindow( d, w ); gc = XCreateGC( d, w, 0, NULL ); XSetForeground( d, gc, verde ); XDrawLine( d, w, gc, 50, 100, 350, 100 ); XSetForeground( d, gc, rojo ); XDrawLine( d, w, gc, 50, 200, 350, 200 ); XFlush( d ); getchar(); }

6.13 Llamadas Xlib: dibujo de puntos


XDrawPoint( Display *d, Drawable drw, GC gc, int x, int y ) XDrawPoints( Display *d, Drawable drw, GC gc, XPoint *puntos, int n, int modo ) XDrawPoint dibuja un punto en las coordenadas especificadas. XDrawPoints dibuja un conjunto de n puntos pasado como un array. La definicin de XPoint es la siguiente: typedef struct { short x, y; } XPoint;

El argumento modo puede tomar los valores CoordModeOrigin o CoordModePrevious. El primero toma las coordenadas como absolutas mientras que el segundo las toma como relativas a partir del segundo punto ( el primer punto siempre se toma en
http://www.lsi.us.es/cursos/xlib-6.html 5 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

coordenadas absolutas).

6.14 Ejemplo: cdigo


El siguiente programa crea una ventana de 400 por 300 pxels y dibuja en ella los siguientes puntos: (100,500), (200,100), (200,200), (250,150), (300,100) y (300,200).
#include <X11/Xlib.h> #include <X11/Xutil.h> #include <stdio.h> main() { Display *d; Window w; GC gc; XPoint puntos[] = { { 200,100 }, { 200,200 }, { 250,150 }, { 300,100 }, { 300,200 } }; d = XOpenDisplay( NULL ); w = XCreateSimpleWindow( d, DefaultRootWindow( d ), 250, 50, 400, 300, 2, BlackPixel( d, DefaultScreen( d ) ), WhitePixel( d, DefaultScreen( d ) ) ); XMapWindow( d, w ); gc = XCreateGC( d, w, 0, NULL ); XDrawPoint( d, w, gc, 100, 150 ); XDrawPoints( d, w, gc, puntos, 5, CoordModeOrigin ); XFlush( d ); getchar(); }

6.15 Llamadas Xlib: dibujo de lneas


XDrawLine( Display *d, Drawable drw, GC gc, int x1, int y1, int x2, int y2 ) XDrawSegments( Display *d, Drawable drw, GC gc, XSegment *segmentos, int n ) XDrawLines( Display *d, Drawable drw, GC gc, XPoint *puntos, int n, int modo ) XDrawLine dibuja una lnea entre ambos pares de coordenadas pasados como argumentos. XDrawSegments dibuja un conjunto de n segmentos pasados como argumentos. La estructura XSegment tiene la siguiente definicin: typedef structure { short x1, y1, x2, y2; } XSegment;

Por ltimo, XDrawLines dibuja la polilnea especificada por los puntos contenidos en el array pasado como argumento.

6.16 Atributos grficos de lneas


Los atributos grficos relacionados con el dibujo de lneas son los siguientes:
foreground background line_width line_style cap_style join_style

Los atributos foreground (color de primer plano) y background (color de fondo) se pueden especificar con las funciones de conveniencia vistas en el apartado 6.11. Los dems atributos, ancho, estilo, terminacin y unin, se pueden especificar mediante la funcin de conveniencia XSelLineAttributes.

Estilo de terminacin (cap_stile)


Hay cuatro estilos de terminacin de lnea:

CapNotLast
Termina la linea de forma cuadrada y sin llegar al punto final.

CapButt
http://www.lsi.us.es/cursos/xlib-6.html 6 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

Termina la linea de forma cuadrada y llegando justo al punto final.

CapRound
Sobrepasa (en un nmero de pxels igual a la mitad del ancho de linea) el punto final y termina en forma redondeada.

CapProyecting
Igual que CapRound, pero de forma cuadrada.

Estilo de unin (join_stile)


Hay tres estilos de unin de lneas que se aplican cuando se una la funcin XDrawLine:

JoinMiter
Con esquina cuadrada

JoinRound
Con esquina arqueada

JoinBevel
Con esquina triangular

6.17 Llamadas Xlib: establecimiento de atributos de lnea


XSetLineAttributes( Display *display, GC gc, unsigned int anchoLinea, int estiloLinea, int estiloTerminacion, int estiloUnion );

El anchoLinea especifica el ancho de la lnea en pxels. El valor por defecto es 0, que produce la lnea ms fina posible. El estiloLinea puede tener uno de los siguientes valores:
LineSolid LineOnOffDash LineDoubleDash

Los otros dos argumentos pueden tomar los valores que pueden verse en 6.16.1 y 6.16.2. Por ejemplo, si se selecciona LineDoubleDash como el valor de estilo de lnea se dibujan lneas discontinuas, en las que los atributos de frente y fondo determinan los dos colores de la lnea.

6.18 Ejemplo: cdigo


El siguiente programa dibuja una lnea discontinua de dos colores entre los puntos (50,100) y (150,100).
#include <X11/Xlib.h> #include <X11/Xutil.h> #include <stdio.h> extern unsigned long Color( Display *display, const char *nombreColor ); main() { Display *d; int pantalla; Window w; long amarillo, rojo; GC gc; d = XOpenDisplay( NULL ); pantalla = DefaultScreen( d ); amarillo = Color( d, "yellow" ); rojo = Color( d, "red" ); w = XCreateSimpleWindow( d, DefaultRootWindow( d ), 400, 200, 300, 200, 2, BlackPixel( d, pantalla ), WhitePixel( d, pantalla ) ); XMapWindow( d, w ); gc = XCreateGC( d, w, 0, NULL ); XSetLineAttributes( d, gc, 5, LineDoubleDash, CapButt, JoinMiter ); XSetForeground( d, gc, rojo ); XSetBackground( d, gc, amarillo );
http://www.lsi.us.es/cursos/xlib-6.html 7 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

XDrawLine( d, w, gc, 50, 100, 250, 100 ); XFlush( d ); getchar(); }

6.19 Llamadas Xlib: definicin de patrones de linea


XSetDashes( Display *display, GC gc, int offset, char lista[], int n )

Se pueden definir patrones de lnea dando la longitud en pxels de las zonas de primer plano y fondo. Para ello se utiliza la funcin XSetDashes. El argumento offset indica la distancia en pxels desde el comienzo de la lnea hasta donde se desea que empiece a dibujarse el patrn. En lista se pasan los valores correspondientes a nmero de pxels con color de primer plano, nmero de pxels con color de fondo, etc, siendo n el nmero de elementos del array, que siempre debe ser par. Por ejemplo, si se quiere que el patrn de dibujo de lneas sea 20 pxels con color de primer plano, 10 con color de fondo, 10 con color de primer plano y 5 con color de fondo el cdigo que lo hara sera el siguiente:
char patron[] = { 20, 10, 10, 5 }; ... XSetDashes( d, gc, 0, patron, 4 ); XDrawLine( d, w, gc, 100, 100, 400, 100 ); ...

6.20 LAB: Dibujo de lneas y segmentos


Escribir un programa que dibuje lneas con todo tipo de estilo, terminacin y unin.

6.21 Llamadas Xlib: dibujo de rectngulos


XDrawRectangle( Display *d, Drawable drw, GC gc, int x, int y, unsigned int anchura, unsigned int altura ) XDrawRectangles( Display *d, Drawable drw, GC gc, XRectangle rectangulos[], int n )

XDrawRectangle
dibuja un rectngulo cuya esquina superior izquierda est en la posicin especificada por x e y, y tiene la altura (sobre y) y la anchura (sobre x) especificadas.

XDrawRectangles
dibuja un conjunto de n rectngulos pasado como un array de XRectangles. La definicin de XRectangle es la siguiente:
typedef struct { short x, y; unsigned short width, height; } XRectangle;

Las siguientes funciones hacen lo mismo pero dibujan un rectngulo relleno:


XFillRectangle( Display *d, Drawable drw, GC gc, int x, int y, unsigned int anchura, unsigned int altura ) XFillRectangles( Display *d, Drawable drw, GC gc, XRectangle rectangulos[], int n )

6.22 Llamadas Xlib: dibujo de arcos


XDrawArc( Display *d, Drawable drw, GC gc, int x, int y, unsigned int anchura, unsigned int altura, int angulo1, angulo2 ); XDrawArcs( Display *d, Drawable drw, GC gc, XArc arcos[], int n )

XDrawArc
dibuja un arco. El angulo1 especifica el comienzo del arco en unidades de grado multiplicadas por 64. El angulo2 especifica la extensin del arco relativo al comienzo del arco (no al origen de ngulos).

XDrawArcs
http://www.lsi.us.es/cursos/xlib-6.html 8 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

dibuja un conjunto de n arcos pasado como un array de XArcs. La definicin de XArc es la siguiente:
typedef struct { short x, y; unsigned short width, height; short angle1, angle2; } XArc

Las siguientes funciones hacen lo mismo pero dibujan el arco relleno:


XFillArc( Display *d, Drawable drw, GC gc, int x, int y, unsigned int anchura, unsigned int altura, int angulo1, int angulo2 ) XFillArcs( Display *d, Drawable drw, GC gc, XArc arcos[], int n )

Hay dos modos de relleno, ArcPieSlice y ArcChord, que se establecen con XSetArcMode:
XSetArcMode( Display *d, GC gc, int modo )

6.23 Llamadas Xlib: relleno de polgonos


XFillPolygon( Display *d, Drawable drw, GC gc, XPoint puntos[], int n, int forma, int modo ) XSetFillRule( Display *d, GC gc, int reglaRelleno ) XFillPolygon dibuja un polgono relleno cuyos n puntos se encuentran en el array de XPoints pasado como argumento. El argumento forma indica el tipo de polgono, y puede tomar los siguientes valores:

Convex
el polgono es convexo.

Nonconvex
el polgono es cncavo y no tiene interseccin de lneas.

Complex
el polgono tiene lneas que intersectan. El argumento modo tiene el mismo significado que en las llamadas vistas anteriormente, indica si las coordenadas han de tomarse como absolutas o como relativas al primer punto.
XSetFillRule establece el modo de relleno de polgonos que tengan lneas que intersectan. Puede tomar dos valores:

EvenOddRule
si varias areas del polgono se superponen un nmero impar de veces no se dibuja el area de interseccin.

WindingRule
las areas de interseccin se rellenan siempre.

6.24 Dibujo de texto


Para dibujar texto hacen falta dos pasos previos: 1. Cargar una fuente Es necesario decirle al servidor qu fuente debe usar para que la cargue. Esto se hace mediante la funcin XLoadFont que devuelve el ID de la fuente para posteriores referencias. 2. Establecer fuente Hay que establecer el fuente como el atributo correspondiente del GC mediante la funcin XSetFont.

6.25 Llamadas Xlib: dibujo de texto


Font XLoadFont( Display *display, char *nombreFuente ) XSetFont( Display *display, GC gc, Font fuente ) XDrawString( Display *d, GC gc, Drawable drw, int x, int y, char *cadena, int n )

XLoadFont

http://www.lsi.us.es/cursos/xlib-6.html

9 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

carga el fuente cuyo nombre se especifica devolviendo un identificador. Los nombres vlidos de fuente se pueden encontrar en el directorio /usr/lib/X11/fonts, donde tienen el sufijo .snf, que no hace falta especificar en el nombre de fuente. Se puede ver el aspecto de una fuente con la utilidad xfd.

XSetFont
establece el fuente pasado como argumento como el fuente del GC tambin pasado como argumento.

XDrawString
dibuja la cadena de longitud n tomando las coordenadas x e y como el comienzo de la lnea base del primer caracter de la cadena.

6.26 Ejemplo problema


Escribir un programa que dibuje la cadena "Abcde" en la posicin (100,100) usando el fuente "9x15".

6.27 Ejemplo: solucin


#include <X11/Xlib.h> #include <X11/Xutil.h> #include <stdio.h> main() { Display *d; Window w; GC gc; Font fuente; char cadena[] = "Abcde"; d = XOpenDisplay( NULL ); w = XCreateSimpleWindow( d, DefaultRootWindow( d ), 200, 300, 400, 300, 2, 0, 1 ); XMapWindow( d, w ); gc = XCreateGC( d, w, 0, NULL ); fuente = XLoadFont( d, "9x15" ); XSetFont( d, gc, fuente ); XDrawString( d, w, gc, 100, 100, cadena, strlen( cadena ) ); XFlush( d ); getchar(); }

6.28 Llamada Xlib: dibujar imgenes de texto


Una imgen de texto tiene el fondo opaco del color del atributo de fondo del GC actual, mientras que un texto normal tiene el fondo transparente. La llamada para dibujar una imgen de texto es:
XDrawImageString( Display *d, Drawable drw, GC gc, int x, int y, char *cadena, int n )

En el ejemplo anterior, si se hubiera querido dibujar la cadena como una imgen de texto con el frente rojo y el fondo azul habra que haber hecho lo siguiente:
... azul = Color( "blue" ); rojo = Color( "red" ); ... XSetFont( d, gc, fuente ); XSetForeground( d, gc, rojo ); XSetBackground( d, gc, azul ); XDrawImageString( d, w, gc, 100, 100, cadena, strlen( cadena ) ); ...

6.29 Manejo de eventos de exposicin


Las ventanas pueden estar superpuestas unas a otras, con lo que la informacin grfica de las ventanas ocultas puede perderse si no se almacena. Algunas estaciones de trabajo con grandes cantidades de memoria se encargan de restaurar las partes ocultas de las ventanas, aunque la mayora no lo hace, ya que resulta ms eficiente manejar el problema usando el evento Expose.
http://www.lsi.us.es/cursos/xlib-6.html 10 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

las ventanas, aunque la mayora no lo hace, ya que resulta ms eficiente manejar el problema usando el evento Expose. Un evento de tipo Expose ocurre siempre que toda o parte de una ventana queda expuesta a la visin del usuario, es decir, cuando deja de estar oculta por otras ventanas. Estas situaciones se pueden dar cuando una ventana pasa de estar no mapeada a mapeada, cuando se la eleva en la pila, cuando se mueve una ventana que la ocultaba total o parcialmente, etc. El tipo de evento como ya se ha dicho es Expose, la mscara de evento asociada es ExposureMask, y la estructura de evento es XExposeEvent, cuyos campos ms importantes son x, y, width, height y count. Cuando se produce un evento de tipo Expose se deben restaurar los grficos de alguna de estas tres formas: Si los grficos no son interactivos, redibujndolos otra vez. Si los grficos son interactivos se deben ir almacenando los datos antes de que se produzcan eventos de tipo Expose para poder redibujar luego. Restaurando slo el rea expuesta, no toda la ventana, ya que los eventos tipo Expose descomponen el rea expuesta en uno o ms rectngulos. Cuando se produce un evento de tipo Expose, las reas expuestas se descomponen en uno o ms rectngulos, cada uno de los cales genera un evento de tipo Expose. Como resultado, una exposicin produce una seria de eventos de tipo Expose. El campo count indica cantos eventos tipo Expose han ocurrido. Cuando es cero indica que es el ltimo evento de la serie. Cada rectngulo expuesto se define mediante los campos x, y, width y height.

6.30 Ejemplo: cdigo


El siguiente programa detecta los eventos de exposicin y redibuja todos los grficos (un rectngulo) cada vez. No hace falta dibujarlos antes de entrar en el bucle de eventos porque al mapear la ventana ya se produce un evento tipo Expose.
#include <X11/Xlib.h> #include <X11/Xutil.h> #include <stdio.h> extern unsigned long Color( Display *display, const char *nombreColor ); main() { Display *d; Window w; XEvent e; GC gc; d = XOpenDisplay( NULL ); w = XCreateSimpleWindow( d, DefaultRootWindow( d ), 200, 300, 400, 300, 2, 0, 1 ); XSelectInput( d, w, ExposureMask | KeyPressMask ); gc = XCreateGC( d, w, 0, NULL ); XSetForeground( d, gc, Color( d, "green" ) ); XMapWindow( d, w ); while ( True ) { XNextEvent( d, &e ); if ( e.type == Expose ) XFillRectangle( d, w, gc, 50, 50, 400, 300 ); else if ( e.type == KeyPress ) exit( 0 ); } }

6.31 Manejo de eventos de exposicin grfica


Las funciones XCopyArea y XCopyPlane pueden copiar un rea especfica de una ventana sobre un dibujable. Si dicha rea est tapada por otras ventanas, la imagen no se puede copiar de forma completa. Para solucionar este problema se usan los eventos especiales GraphicsExpose y NoExpose. El evento GraphicsExpose se enva desde el servidor si el rea que se copia est tapada parcial o totalmente por otras ventanas, en caso contrario se enva al evento NoExpose. Estos dos eventos no tienen una mscara de eventos propia (recordemos que estaban marcados con un asterisco en la tabla 4.3) sino que se controlan con el atributo graphics_exposures del GC. Si dicho atributo est a True, se envan los eventos, si est a False no se envan. Las estructuras de los eventos correspondientes son las siguientes:
typedef struct { int type; unsigned long serial;
http://www.lsi.us.es/cursos/xlib-6.html

/* no. de la ltima peticin atendida por el servidor */


11 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

Bool send_event; Display *display; Drawable drawable; int x, y; int width, height; int count; int major_code; int minor_code } XGraphicsExposeEvent; typedef struct { int type; unsigned long serial; Bool send_event; Display *display; Drawable drawable; int major_code; int minor_code } XNoExposeEvent;

/* verdadero si procede de una peticin SendEvent */ /* Display donde ocurri el evento */

/* no. de la ltima peticin atendida por el servidor */ /* verdadero si procede de una peticin SendEvent */ /* Display donde ocurri el evento */

Los campos x, y, width y height tienen el mismo significado que en la estructura del evento XExposeEvent, y hacen referencia a los dibujables de destino, que es a quienes estn dirigidos estos eventos. El campo major_code puede tomar los valores X_CopyArea o X_CopyPlane, e indica que la causa que provoc el evento fu una funcin XCopyArea o una funcin XCopyPlane. El campo drawable es el ID de la ventana o pixmap sobre el que se hizo la copia.

6.32 Ejemplo: programa


Se quiere realizar el siguiente programa: Paso 1 Crear una ventana w de 400 por 500 y una ventana s 125 por 150, ambas con el mismo origen. Mapear slo la ventana w. Dibujar una estrella en la ventana w de forma que si la ventana s se mapease la ocultara en parte. Paso 2 Copiar la estrella a la esquina inferior derecha de la ventana w Como nada la oculta se genera un evento NoExpose Paso 3 Mapear la ventana s, con lo que oculta parte de la estrella Copiar de nuevo la estrella, con lo que se genera un evento GraphicsExpose Elevar la ventana w, redibujar la estrella y copiarla de nuevo, con lo que se produce otro evento NoExpose NOTA: El paso 3 se debe llevar a cabo cuando se pulse el botn 3 del ratn, y el 2 cuando se pulse el botn 1.
#include #include #include #include #include <X11/Xlib.h> <X11/Xutil.h> <stdlib.h> <unistd.h> <stdio.h>

main() { Display *d; Window raiz, w, s; XEvent e; GC gc; unsigned long blanco, negro; XPoint estrella[] = { { 125,75 }, { -25,75 }, { 75,-50 }, { -100,0 }, { 75,50 } }; d raiz blanco negro = = = = XOpenDisplay( NULL ); DefaultRootWindow( d ); WhitePixel( d, DefaultScreen( d ) ); BlackPixel( d, DefaultScreen( d ) );

w = XCreateSimpleWindow( d, raiz, 350, 50, 500, 400, 2, negro, blanco ); s = XCreateSimpleWindow( d, raiz, 350, 50, 125, 150, 2, negro, blanco ); XSelectInput( d, w, ExposureMask | ButtonPressMask | KeyPressMask ); gc = XCreateGC( d, w, 0, NULL ); XSetFillRule( d, gc, WindingRule ); XMapWindow( d, w ); while ( True ) { XNextEvent( d, &e ); switch( e.type ) { case Expose:
http://www.lsi.us.es/cursos/xlib-6.html 12 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

XFillPolygon( d, w, gc, estrella, 5, Complex, CoordModePrevious ); break; case ButtonPress: if ( e.xbutton.button == Button1 ) XCopyArea( d, w, w, gc, 50, 50, 150, 150, 300, 200 ); else if ( e.xbutton.button == Button3 ) XMapRaised( d, s ); break; case GraphicsExpose: puts( "Evento de exposicin" ); sleep( 3 ); XRaiseWindow( d, w ); XFillPolygon( d, w, gc, estrella, 5, Complex, CoordModePrevious ); XCopyArea( d, w, w, gc, 50, 50, 150, 150, 300, 200 ); break; case NoExpose: puts( "Evento de no exposicin" ); break; case KeyPress: exit( 0 ); } } }

6.33 LAB: manejo de exposiciones


Crear un programa que haga lo siguiente: 1. Crear una ventana blanca grande con borde negro. Establecer la mscara de eventos para que se detecten pulsaciones del botn del ratn, exposiciones y pulsaciones de teclas. 2. Crear un GC. 3. Desarrollar un bucle de eventos que: 1. Para cada pulsacin del botn del ratn (despus de la primera) dibuje una lnea desde la posicin actual hasta la ltima posicin del ratn. 2. Si se detecta una exposicin despus de que se hayan dibujado varias lneas, redibujar todas las lneas hasta un mximo de 99 lneas. 3. Salir del programa cuando se pulse una tecla.

6.34 LAB (6.20): Solucin


#include #include #include #include <X11/Xlib.h> <X11/Xutil.h> <stdlib.h> <stdio.h>

extern unsigned long Color( Display *display, char *nombreColor ); main() { Display *d; Window w; GC gc; unsigned long azul, blanco, naranja, negro, rojo, verde; XSetWindowAttributes atributos; XPoint lineas1[] = { { 200,300 }, { 250,200 }, { 300,250 }, { 350,100 }, { 400,300 } }; XPoint lineas2[] = { { 200,50 }, { 450,50 }, { 450, 375 } }; XSegment segmentos[] = { { 50,200,100,300 }, { 100,150,50,300 }, { 150,100,150,300 } }; char patron[] = { 20, 5, 10, 15 }; d = XOpenDisplay( NULL ); azul = Color( d, "blue" ); blanco = Color( d, "white" ); naranja = Color( d, "orange" ); negro = Color( d, "black" ); rojo = Color( d, "red" ); verde = Color( d, "green" ); w = XCreateSimpleWindow( d, DefaultRootWindow( d ), 100, 200, 500, 400, 10, negro, blanco ); atributos.override_redirect = True; /* para puentear al WM */

http://www.lsi.us.es/cursos/xlib-6.html

13 / 14

Programacin en X Window: Dibujo de grficos

27/06/2013

XChangeWindowAttributes( d, w, CWOverrideRedirect, &atributos ); XMapWindow( d, w ); gc = XCreateGC( d, w, 0, NULL ); XSetForeground( d, gc, negro ); XSetLineAttributes( d, gc, 4, LineSolid, CapButt, 0 ); XDrawLine( d, w, gc, 50, 350, 450, 350 ); XSetForeground( d, gc, azul ); XSetBackground( d, gc, verde ); XSetLineAttributes( d, gc, 8, LineDoubleDash, CapButt, 0); XDrawSegments( d, w, gc, segmentos, 3 ); XSetLineAttributes( d, gc, 15, LineSolid, CapRound, JoinRound ); XDrawLines( d, w, gc, lineas1, 5, CoordModeOrigin ); XSetForeground( d, gc, naranja ); XSetBackground( d, gc, verde ); XSetLineAttributes( d, gc, 20, LineDoubleDash, CapProjecting, JoinBevel ); XDrawLines( d, w, gc, lineas2, 3, CoordModeOrigin ); XFlush( d ); getchar(); }

6.35 LAB (6.33): Solucin


#include #include #include #include <X11/Xlib.h> <X11/Xutil.h> <string.h> <stdlib.h>

#define MAXPOS 100 main() { Display *d; Window w; XEvent e; GC gc; XPoint puntos[ MAXPOS ]; int p = 0; d = XOpenDisplay( NULL ); w = XCreateSimpleWindow( d, DefaultRootWindow( d ), 100, 100, 400, 400, 2, BlackPixel( d, DefaultScreen( d ) ), WhitePixel( d, DefaultScreen( d ) ) ); gc = XCreateGC( d, w, 0, NULL ); XSelectInput( d, w, ExposureMask | ButtonPressMask | KeyPressMask ); XMapWindow( d, w ); while ( True ) { XNextEvent( d, &e ); switch( e.type ) { case ButtonPress: puntos[ p ].x = e.xbutton.x; puntos[ p ].y = e.xbutton.y; if ( p ) /* si no es el primer punto */ XDrawLines( d, w, gc, &puntos[p-1], 2, CoordModeOrigin ); if ( p < MAXPOS ) p++; else /* array circular de andar por casa */ memmove( puntos, &puntos[1], (MAXPOS-1) * sizeof(XPoint)); break; case Expose: /* si es el ltimo evento de exposicin */ if ( !e.xexpose.count ) XDrawLines( d, w, gc, puntos, p, CoordModeOrigin ); break; case KeyPress: exit( 0 ); } } }

Previous Next Table of Contents

http://www.lsi.us.es/cursos/xlib-6.html

14 / 14

Vous aimerez peut-être aussi