From: Leandro Lucarella Date: Tue, 7 Oct 2003 03:25:26 +0000 (+0000) Subject: Se corrige un bug. Los colores se ponían presuponiendo un Display de 24 bits. Ahora... X-Git-Tag: svn_import~4 X-Git-Url: https://git.llucax.com/z.facultad/75.42/figuras.git/commitdiff_plain/dae5f5f69bbdb51a2ef79080cdb0be0bf1d4aa8d Se corrige un bug. Los colores se ponían presuponiendo un Display de 24 bits. Ahora se alocan los colores (eligiendo el más cercano de no poder obtenerlo) como corresponde para que ande en cualquier profundidad de colores. --- diff --git a/Makefile b/Makefile index b66efef..63dd15b 100644 --- a/Makefile +++ b/Makefile @@ -15,9 +15,9 @@ # Opciones para el compilador. CXXFLAGS=`pkg-config --cflags gtk+-2.0` -CXXFLAGS+=-ansi -pedantic -Wall -O3 +#CXXFLAGS+=-ansi -pedantic -Wall -O3 #CXXFLAGS+=-ansi -pedantic -Wall -g3 -#CXXFLAGS+=-ansi -pedantic -Wall -g3 -DDEBUG +CXXFLAGS+=-ansi -pedantic -Wall -g3 -DDEBUG LDFLAGS=`pkg-config --libs gtk+-2.0` @@ -46,7 +46,7 @@ circulo.o: figura.h circulo.cpp circulo.h rectangulo.o: figura.h rectangulo.cpp rectangulo.h -cuadrado.o: rectangulo.h cuadrado.cpp cuadrado.h +cuadrado.o: figura.h rectangulo.h cuadrado.cpp cuadrado.h dibujo.o: dllist.h figura.h dibujo.cpp dibujo.h diff --git a/circulo.cpp b/circulo.cpp index 6b03e9a..2d2968e 100644 --- a/circulo.cpp +++ b/circulo.cpp @@ -38,10 +38,8 @@ void Circulo::dibujar(GtkWidget* widget) const { #ifdef DEBUG std::cerr << "En dibujar de Círculo." << std::endl; #endif - // Copio el contexto gráfico del área de dibujo. - GdkGC* gc = gdk_gc_new(GDK_DRAWABLE(widget->window)); - // Le doy los nuevos valores. - set_gc(gc); + // Obtengo un contexto gráfico con el grosor y color de la figura. + GdkGC* gc = get_gc(widget); // Dibujo el círculo. gdk_draw_arc( // Área dibujable. diff --git a/figura.cpp b/figura.cpp index 99f4ad5..bd93450 100644 --- a/figura.cpp +++ b/figura.cpp @@ -24,50 +24,32 @@ GdkColor* Figura::traducir_color(GdkColor* c) const { // Elimino el color anterior. c->pixel = 0; - // Tiene el primer bit en 1. + c->red = 0; + c->green = 0; + c->blue = 0; + // Tiene el primer bit en 1 tiene pigmento azul. if (color & 1) { - // Entonces activo los bits 1,2,3,4,5,6,7 del color de 24 bits. - // (quedaría con la componente azul en 0x7F) - c->pixel |= 0x7F; + // Si tiene el cuarto bit, es bien saturado. + c->blue = (color & (1 << 3)) ? 0xFFFF : 0x7FFF; } - // Tiene el segundo bit en 1. + // Tiene el segundo bit en 1 tiene pigmento verde. if (color & (1 << 1)) { - // Entonces activo los bits 9,10,11,12,13,14,15 del color de 24 bits. - // (quedaría con la componente verde en 0x7F) - c->pixel |= 0x7F << 8; + // Si tiene el cuarto bit, es bien saturado. + c->green = (color & (1 << 3)) ? 0xFFFF : 0x7FFF; } - // Tiene el tercer bit en 1. + // Tiene el tercer bit en 1 tiene pigmento rojo. if (color & (1 << 2)) { - // Entonces activo los bits 17,18,19,20,21,22,23 del color de 24 bits. - // (quedaría con la componente roja en 0x7F) - c->pixel |= 0x7F << 16; + // Si tiene el cuarto bit, es bien saturado. + c->red = (color & (1 << 3)) ? 0xFFFF : 0x7FFF; } - // Tiene el cuarto bit en 1. - if (color & (1 << 3)) { - // Si tiene alguno de los bits menos significativos (tiene pigmento). - if (color & 7) { - c->pixel = - // Desplazo los bits del color de 24 bits 1 lugar a la - // izquierda (si era, por ejemplo 0111 1111, quedaría - // 1111 1110). - (c->pixel << 1) - // Al resultado le aplico una máscara para que quede 'prendido' - // el bit más significativo de los colores activados - // anteriormente (y de esta manera darles el doble de "luz"). - // Por ejemplo: 1111 1110 & 1000 0000 = 1000 0000. - & 0x808080 - // Finalmente, prendo los bits resultantes en el color de 24 bits. - // Por ejemplo: 1000 0000 | 0111 1111 = 1111 1111. - | c->pixel; - // Si no tiene pigmento no lo dejo negro porque negro ya es cuando están - // todos los bits apagados. - } else { - // Asigno un gris claro, combinación que no se da de otra manera. - c->pixel = 0xF0F0F0; - } + // Tiene el cuarto bit en 1 y todo el resto en 0, le asigno un gris claro + // porque negro ya es cuando son todos 0. + if (color == (1 << 3)) { + c->red = c->green = c->blue = 0xD000; } #ifdef DEBUG - std::cerr << "En Figura::traducir_color: 0x" << std::hex << c->pixel + std::cerr << "En Figura::traducir_color: 0x" << std::hex << c->red + << ", 0x" << std::hex << c->green << ", 0x" << std::hex << c->blue << "." << std::endl; #endif return c; @@ -103,7 +85,9 @@ Figura::~Figura(void) { #endif } -void Figura::set_gc(GdkGC* gc) const { +GdkGC* Figura::get_gc(GtkWidget* widget) const { + // Copio el contexto gráfico del área de dibujo. + GdkGC* gc = gdk_gc_new(GDK_DRAWABLE(widget->window)); // Asigna propiedades del trazo. gdk_gc_set_line_attributes( gc, // Contexto gráfico al cual asignar propiedades. @@ -111,8 +95,20 @@ void Figura::set_gc(GdkGC* gc) const { GDK_LINE_SOLID, // Tipo de línea (sólida en este caso). GDK_CAP_ROUND, // Tipo de terminación (redondeada en este caso). GDK_JOIN_ROUND); // Forma de unir trazos (también redondeado). + // Obtengo el color. GdkColor c; + traducir_color(&c); + // Aloco el color en el mapa de colores del área de dibujo para que funcione + // en un display de menos de 24 bits. + gdk_colormap_alloc_color(gtk_widget_get_colormap(widget), &c, FALSE, TRUE); + // Indica que no se puede escribir, para que /______________| | + // se pueda compartir con otras aplicaciones. \ | + // | + // Indica que si no se puede alocar, que trate de /___________________| + // buscar un color similar. \. + // Cambia el color del trazo. - gdk_gc_set_foreground(gc, traducir_color(&c)); + gdk_gc_set_foreground(gc, &c); + return gc; } diff --git a/figura.h b/figura.h index c79d65f..7e1b9f7 100644 --- a/figura.h +++ b/figura.h @@ -44,13 +44,15 @@ class Figura { char nombre[MAX_NOMBRE]; /** - * Modifica el contexto gráfico. - * Modifica el contexto gráfico según las propiedades de la figura - * (color y grosor). + * Crea un nuevo contexto gráfico. + * Crea un nuevo contexto gráfico con las propiedades de la figura + * (color y grosor) partiendo del contexto gráfico de un widget. + * + * \param widget Widget de donde copiar el GC inicial. * - * \param gc Contexto gráfico a modificar. + * \return Contexto gráfico a modificar. */ - virtual void set_gc(GdkGC* gc) const; + virtual GdkGC* get_gc(GtkWidget* widget) const; /** * Traduce los 16 colores (de 4 bits) en colores de 24 bits. diff --git a/linea.cpp b/linea.cpp index 924bf9f..7c4cebe 100644 --- a/linea.cpp +++ b/linea.cpp @@ -38,10 +38,8 @@ void Linea::dibujar(GtkWidget* widget) const { #ifdef DEBUG std::cerr << "En dibujar de Línea." << std::endl; #endif - // Copio el contexto gráfico del área de dibujo. - GdkGC* gc = gdk_gc_new(GDK_DRAWABLE(widget->window)); - // Le doy los nuevos valores. - set_gc(gc); + // Obtengo un contexto gráfico con el grosor y color de la figura. + GdkGC* gc = get_gc(widget); // Dibujo la línea. gdk_draw_line( // Área dibujable. diff --git a/rectangulo.cpp b/rectangulo.cpp index da7e087..c737320 100644 --- a/rectangulo.cpp +++ b/rectangulo.cpp @@ -38,10 +38,8 @@ void Rectangulo::dibujar(GtkWidget* widget) const { #ifdef DEBUG std::cerr << "En dibujar de Rectángulo." << std::endl; #endif - // Copio el contexto gráfico del área de dibujo. - GdkGC* gc = gdk_gc_new(GDK_DRAWABLE(widget->window)); - // Le doy los nuevos valores. - set_gc(gc); + // Obtengo un contexto gráfico con el grosor y color de la figura. + GdkGC* gc = get_gc(widget); // Lado de la izquierda. gdk_draw_line( // Área dibujable.