clip origin, and **clip mask origion** ??



I have an xpm file with multiple pixmaps on it. I am drawing a new pixmap
by copying the smaller pictures out of the xpm file to the new pixmap.
I have encountered what I figure has a simple solution but of which I have
not found. Clipping the origin on the loaded xpm appears to solve the
drawing problem and I can copy it but the mask still remains the original.
So if the xpm has a circle in the top left 40x40 square and I'm trying to
copy a 40x40 square that is in the bottom right it will copy the right
information but the mask is still a circle.

To solve this problem I have copyed the correct information out of the
loaded gchar** xpm data array that just contains all the colors and only
the 40x40 square then I create a new gdk_pixmap in order to make the
correct mask. Now I can copy the xpm small picture using the mask I just
created.

This solution works perfectly but is really really really slow and is
really rediculus.

I need to be able to use the mask that already exists but be able to
specify its top left hand corner each time I use it.

I've attached part of the file which needs this command.

All help is VERY appreciated.


Travis Loyd
[email: lelandg@usa.net				Encrypt your email too: ]
[other: s201635@mail.nwmissouri.edu		     http://www.pgp.com	]
[  pgp: send email with subject: sendmepgp				]
#include <gtk/gtk.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h> /* for random blank tiles */
#include "loadfile.h"
#include "define.h"
#include "tileset.h"

struct reference_hold {
	GtkWidget *main_window;	/* The window the factory tile is displayed in */
	GdkPixmap *factory_tile_xpm;	/* The pixmap we are drawing on */
	GdkBitmap *factory_tile_mask;

	GdkPixmap *tileset_xpm;	/* The pixmap we are copying from */
	GdkBitmap *tileset_mask;
	GdkGC *tileset_gc;

	GtkStyle *style;

	unsigned char *factory_tile_layout;	/* The factory tile description in memory */
	gint factory_tile_size;				/* Length of factory tile description */
};

void add_back_grid(struct reference_hold*);
void add_square_grid(struct reference_hold*);
void add_normal_conveyors(struct reference_hold*);
void add_express_conveyors(struct reference_hold*);
void add_normal_turning_arrows(struct reference_hold *sister);
void add_express_turning_arrows(struct reference_hold *sister);
void add_normal_strait_arrows(struct reference_hold *sister);
void add_express_strait_arrows(struct reference_hold *sister);
void add_gears(struct reference_hold *sister);
void add_pits(struct reference_hold *sister);
void add_walls(struct reference_hold *sister);
void add_lasers(struct reference_hold *sister);
void add_pushers(struct reference_hold *sister);
void add_crushers(struct reference_hold *sister);
void add_repair_site(struct reference_hold *sister);

void my_set_gc_clip_mask(struct reference_hold *sister, gint xptr, gint yptr) {
	gchar *new_xpm[40000];
	gchar buff[512], buff2[512], *ptr;
	gint ctr, loop, y, size, size_of_array;
	GdkPixmap *pixmap;
	GdkBitmap *bitmap;

	size_of_array = 20000;

//g_print("\n/* XPM */\nstatic char * new_xpm[] = {\n");

	for(ctr = 0; ctr < size_of_array; ctr ++) {
		new_xpm[ctr] = 0;
	}

	new_xpm[0] = strdup(tileset_xpm[0]);
	new_xpm[0][0] = 0;

	/* Find the third string which is the number of colors */
	ptr = strchr(tileset_xpm[0], ' '); ++ptr;
	ptr = strchr(ptr, ' '); ++ptr;
	strcpy(buff, ptr);
	ptr = strchr(buff, ' ');
	ptr[0] = 0; ptr++;

	sprintf(buff2, "%d", TILE_SIZE);
	strcat(new_xpm[0], buff2);
	strcat(new_xpm[0], " ");
	strcat(new_xpm[0], buff2);
	strcat(new_xpm[0], " ");
	strcat(new_xpm[0], buff);
	strcat(new_xpm[0], " ");
	strcat(new_xpm[0], ptr);
	size = atoi(ptr);
	xptr *= size;

	/* Just copy off the length of colors from the tileset */
	loop = atoi(buff);
	for(ctr = 1; ctr <= loop; ctr ++) {
		new_xpm[ctr] = g_strdup(tileset_xpm[ctr]);
	}

	/* Now copy off the square of pixels which represent our square */
	yptr += loop + 1;

	for(y = yptr; y < yptr+TILE_SIZE; y ++) {
		strncpy(buff, tileset_xpm[y]+xptr, TILE_SIZE*size);
		buff[TILE_SIZE*size] = 0;
		new_xpm[++loop] = g_strdup(buff);
	}

	loop ++;

//	g_print("\"%s\"", new_xpm[0]);
//	for(ctr = 1; ctr < loop; ctr ++) {
//		g_print(",\n\"%s\"", new_xpm[ctr]);
//	}
//	g_print("};\n");

	pixmap = gdk_pixmap_create_from_xpm_d(
			sister->main_window->window, &bitmap,
			&sister->style->bg[GTK_STATE_NORMAL], new_xpm);
	gdk_gc_set_clip_mask(sister->tileset_gc, bitmap);

	gdk_pixmap_unref(pixmap);
	gdk_bitmap_unref(bitmap);

	for(ctr = 0; ctr < size_of_array; ctr ++) {
		if(new_xpm[ctr])
			g_free(new_xpm[ctr]);
	}
}

GdkPixmap* generate_factory_tile(GtkWidget *da_main_win, gchar *boardname) {
	struct reference_hold tmp;
	struct reference_hold *sister;

	sister = &tmp;

	load_board_to_memory(boardname, &sister->factory_tile_layout, &sister->factory_tile_size);

	sister->main_window = da_main_win;

	gtk_widget_realize(sister->main_window);

	/* Create the actual board */
	sister->factory_tile_xpm = gdk_pixmap_new(
			sister->main_window->window, (12*TILE_SIZE), (12*TILE_SIZE), -1);

g_print("Loading tileset: [");
	sister->style = gtk_widget_get_style(sister->main_window);
	sister->tileset_xpm = gdk_pixmap_create_from_xpm_d(
			sister->main_window->window, &sister->tileset_mask,
			&sister->style->bg[GTK_STATE_NORMAL], tileset_xpm);
	sister->tileset_gc = gdk_gc_new(sister->tileset_xpm);
	gdk_gc_set_clip_mask(sister->tileset_gc, sister->tileset_mask);
	g_print(".");

	/* Display a grid on the board */
//g_print("adding a background tile to each square\n");
	add_back_grid(sister);
	g_print(".");
//g_print("adding repair sites to the factory tile\n");
	add_repair_site(sister);
	g_print(".");
//g_print("adding normal conveyors from all arrows stored\n");
	add_normal_conveyors(sister);
	g_print(".");
//g_print("adding express conveyors from all arrows stored\n");
	add_express_conveyors(sister);
	g_print(".");
//g_print("adding adding normal straight arrows\n");
	add_normal_strait_arrows(sister);
	g_print(".");
//g_print("adding express straight arrows\n");
	add_express_strait_arrows(sister);
	g_print(".");
//g_print("adding normal turning arrows stored\n");
	add_normal_turning_arrows(sister);
	g_print(".");
//g_print("adding express turning arrows stored\n");
	add_express_turning_arrows(sister);
	g_print(".");
//g_print("adding pits\n");
	add_pits(sister);
	g_print(".");
//g_print("adding gears\n");
	add_gears(sister);
	g_print(".");
//g_print("adding laser mounts\n");
	add_lasers(sister);
	g_print(".");
//g_print("adding a pushers to the factory tile\n");
	add_pushers(sister);
	g_print(".");
//g_print("adding a crushers to the factory tile\n");
	add_crushers(sister);
	g_print(".");
//g_print("adding walls\n");
	add_walls(sister);
	g_print(".");
//g_print("adding a grid to the factory tile\n");
//	add_square_grid(sister);
//	g_print(".");
	g_print("]\n");

	g_print("Freeing up no longer used resources.\n");
	gdk_gc_unref(sister->tileset_gc);
	gdk_bitmap_unref(sister->tileset_mask);
	gdk_pixmap_unref(sister->tileset_xpm);

	/* Freeing up the memory previously used */
	g_free(sister->factory_tile_layout);

	/* Return the factory tile to be placed on the factory layout */
	return (sister->factory_tile_xpm);
}

void add_back_grid(struct reference_hold *sister) {
	gint x, y;

	my_set_gc_clip_mask(sister, (BACK_A_X), (BACK_A_Y));

	/* Combine 2 images here */
	for(y = 0; y < 12; y++) {
		for(x = 0; x < 12; x++) {

			/* Randomly choose which tile to use */
			switch(rand() % 3) {
				case 0:
					gdk_gc_set_clip_origin(sister->tileset_gc,
						(x*TILE_SIZE), (y*TILE_SIZE));
					gdk_draw_pixmap(
						sister->factory_tile_xpm, sister->tileset_gc,
						sister->tileset_xpm, BACK_A_X, BACK_A_Y,
						(x*TILE_SIZE), (y*TILE_SIZE), TILE_SIZE, TILE_SIZE);
					break;
				case 1:
					gdk_gc_set_clip_origin(sister->tileset_gc,
						(x*TILE_SIZE), (y*TILE_SIZE));
					gdk_draw_pixmap(
						sister->factory_tile_xpm, sister->tileset_gc,
						sister->tileset_xpm, BACK_B_X, BACK_B_Y,
						(x*TILE_SIZE), (y*TILE_SIZE), TILE_SIZE, TILE_SIZE);
					break;
				case 2:
					gdk_gc_set_clip_origin(sister->tileset_gc,
						(x*TILE_SIZE), (y*TILE_SIZE));
					gdk_draw_pixmap(
						sister->factory_tile_xpm, sister->tileset_gc,
						sister->tileset_xpm, BACK_C_X, BACK_C_Y,
						(x*TILE_SIZE), (y*TILE_SIZE), TILE_SIZE, TILE_SIZE);
					break;
			}
		}
	}
}

void add_normal_turning_arrows(struct reference_hold *sister) {
	gint x, y, z, ptr;

	for(ptr = 0; ptr < sister->factory_tile_size; ptr ++) {
		if(sister->factory_tile_layout[ptr] == 0xd5) {
			for(++ptr;ptr < sister->factory_tile_size; ptr ++) {
				if(sister->factory_tile_layout[ptr] >= 0xd0) {
					/* We are out of conveyors */
//					ptr--;
					break;
				}

				x = sister->factory_tile_layout[ptr];
				y = sister->factory_tile_layout[++ptr];
				z = sister->factory_tile_layout[++ptr];

				switch(z) {
					case 0:
						my_set_gc_clip_mask(sister,
							(NORMAL_CLOCK_NORTH_X), (NORMAL_CLOCK_NORTH_Y));
						gdk_gc_set_clip_origin(sister->tileset_gc,
							(x*TILE_SIZE), (y*TILE_SIZE));
						gdk_draw_pixmap(
							sister->factory_tile_xpm, sister->tileset_gc,
							sister->tileset_xpm,
							NORMAL_CLOCK_NORTH_X, NORMAL_CLOCK_NORTH_Y,
							(x*TILE_SIZE), (y*TILE_SIZE), TILE_SIZE, TILE_SIZE);
						break;
					case 1:
						my_set_gc_clip_mask(sister,
							(NORMAL_CLOCK_EAST_X), (NORMAL_CLOCK_EAST_Y));
						gdk_gc_set_clip_origin(sister->tileset_gc,
							(x*TILE_SIZE), (y*TILE_SIZE));
						gdk_draw_pixmap(
							sister->factory_tile_xpm, sister->tileset_gc,
							sister->tileset_xpm,
							NORMAL_CLOCK_EAST_X, NORMAL_CLOCK_EAST_Y,
							(x*TILE_SIZE), (y*TILE_SIZE), TILE_SIZE, TILE_SIZE);
						break;
					case 2:
						my_set_gc_clip_mask(sister,
							(NORMAL_CLOCK_SOUTH_X), (NORMAL_CLOCK_SOUTH_Y));
						gdk_gc_set_clip_origin(sister->tileset_gc,
							(x*TILE_SIZE), (y*TILE_SIZE));
						gdk_draw_pixmap(
							sister->factory_tile_xpm, sister->tileset_gc,
							sister->tileset_xpm,
							NORMAL_CLOCK_SOUTH_X, NORMAL_CLOCK_SOUTH_Y,
							(x*TILE_SIZE), (y*TILE_SIZE), TILE_SIZE, TILE_SIZE);
						break;
					case 3:
						my_set_gc_clip_mask(sister,
							(NORMAL_CLOCK_WEST_X), (NORMAL_CLOCK_WEST_Y));
						gdk_gc_set_clip_origin(sister->tileset_gc,
							(x*TILE_SIZE), (y*TILE_SIZE));
						gdk_draw_pixmap(
							sister->factory_tile_xpm, sister->tileset_gc,
							sister->tileset_xpm,
							NORMAL_CLOCK_WEST_X, NORMAL_CLOCK_WEST_Y,
							(x*TILE_SIZE), (y*TILE_SIZE), TILE_SIZE, TILE_SIZE);
						break;
					case 4:
						my_set_gc_clip_mask(sister,
							(NORMAL_CCLOCK_NORTH_X), (NORMAL_CCLOCK_NORTH_Y));
						gdk_gc_set_clip_origin(sister->tileset_gc,
							(x*TILE_SIZE), (y*TILE_SIZE));
						gdk_draw_pixmap(
							sister->factory_tile_xpm, sister->tileset_gc,
							sister->tileset_xpm,
							NORMAL_CCLOCK_NORTH_X, NORMAL_CCLOCK_NORTH_Y,
							(x*TILE_SIZE), (y*TILE_SIZE), TILE_SIZE, TILE_SIZE);
						break;
					case 5:
						my_set_gc_clip_mask(sister,
							(NORMAL_CCLOCK_EAST_X), (NORMAL_CCLOCK_EAST_Y));
						gdk_gc_set_clip_origin(sister->tileset_gc,
							(x*TILE_SIZE), (y*TILE_SIZE));
						gdk_draw_pixmap(
							sister->factory_tile_xpm, sister->tileset_gc,
							sister->tileset_xpm,
							NORMAL_CCLOCK_EAST_X, NORMAL_CCLOCK_EAST_Y,
							(x*TILE_SIZE), (y*TILE_SIZE), TILE_SIZE, TILE_SIZE);
						break;
					case 6:
						my_set_gc_clip_mask(sister,
							(NORMAL_CCLOCK_SOUTH_X), (NORMAL_CCLOCK_SOUTH_Y));
						gdk_gc_set_clip_origin(sister->tileset_gc,
							(x*TILE_SIZE), (y*TILE_SIZE));
						gdk_draw_pixmap(
							sister->factory_tile_xpm, sister->tileset_gc,
							sister->tileset_xpm,
							NORMAL_CCLOCK_SOUTH_X, NORMAL_CCLOCK_SOUTH_Y,
							(x*TILE_SIZE), (y*TILE_SIZE), TILE_SIZE, TILE_SIZE);
						break;
					case 7:
						my_set_gc_clip_mask(sister,
							(NORMAL_CCLOCK_WEST_X), (NORMAL_CCLOCK_WEST_Y));
						gdk_gc_set_clip_origin(sister->tileset_gc,
							(x*TILE_SIZE), (y*TILE_SIZE));
						gdk_draw_pixmap(
							sister->factory_tile_xpm, sister->tileset_gc,
							sister->tileset_xpm,
							NORMAL_CCLOCK_WEST_X, NORMAL_CCLOCK_WEST_Y,
							(x*TILE_SIZE), (y*TILE_SIZE), TILE_SIZE, TILE_SIZE);
						break;
				}
			}
			break;
		}
	}
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]