#ifdef USE_GL /* whole file */
+#include <stdlib.h>
#include <ctype.h>
#include <GL/glu.h>
static void
print_title_string (ModeInfo *mi, const char *string,
- GLfloat x, GLfloat y, GLfloat line_height)
+ GLfloat x, GLfloat y, XFontStruct *font)
{
molecule_configuration *mc = &mcs[MI_SCREEN(mi)];
-
+ GLfloat line_height = font->ascent + font->descent;
+ GLfloat sub_shift = (line_height * 0.3);
+
y -= line_height;
glPushAttrib (GL_TRANSFORM_BIT | /* for matrix contents */
glPushMatrix();
{
int i;
+ int x2 = x;
+ Bool sub_p = False;
glLoadIdentity();
gluOrtho2D (0, mi->xgwa.width, 0, mi->xgwa.height);
{
char c = string[i];
if (c == '\n')
- glRasterPos2f (x, (y -= line_height));
+ {
+ glRasterPos2f (x, (y -= line_height));
+ x2 = x;
+ }
+ else if (c == '(' && (isdigit (string[i+1])))
+ {
+ sub_p = True;
+ glRasterPos2f (x2, (y -= sub_shift));
+ }
+ else if (c == ')' && sub_p)
+ {
+ sub_p = False;
+ glRasterPos2f (x2, (y += sub_shift));
+ }
else
- glCallList (mc->font2_dlist + (int)(c));
+ {
+ glCallList (mc->font2_dlist + (int)(c));
+ x2 += (font->per_char
+ ? font->per_char[c - font->min_char_or_byte2].width
+ : font->min_bounds.width);
+ }
}
}
glPopMatrix();
if (do_titles && m->label && *m->label)
print_title_string (mi, m->label,
10, mi->xgwa.height - 10,
- mc->xfont2->ascent + mc->xfont2->descent);
+ mc->xfont2);
}
}
+typedef struct { char *atom; int count; } atom_and_count;
+
+/* When listing the components of a molecule, the convention is to put the
+ carbon atoms first, the hydrogen atoms second, and the other atom types
+ sorted alphabetically after that (although for some molecules, the usual
+ order is different: we special-case a few of those.)
+ */
+static int
+cmp_atoms (const void *aa, const void *bb)
+{
+ const atom_and_count *a = (atom_and_count *) aa;
+ const atom_and_count *b = (atom_and_count *) bb;
+ if (!a->atom) return 1;
+ if (!b->atom) return -1;
+ if (!strcmp(a->atom, "C")) return -1;
+ if (!strcmp(b->atom, "C")) return 1;
+ if (!strcmp(a->atom, "H")) return -1;
+ if (!strcmp(b->atom, "H")) return 1;
+ return strcmp (a->atom, b->atom);
+}
+
+static void special_case_formula (char *f);
+
static void
generate_molecule_formula (molecule *m)
{
char *buf = (char *) malloc (m->natoms * 10);
char *s = buf;
int i;
- struct { char *atom; int count; } counts[200];
+ atom_and_count counts[200];
memset (counts, 0, sizeof(counts));
*s = 0;
for (i = 0; i < m->natoms; i++)
counts[j].count++;
}
+ i = 0;
+ while (counts[i].atom) i++;
+ qsort (counts, i, sizeof(*counts), cmp_atoms);
+
i = 0;
while (counts[i].atom)
{
i++;
}
+ special_case_formula (buf);
+
if (!m->label) m->label = strdup("");
s = (char *) malloc (strlen (m->label) + strlen (buf) + 2);
strcpy (s, m->label);
m->label = s;
}
+/* thanks to Rene Uittenbogaard <ruittenb@wish.nl> */
+static void
+special_case_formula (char *f)
+{
+ if (!strcmp(f, "H(2)Be")) strcpy(f, "BeH(2)");
+ else if (!strcmp(f, "H(3)B")) strcpy(f, "BH(3)");
+ else if (!strcmp(f, "H(3)N")) strcpy(f, "NH(3)");
+ else if (!strcmp(f, "CHN")) strcpy(f, "HCN");
+ else if (!strcmp(f, "CKN")) strcpy(f, "KCN");
+ else if (!strcmp(f, "H(4)N(2)")) strcpy(f, "N(2)H(4)");
+ else if (!strcmp(f, "Cl(3)P")) strcpy(f, "PCl(3)");
+ else if (!strcmp(f, "Cl(5)P")) strcpy(f, "PCl(5)");
+}
+
+
static void
insert_vertical_whitespace (char *string)
{
static void
gl_init (ModeInfo *mi)
{
- static GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0};
+ static GLfloat pos[4] = {1.0, 0.4, 0.9, 0.0};
+ static GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0};
+ static GLfloat dif[4] = {0.8, 0.8, 0.8, 1.0};
+ static GLfloat spc[4] = {1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
orig_do_labels = do_labels;
orig_do_bonds = do_bonds;
print_title_string (mi, s,
mi->xgwa.width - (string_width (mc->xfont2, s) + 40),
10 + mc->xfont2->ascent + mc->xfont2->descent,
- mc->xfont2->ascent + mc->xfont2->descent);
+ mc->xfont2);
glFinish();
glXSwapBuffers(MI_DISPLAY(mi), MI_WINDOW(mi));
}