Académique Documents
Professionnel Documents
Culture Documents
27/06/2013
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.
http://www.lsi.us.es/cursos/xlib-6.html
1 / 14
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.
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.
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
27/06/2013
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.
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.
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.
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
27/06/2013
coordenadas absolutas).
Por ltimo, XDrawLines dibuja la polilnea especificada por los puntos contenidos en el array pasado como argumento.
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.
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
27/06/2013
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.
JoinMiter
Con esquina cuadrada
JoinRound
Con esquina arqueada
JoinBevel
Con esquina triangular
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.
27/06/2013
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 ); ...
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;
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
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
Hay dos modos de relleno, ArcPieSlice y ArcChord, que se establecen con XSetArcMode:
XSetArcMode( Display *d, GC gc, int modo )
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.
XLoadFont
http://www.lsi.us.es/cursos/xlib-6.html
9 / 14
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.
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 ) ); ...
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.
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;
/* 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.
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
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 ); } } }
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
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(); }
#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 ); } } }
http://www.lsi.us.es/cursos/xlib-6.html
14 / 14