File: draw_seahorse.c

package info (click to toggle)
garlic 1.6-1
  • links: PTS, VCS
  • area: main
  • in suites: lenny, squeeze
  • size: 4,440 kB
  • ctags: 1,403
  • sloc: ansic: 52,465; makefile: 1,133
file content (278 lines) | stat: -rw-r--r-- 7,808 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/* Copyright (C) 2001-2003 Damir Zucic */

/*=============================================================================

				draw_seahorse.c

Purpose:
	Draw the seahorse in the middle of the representative bond. Write
	a small hint to the top right corner of the main window.

Input:
	(1) Pointer to MolComplexS structure.
	(2) Pointer to RuntimeS structure.
	(3) Pointer to ConfigS structure.
	(4) Pointer to GUIS structure.
	(5) Pointer to NearestAtomS structure.
	(6) The number of pixels in the main window free area.
	(7) The refreshI index.

Output:
	(1) Seahorse drawn to the main pixmap.
	(2) Return value.

Return value:
	(1) Positive on success.
	(2) Negative on failure.

=============================================================================*/

#include <stdio.h>

#include <string.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>

#include "defines.h"
#include "typedefs.h"
#include "seahorse.xpm"

/*======function prototypes:=================================================*/

int		ParseColor_ (RGBS *, unsigned long *, GUIS *, char *, char *);

/*======draw seahorse:=======================================================*/

int DrawSeahorse_ (MolComplexS *mol_complexSP,
		   RuntimeS *runtimeSP, ConfigS *configSP, GUIS *guiSP,
		   NearestAtomS *nearest_atomSP, size_t pixelsN,
		   unsigned int refreshI)
{
static int		called_beforeF;
int			imageI, imagesN;
int			left_edge[2], right_edge[2];
int			colorsN = 10, colorI;
int			stringI;
MolComplexS		*default_mol_complexSP;
char			*color_stringP;
static RGBS		rgbS;
static unsigned long	colorIDA[10];
size_t			atomsN, atom1I, atom2I;
AtomS			*atom1SP, *atom2SP;
int			screen_x0, screen_y0, screen_x, screen_y;
double			z;
int			width = 80, height = 143, columnI, rowI;
int			current_char;
size_t			pixelI;
NearestAtomS		*curr_pixelSP;
int			edit_modeI;
char			stringA[SHORTSTRINGSIZE];
int			text_width;
unsigned int		hint_width, hint_height;

/*------draw the seahorse:---------------------------------------------------*/

/* Number of images: */
if (configSP->stereoF) imagesN = 2;
else imagesN = 1;

/* Left and right image edge (in stereo mode there are two images): */
left_edge[0]  = configSP->image_screen_x0[0];
right_edge[0] = configSP->image_screen_x1[0];
left_edge[1]  = configSP->image_screen_x0[1];
right_edge[1] = configSP->image_screen_x1[1];

/* Prepare colors if this function is called for the first time: */
if (!called_beforeF)
	{
	for (colorI = 0; colorI < colorsN; colorI++)
		{
		/* The third  string  specifies  the first */
		/* color. The index of this string is two: */
		stringI = colorI + 2;

		/* The color string follows the substring "c ": */
		color_stringP = strstr (seahorse_xpm[stringI], "c ") + 2;

		/* Parse color: */
		ParseColor_ (&rgbS, &colorIDA[colorI],
			     guiSP, color_stringP, "white");
		}
	}

/* Set the flag which signals that this function was used at least once: */
called_beforeF = 1;

/* Copy colors to GC's: */
for (colorI = 0; colorI < colorsN; colorI++)
	{
	XSetForeground (guiSP->displaySP, guiSP->theGCA[colorI],
			colorIDA[colorI]);
	}

/* Pointer to default macromolecular complex: */
default_mol_complexSP = mol_complexSP + runtimeSP->default_complexI;

/* Check the array indices of the representative atoms: */
atomsN = default_mol_complexSP->atomsN;
atom1I = runtimeSP->atom1_arrayI;
atom2I = runtimeSP->atom2_arrayI;
if (atom1I >= atomsN) return -1;
if (atom2I >= atomsN) return -2;
if (atom1I == atom2I) return -3;

/* Prepare the pointers to representative atoms: */
atom1SP = default_mol_complexSP->atomSP + atom1I;
atom2SP = default_mol_complexSP->atomSP + atom2I;

/* Draw one (mono) or two pixels (stereo): */
for (imageI = 0; imageI < imagesN; imageI++)
	{
	/* Prepare the screen coordinates for the seahorse: */
	screen_x0 = (atom1SP->raw_atomS.screen_x[imageI] +
		     atom2SP->raw_atomS.screen_x[imageI]) / 2;
	screen_y0 = (atom1SP->raw_atomS.screen_y +
		     atom2SP->raw_atomS.screen_y) / 2;

	/* Prepare the z coordinate: */
	z = (atom1SP->raw_atomS.z[imageI] + atom2SP->raw_atomS.z[imageI]) / 2;

	/* Now scan the pixmap. */

	/* Vertical scan (top to bottom): */
	for (rowI = 0; rowI < height; rowI++)
		{
		/* Prepare the string index: */
		stringI = rowI + 12;

		/* Horizontal scan (left to right): */
		for (columnI = 0; columnI < width; columnI++)
			{
			/* Prepare the current character: */
			current_char = seahorse_xpm[stringI][columnI];

			/* Check is it this pixel transparent: */
			if (current_char == ' ') continue;

			/* Prepare the color index: */
			switch (current_char)
				{
				case '.':
					colorI = 0;
					break;
				case '+':
					colorI = 1;
					break;
				case '@':
					colorI = 2;
					break;
				case '#':
					colorI = 3;
					break;
				case '$':
					colorI = 4;
					break;
				case '%':
					colorI = 5;
					break;
				case '&':
					colorI = 6;
					break;
				case '*':
					colorI = 7;
					break;
				case '=':
					colorI = 8;
					break;
				case '-':
					colorI = 9;
					break;
				default:
					;
				}

			/* Prepare and check the screen coordinates: */
			screen_x = screen_x0 + columnI -  11;
			screen_y = screen_y0 + rowI    - 143;
			if (screen_x <  left_edge[imageI])  break;
			if (screen_x >= right_edge[imageI]) break;

			/* Prepare index  to the array */
			/* of NearestAtomS structures: */
			pixelI = guiSP->main_win_free_area_width * screen_y +
				 screen_x;

			/* Check the pixel index: */
			if (pixelI >= pixelsN) break;

			/* Pointer to  NearestAtomS struct. */
			/* assigned to current coordinates: */
			curr_pixelSP = nearest_atomSP + pixelI;

			/* Check was  this pixel used  already in */
			/* this drawing step;  if it was, compare */
			/* the z value of the current atom with z */
			/* value previously stored to this pixel: */
			if (refreshI == curr_pixelSP->last_refreshI)
				{
				if (z >= curr_pixelSP->z) continue;
				}

			/* Draw this pixel: */
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[colorI],
				    screen_x, screen_y);
			}
		}
	}   /* imageI loop */

/*------draw the hint:-------------------------------------------------------*/

/* Copy the edit mode index: */
edit_modeI = runtimeSP->edit_modeI;

/* If editing PHI, PSI, OMEGA or BOND: */
if ((edit_modeI == 2) || (edit_modeI == 3) ||
    (edit_modeI == 4) || (edit_modeI == 6))
	{
	strcpy (stringA, "Use keys 7 and 9 on numeric keypad");
	}

/* If editing MAIN or SIDE chain: */
else if ((edit_modeI == 5) || (edit_modeI == 7))
	{
	strcpy (stringA, "Use 2, 4, 6 and 8 on numeric keypad");
	}

/* Draw the red filled rectangle and the yellow text inside this rectangle: */
text_width = XTextWidth (guiSP->main_winS.fontSP, stringA, strlen (stringA));
screen_x0 = guiSP->main_win_free_area_width - text_width -
	    guiSP->main_winS.half_font_height -
	    2 * guiSP->main_winS.border_width;
screen_y0 = guiSP->main_winS.font_height + 9;
hint_width  = text_width + guiSP->main_winS.half_font_height;
hint_height = guiSP->main_winS.font_height + 4;
XSetForeground (guiSP->displaySP, guiSP->theGCA[0], guiSP->red_colorID);
XFillRectangle (guiSP->displaySP,
		guiSP->main_hidden_pixmapID,
		guiSP->theGCA[0],
		screen_x0, screen_y0, hint_width, hint_height);
XSetForeground (guiSP->displaySP, guiSP->theGCA[0], guiSP->yellow_colorID);
screen_x0 += guiSP->main_winS.quarter_font_height;
screen_y0 += guiSP->main_winS.font_height - 2;
XDrawString (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[0],
             screen_x0, screen_y0, stringA, strlen (stringA));

/*---------------------------------------------------------------------------*/

/* Return positive value on success: */
return 1;
}

/*===========================================================================*/