/*
* surf - visualizing algebraic curves and algebraic surfaces
* Copyright (C) 1996-1997 Friedrich-Alexander-Universitaet
* Erlangen-Nuernberg
* 1997-2000 Johannes Gutenberg-Universitaet Mainz
* Authors: Stephan Endrass, Hans Huelf, Ruediger Oertel,
* Kai Schneider, Ralf Schmitt, Johannes Beigel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <iostream.h>
#include <gdk/gdkx.h>
#include "mycolor.h"
#include "color.h"
#include "DrawingArea.h"
#include "RGBToStandard.h"
#include "RgbBuffer.h"
// #define DEBUG
#include "debug.h"
#include "defs.h"
#include "bit_buffer.h"
#include "RGBToNetscape.h"
#include "ColorWindow.h"
extern XStandardColormap *xstandardColormap;
DrawingArea::DrawingArea(bool colored)
{
width = 200;
height = 200;
locks = 1;
isColored = colored;
gtkdrawingArea = gtk_drawing_area_new();
gtk_widget_set_usize(gtkdrawingArea, width, height);
gtk_signal_connect (GTK_OBJECT(gtkdrawingArea), "configure_event", GTK_SIGNAL_FUNC(handle_configure), this);
gtk_signal_connect (GTK_OBJECT(gtkdrawingArea), "expose_event", GTK_SIGNAL_FUNC(handle_expose), this);
gtk_signal_connect (GTK_OBJECT(gtkdrawingArea), "realize", GTK_SIGNAL_FUNC(handle_realize), this);
}
DrawingArea::~DrawingArea()
{
}
void DrawingArea::show()
{
if (windowToShow) {
windowToShow->show();
}
}
void DrawingArea::setSize (int w, int h)
{
if (width == w && height == h)
return;
width=w;
height=h;
gtk_widget_set_usize(gtkdrawingArea, width, height);
if (gdkpixmap) {
gdk_pixmap_unref(gdkpixmap);
gdkpixmap = gdk_pixmap_new(gtkdrawingArea->window, width, height, isColored ? -1 : 1);
xpixmap = ((GdkPixmapPrivate *)gdkpixmap)->xwindow;
}
}
void DrawingArea::drawRectangle (int x, int y, int w, int h, float r, float g, float b)
{
switch (myColorMode) {
case COLOR_NETSCAPE:
XSetForeground (xdisplay, xgc, pixels[RGBToNetscape(r,g, b, x, y)]);
break;
case COLOR_TRUE:
XSetForeground (xdisplay, xgc, RGBToStandard(r,g,b, xstandardColormap));
break;
}
XFillRectangle (xdisplay, xpixmap, xgc, x, y, w, h);
}
void DrawingArea::drawPoint (int x, int y, float r, float g, float b)
{
switch (myColorMode) {
case COLOR_NETSCAPE:
XSetForeground (xdisplay, xgc, pixels[RGBToNetscape(r,g, b, x, y)]);
break;
case COLOR_TRUE:
XSetForeground (xdisplay, xgc, RGBToStandard(r,g,b, xstandardColormap));
break;
}
XDrawPoint (xdisplay, xpixmap, xgc, x,y);
}
void DrawingArea::draw (int x, int y, int w, int h)
{
GdkRectangle rect;
rect.x = x;
rect.y = y;
rect.width = w;
rect.height = h;
gtk_widget_draw (gtkdrawingArea, &rect);
// if (isColored) {
// XCopyArea (xdisplay, xpixmap, ((GdkWindowPrivate *)GTK_WIDGET(gtkdrawingArea)->window)->xwindow, xgc, x, y, w, h, x, y);
// XFlush(xdisplay);
// } else {
// XCopyPlane (xdisplay, xpixmap, GDK_WINDOW_XWINDOW(gtkdrawingArea->window), xgc,
// x, y, w, h,
// x,y,1);
// }
}
void DrawingArea::drawPoint (int x, int y, bool set)
{
gdk_draw_point (gdkpixmap, set ? bitmap_set_gc : bitmap_unset_gc, x, y);
}
void DrawingArea::drawBitbuffer (bit_buffer &bb)
{
setSize (bb.getWidth(), bb.getHeight());
// XClearArea (xdisplay, xpixmap, 0,0,width,height, FALSE);
int x;
for (x=0; x<width; x++) {
int y;
for (y=0; y<height; y++) {
drawPoint (x,y, !bb.getPixel(x, y));
}
}
draw (0, 0, width, height);
}
void DrawingArea::drawRgbBuffer (RgbBuffer &buffer)
{
setSize (buffer.getWidth(), buffer.getHeight());
int x,y;
int i=0;
for (y=0; y<buffer.height; y++) {
for (x=0; x<buffer.width; x++,i++) {
drawPoint(x,y,
((float)buffer.r[i])/255.0,
((float)buffer.g[i])/255.0,
((float)buffer.b[i])/255.0);
}
}
draw(0,0,width,height);
}
void DrawingArea::drawCurve (RgbBuffer &rgbbuffer, int curve_r, int curve_g, int curve_b)
{
int r_tmp,Layer1r;
int g_tmp,Layer1g;
int b_tmp,Layer1b;
float rr,gg,bb;
double Layer2;
int num = 0;
for( int y = 0; y < rgbbuffer.height; y++ ) {
for( int x = 0; x < rgbbuffer.width; x++, num++ ) {
if( rgbbuffer.GetTag(x,y,CURVEBIT) ) {
Layer1r = rgbbuffer.r[num] ;
Layer1g = rgbbuffer.g[num] ;
Layer1b = rgbbuffer.b[num] ;
// get intensity from curve at this pixel
Layer2 = (double)rgbbuffer.curv[num]/255.0;
r_tmp=(int)( (Layer1r*(1-Layer2)) + ( curve_r*Layer2));
g_tmp=(int)( (Layer1g*(1-Layer2)) + ( curve_g*Layer2));
b_tmp=(int)( (Layer1b*(1-Layer2)) + ( curve_b*Layer2));
rgbbuffer.r[num]=Layer1r = (r_tmp >255) ? 255 : r_tmp;
rgbbuffer.g[num]=Layer1g = (g_tmp >255) ? 255 : g_tmp;
rgbbuffer.b[num]=Layer1b = (b_tmp >255) ? 255 : b_tmp;
rgbbuffer.DelTag(x,y,CURVEBIT);
rgbbuffer.SetTag(x,y,DATABIT);
rr = Layer1r/255.0;
gg = Layer1g/255.0;
bb = Layer1b/255.0;
drawPoint(x, y, rr, gg, bb);
}
}
}
draw(0,0,width,height);
}
//
// --- GTK Callbacks
//
void DrawingArea::handle_realize (GtkWidget *widget, gpointer data)
{
DrawingArea *This = (DrawingArea *)data;
This->gdkpixmap = gdk_pixmap_new(widget->window, This->width, This->height, This->isColored ? -1 : 1);
This->gdkgc = gdk_gc_new (widget->window);
gdk_gc_copy (This->gdkgc, widget->style->white_gc);
// we need the next two lines to make the dither window work on 8 bit displays
gdk_gc_set_foreground(This->gdkgc, &widget->style->white);
gdk_gc_set_background(This->gdkgc, &widget->style->black);
This->xdisplay = GDK_GC_XDISPLAY(This->gdkgc);
This->xpixmap = ((GdkPixmapPrivate *)This->gdkpixmap)->xwindow;
This->xgc = GDK_GC_XGC(This->gdkgc);
if (This->isColored) {
This->drawRectangle (0, 0, This->width, This->height, 0,0,0);
#if 0
int i,j;
for (i=0; i<200; i++)
for (j=0; j<200; j++) {
This->drawRectangle (i,j,1,1, (i % 100) / 200.0 * 2, j / 200.0, i*j/40000.0);
}
#endif
} else {
GdkGCValues gcval;
This->bitmap_set_gc = gdk_gc_new (This->gdkpixmap);
gdk_gc_get_values (This->bitmap_set_gc, &gcval);
This->bitmap_unset_gc = gdk_gc_new (This->gdkpixmap);
gdk_gc_set_foreground (This->bitmap_unset_gc, &gcval.background);
gdk_draw_rectangle (This->gdkpixmap, This->bitmap_unset_gc, TRUE, 0,0, This->width, This->height);
#if 0
int i,j;
for (i=0; i<200; i++)
for (j=0; j<200; j++)
This->drawPoint(i,j, i==j || (i-100)*(i-100)+(j-100)*(j-100) < 100 );
#endif
}
// gdk_window_set_back_pixmap (This->gtkdrawingArea->window, This->gdkpixmap, 0);
}
void DrawingArea::handle_configure (GtkWidget *widget, GdkEventConfigure *event, gpointer data)
{
}
void DrawingArea::handle_expose (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
DrawingArea *This = (DrawingArea *) data;
if (This->isColored) {
XCopyArea (This->xdisplay, This->xpixmap, GDK_WINDOW_XWINDOW(widget->window), This->xgc,
event->area.x, event->area.y, event->area.width, event->area.height,
event->area.x, event->area.y);
} else {
XCopyPlane (This->xdisplay, This->xpixmap, GDK_WINDOW_XWINDOW(widget->window), This->xgc,
event->area.x, event->area.y, event->area.width, event->area.height,
event->area.x, event->area.y, 1);
// gdk_draw_bitmap (widget->window, This->gdkgc, This->gdkpixmap,
// event->area.x, event->area.y,
// event->area.x, event->area.y,
// event->area.width, event->area.height);
}
}
syntax highlighted by Code2HTML, v. 0.9.1