/*
* functions for in and output
*/
#include "ct1.h"
#include "inout.h"
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include "gdk/gdkprivate.h"
#include <locale.h>
#ifdef EMF
#include <emf.h>
#endif
#ifdef GTK2
extern PangoFontDescription *font[7], *smallfont[7], *symbfont[7],
*ssymbfont[7], *slfont[7],
*boldfont[7], *textfont[7];
#else
extern GdkFont *font[7],*smallfont[7],*symbfont[7],*boldfont[7],*slfont[7];
#endif
static char babeloutp[4];
int
save_mol (FILE * fp, int partial)
/* saves the current structure to a file in native chemtool format */
{
int d;
int w, h;
struct data *hp_b;
struct dc *hp_a;
struct spline *hp_sp;
int mbonds = 0, mlabels = 0, msplines = 0;
#ifdef GTK2
setlocale (LC_NUMERIC,"C");
#endif
/* get true extents of drawing*/
w = 0;
h = 0;
hp_b = da_root.next;
for (d = 0; d < hp->n; d++)
{
if (partial == 1 && hp_b->smarked == 0 && hp_b->tmarked == 0)
{
hp_b = hp_b->next;
}
else
{
if (partial)
mbonds++;
w = MAX (w, hp_b->x);
w = MAX (w, hp_b->tx);
h = MAX (h, hp_b->y);
h = MAX (h, hp_b->ty);
hp_b = hp_b->next;
}
}
hp_a = dac_root.next;
for (d = 0; d < hp->nc; d++)
{
if (partial && !hp_a->marked)
{
hp_a = hp_a->next;
}
else
{
if (partial)
mlabels++;
w = MAX (w, hp_a->x);
h = MAX (h, hp_a->y);
hp_a = hp_a->next;
}
}
hp_sp = sp_root.next;
for (d = 0; d < hp->nsp; d++)
{
if (partial && !hp_sp->marked)
{
hp_sp = hp_sp->next;
}
else
{
if (partial)
msplines++;
w = MAX (w, hp_sp->x0);
h = MAX (h, hp_sp->y0);
w = MAX (w, hp_sp->x1);
h = MAX (h, hp_sp->y1);
w = MAX (w, hp_sp->x2);
h = MAX (h, hp_sp->y2);
w = MAX (w, hp_sp->x3);
h = MAX (h, hp_sp->y3);
hp_sp = hp_sp->next;
}
}
w = (int) (w * 1.1);
h = (int) (h * 1.1);
fprintf (fp, "Chemtool Version " VERSION "\n");
fprintf (fp, "geometry %i %i\n", w, h);
hp_b = da_root.next;
if (partial)
fprintf (fp, "bonds %i\n", mbonds);
else
fprintf (fp, "bonds %i\n", hp->n);
for (d = 0; d < hp->n; d++)
{
if (partial && !hp_b->smarked && !hp_b->tmarked)
{
hp_b = hp_b->next;
}
else
{
/* if (hp_b->decoration == 1) {*/
fprintf (fp, "%i %i %i %i %i %i %i\n",
hp_b->x, hp_b->y, hp_b->tx, hp_b->ty, hp_b->bond, hp_b->decoration,hp_b->color);
/* }else{
fprintf (fp, "%i %i %i %i %i\n",
hp_b->x, hp_b->y, hp_b->tx, hp_b->ty, hp_b->bond);
}*/
hp_b = hp_b->next;
}
}
hp_a = dac_root.next;
if (partial)
fprintf (fp, "atoms %i\n", mlabels);
else
fprintf (fp, "atoms %i\n", hp->nc);
for (d = 0; d < hp->nc; d++)
{
if (partial && !hp_a->marked)
{
hp_a = hp_a->next;
}
else
{
fprintf (fp, "%i %i %s %i %i %i %i\n",
hp_a->x, hp_a->y, hp_a->c, hp_a->direct, hp_a->color,hp_a->font,hp_a->size);
hp_a = hp_a->next;
}
}
hp_sp = sp_root.next;
if (partial)
fprintf (fp, "splines %i\n", msplines);
else
fprintf (fp, "splines %i\n", hp->nsp);
for (d = 0; d < hp->nsp; d++)
{
if (partial && !hp_sp->marked)
{
hp_sp = hp_sp->next;
}
else
{
fprintf (fp,
"%i %i %i %i %i %i %i %i %i %i\n",
hp_sp->x0, hp_sp->y0, hp_sp->x1, hp_sp->y1, hp_sp->x2,
hp_sp->y2, hp_sp->x3, hp_sp->y3, hp_sp->type,hp_sp->color);
hp_sp = hp_sp->next;
}
}
if (addflag==1) {
fprintf (fp,"attach %i %i\n",refx,refy);
}
/* fclose (fp);*/
return (0);
}
int
load_mol (char *filename)
/* loads a chemtool file, checking for correct header */
{
int d, n, i;
int x, y, tx, ty, x2, y2, x3, y3, b, deco, col, fnt, siz;
int res;
char str[255], str1[255];
FILE *fp;
char version[10];
#ifdef GTK2
setlocale (LC_NUMERIC,"C");
#endif
if ((fp = fopen (filename, "r")) == NULL)
return (1);
res = fscanf (fp, "%s %s %s", str, str1, version);
if (res != 3)
{
fclose (fp);
return (2);
}
if (strcmp (str, "Chemtool") || strcmp (str1, "Version"))
{
fclose (fp);
return (2);
}
clear_data ();
res = fscanf (fp, "%s %i %i", str, &x, &y);
if (res == 3 && !strcmp (str, "geometry"))
{
head.width = MAX (head.width, x);
head.height = MAX (head.height, y);
}
res = fscanf (fp, "%s %i", str, &n);
if (res == 2 && (!strcmp (str, "bonds") || !strcmp (str, "bounds")))
{ /* typo in versions < 1.1.2 */
res = fgetc(fp);
if (res == EOF) {
fclose (fp);
return (2);
}
for (d = 0; d < n; d++)
{
if (!fgets(str,80,fp)) {
fclose (fp);
return (2);
}
i=sscanf (str, "%i %i %i %i %i %i %i", &x, &y, &tx, &ty, &b, &deco, &col);
if (i == 7)
add_struct (x, y, tx, ty, b, 0, 0, deco, col);
else if (i == 6)
add_struct (x, y, tx, ty, b, 0, 0, deco, 0);
else
add_struct (x, y, tx, ty, b, 0, 0, 0, 0);
}
}
res = fscanf (fp, "%s %i", str, &n);
if (res == 2 && !strcmp (str, "atoms"))
{
res = fgetc(fp);
if (res == EOF) {
fclose (fp);
return (2);
}
for (d = 0; d < n; d++)
{
if (!fgets(str,33+MAXCL,fp)){
fclose (fp);
return (2);
}
i=sscanf (str, "%i %i %s %i %i %i %i", &x, &y, str, &b, &col, &fnt, &siz);
if (i==7)
add_char (x, y, str, b, 0, col, fnt, siz);
else if (i == 6)
add_char (x, y, str, b, 0, col, fnt, 3);
else if (i<5)
add_char (x, y, str, b, 0, 0, 0, 3);
else
add_char (x, y, str, b, 0, col, 0, 3);
}
}
res = fscanf (fp, "%s %i", str, &n);
if (res == 2 && !strcmp (str, "splines"))
{
if (n > 0) {
res = fgetc(fp);
if (res == EOF) {
fclose (fp);
return (2);
}
for (d = 0; d < n; d++)
{
if (!fgets(str,80,fp)){
fclose (fp);
return (2);
}
i=sscanf (str, "%i %i %i %i %i %i %i %i %i %i", &x, &y, &tx, &ty,
&x2, &y2, &x3, &y3, &b,&col);
if (i<10)
add_spline (x, y, tx, ty, x2, y2, x3, y3, b, 0, 0);
else
add_spline (x, y, tx, ty, x2, y2, x3, y3, b, 0, col);
}
}
}
res = fscanf (fp, "%s %i %i", str, &x,&y);
if (res == 3 && !strcmp(str,"attach")){
refx=x;
refy=y;
addflag=1;
}
fclose (fp);
if (atof (version) > atof (VERSION))
return (3);
return (0);
}
int
load_preview (char *filename)
/* loads a chemtool file, checking for correct header */
{
int d, n;
int x, y, tx, ty, x2, y2, x3, y3, b, col, fnt;
int res;
float savedfactor;
char str[255], str1[255];
FILE *fp;
char version[10];
GdkRectangle update_rect;
int fontsize;
#ifdef GTK2
setlocale (LC_NUMERIC,"C");
#endif
if ((fp = fopen (filename, "r")) == NULL)
return (1);
savedfactor = size_factor;
res = fscanf (fp, "%s %s %s", str, str1, version);
if (res != 3)
{
fclose (fp);
return (2);
}
if (strcmp (str, "Chemtool") || strcmp (str1, "Version"))
{
fclose (fp);
return (2);
}
res = fscanf (fp, "%s %i %i", str, &x, &y);
if (res != 3)
{
fclose (fp);
return (2);
}
size_factor = MIN (200. / x, 100. / y);
res = fscanf (fp, "%s %i", str, &n);
if (res == 2 && (!strcmp (str, "bonds") || !strcmp (str, "bounds")))
{ /* typo in versions < 1.1.2 */
res = fgetc(fp);
if (res == EOF) {
fclose(fp);
return(2);
}
for (d = 0; d < n; d++)
{
if (!fgets(str,80,fp)) {
fclose(fp);
return(2);
}
res = sscanf (str, "%i %i %i %i %i %i", &x, &y, &tx, &ty, &b, &col);
if (res == 6) draw_preview_bonds (x, y, tx, ty, b);
}
}
res = fscanf (fp, "%s %i", str, &n);
if (res == 2 && !strcmp (str, "atoms"))
{
if (size_factor < 0.15)
fontsize=0;
else
fontsize=1;
res = fgetc(fp);
if (res == EOF) {
fclose(fp);
return(2);
}
for (d = 0; d < n; d++)
{
if (!fgets(str,33+MAXCL,fp)){
fclose(fp);
return(2);
}
res = sscanf (str, "%i %i %s %i %i %i", &x, &y, str, &b, &col,&fnt);
if (res >= 4) Drawstring (x, y, str, b, 0,0,0,1,fontsize);
}
}
res = fscanf (fp, "%s %i", str, &n);
if (res == 2 && !strcmp (str, "splines"))
{
if (n>0) {
res = fgetc(fp);
if (res == EOF) {
fclose(fp);
return(2);
}
for (d = 0; d < n; d++)
{
if (!fgets(str,80,fp)){
fclose(fp);
return(2);
}
res = sscanf (str, "%i %i %i %i %i %i %i %i %i %i", &x, &y, &tx, &ty,
&x2, &y2, &x3, &y3, &b,&col);
if (res >= 9) Drawspline (x, y, tx, ty, x2, y2, x3, y3, b, 0,0);
}
}
}
res = fscanf (fp, "%s %i %i", str, &xref,&yref);
if (res == 3 && !strcmp(str,"attach")){
draw_preview_bonds(xref-4,yref-4,xref+4,yref+4,0);
draw_preview_bonds(xref-4,yref+4,xref+4,yref-4,0);
}
gdk_draw_pixmap (preview_area->window,
drawing_area->style->
fg_gc[GTK_WIDGET_STATE (drawing_area)], picture, 0, 0, 0,
0, 200, 100);
update_rect.x = 0;
update_rect.y = 0;
update_rect.width = 200;
update_rect.height = 100;
gtk_widget_draw ((GtkWidget *) preview_area, &update_rect);
size_factor = savedfactor;
fclose (fp);
return (0);
}
int
add_mol (char *filename)
/* loads a chemtool file and adds its contents at a given position */
{
int d, n, i;
int x, y, tx, ty, x2, y2, x3, y3, b, deco, col, fnt, siz;
int res;
int xdiff = 0, ydiff = 0;
char str[255];
FILE *fp;
char version[10];
#ifdef GTK2
setlocale (LC_NUMERIC,"C");
#endif
if ((fp = fopen (filename, "r")) == NULL)
return (1);
res = fscanf (fp, "%s %s %s", str, str, version);
if (res != 3 || atof (version) > atof (VERSION))
{
fclose (fp);
return (2);
}
Unmark_all();
res = fscanf (fp, "%s %i %i", str, &x, &y);
if (res == 3 && !strcmp (str, "geometry"))
{
head.width += x;
mark.w = x;
head.height += y;
mark.h = y;
mark.flag = 1;
}
res = fscanf (fp, "%s %i", str, &n);
if (res == 2 && (!strcmp (str, "bonds") || !strcmp (str, "bounds")))
{
res = fgetc(fp);
if (res == EOF) {
fclose(fp);
return(2);
}
for (d = 0; d < n; d++)
{
if (!fgets(str,80,fp)){
fclose(fp);
return(2);
}
i= sscanf (str, "%i %i %i %i %i %i %i", &x, &y, &tx, &ty, &b, &deco, &col);
if (i == 7)
add_struct (x, y, tx, ty, b, 1, 1, deco, col);
else if (i == 6)
add_struct (x, y, tx, ty, b, 1, 1, deco, 0);
else
add_struct (x, y, tx, ty, b, 1, 1, 0, 0);
}
}
res = fscanf (fp, "%s %i", str, &n);
if (res == 2 && !strcmp (str, "atoms"))
{
res = fgetc(fp);
if (res == EOF) {
fclose(fp);
return(2);
}
for (d = 0; d < n; d++)
{
if (!fgets(str,33+MAXCL,fp))
{
fclose(fp);
return(2);
}
i=sscanf (str, "%i %i %s %i %i %i %i", &x, &y, str, &b, &col, &fnt, &siz);
x = x + xdiff;
y = y + ydiff;
if (i==7)
add_char (x, y, str, b, 1, col, fnt, siz);
else if (i==6)
add_char (x, y, str, b, 1, col, fnt, 3);
else if (i<5)
add_char (x, y, str, b, 1, 0, 0, 3);
else
add_char (x, y, str, b, 1, col, 0, 3);
}
}
res = fscanf (fp, "%s %i ", str, &n);
if (res == 2 && !strcmp (str, "splines"))
{
if (n>0) {
res = fgetc(fp);
if (res == EOF) {
fclose(fp);
return(2);
}
for (d = 0; d < n; d++)
{
if (!fgets(str,80,fp)) {
fclose(fp);
return(2);
}
i=sscanf (str, "%i %i %i %i %i %i %i %i %i %i", &x, &y, &tx, &ty,
&x2, &y2, &x3, &y3, &b,&col);
if (i<10)
add_spline (x, y, tx, ty, x2, y2, x3, y3, b, 0,0);
else
add_spline (x, y, tx, ty, x2, y2, x3, y3, b, 0,col);
}
}
}
res = fscanf (fp, "%s %i %i", str, &xref,&yref);
if (res == 3 && !strcmp (str, "attach")) {
xref=refx-xref;
yref=refy-yref;
partial_move (0,0,0,0,xref,yref);
}
fclose(fp);
return (0);
}
int
import_pdb (char *filename)
{
char line[255];
int i, j,m;
int res;
int connect = 0;
double dist;
double pdbxmin = 100000., pdbxmax = -100000., pdbymin = 1000000., pdbymax =
-100000., pdbzmin = 100000., pdbzmax = -100000.;
char code[8];
float pdbfactor = 50.;
int pdboffset = 500;
int at0, con[6];
FILE *fp;
int *atnum=NULL;
int found=0;
#ifdef GTK2
setlocale (LC_NUMERIC,"C");
#endif
if ((fp = fopen (filename, "r")) == NULL)
return (1);
/* skip to the first atom or heteroatom record */
for (i = 0;; i++)
{
if (fgets (line, (int)sizeof (line), fp) == NULL)
{
fclose (fp);
return (1);
}
if (!strncmp (line, "END", 3) || feof (fp))
{ /*premature end */
fclose (fp);
return (1);
}
if (!strncmp (line, "ATOM", 4) || !strncmp (line, "HETATM", 6))
break;
}
clear_data ();
FreePix();
i = -1;
/* read in atom block data */
while (!feof (fp))
{
if (!strncmp (line, "ATOM", 4) || !strncmp (line, "HETATM", 6))
{
i++;
pdbx = realloc (pdbx, (i + 1) * sizeof (double));
pdby = realloc (pdby, (i + 1) * sizeof (double));
pdbz = realloc (pdbz, (i + 1) * sizeof (double));
atjust = realloc (atjust, (i + 1) * sizeof (short));
atcode = realloc (atcode, (i + 1) * sizeof (char *));
atnum = realloc (atnum,(i+1)*sizeof(int));
atcode[i] = malloc (9 * sizeof (char));
atjust[i] = 0;
res = sscanf (line, "%s %d %s %*6c %*6c %lf %lf %lf", code, &atnum[i],atcode[i],
&pdbx[i], &pdby[i], &pdbz[i]);
if (res < 6) {
fclose (fp);
return (1);
}
pdbxmin = MIN (pdbxmin, pdbx[i]);
pdbxmax = MAX (pdbxmax, pdbx[i]);
pdbymin = MIN (pdbymin, pdby[i]);
pdbymax = MAX (pdbymax, pdby[i]);
pdbzmin = MIN (pdbzmin, pdbz[i]);
pdbzmax = MAX (pdbzmax, pdbz[i]);
}
else
break;
if (!fgets (line, (int)sizeof (line), fp)) break;
}
pdbn = i;
nbonds = -1;
while (!feof (fp))
{
if (!strncmp (line, "CONECT", 6))
{
connect = 1;
con[0] = con[1] = con[2] = con[3] = con[4] = con[5] = 0;
res = sscanf (line, "%*s %d %d %d %d %d %d %d", &at0, &con[0], &con[1], &con[2],
&con[3],&con[4],&con[5]);
for (i = 0; i < res; i++)
{
if (con[i] > 0)
{
found=0;
for (m=0;m<=pdbn;m++){
if (atnum[m]==at0) {
at0=m+1;
found=1;
break;
}
}
for (m=0;m<=pdbn;m++){
if (atnum[m]==con[i]) {
con[i]=m+1;
found++;
break;
}
}
if (found==2){
nbonds++;
bondfrom = realloc (bondfrom, (nbonds + 1) * sizeof (int));
bondto = realloc (bondto, (nbonds + 1) * sizeof (int));
bondtype =
realloc (bondtype, (nbonds + 1) * sizeof (short));
bondfrom[nbonds] = at0 - 1;
bondto[nbonds] = con[i] - 1;
bondtype[nbonds] = 0;
dist =
(pdbx[at0 - 1] - pdbx[con[i] - 1]) * (pdbx[at0 - 1] -
pdbx[con[i] - 1]) +
(pdby[at0 - 1] - pdby[con[i] - 1]) * (pdby[at0 - 1] -
pdby[con[i] - 1]) +
(pdbz[at0 - 1] - pdbz[con[i] - 1]) * (pdbz[at0 - 1] -
pdbz[con[i] - 1]);
if (dist < 1.45 * 1.45)
{
if (!strncmp (atcode[at0 - 1], "C", 1)
&& !strncmp (atcode[con[i] - 1], "C", 1))
bondtype[nbonds] = 4;
}
/* fprintf(stderr,"CONECTED %d %d (%f)\n",at0,con[i],dist);*/
/* Drawline ((int) (pdbx[at0 - 1] * pdbfactor + pdboffset),
(int) (pdby[at0 - 1] * pdbfactor + pdboffset),
(int) (pdbx[con[i] - 1] * pdbfactor + pdboffset),
(int) (pdby[con[i] - 1] * pdbfactor + pdboffset),
1);*/
}
}
}
}
else
{
break;
}
(void)fgets (line, (int)sizeof (line), fp);
}
fclose (fp);
free (atnum);
atnum=NULL;
pdbxcent = (pdbxmax + pdbxmin) / 2.;
pdbycent = (pdbymax + pdbymin) / 2.;
pdbzcent = (pdbzmax + pdbzmin) / 2.;
for (i = 0; i <= pdbn; i++)
{
pdbx[i] = pdbx[i] - pdbxcent;
pdby[i] = pdby[i] - pdbycent;
pdbz[i] = pdbz[i] - pdbzcent;
}
if (connect == 0)
{ /* if no bonds exist, i.e. there were no CONECTs */
for (i = 0; i <= pdbn; i++)
{
for (j = i + 1; j <= pdbn; j++)
{
dist = (pdbx[i] - pdbx[j]) * (pdbx[i] - pdbx[j]) +
(pdby[i] - pdby[j]) * (pdby[i] - pdby[j]) +
(pdbz[i] - pdbz[j]) * (pdbz[i] - pdbz[j]);
if (dist < 1.58 * 1.58)
{
nbonds++;
bondfrom = realloc (bondfrom, (nbonds + 1) * sizeof (int));
bondto = realloc (bondto, (nbonds + 1) * sizeof (int));
bondtype =
realloc (bondtype, (nbonds + 1) * sizeof (short));
bondfrom[nbonds] = i;
bondto[nbonds] = j;
bondtype[nbonds] = 0;
if (dist < 1.45 * 1.45)
{
if (!strncmp (atcode[i], "C", 1)
&& !strncmp (atcode[j], "C", 1))
bondtype[nbonds] = 4;
}
/* Drawline ((int) (pdbx[i] * pdbfactor + pdboffset),
(int) (pdby[i] * pdbfactor + pdboffset),
(int) (pdbx[j] * pdbfactor + pdboffset),
(int) (pdby[j] * pdbfactor + pdboffset), 1);*/
}
}
}
}
/* CopyPlane ();*/
importflag = 1;
importfactor = pdbfactor;
importoffset = pdboffset;
pdbrotate(0,0,0);
return (0);
}
void
pdbrotate (int nx, int ny, int nz)
{
double l, r, s, t, u, v, w, a, b, c, d, e, f, g, h, i;
int ii, j;
double x[3], xx, yy, zz;
int dx, dy;
double ang = 0.;
GdkRectangle update_rect;
if (nz != 2)
{
dy = nx - hp->x;
dx = ny - hp->y;
hp->x = nx;
hp->y = ny;
x[0] = (dx != 0 ? 1. : 0.);
x[1] = (dy != 0 ? 1. : 0.);
x[2] = (nz != 0 ? 1. : 0.);
if (abs (dx) < abs (dy))
{
dx = dy;
x[0] = 0.;
x[1] = 1.;
}
else
{
x[0] = 1.;
x[1] = 0.;
}
ang = (float) dx / 2.;
if (ang < -360.)
ang = ang + 360.;
if (ang > 360.)
ang = ang - 360.;
if (x[2] == 1)
{
x[0] = 0.;
x[1] = 0.;
}
/*fprintf(stderr,"rotate %f %f %f : %f\n",x[0],x[1],x[2],ang);*/
l = sqrt (x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
r = x[0] / l;
s = x[1] / l;
t = x[2] / l;
v = sin (ang * M_PI / 180.);
u = cos (ang * M_PI / 180.);
w = 1.0 - u;
a = u + w * r * r;
b = t * v + w * r * s;
c = -s * v + w * r * t;
d = -t * v + w * s * r;
e = u + w * s * s;
f = r * v + w * s * t;
g = s * v + w * t * r;
h = -r * v + w * t * s;
i = u + w * t * t;
for (j = 0; j <= pdbn; j++)
{
xx = pdbx[j];
yy = pdby[j];
zz = pdbz[j];
pdbx[j] = a * xx + b * yy + c * zz;
pdby[j] = d * xx + e * yy + f * zz;
pdbz[j] = g * xx + h * yy + i * zz;
}
}
FreePix ();
for (ii = 0; ii <= nbonds; ii++)
Drawline ((int) (pdbx[bondfrom[ii]] * importfactor + importoffset),
(int) (pdby[bondfrom[ii]] * importfactor + importoffset),
(int) (pdbx[bondto[ii]] * importfactor + importoffset),
(int) (pdby[bondto[ii]] * importfactor + importoffset), 1, 0);
gdk_draw_pixmap (drawing_area->window,
drawing_area->style->
fg_gc[GTK_WIDGET_STATE (drawing_area)], picture, 0, 0, 0,
0, (gint)drawing_area->allocation.width,
(gint)drawing_area->allocation.height);
update_rect.x = 0;
update_rect.y = 0;
update_rect.width = drawing_area->allocation.width;
update_rect.height = drawing_area->allocation.height;
gtk_widget_draw ((GtkWidget *) drawing_area, &update_rect);
}
void
pdbstore ()
{
int i, j;
char tmpstr[10];
for (i = 0; i <= pdbn; i++)
{
/*
pdbx[i] = (pdbx[i] + pdbxcent) * importfactor + importoffset;
pdby[i] = (pdby[i] + pdbycent) * importfactor + importoffset;
pdbz[i] = (pdbz[i] + pdbzcent) * importfactor + importoffset;
*/
pdbx[i] = pdbx[i] * importfactor + importoffset;
pdby[i] = pdby[i] * importfactor + importoffset;
pdbz[i] = pdbz[i] * importfactor + importoffset;
if (importflag == 1)
{
switch (pdbmode)
{
case 0: /* add all labels */
add_char ((int) (pdbx[i]), (int) (pdby[i]), atcode[i],
atjust[i], 0, 0, 0, zoom_factor);
break;
case 1: /* add all non-H labels */
if (strncmp (atcode[i], "H", 1))
add_char ((int) (pdbx[i]), (int) (pdby[i]), atcode[i],
atjust[i], 0, 0, 0, zoom_factor);
break;
case 3: /* only non-H without numeric identifiers */
if (!strncmp (atcode[i], "H", 1))
break;
/* fall through to case 2 otherwise */
case 2: /* all labels, without the numeric part */
j = (int) strcspn (atcode[i], "1234567890");
strncpy (tmpstr, atcode[i], (size_t)j);
tmpstr[j] = '\0';
add_char ((int) (pdbx[i]), (int) (pdby[i]), tmpstr, atjust[i],
0, 0, 0, zoom_factor);
break;
case 4: /* no labels */
default:
break;
}
}
else
{ /* in MDL import, add all non-C labels */
if (strncmp (atcode[i], "C", 1))
add_char ((int) (pdbx[i]), (int) (pdby[i]), atcode[i], atjust[i],
0,0,0, zoom_factor);
}
}
for (i = 0; i <= nbonds; i++)
add_struct ((int) (pdbx[bondfrom[i]]),
(int) (pdby[bondfrom[i]]),
(int) (pdbx[bondto[i]]),
(int) (pdby[bondto[i]]), (int) bondtype[i], 0, 0, 0, 0);
free (pdbx);
free (pdby);
free (pdbz);
free (bondfrom);
free (bondto);
free (bondtype);
free (atjust);
for (i = 0; i <= pdbn; i++)
free (atcode[i]);
free (atcode);
pdbx = NULL;
pdby = NULL;
pdbz = NULL;
bondfrom = NULL;
bondto = NULL;
bondtype = NULL;
atjust = NULL;
atcode = NULL;
importflag = 0;
pdbn = 0;
FreePix ();
Display_Mol ();
}
int
import_mdl_mol (char *filename, int skip)
/* imports a MDL Molfile structure */
{
/* int x, y, tx, ty;*/ /* the coordinates */
/* int bond = 0; */ /* Chemtool bondstyle */
float mdlfactor = 60.0; /* conversion factor .cht <-> .mol */
int mdloffset = 200;
int text_direct = 0; /* Chemtool text direction */
int d, e; /* dummy variables */
int v3=0;
char line[255];
char prop[41],*cfg;
double pdbxmin = 100000., pdbxmax = -100000., pdbymin = 1000000., pdbymax =
-100000., pdbzmin = 100000., pdbzmax = -100000.;
/* the counts line, see ctfile.pdf for more information */
int a; /* number of atoms */
int b; /* number of bonds */
/* not parsed right now: */
int l; /* number of atoms list */
int f; /* obsolete */
int c; /* chiral flag, 0=not chiral, 1=chiral */
int s; /* number of stext entries */
int x_; /* number of reaction components + 1 */
int r; /* number of reactants */
int p; /* number of products */
int i; /* number of intermediates */
int m; /* number of additional properties,
no longer supported and set to 999 */
char v[6]; /* ctab version, 'v2000' or 'v3000' */
/* end of counts line */
/* the atom block */
/*float xxx, yyy, zzz; */ /* the coordinates of the atom */
char aaa[3]; /* the atomic symbol */
/* not parsed right now: */
int dd; /* mass difference for isotopes */
int ccc; /* charge */
int sss; /* atom stereo parity */
int hhh; /* hydrogen count+1 */
int bbb; /* stereo care box */
int vvv; /* valence */
int HHH; /* H designator, redundant */
int rrr; /* reaction component type */
int iii; /* reaction component number */
int mmm; /* atom-atom mapping number */
int nnn; /* inversion/retention flag */
int eee; /* exact change flag */
/* end atom block */
/* the bond block */
int atom1; /* first atom number */
int atom2; /* second atom number */
int tt; /* bond type */
int ss; /* bond stereo */
int xx; /* not used */
int rr; /* bond topology, 0=eighter, 1=ring, 2=chain */
int cc; /* reaction center status */
/* end bond block */
char label[20]; /* a label defined in the .mol-file */
char aa[4],bb[4];
int res;
FILE *fp;
/*struct dc *hp_a; */
#ifdef GTK2
setlocale (LC_NUMERIC,"C");
#endif
if ((fp = fopen (filename, "r")) == NULL)
return (1);
if (skip >0 ) {
d = 0;
while ( d <skip) {
if (! fgets(line, (int)sizeof(line),fp)) {
fclose(fp);
return(1);
}
if (!strncmp(line,"$$$$",4)) d++;
}
}
/* skip the first three lines (header) */
for (d = 0; d < 3; d++)
{
if (!fgets (line, (int)sizeof (line), fp)) {
fclose(fp);
return(1);
}
}
/* parse the counts-line */
if (!fgets (line, (int)sizeof (line), fp)) {
fclose(fp);
return(1);
}
if (strstr(line,"V3000")) v3=1;
if(v3==1) {
if (!fgets(line,(int)sizeof(line),fp)) {
fclose(fp);
return(1);
}
if (strncmp(line,"M V30 BEGIN CTAB",16)) {
fclose(fp);
return(1);
}
if (!fgets(line,(int)sizeof(line),fp)) {
fclose(fp);
return(1);
}
d = sscanf (line,"M V30 COUNTS %d %d",&a,&b);
if (!fgets(line,(int)sizeof(line),fp)) {
fclose(fp);
return(1);
}
if (strncmp(line,"M V30 BEGIN ATOM",16)) {
fclose(fp);
return(1);
}
} else {
d = sscanf (line, "%c%c%c%c%c%c %i %i %i %i %i %i %i %i %i %s",
&aa[0],&aa[1],&aa[2],&bb[0],&bb[1],&bb[2], &l, &f, &c, &s, &x_, &r, &p, &i, &m, v);
aa[3]='\0';
bb[3]='\0';
sscanf(aa,"%i",&a);
sscanf(bb,"%i",&b);
if (d == 0 || a <= 0 || b < 0 || a > 100000 || b > 100000) {
fclose(fp);
return (1);
}
}
clear_data ();
pdbn = -1;
/* read in atom block data */
for (d = 0; d < a; d++)
{
if (!fgets (line, (int)sizeof (line), fp)) {
fclose(fp);
return(1);
}
pdbn++;
pdbx = realloc (pdbx, (pdbn + 1) * sizeof (double));
pdby = realloc (pdby, (pdbn + 1) * sizeof (double));
pdbz = realloc (pdbz, (pdbn + 1) * sizeof (double));
atjust = realloc (atjust, (pdbn + 1) * sizeof (short));
atcode = realloc (atcode, (pdbn + 1) * sizeof (char *));
atcode[pdbn] = malloc (9 * sizeof (char));
if (v3==0)
res = sscanf (line, "%lf %lf %lf %s %i %i %i %i %i %i %i %i %i %i %i %i",
&pdbx[pdbn], &pdby[pdbn], &pdbz[pdbn], atcode[pdbn], &dd, &ccc,
&sss, &hhh, &bbb, &vvv, &HHH, &rrr, &iii, &mmm, &nnn, &eee);
else
res = sscanf (line, "M V30 %*d %s %lf %lf %lf",
atcode[pdbn],&pdbx[pdbn], &pdby[pdbn], &pdbz[pdbn]);
if (res <3 ) {
fclose(fp);
return(1);
}
pdbxmin = MIN (pdbxmin, pdbx[d]);
pdbxmax = MAX (pdbxmax, pdbx[d]);
pdbymin = MIN (pdbymin, pdby[d]);
pdbymax = MAX (pdbymax, pdby[d]);
pdbzmin = MIN (pdbzmin, pdbz[d]);
pdbzmax = MAX (pdbzmax, pdbz[d]);
atjust[pdbn] = -1; /*default to centered labels */
}
if (v3==1) {
if (!fgets(line,(int)sizeof(line),fp)) {
fclose(fp);
return(1);
}
if (strncmp(line,"M V30 END ATOM",14)) {
fclose(fp);
return(1);
}
if (!fgets(line,(int)sizeof(line),fp)) {
fclose(fp);
return(1);
}
if (strncmp(line,"M V30 BEGIN BOND",16)) {
fclose(fp);
return(1);
}
}
nbonds = -1;
/* read in bond block data */
for (d = 0; d < b; d++)
{
if (!fgets (line, (int)sizeof (line), fp)) {
fclose(fp);
return(1);
}
if (v3==1) {
memset(prop,0,40);
res = sscanf (line, "M V30 %*d %i %i %i %40c",
&tt,&atom1,&atom2,prop);
if (res <2) {
fclose(fp);
return(1);
}
ss = 0;
if ( (cfg=strstr(prop,"CFG=")) != NULL) {
res = sscanf(cfg,"CFG=%d",&ss);
if (ss == 3) ss = 6;
}
}else{
res = sscanf (line, "%c%c%c%c%c%c %i %i %i %i %i",
&aa[0],&aa[1],&aa[2], &bb[0], &bb[1], &bb[2], &tt, &ss, &xx, &rr, &cc);
res = sscanf(aa,"%i",&atom1);
res = sscanf(bb,"%i",&atom2);
}
nbonds++;
bondfrom = realloc (bondfrom, (nbonds + 1) * sizeof (int));
bondto = realloc (bondto, (nbonds + 1) * sizeof (int));
bondtype = realloc (bondtype, (nbonds + 1) * sizeof (short));
bondfrom[nbonds] = atom1 - 1;
bondto[nbonds] = atom2 - 1;
switch (tt)
{
case 1: /* single */
bondtype[nbonds] = 0;
if (ss == 1) /* stereo up */
bondtype[nbonds] = 5;
if (ss == 2 || ss == 4) /* either */
bondtype[nbonds] = 7;
if (ss == 6) /* down */
bondtype[nbonds] = 6;
break;
case 2: /* double */
bondtype[nbonds] = 1;
break;
case 3:
bondtype[nbonds] = 3;
break;
default:
bondtype[nbonds] = 0;
}
}
if (v3 == 1) {
if (!fgets (line, (int)sizeof (line), fp)) {
fclose(fp);
return(1);
}
} else {
/* check for additional labels */
res = fscanf (fp, "%s %s", aaa, line);
while (res >0 && !strcmp (aaa, "A"))
{
atom1 = atoi (line);
res = fscanf (fp, "%s", label);
if (res == 0) break;
/* found a label "label" at atom "atom1" */
/* check for numbers, interpret as indices: */
text_direct = 0;
f = (int)strlen (label);
if (f == 1)
text_direct = -1; /*center label if only one character */
for (e = 0; label[e] != '\0'; e++)
{
if (isdigit (label[e]))
{
/* If there's a number at the beginning, assume right-
* justified text: */
if (e == 0)
text_direct = -2;
/* copy already processed string in auxiliary string 'line': */
strncpy (line, label, (size_t)e);
/* append a '_', the number and a NULL-string: */
line[e] = '_';
line[e + 1] = label[e];
line[e + 2] = '\0';
/* append the rest of the label-string to 'line': */
strcat (line, strrchr (label, label[e + 1]));
/* copy 'line' back to 'label' and add a NULL-string at the end: */
strcpy (label, line);
e++;
label[++f] = '\0';
}
}
strcpy (atcode[atom1 - 1], label);
atjust[atom1 - 1] = (short)text_direct;
res = fscanf (fp, "%s %s", aaa, line);
}
}
/* check last line for "M END" */
if (strcmp(line,"END") && strcmp(line,"$$$$") ) {
do {
if (!fgets (line,80,fp)){
fprintf(stderr,"EOF\n");
break;
}
} while (strncmp (line, "M END",6) && strncmp(line,"$$$$",4) );
if (strncmp (line, "M END",6) && strncmp (line,"$$$$",4) )
{
fprintf(stderr,"endless molfile???: %s\n",line);
clear_data ();
fclose (fp);
return (2);
}
}
fclose (fp);
pdbxcent = (pdbxmax + pdbxmin) / 2.;
pdbycent = (pdbymax + pdbymin) / 2.;
pdbzcent = (pdbzmax + pdbzmin) / 2.;
for (i = 0; i <= pdbn; i++)
{
pdbx[i] = pdbx[i] - pdbxcent;
pdby[i] = pdby[i] - 2. * (pdby[i] - pdbycent);
pdbz[i] = pdbz[i] - pdbzcent;
}
/* try to normalize bond lengths based on first bond */
mdlfactor =
mdlfactor / sqrt ((pdbx[bondfrom[0]] - pdbx[bondto[0]]) *
(pdbx[bondfrom[0]] - pdbx[bondto[0]]) +
(pdby[bondfrom[0]] -
pdby[bondto[0]]) * (pdby[bondfrom[0]] -
pdby[bondto[0]]) +
(pdbz[bondfrom[0]] -
pdbz[bondto[0]]) * (pdbz[bondfrom[0]] -
pdbz[bondto[0]]));
for (i = 0; i <= nbonds; i++)
Drawline ((int) (pdbx[bondfrom[i]] * mdlfactor + mdloffset),
(int) (pdby[bondfrom[i]] * mdlfactor + mdloffset),
(int) (pdbx[bondto[i]] * mdlfactor + mdloffset),
(int) (pdby[bondto[i]] * mdlfactor + mdloffset), 1, 0);
CopyPlane ();
importflag = 2;
importfactor = mdlfactor;
importoffset = mdloffset;
return (0);
}
int
preview_mdl_mol (char *filename, int skip)
/* imports a MDL Molfile structure into the preview widget*/
{
/* int x, y, tx, ty;*/ /* the coordinates */
/* int bond = 0; */ /* Chemtool bondstyle */
float mdlfactor = 60.0; /* conversion factor .cht <-> .mol */
float previewscale;
int text_direct = 0; /* Chemtool text direction */
int d, e; /* dummy variables */
GdkRectangle update_rect;
int v3=0;
char prop[41],*cfg;
char line[255];
double pdbxmin = 100000., pdbxmax = -100000., pdbymin = 1000000., pdbymax =
-100000.;
/* the counts line, see ctfile.pdf for more information */
int a; /* number of atoms */
int b; /* number of bonds */
/* not parsed right now: */
int l; /* number of atoms list */
int f; /* obsolete */
int c; /* chiral flag, 0=not chiral, 1=chiral */
int s; /* number of stext entries */
int x_; /* number of reaction components + 1 */
int r; /* number of reactants */
int p; /* number of products */
int i; /* number of intermediates */
int m; /* number of additional properties,
no longer supported and set to 999 */
char v[6]; /* ctab version, 'v2000' or 'v3000' */
/* end of counts line */
/* the atom block */
/*float xxx, yyy, zzz; */ /* the coordinates of the atom */
char aaa[3]; /* the atomic symbol */
/* not parsed right now: */
int dd; /* mass difference for isotopes */
int ccc; /* charge */
int sss; /* atom stereo parity */
int hhh; /* hydrogen count+1 */
int bbb; /* stereo care box */
int vvv; /* valence */
int HHH; /* H designator, redundant */
int rrr; /* reaction component type */
int iii; /* reaction component number */
int mmm; /* atom-atom mapping number */
int nnn; /* inversion/retention flag */
int eee; /* exact change flag */
/* end atom block */
/* the bond block */
int atom1; /* first atom number */
int atom2; /* second atom number */
int tt; /* bond type */
int ss; /* bond stereo */
int xx; /* not used */
int rr; /* bond topology, 0=eighter, 1=ring, 2=chain */
int cc; /* reaction center status */
/* end bond block */
char label[20]; /* a label defined in the .mol-file */
char aa[4],bb[4];
int res;
FILE *fp;
/*struct dc *hp_a; */
#ifdef GTK2
setlocale (LC_NUMERIC,"C");
#endif
if ((fp = fopen (filename, "r")) == NULL)
return (1);
if (skip >0 ) {
d = 0;
while ( d <skip) {
if (! fgets(line, (int)sizeof(line),fp)) {
sdfindex--;
fclose(fp);
return(1);
}
if (!strncmp(line,"$$$$",4)) d++;
}
}
/* skip the first three lines (header) */
for (d = 0; d < 3; d++)
{
if (!fgets (line, (int)sizeof (line), fp)) {
fclose(fp);
return(1);
}
}
/* parse the counts-line */
if (!fgets (line, (int)sizeof (line), fp)){
fclose(fp);
return(1);
}
if (strstr(line,"V3000")) v3=1;
if(v3==1) {
if(!fgets(line,(int)sizeof(line),fp)) {
fclose(fp);
return(1);
}
if (strncmp(line,"M V30 BEGIN CTAB",16)) {
fclose(fp);
return(1);
}
if (!fgets(line,(int)sizeof(line),fp)) {
fclose(fp);
return(1);
}
d = sscanf (line,"M V30 COUNTS %d %d",&a,&b);
if(!fgets(line,(int)sizeof(line),fp)) {
fclose(fp);
return(1);
}
if (strncmp(line,"M V30 BEGIN ATOM",16)) {
fclose(fp);
return(1);
}
} else {
d = sscanf (line, "%c%c%c%c%c%c %i %i %i %i %i %i %i %i %i %s",
&aa[0],&aa[1],&aa[2],&bb[0],&bb[1],&bb[2], &l, &f, &c, &s, &x_, &r, &p, &i, &m, v);
aa[3]='\0';
bb[3]='\0';
sscanf(aa,"%i",&a);
sscanf(bb,"%i",&b);
if (d == 0 || a <= 0 || b < 0 || a > 100000 || b > 100000) {
fclose(fp);
return (1);
}
}
clear_data ();
pdbn = -1;
/* read in atom block data */
for (d = 0; d < a; d++)
{
if (!fgets (line, (int)sizeof (line), fp)){
fclose(fp);
return(1);
}
pdbn++;
pdbx = realloc (pdbx, (pdbn + 1) * sizeof (double));
pdby = realloc (pdby, (pdbn + 1) * sizeof (double));
atjust = realloc (atjust, (pdbn + 1) * sizeof (short));
atcode = realloc (atcode, (pdbn + 1) * sizeof (char *));
atcode[pdbn] = malloc (9 * sizeof (char));
if (v3==0)
res = sscanf (line, "%lf %lf %*f %s %i %i %i %i %i %i %i %i %i %i %i %i",
&pdbx[pdbn], &pdby[pdbn], atcode[pdbn], &dd, &ccc,
&sss, &hhh, &bbb, &vvv, &HHH, &rrr, &iii, &mmm, &nnn, &eee);
else
res= sscanf (line, "M V30 %*d %s %lf %lf",
atcode[pdbn],&pdbx[pdbn], &pdby[pdbn]);
if (res <3) {
fclose(fp);
return(1);
}
atjust[pdbn] = -1; /*default to centered labels */
}
if (v3==1) {
if (!fgets(line,(int)sizeof(line),fp)) {
fclose(fp);
return(1);
}
if (strncmp(line,"M V30 END ATOM",14)) {
fclose(fp);
return(1);
}
if (!fgets(line,(int)sizeof(line),fp)) {
fclose(fp);
return(1);
}
if (strncmp(line,"M V30 BEGIN BOND",16)) {
fclose(fp);
return(1);
}
}
nbonds = -1;
/* read in bond block data */
for (d = 0; d < b; d++)
{
if (!fgets (line, (int)sizeof (line), fp)) {
fclose(fp);
return(1);
}
if (v3==1) {
memset(prop,0,40);
res = sscanf (line, "M V30 %*d %i %i %i %40c",
&tt,&atom1,&atom2,prop);
ss = 0;
if ( (cfg=strstr(prop,"CFG=")) != NULL) {
res = sscanf(cfg,"CFG=%d",&ss);
if (ss == 3) ss = 6;
}
}else{
res = sscanf (line, "%c%c%c%c%c%c %i %i %i %i %i",
&aa[0],&aa[1],&aa[2], &bb[0], &bb[1], &bb[2], &tt, &ss, &xx, &rr, &cc);
res = sscanf(aa,"%i",&atom1);
res = sscanf(bb,"%i",&atom2);
}
nbonds++;
bondfrom = realloc (bondfrom, (nbonds + 1) * sizeof (int));
bondto = realloc (bondto, (nbonds + 1) * sizeof (int));
bondtype = realloc (bondtype, (nbonds + 1) * sizeof (short));
bondfrom[nbonds] = atom1 - 1;
bondto[nbonds] = atom2 - 1;
switch (tt)
{
case 1: /* single */
bondtype[nbonds] = 0;
if (ss == 1) /* stereo up */
bondtype[nbonds] = 5;
if (ss == 2 || ss == 4) /* either */
bondtype[nbonds] = 7;
if (ss == 6) /* down */
bondtype[nbonds] = 6;
break;
case 2:
bondtype[nbonds] = 1;
break;
case 3:
bondtype[nbonds] = 3;
break;
default:
bondtype[nbonds] = 0;
}
}
if (v3 == 1) {
if (!fgets (line, (int)sizeof (line), fp)) {
fclose(fp);
return(1);
}
} else {
/* check for additional labels */
res = fscanf (fp, "%s %s", aaa, line);
while (res >0 && !strcmp (aaa, "A"))
{
atom1 = atoi (line);
res = fscanf (fp, "%s", label);
if (res == 0) break;
/* found a label "label" at atom "atom1" */
/* check for numbers, interpret as indices: */
text_direct = 0;
f = (int)strlen (label);
if (f == 1)
text_direct = -1; /*center label if only one character */
for (e = 0; label[e] != '\0'; e++)
{
if (isdigit (label[e]))
{
/* If there's a number at the beginning, assume right-
* justified text: */
if (e == 0)
text_direct = -2;
/* copy already processed string in auxiliary string 'line': */
strncpy (line, label, (size_t)e);
/* append a '_', the number and a NULL-string: */
line[e] = '_';
line[e + 1] = label[e];
line[e + 2] = '\0';
/* append the rest of the label-string to 'line': */
strcat (line, strrchr (label, label[e + 1]));
/* copy 'line' back to 'label' and add a NULL-string at the end: */
strcpy (label, line);
e++;
label[++f] = '\0';
}
}
strcpy (atcode[atom1 - 1], label);
atjust[atom1 - 1] = (short)text_direct;
res = fscanf (fp, "%s %s", aaa, line);
}
}
/* check last line for "M END" */
if (strcmp(line,"END") && strcmp(line,"$$$$") ) {
do {
if (!fgets (line,80,fp)){
fprintf(stderr,"EOF\n");
break;
}
} while (strncmp (line, "M END",6) && strncmp(line,"$$$$",4) );
if (strncmp (line, "M END",6) && strncmp (line,"$$$$",4) )
{
fprintf(stderr,"endless molfile???: %s\n",line);
clear_data ();
fclose (fp);
return (2);
}
}
fclose (fp);
/* try to normalize bond lengths based on first bond */
mdlfactor =
mdlfactor / sqrt ((pdbx[bondfrom[0]] - pdbx[bondto[0]]) *
(pdbx[bondfrom[0]] - pdbx[bondto[0]]) +
(pdby[bondfrom[0]] -
pdby[bondto[0]]) * (pdby[bondfrom[0]] -
pdby[bondto[0]]) );
pdbxmin=10000.;
pdbymin=10000.;
pdbxmax=-10000.;
pdbymax=-10000.;
for (i = 0; i <= pdbn; i++) {
pdbx[i] = pdbx[i]*mdlfactor;
pdby[i] = pdby[i]*mdlfactor;
pdbxmin = MIN (pdbxmin, pdbx[i]);
pdbxmax = MAX (pdbxmax, pdbx[i]);
pdbymin = MIN (pdbymin, pdby[i]);
pdbymax = MAX (pdbymax, pdby[i]);
}
/* center molecule and scale it to fit into the effective
drawing area (300x150 plus small border) */
pdbxcent = (pdbxmax + pdbxmin) / 2.;
pdbycent = (pdbymax + pdbymin) / 2.;
previewscale = MIN(280./(pdbxmax-pdbxmin),140./(pdbymax-pdbymin));
for (i = 0; i <= pdbn; i++) {
pdbx[i] = (pdbx[i]- pdbxcent)*previewscale+140.;
pdby[i] = (pdby[i]- 2. * pdby[i] + pdbycent)*previewscale+75.;
}
for (i = 0; i <= nbonds; i++)
draw_preview_bonds ((int) pdbx[bondfrom[i]],
(int) pdby[bondfrom[i]],
(int) pdbx[bondto[i]],
(int) pdby[bondto[i]], 0);
for (i = 0; i <= pdbn; i++)
if (strcmp(atcode[i],"C") && strcmp(atcode[i],"H"))
Drawstring ((int)pdbx[i], (int)pdby[i], atcode[i], atjust[i], 0,0,0,1, 1);
gdk_draw_pixmap (preview_area->window,
drawing_area->style->
fg_gc[GTK_WIDGET_STATE (drawing_area)], picture, 0, 0, 0,
0, 200, 100);
update_rect.x = 0;
update_rect.y = 0;
update_rect.width = 200;
update_rect.height = 100;
gtk_widget_draw ((GtkWidget *) preview_area, &update_rect);
return (0);
}
int
import_babel (char *filename)
/* imports a foreign file via BABEL as a MDL Molfile structure */
{
/* int x, y, tx, ty;*/ /* the coordinates */
/* int bond = 0; */ /* Chemtool bondstyle */
float mdlfactor = 60.0; /* conversion factor .cht <-> .mol */
int mdloffset = 200;
int text_direct = 0; /* Chemtool text direction */
int d, e; /* dummy variables */
char line[255];
double pdbxmin = 100000., pdbxmax = -100000., pdbymin = 1000000., pdbymax =
-100000., pdbzmin = 100000., pdbzmax = -100000.;
/* the counts line, see ctfile.pdf for more information */
int a; /* number of atoms */
int b; /* number of bonds */
/* not parsed right now: */
int l; /* number of atoms list */
int f; /* obsolete */
int c; /* chiral flag, 0=not chiral, 1=chiral */
int s; /* number of stext entries */
int x_; /* number of reaction components + 1 */
int r; /* number of reactants */
int p; /* number of products */
int i; /* number of intermediates */
int m; /* number of additional properties,
no longer supported and set to 999 */
char v[6]; /* ctab version, 'v2000' or 'v3000' */
/* end of counts line */
/* the atom block */
/*float xxx, yyy, zzz; */ /* the coordinates of the atom */
char aaa[3]; /* the atomic symbol */
/* not parsed right now: */
int dd; /* mass difference for isotopes */
int ccc; /* charge */
int sss; /* atom stereo parity */
int hhh; /* hydrogen count+1 */
int bbb; /* stereo care box */
int vvv; /* valence */
int HHH; /* H designator, redundant */
int rrr; /* reaction component type */
int iii; /* reaction component number */
int mmm; /* atom-atom mapping number */
int nnn; /* inversion/retention flag */
int eee; /* exact change flag */
/* end atom block */
/* the bond block */
int atom1; /* first atom number */
int atom2; /* second atom number */
int tt; /* bond type */
int ss; /* bond stereo */
int xx; /* not used */
int rr; /* bond topology, 0=eighter, 1=ring, 2=chain */
int cc; /* reaction center status */
/* end bond block */
int res;
char label[20]; /* a label defined in the .mol-file */
char aa[4],bb[4];
FILE *fp;
/*struct dc *hp_a; */
#ifdef GTK2
setlocale(LC_NUMERIC,"C");
#endif
if (!filename || !babel ) return (1); /* no filename or no input mode */
snprintf(line,255,"babel -i%s %s -omdl %s",babel,filename,babeloutp);
/* fprintf(stderr,"%s\n",line);*/
/*@ignore@ splint does not recognize popen */
if ((fp = popen (line, "r")) == NULL)
/*@end@*/
return (1);
/* skip the first three lines (header) */
for (d = 0; d < 3; d++)
{
if (!fgets (line, (int)sizeof (line), fp)) {
/*@ignore@*/
pclose(fp);
/*@end@*/
return(1);
}
}
/* parse the counts-line */
if (!fgets (line, (int)sizeof (line), fp)) {
/*@ignore@*/
pclose(fp);
/*@end@*/
return(1);
}
d = sscanf (line, "%c%c%c%c%c%c %i %i %i %i %i %i %i %i %i %s",
&aa[0],&aa[1],&aa[2], &bb[0], &bb[1], &bb[2], &l, &f, &c, &s, &x_, &r, &p, &i, &m, v);
aa[3]=bb[3]='\0';
sscanf(aa,"%i",&a);
sscanf(bb,"%i",&b);
if (d == 0 || a <= 0 || b < 0 || a > 100000 || b > 100000) {
/*@ignore@*/
pclose(fp);
/*@end@*/
return (1);
}
fprintf(stderr, "expecting na %d nb %d\n",a,b);
clear_data ();
pdbn = -1;
/* read in atom block data */
for (d = 0; d < a; d++)
{
if (!fgets (line, (int)sizeof (line), fp)) {
/*@ignore@*/
pclose(fp);
/*@end@*/
return(1);
}
pdbn++;
pdbx = realloc (pdbx, (pdbn + 1) * sizeof (double));
pdby = realloc (pdby, (pdbn + 1) * sizeof (double));
pdbz = realloc (pdbz, (pdbn + 1) * sizeof (double));
atjust = realloc (atjust, (pdbn + 1) * sizeof (short));
atcode = realloc (atcode, (pdbn + 1) * sizeof (char *));
atcode[pdbn] = malloc (9 * sizeof (char));
res = sscanf (line, "%lf %lf %lf %s %i %i %i %i %i %i %i %i %i %i %i %i",
&pdbx[pdbn], &pdby[pdbn], &pdbz[pdbn], atcode[pdbn], &dd, &ccc,
&sss, &hhh, &bbb, &vvv, &HHH, &rrr, &iii, &mmm, &nnn, &eee);
if (res <3) {
/*@ignore@*/
pclose(fp);
/*@end@*/
return(1);
}
pdbxmin = MIN (pdbxmin, pdbx[d]);
pdbxmax = MAX (pdbxmax, pdbx[d]);
pdbymin = MIN (pdbymin, pdby[d]);
pdbymax = MAX (pdbymax, pdby[d]);
pdbzmin = MIN (pdbzmin, pdbz[d]);
pdbzmax = MAX (pdbzmax, pdbz[d]);
atjust[pdbn] = -1; /*default to centered labels */
}
nbonds = -1;
/* read in bond block data */
for (d = 0; d < b; d++)
{
if (!fgets (line, (int)sizeof (line), fp)) {
/*@ignore@*/
pclose(fp);
/*@end@*/
return(1);
}
res = sscanf (line, "%c%c%c%c%c%c %i %i %i %i %i",
&aa[0],&aa[1],&aa[2],&bb[0],&bb[1],&bb[2], &tt, &ss, &xx, &rr, &cc);
res = sscanf(aa,"%i",&atom1);
res = sscanf(bb,"%i",&atom2);
nbonds++;
bondfrom = realloc (bondfrom, (nbonds + 1) * sizeof (int));
bondto = realloc (bondto, (nbonds + 1) * sizeof (int));
bondtype = realloc (bondtype, (nbonds + 1) * sizeof (short));
bondfrom[nbonds] = atom1 - 1;
bondto[nbonds] = atom2 - 1;
switch (tt)
{
case 1:
bondtype[nbonds] = 0;
if (ss == 1)
bondtype[nbonds] = 5;
if (ss == 6)
bondtype[nbonds] = 6;
break;
case 2:
bondtype[nbonds] = 1;
break;
case 3:
bondtype[nbonds] = 3;
break;
default:
bondtype[nbonds] = 0;
}
}
/* check for additional labels */
res = fscanf (fp, "%s %s", aaa, line);
while (res >0 && !strcmp (aaa, "A"))
{
atom1 = atoi (line);
res = fscanf (fp, "%s", label);
if (res <1) break;
/* found a label "label" at atom "atom1" */
/* check for numbers, interpret as indices: */
text_direct = 0;
f = (int)strlen (label);
if (f == 1)
text_direct = -1; /*center label if only one character */
for (e = 0; label[e] != '\0'; e++)
{
if (isdigit (label[e]))
{
/* If there's a number at the beginning, assume right-
* justified text: */
if (e == 0)
text_direct = -2;
/* copy already processed string in auxiliary string 'line': */
strncpy (line, label, (size_t)e);
/* append a '_', the number and a NULL-string: */
line[e] = '_';
line[e + 1] = label[e];
line[e + 2] = '\0';
/* append the rest of the label-string to 'line': */
strcat (line, strrchr (label, label[e + 1]));
/* copy 'line' back to 'label' and add a NULL-string at the end: */
strcpy (label, line);
e++;
label[++f] = '\0';
}
}
strcpy (atcode[atom1 - 1], label);
atjust[atom1 - 1] = (short)text_direct;
res = fscanf (fp, "%s %s", aaa, line);
}
/* check last line for "M END" */
while (strcmp (line, "END"))
{
if (fscanf (fp, "%s", line) == EOF)
break;
if (fscanf (fp, "%s %s", aaa, line) == EOF)
break;
}
if (strcmp (aaa, "M") || strcmp (line, "END"))
{
clear_data ();
/*@ignore@ splint does not know pclose */
pclose (fp);
/*@end@*/
return (2);
}
pclose (fp);
pdbxcent = (pdbxmax + pdbxmin) / 2.;
pdbycent = (pdbymax + pdbymin) / 2.;
pdbzcent = (pdbzmax + pdbzmin) / 2.;
if (pdbn <=0) return (1); /* complain if no atoms */
for (i = 0; i <= pdbn; i++)
{
pdbx[i] = pdbx[i] - pdbxcent;
pdby[i] = pdby[i] - 2. * (pdby[i] - pdbycent);
pdbz[i] = pdbz[i] - pdbzcent;
}
/* try to normalize bond lengths based on first bond */
mdlfactor =
mdlfactor / sqrt ((pdbx[bondfrom[0]] - pdbx[bondto[0]]) *
(pdbx[bondfrom[0]] - pdbx[bondto[0]]) +
(pdby[bondfrom[0]] -
pdby[bondto[0]]) * (pdby[bondfrom[0]] -
pdby[bondto[0]]) +
(pdbz[bondfrom[0]] -
pdbz[bondto[0]]) * (pdbz[bondfrom[0]] -
pdbz[bondto[0]]));
for (i = 0; i <= nbonds; i++)
Drawline ((int) (pdbx[bondfrom[i]] * mdlfactor + mdloffset),
(int) (pdby[bondfrom[i]] * mdlfactor + mdloffset),
(int) (pdbx[bondto[i]] * mdlfactor + mdloffset),
(int) (pdby[bondto[i]] * mdlfactor + mdloffset), 1, 0);
CopyPlane ();
importflag = 2;
importfactor = mdlfactor;
importoffset = mdloffset;
return (0);
}
int
export_mdl_mol (FILE *fp, int topipe)
/* exports a MDL Molfile structure */
{
float factor = 76.0; /* conversion factor .cht <-> .mol */
int d, e, f; /* dummy variables */
char aaa[3]; /* the atomic symbol */
int atom1 = 0; /* first atom number */
int atom2 = 0; /* second atom number */
int tt; /* bond type */
int ss; /* bond stereo */
struct dc *hp_a;
struct data *hp_b;
int atoms[999][2]; /* coordinates of unique labels */
int start_already_there;
int end_already_there;
int is_label;
int labelcount; /* number of unique atoms/labels */
int omit; /* number of decorative lines (boxes etc) */
int hcount=0; /* for explicit CH_3, CH_2, CH */
#ifdef GTK2
setlocale(LC_NUMERIC,"C");
#endif
/* FIXME: Write some sane stuff in the header */
fprintf (fp, "Molecule exported from chemtool\n");
fprintf (fp, "\n");
fprintf (fp, "\n");
labelcount = 0;
omit = 0;
atoms[0][0]=atoms[0][1]=0;
/* Get coordinates of all unique bond-delimiters
* and, more importantly, the number of unique atoms,
* chemtool only knows the number of bonds and the
* number of non-carbon atoms :( */
hp_b = da_root.next;
for (d = 0; d < hp->n; d++)
{
if (!(mark.flag && (hp_b->smarked + hp_b->tmarked) == 0))
{
if (hp_b->decoration == 1) omit++;
else {
/* Check for already parsed atoms on same coordinates */
start_already_there = 0;
end_already_there = 0;
for (f = 0; f <= labelcount; f++)
{
if (hp_b->x == atoms[f][0] && hp_b->y == atoms[f][1])
{
start_already_there = 1;
}
if (hp_b->tx == atoms[f][0] && hp_b->ty == atoms[f][1])
{
end_already_there = 1;
}
}
if (!start_already_there)
{
atoms[labelcount][0] = hp_b->x;
atoms[labelcount][1] = hp_b->y;
labelcount++;
}
if (!end_already_there)
{
atoms[labelcount][0] = hp_b->tx;
atoms[labelcount][1] = hp_b->ty;
labelcount++;
}
}
}
hp_b = hp_b->next;
}
/* The counts line: */
fprintf (fp, "%3i%3i 0 0 0 0 0 0 0 0999 V2000\n", labelcount,
hp->n-omit);
/* Now write down the labels.
* start all over */
for (d = 0; d < labelcount; d++)
{
/* Check for label on same position */
hp_a = dac_root.next;
is_label = 0;
for (e = 0; e < hp->nc; e++)
{
if (atoms[d][0] == hp_a->x && atoms[d][1] == hp_a->y)
{
is_label = 1;
break;
}
hp_a = hp_a->next;
}
if (is_label)
{
hcount = 0;
if (!strcmp(hp_a->c,"CH") || !strcmp(hp_a->c,"HC") )
{
hcount=1;
strcpy (aaa, "C");
} else
if (!strcmp(hp_a->c,"OH") || !strcmp(hp_a->c,"HO") )
{
hcount=1;
strcpy (aaa, "O");
} else
if (!strcmp(hp_a->c,"NH") || !strcmp(hp_a->c,"HN") )
{
hcount=1;
strcpy (aaa, "N");
} else
if (!strcmp(hp_a->c,"SH") || !strcmp(hp_a->c,"HS") )
{
hcount=1;
strcpy (aaa, "S");
} else
if (!strcmp(hp_a->c,"PH") || !strcmp(hp_a->c,"HP") )
{
hcount=1;
strcpy (aaa, "P");
} else
if ((int)strlen (hp_a->c) < 4)
{
strcpy (aaa, hp_a->c);
}
else if (!strncmp(hp_a->c,"CH_3",4) || !strncmp(hp_a->c,"H_3C",4))
{
hcount = 3;
strcpy (aaa, "C");
}
else if ( !strncmp(hp_a->c,"CH_2",4) || !strncmp(hp_a->c,"H2_C",4))
{
hcount = 2;
strcpy (aaa, "C");
}
else if (!strncmp(hp_a->c,"NH_3",4) || !strncmp(hp_a->c,"H_3N",4))
{
hcount = 3;
strcpy (aaa, "N");
}
else if ( !strncmp(hp_a->c,"NH_2",4) || !strncmp(hp_a->c,"H2_N",4))
{
hcount = 2;
strcpy (aaa, "N");
}
else
{
fprintf(stderr,"untranslatable label %s\n",hp_a->c);
strcpy (aaa, "X");
}
}
else
{
strcpy (aaa, "C");
}
fprintf (fp,
"%10.4f%10.4f%10.4f %-3s 0 0 0 %1d 0 0 0 0 0 0 0 0\n",
(double) atoms[d][0] / factor, (double) atoms[d][1] / factor,
0.0, aaa, hcount);
}
/* Now for the bonds */
hp_b = da_root.next;
for (d = 0; d < hp->n; d++)
{
if (hp_b->decoration == 0 && (!(mark.flag && (hp_b->smarked + hp_b->tmarked) == 0)))
{
atom1 = 0;
atom2 = 0;
for (e = 0; e < labelcount; e++)
{
if (atoms[e][0] == hp_b->x && atoms[e][1] == hp_b->y)
{
atom1 = e + 1;
}
if (atoms[e][0] == hp_b->tx && atoms[e][1] == hp_b->ty)
{
atom2 = e + 1;
}
}
}
/* parse the bond type */
tt = 1;
ss = 0;
switch (hp_b->bond)
{
case 1:
case 2:
tt = 2; /*double*/ /* 7=double or aromatic */
break;
case 4:
tt = 2; /* double */
break;
case 3:
case 18:
case 19: /* FIXME: does MOL handle quadruple bonds at all ?*/
tt = 3; /* triple */
break;
case 5:
case 10:
ss = 1; /* stereo up */
break;
case 6:
case 16:
ss = 6; /* stereo down */
break;
case 7:
ss = 4; /* stereo either */
break;
case 8:
case 9:
case 11:
/* case 12: */ /* bond or not? */
case 17:
tt = 0; /* assume no chemical bond */
break;
case 14:
case 15:
tt = 1; /* 6 = single or aromatic */
break;
default:
tt = 1; /* single */
break;
}
if (tt)
{
fprintf (fp, "%3i%3i%3i%3i 0 0 0\n", atom1, atom2, tt, ss);
}
hp_b = hp_b->next;
}
fprintf (fp, "M END\n");
if (!topipe) fclose (fp);
return 0;
}
int
export_svg (char *filename)
/* exports the current drawing to a Scaled Vector Graphics file */
{
FILE *fp;
int x, y, tx, ty, w, h;
int x1,y1,x2,y2;
float area;
float factor;
struct data *hp_b,*hp_bx;
struct dc *hp_a;
struct spline *hp_sp;
struct xy_co *coord;
int d, i, dd;
int dy;
int xbase, ybase, xside, yside, xend, yend, xlen, ylen;
int shifted = 0;
int unicodechar;
int bond_already_tuned=0;
static char svgcolor[7][8]={"#000000","#0000ff","#00ff00","#00ffff","#ff0000","#ff00ff",
"#ffff00"};
#ifdef GTK2
setlocale(LC_NUMERIC,"C");
#endif
if ((fp = fopen (filename, "w")) == NULL)
return (1);
fprintf (fp,
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
fprintf (fp, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n");
fprintf (fp, " \"http://www.w3.org/TR/SVG/DTD/svg10.dtd\">\n");
if (mark.flag && mark.w != 0 && mark.h != 0)
{
w = mark.w * size_factor - 6;
h = mark.h * size_factor - 6;
}
else
{
/* get true extents of drawing*/
w = 0;
h = 0;
hp_b = da_root.next;
for (d = 0; d < hp->n; d++)
{
w = MAX (w, hp_b->x);
w = MAX (w, hp_b->tx);
h = MAX (h, hp_b->y);
h = MAX (h, hp_b->ty);
hp_b = hp_b->next;
}
hp_a = dac_root.next;
for (d = 0; d < hp->nc; d++)
{
w = MAX (w, hp_a->x);
if (hp_a->direct > -2)
w = MAX (w, hp_a->x + (int)strlen (hp_a->c) * (6 + 2 * size_factor));
h = MAX (h, hp_a->y + 8);
hp_a = hp_a->next;
}
hp_sp = sp_root.next;
for (d = 0; d < hp->nsp; d++)
{
w = MAX (w, hp_sp->x0);
h = MAX (h, hp_sp->y0);
w = MAX (w, hp_sp->x1);
h = MAX (h, hp_sp->y1);
w = MAX (w, hp_sp->x2);
h = MAX (h, hp_sp->y2);
w = MAX (w, hp_sp->x3);
h = MAX (h, hp_sp->y3);
hp_sp = hp_sp->next;
}
w = (int) (w * 1.1) ;
h = (int) (h * 1.1) ;
}
fprintf (fp,
"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"%dpx\" height=\"%dpx\" >\n", w, h);
fprintf (fp, "<desc>\nCreated with Chemtool 1.6.10 from file %s \n</desc>\n",
filename);
fprintf (fp, "<g>\n");
hp_b = da_root.next;
for (d = 0; d < hp->n; d++)
{
if (mark.flag && (hp_b->smarked + hp_b->tmarked) == 0)
{
}
else
{
coord = bond_cut (hp_b->x, hp_b->y, hp_b->tx, hp_b->ty, 12);
x = coord->x;
y = coord->y;
tx = coord->tx;
ty = coord->ty;
if (!hp_b->bond)
{
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
x, y, tx, ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
if (hp_b->bond == 5)
{
bond_already_tuned = 0;
x1 = tx - (int) (0.1 * (float) (ty - y));
y1 = ty + (int) (0.1 * (float) (tx - x));
x2 = tx + (int) (0.1 * (float) (ty - y));
y2 = ty - (int) (0.1 * (float) (tx - x));
factor=1.;
hp_bx=da_root.next;
for (dd = 0; dd < hp->n; dd++)
{
if (hp_bx->bond == 10)
{
if (
(abs (hp_bx->x * factor - tx) < 3
&& abs (hp_bx->y * factor - ty) < 3)
|| (abs (hp_bx->tx * factor - tx) < 3
&& abs (hp_bx->ty * factor - ty) < 3))
{
coord =
center_double_bond (hp_bx->x, hp_bx->y, hp_bx->tx, hp_bx->ty, db_dist);
if (abs (hp_bx->x * factor - tx) < 3
&& abs (hp_bx->y * factor - ty) < 3)
{
x1 = coord->x * factor;
y1 = coord->y * factor;
coord++;
x2 = coord->x * factor;
y2 = coord->y * factor;
}
else
{
x1 = coord->tx * factor;
y1 = coord->ty * factor;
coord++;
x2 = coord->tx * factor;
y2 = coord->ty * factor;
}
area = (0.5 * abs (x * (y1 - y2)
+ x1 * (y2 - y) + x2 * (y - y1)));
if (fabs (area) < 76. * factor)
{
x1 = tx - (int) (0.05 * (float) (ty - y));
y1 = ty + (int) (0.05 * (float) (tx - x));
x2 = tx + (int) (0.05 * (float) (ty - y));
y2 = ty - (int) (0.05 * (float) (tx - x));
}
else bond_already_tuned = 1;
} /* if connected to wide end of this wedge */
} /* if adjoining bond is wide */
if (hp_bx->bond == 0 && !bond_already_tuned) {
if ((abs (hp_bx->x * factor - tx) < 3 && abs (hp_bx->y * factor - ty) < 3)
||(abs (hp_bx->tx * factor - tx) < 3 && abs (hp_bx->ty * factor - ty) < 3))
/* let the wedge join smoothly alongside another bond */
{
coord = intersect(x,y,x1,y1,hp_bx->x*factor,hp_bx->y*factor,
hp_bx->tx*factor,hp_bx->ty*factor);
coord->tx = coord->x;
coord->ty = coord->y;
coord = intersect(x,y,x2,y2,hp_bx->x*factor,hp_bx->y*factor,
hp_bx->tx*factor,hp_bx->ty*factor);
x1 = coord->tx;
y1 = coord->ty;
x2 = coord->x;
y2 = coord->y;
area = 0.5 * abs (x * (y1 - y2)
+ x1 * (y2 - y) + x2 * (y - y1));
if (fabs (area) > 3300. * factor || fabs(area) < 1750. * factor)
{
x1 = tx - (int) (0.1 * (float) (ty - y));
y1 = ty + (int) (0.1 * (float) (tx - x));
x2 = tx + (int) (0.1 * (float) (ty - y));
y2 = ty - (int) (0.1 * (float) (tx - x));
}
} /* if connected to wide end of this wedge */
} /* if adjoining bond is single, and not already adjusted */
hp_bx = hp_bx->next;
} /* for dd */
fprintf (fp,
"<polygon style=\"fill:%s; stroke:%s; stroke-width:1\"\n",
svgcolor[hp_b->color],svgcolor[hp_b->color]);
fprintf (fp, " points=\"%d,%d %d,%d %d,%d\" />\n", x,
y, x1,y1,x2,y2);
/* fprintf (fp, " points=\"%d,%d %d,%d %d,%d\" />\n", x,
y, (int) (tx - 0.08 * (ty - y)),
(int) (ty + 0.08 * (tx - x)),
(int) (tx + 0.08 * (ty - y)),
(int) (ty - 0.08 * (tx - x)));
*/
}
if (hp_b->bond == 6)
{
for (i = 0; i < 8; i++)
{
fprintf (fp,
"<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
(int) (x + 0.125 * i * (tx - x) -
0.01 * (ty - y) * i),
(int) (y + 0.125 * i * (ty - y) +
0.01 * (tx - x) * i),
(int) (x + 0.125 * i * (tx - x) +
0.01 * (ty - y) * i),
(int) (y + 0.125 * i * (ty - y) -
0.01 * (tx - x) * i));
fprintf (fp, "style=\"stroke-width:1; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
}
if (hp_b->bond == 7)
{
i=MAX(abs(tx-x),abs(ty-y))/10;
fprintf (fp, "<path d=\"M %d,%d\n", x, y);
fprintf (fp, "A %d,%d %d %d %d %d %d\n",
i,i,0,0,0,x+(tx-x)/5,y+(ty - y)/5);
fprintf (fp, "A %d,%d %d %d %d %d %d\n",
i,i,0,1,1,x+2*(tx-x)/5,y+2*(ty - y)/5);
fprintf (fp, "A %d,%d %d %d %d %d %d\n",
i,i,0, 0,0,x+3*(tx-x)/5,y+3*(ty - y)/5);
fprintf (fp, "A %d,%d %d %d %d %d %d\n",
i,i,0,1,1,x+4*(tx-x)/5,y+4*(ty - y)/5);
fprintf (fp, "A %d,%d %d %d %d %d %d\"\n",
i,i,0,0,0,tx,ty);
fprintf (fp,
"style=\"stroke-width:2; stroke:%s; fill:none\" />\n",svgcolor[hp_b->color]);
}
if (hp_b->bond == 8)
{
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
x, y, (int)(x+0.8*(tx-x)), (int)(y+0.8*(ty-y)));
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
fprintf (fp,
"<polygon style=\"fill:%s; stroke:%s; stroke-width:1\"\n",svgcolor[hp_b->color],svgcolor[hp_b->color]);
fprintf (fp, " points=\"%d,%d %d,%d %d,%d\" />\n",
(int) (x + 0.8 * (tx - x)), (int) (y + 0.8 * (ty - y)),
(int) (x + 0.8 * (tx - x) + 0.1 * (ty - y)),
(int) (y + 0.8 * (ty - y) - 0.1 * (tx - x)), tx, ty);
}
if (hp_b->bond == 9)
{
int xlen = tx - x;
int ylen = ty - y;
float veclen = sqrt ((double)(xlen * xlen + ylen * ylen));
float scalefact=64./veclen; /* keep arrowhead size constant (64=std length)*/
int xbase = (int) (tx - 0.2 *xlen*scalefact);
int ybase = (int) (ty - 0.2 *ylen*scalefact);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
x, y, xbase, ybase);
/*x, y, (int)(x+0.8*(tx-x)), (int)(y+0.8*(ty-y)));*/
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
fprintf (fp,
"<polygon style=\"fill:%s; stroke:%s; stroke-width:1\"\n",svgcolor[hp_b->color],svgcolor[hp_b->color]);
fprintf (fp, " points=\"%d,%d %d,%d %d,%d\" />\n",
tx, ty,(int)(xbase + 0.1 * ylen*scalefact),
(int)(ybase - 0.1 * xlen*scalefact) ,
(int)(xbase - 0.1 * ylen*scalefact),
(int)(ybase + 0.1 * xlen*scalefact) );
/*(int) (x + 0.8 * (tx - x) + 0.1 * (ty - y)),
(int) (y + 0.8 * (ty - y) - 0.1 * (tx - x)),
(int) (x + 0.8 * (tx - x) - 0.1 * (ty - y)),
(int) (y + 0.8 * (ty - y) + 0.1 * (tx - x)));*/
}
if (hp_b->bond == 11)
{
fprintf (fp, "<circle cx=\"%d\" cy=\"%d\" r=\"%d\"\n",
x, y, calc_vector (x - tx, y - ty));
fprintf (fp,
"style=\"fill:none; stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
if (hp_b->bond == 10)
{
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
x, y, tx, ty);
fprintf (fp, "style=\"stroke-width:10; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
if (hp_b->bond == 12)
{
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
x, y, tx, ty);
fprintf (fp,
"style=\"stroke-width:2; stroke-dasharray:1,2; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
if (hp_b->bond == 13)
{
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
x + (tx - x) / 4, y + (ty - y) / 4,
tx - (tx - x) / 4, ty - (ty - y) / 4);
fprintf (fp, "style=\"stroke-width:2; stroke:white\" />\n");
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
x, y, tx, ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
if (hp_b->bond == 4)
{
coord = center_double_bond (x, y, tx, ty, db_dist);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
coord->x, coord->y, coord->tx, coord->ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
coord++;
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
coord->x, coord->y, coord->tx, coord->ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
if (hp_b->bond == 1 || hp_b->bond == 3)
{
coord = multi_bonds (x, y, tx, ty, mb_dist);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
x, y, tx, ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
coord->x, coord->y, coord->tx, coord->ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
if (hp_b->bond == 2 || hp_b->bond == 3)
{
coord = multi_bonds (tx, ty, x, y, mb_dist);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
x, y, tx, ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
coord->x, coord->y, coord->tx, coord->ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
if (hp_b->bond == 14)
{
coord = multi_bonds (x, y, tx, ty, mb_dist);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
x, y, tx, ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
coord->x, coord->y, coord->tx, coord->ty);
fprintf (fp,
"style=\"stroke-width:2; stroke-dasharray:4,1; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
if (hp_b->bond == 15)
{
coord = multi_bonds (tx, ty, x, y, mb_dist);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
x, y, tx, ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
coord->x, coord->y, coord->tx, coord->ty);
fprintf (fp,
"style=\"stroke-width:2; stroke-dasharray:4,1; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
if (hp_b->bond == 16)
{
coord = center_double_bond (x, y, tx, ty, db_dist);
x = coord->x;
y = coord->y;
tx = coord->tx;
ty = coord->ty;
coord++;
for (i = 0; i < 10; i++) {
fprintf (fp,
"<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
(int) (x + 0.1 * i * (tx - x)),
(int) (y + 0.1 * i * (ty - y)),
(int) (coord->x + 0.1 * i * (coord->tx - coord->x)),
(int) (coord->y + 0.1 * i * (coord->ty - coord->y)));
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
}
if (hp_b->bond == 18)
{
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
x, y, tx, ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
coord = center_double_bond (x, y, tx, ty, db_dist+1);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
coord->x, coord->y, coord->tx, coord->ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
coord++;
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
coord->x, coord->y, coord->tx, coord->ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
if (hp_b->bond == 19)
{
int tmpx1,tmpx2,tmpy1,tmpy2,tmptx1,tmptx2,tmpty1,tmpty2;
coord = center_double_bond (x, y, tx, ty, db_dist+1);
tmpx1=coord->x;
tmpy1=coord->y;
tmptx1=coord->tx;
tmpty1=coord->ty;
coord++;
tmpx2=coord->x;
tmpy2=coord->y;
tmptx2=coord->tx;
tmpty2=coord->ty;
coord = center_double_bond (tmpx1, tmpy1, tmptx1, tmpty1, db_dist-1);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
coord->x, coord->y, coord->tx, coord->ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
coord++;
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
coord->x, coord->y, coord->tx, coord->ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
coord = center_double_bond (tmpx2, tmpy2, tmptx2, tmpty2, db_dist-1);
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
coord->x, coord->y, coord->tx, coord->ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
coord++;
fprintf (fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
coord->x, coord->y, coord->tx, coord->ty);
fprintf (fp, "style=\"stroke-width:2; stroke:%s\" />\n",svgcolor[hp_b->color]);
}
}
hp_b = hp_b->next;
}
hp_a = dac_root.next;
for (d = 0; d < hp->nc; d++)
{
if (mark.flag && hp_a->marked == 0)
{
}
else
{
if (hp_a->font == 0 ) {
switch (hp_a->direct)
{
case Middle_Text:
fprintf (fp,
"<text x=\"%d\" y=\"%d\" style=\"font-family:Helvetica; font-size:%dpt; fill:%s;",
hp_a->x - 2, hp_a->y + 8,12+hp_a->size*2,svgcolor[hp_a->color]);
fprintf (fp, "text-anchor:middle;\" > \n<tspan>\n");
break;
case Left_Text:
fprintf (fp,
"<text x=\"%d\" y=\"%d\" style=\"font-family:Helvetica; font-size:%dpt; fill:%s;",
hp_a->x - 8 , hp_a->y + 8,12+hp_a->size*2,svgcolor[hp_a->color]);
fprintf (fp, "text-anchor:start;\" > \n<tspan>\n");
break;
case Right_Text:
fprintf (fp,
"<text x=\"%d\" y=\"%d\" style=\"font-family:Helvetica; font-size:%dpt; fill:%s;",
hp_a->x + 6, hp_a->y + 8,12+hp_a->size*2,svgcolor[hp_a->color]);
fprintf (fp, "text-anchor:end;\" > \n<tspan>\n");
break;
default:
fprintf (stderr, "undefined text direction in svg output\n");
;;
}
} else {
switch (hp_a->direct)
{
case Middle_Text:
fprintf (fp,
"<text x=\"%d\" y=\"%d\" style=\"font-family:Times; font-size:%dpt; fill:%s;",
hp_a->x - 2, hp_a->y + 8,12+hp_a->size*2,svgcolor[hp_a->color]);
fprintf (fp, "text-anchor:middle;\" > \n<tspan>\n");
break;
case Left_Text:
fprintf (fp,
"<text x=\"%d\" y=\"%d\" style=\"font-family:Times; font-size:%dpt; fill:%s;",
hp_a->x - 8 , hp_a->y + 8,12+hp_a->size*2,svgcolor[hp_a->color]);
fprintf (fp, "text-anchor:start;\" > \n<tspan>\n");
break;
case Right_Text:
fprintf (fp,
"<text x=\"%d\" y=\"%d\" style=\"font-family:Times; font-size:%dpt; fill:%s;",
hp_a->x + 6, hp_a->y + 8,12+hp_a->size*2,svgcolor[hp_a->color]);
fprintf (fp, "text-anchor:end;\" > \n<tspan>\n");
break;
default:
fprintf (stderr, "undefined text direction in svg output\n");
;;
}
}
for (i = 0; i < (int)strlen (hp_a->c); ++i)
{
if (hp_a->c[i] == '\\')
hp_a->c[i] = ' ';
if (hp_a->c[i] == '@')
{
unicodechar=848+hp_a->c[++i];
switch (unicodechar){ /* catch sequence mismatches with X Symbol font*/
case 915: /*C*/
case 947: /*c*/
unicodechar+=20;
break;
case 918:
case 950: /*f*/
unicodechar+=16;
break;
case 919:
case 951: /*g*/
unicodechar-=4;
break;
case 920:
case 952: /*h*/
unicodechar-=1;
break;
case 922: /*J is vartheta*/
unicodechar=977;
break;
case 954: /*j is varphi*/
unicodechar=981;
break;
case 923:
case 924:
case 925:
case 955:
case 956:
case 957:
unicodechar-=1;
break;
case 926: /*N*/
unicodechar=78;
break;
case 958: /*n*/
unicodechar=118;
break;
case 929: /*Q*/
unicodechar=920;
break;
case 961: /*p*/
unicodechar=952;
break;
case 962:
unicodechar-=1;
break;
case 966:/*v*/
unicodechar=982;
break;
case 967: /*w*/
unicodechar=969;
break;
case 968:
unicodechar=958;
break;
case 969:
unicodechar-=1;
break;
case 970:
unicodechar=950;
break;
case 930: /*R*/
unicodechar-=1;
break;
case 934: /*V*/
unicodechar=962;
break;
case 935: /*W*/
unicodechar+=2;
break;
case 936: /*X*/
unicodechar=926;
break;
case 937: /*Y*/
unicodechar-=1;
break;
case 938:
unicodechar=90;
break;
case 1031: case 775: /* bullet */
unicodechar=8226;
break;
default:
break;
}
fprintf (fp, "&#%04d;", unicodechar);
/*FIXME: unicode greek does not always map to X11 Symbol, e.g. F is Z not Phi */
}
else if (hp_a->c[i] == '#')
{
fprintf (fp, "\n<tspan style=\"font-weight:bold;\">");
fprintf (fp, "%c", hp_a->c[++i]);
fprintf (fp, "</tspan>\n");
}
else if (hp_a->c[i] == '|')
{
fprintf (fp, "\n<tspan style=\"font-style:oblique;\">");
fprintf (fp, "%c", hp_a->c[++i]);
fprintf (fp, "</tspan>\n");
}
else if (hp_a->c[i] == '_')
{
dy=2+hp_a->size;
fprintf (fp, "</tspan>\n<tspan dy=\"%d\" style=\"font-size:%dpt;\">", dy, 8+hp_a->size*2);
if (hp_a->c[i + 1] && hp_a->c[i + 1] == '{')
{
shifted = 1;
i++;
}
if (shifted == 1)
{
while (hp_a->c[i + 1] && hp_a->c[i + 1] != '}')
fprintf (fp, "%c", hp_a->c[++i]);
shifted = 0;
i++;
}
else
{
fprintf (fp, "%c", hp_a->c[++i]);
}
fprintf (fp, "</tspan>\n<tspan dy=\"%d\">\n", -dy);
}
else if (hp_a->c[i] == '^')
{
dy=-2 * (2 + hp_a->size); /* BUG FIX 1 */
fprintf (fp, "</tspan>\n<tspan dy=\"%d\" style=\"font-size:%dpt;\">", dy, 8+hp_a->size*2);
if (hp_a->c[i + 1] && hp_a->c[i + 1] == '{')
{
shifted = 1;
i++;
}
if (shifted == 1)
{
while (hp_a->c[i + 1] && hp_a->c[i + 1] != '}')
fprintf (fp, "%c", hp_a->c[++i]);
shifted = 0;
i++;
}
else
{
fprintf (fp, "%c", hp_a->c[++i]);
}
fprintf (fp, "</tspan>\n<tspan dy=\"%d\">\n", -dy);
}
else
{
#ifndef GTK2
if ((unsigned char)hp_a->c[i] >128)
fprintf (fp, "&#%03d;",(unsigned char)hp_a->c[i]);
else
#endif
fprintf (fp, "%c", hp_a->c[i]);
}
if (hp_a->c[i]==' ') /* protect blanks again after output */
hp_a->c[i]='\\';
}
fprintf (fp, "</tspan>\n</text>\n");
}
hp_a = hp_a->next;
}
hp_sp = sp_root.next;
for (d = 0; d < hp->nsp; d++)
{
if (mark.flag == 1 && hp_sp->marked == 0)
{
}
else
{
fprintf (fp, "<path d=\"M %d,%d\n", hp_sp->x0, hp_sp->y0);
fprintf (fp, "C %d,%d %d,%d %d,%d\"\n", hp_sp->x1, hp_sp->y1,
hp_sp->x2, hp_sp->y2, hp_sp->x3, hp_sp->y3);
switch (hp_sp->type)
{
case 0:
case 1:
case 2:
fprintf (fp,
"style=\"stroke-width:2; stroke:%s; fill:none\">\n",svgcolor[hp_sp->color]);
break;
;;
case -2:
fprintf (fp,
"style=\"stroke-width:2; stroke-dasharray:4,1; stroke:%s fill:none\">\n",svgcolor[hp_sp->color]);
break;
;;
case -1:
fprintf (fp,
"style=\"stroke-width:2; stroke:%s; fill:solid\">\n",svgcolor[hp_sp->color]);
}
fprintf (fp, "</path>\n");
if (hp_sp->type > 0)
{
xbase = (int)
(0.7 * 0.7 * 0.7 * (double) hp_sp->x3 + 3. * 0.7 * 0.7 * (1. -
0.7)
* (double) hp_sp->x2 + 3. * 0.7 * (1. - 0.7) * (1. -
0.7) *
(double) hp_sp->x1 + (1. - 0.7) * (1. - 0.7) * (1. -
0.7) *
hp_sp->x0);
ybase = (int)
(0.7 * 0.7 * 0.7 * (double) hp_sp->y3 + 3. * 0.7 * 0.7 * (1. -
0.7)
* (double) hp_sp->y2 + 3. * 0.7 * (1. - 0.7) * (1. -
0.7) *
(double) hp_sp->y1 + (1. - 0.7) * (1. - 0.7) * (1. -
0.7) *
hp_sp->y0);
xlen = hp_sp->x3 - xbase;
ylen = hp_sp->y3 - ybase;
if (xlen != 0)
xlen = (int) copysign (50., (double)xlen);
if (ylen != 0)
ylen = (int) copysign (50., (double)ylen);
xside = (int) (xbase + 0.15 * ylen);
yside = (int) (ybase - 0.15 * xlen);
if (hp_sp->type == 1)
{
xend = (int) (xbase - 0.15 * ylen);
yend = (int) (ybase + 0.15 * xlen);
x =
(xside - hp_sp->x0) * (xside - hp_sp->x0) + (yside -
hp_sp->y0) *
(yside - hp_sp->y0);
tx =
(xend - hp_sp->x0) * (xend - hp_sp->x0) + (yend -
hp_sp->y0) *
(yend - hp_sp->y0);
if (tx > x)
{
xside = xend;
yside = yend;
}
xend = xbase; /*on baseline */
yend = ybase;
}
else
{
xend = (int) (xbase - 0.15 * ylen);
yend = (int) (ybase + 0.15 * xlen);
}
fprintf (fp,
"<polygon style=\"fill:%s; stroke:%s; stroke-width:2\"\n",svgcolor[hp_sp->color],svgcolor[hp_sp->color]);
fprintf (fp, " points=\"%d,%d %d,%d, %d,%d\" />\n",
hp_sp->x3, hp_sp->y3, xside, yside, xend, yend);
}
}
hp_sp = hp_sp->next;
}
fprintf (fp, "</g>\n</svg>\n");
fclose (fp);
return (0);
}
int
export_emf (char *filename)
/* exports the current drawing to an ECMA Enhanced Metafile */
#ifndef EMF
{
char com[255];
FILE *xfile;
int rval;
#if 1
char tmpfile[512];
FILE *fp;
int fd;
#endif
#ifdef GTK2
setlocale(LC_NUMERIC,"C");
#endif
if (figversion == 0)
return (1); /* cannot export without fig2dev */
if ((int)strlen (filename))
{
#if 0
snprintf (com,255, "fig2dev -L emf > %s", filename);
xfile = popen (com, "w");
#else
strcpy (tmpfile, "/tmp/chtXXXXXX");
/*@ignore@ splint does not recognize mkstemp */
fd = mkstemp (tmpfile);
/*@end@*/
if (fd == -1)
return (1);
fp = fdopen (fd, "w");
rval = exfig (fp, 0);
if (rval != 0)
return(rval);
if (fclose (fp) != 0)
return(1);
snprintf (com,255, "fig2dev -L emf %s> %s", tmpfile, filename);
xfile = popen (com, "w");
#endif
if (pclose (xfile) != 0)
return (1);
return (rval);
}
else
return (1);
}
#else
{
int x, y, tx, ty, w, h;
struct data *hp_b;
struct dc *hp_a;
struct spline *hp_sp;
struct xy_co *coord;
int d, i;
int xbase, ybase, xside, yside, xend, yend, xlen, ylen;
int shifted = 0;
int ha,fzoom,xpos,chl,nsub,nsup,rval,l;
int csize,fontsize,offset,savedpos;
LPPOINT dummy={0};
POINT points[4];
HWND desktop = GetDesktopWindow();
HDC dc= GetDC(desktop);
PCSTR description = "Created by\0chemtool 1.6.10\0";
char *tmpstring=malloc(80*sizeof(char));
HENHMETAFILE mfh;
HDC metaDC ;
HPEN nopen=CreatePen(PS_SOLID,0,RGB(0xff,0xff,0xff));
HPEN pen=CreatePen(PS_SOLID,1,RGB(0x00,0x00,0x00));
HPEN widepen=CreatePen(PS_SOLID,5,RGB(0x00,0x00,0x00));
HPEN dashedpen=CreatePen(PS_DASH,1,RGB(0x00,0x00,0x00));
HPEN dottedpen=CreatePen(PS_DOT,1,RGB(0x00,0x00,0x00));
HPEN whitepen=CreatePen(PS_SOLID,5,RGB(0xff,0xff,0xff));
HBRUSH fill=CreateSolidBrush(RGB(0x00,0x00,0x00));
HFONT normalfont=CreateFontA(-11,0,0,0,FW_MEDIUM,0,0,0,ANSI_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH| FF_DONTCARE, "Helvetica");
HFONT smallfont=CreateFontA(-8,0,0,0,FW_MEDIUM,0,0,0,ANSI_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH| FF_DONTCARE, "Helvetica");
HFONT italicfont=CreateFontA(11,0,12,0,FW_MEDIUM,1,0,0,ANSI_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH| FF_DONTCARE, "Helvetica");
HFONT smallitalicfont=CreateFontA(8,0,8,0,FW_MEDIUM,1,0,0,ANSI_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH| FF_DONTCARE, "Helvetica");
HFONT boldfont=CreateFontA(11,0,12,0,FW_BOLD,0,0,0,ANSI_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH| FF_DONTCARE, "Helvetica");
HFONT smallboldfont=CreateFontA(8,0,8,0,FW_BOLD,0,0,0,ANSI_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH| FF_DONTCARE, "Helvetica");
HFONT symbolfont=CreateFontA(11,0,12,0,FW_MEDIUM,0,0,0,SYMBOL_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH| FF_DONTCARE, "Helvetica");
HFONT smallsymbolfont=CreateFontA(8,0,8,0,FW_MEDIUM,0,0,0,SYMBOL_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH| FF_DONTCARE, "Helvetica");
savedpos = 0;
switch (zoom_factor)
{
case 0:
fontsize = 8; /*8 */
fzoom = 6; /*6,4 */
break;
case 1:
fontsize = 10; /*6? */
fzoom = 7; /*5? */
break;
case 2:
fontsize = 12; /*9? */
fzoom = 8; /*7? */
break;
case 3:
fontsize = 16; /*12? */
fzoom = 9; /*12,10? */
break;
case 4:
fontsize = 18;
fzoom = 10;
break;
default:
fprintf (stderr, "no emf font parameters for zoom factor %d\n",
zoom_factor);
rval = 2;
}
fzoom=size_factor;
if (mark.flag && mark.w != 0 && mark.h != 0)
{
x = mark.x * size_factor + 3;
y = mark.y * size_factor + 3;
w = mark.w * size_factor - 6;
h = mark.h * size_factor - 6;
}
else
{
/* get true extents of drawing*/
x = 10000;
y = 10000;
w = 0;
h = 0;
hp_b = da_root.next;
for (d = 0; d < hp->n; d++)
{
w = MAX (w, hp_b->x);
w = MAX (w, hp_b->tx);
h = MAX (h, hp_b->y);
h = MAX (h, hp_b->ty);
x = MIN (x, hp_b->x);
x = MIN (x, hp_b->tx);
y = MIN (y, hp_b->y);
y = MIN (y, hp_b->ty);
hp_b = hp_b->next;
}
hp_a = dac_root.next;
for (d = 0; d < hp->nc; d++)
{
w = MAX (w, hp_a->x);
if (hp_a->direct > -2)
w = MAX (w, (hp_a->x + (int)strlen (hp_a->c) * 30));
h = MAX (h, hp_a->y + 12);
x = MIN (x, hp_a->x);
if (hp_a->direct < 0)
x = MIN (x, (hp_a->x - (int)strlen (hp_a->c) * 30));
y = MIN (y, hp_a->y - 12);
hp_a = hp_a->next;
}
hp_sp = sp_root.next;
for (d = 0; d < hp->nsp; d++)
{
w = MAX (w, hp_sp->x0);
h = MAX (h, hp_sp->y0);
w = MAX (w, hp_sp->x1);
h = MAX (h, hp_sp->y1);
w = MAX (w, hp_sp->x2);
h = MAX (h, hp_sp->y2);
w = MAX (w, hp_sp->x3);
h = MAX (h, hp_sp->y3);
x = MIN (x, hp_sp->x0);
y = MIN (y, hp_sp->y0);
x = MIN (x, hp_sp->x1);
y = MIN (y, hp_sp->y1);
x = MIN (x, hp_sp->x2);
y = MIN (y, hp_sp->y2);
x = MIN (x, hp_sp->x3);
y = MIN (y, hp_sp->y3);
hp_sp = hp_sp->next;
}
x = x * size_factor/2 * 0.8;
y = y * size_factor/2 * 0.8;
w = (w-x) * size_factor/2 * 1.1 ;
h = (h-y) * size_factor/2 * 1.1 ;
}
#ifdef GTK2
setlocale(LC_NUMERIC,"C");
#endif
metaDC = CreateEnhMetaFile (dc, filename, NULL, description);
SetMapMode (dc, MM_ANISOTROPIC);
SetViewportExtEx(dc,10,-10,NULL);
/* invisible box for image sizing */
SelectObject(metaDC,nopen);
MoveToEx(metaDC,x,h,NULL);
LineTo(metaDC,w,h);
LineTo(metaDC,w,y);
LineTo(metaDC,x,y);
LineTo(metaDC,x,h);
/* now do the actual drawing */
SelectObject(metaDC,pen);
SelectObject(metaDC,fill);
SetTextColor(metaDC,RGB(0x00,0x00,0x00));
SetTextAlign(metaDC,TA_LEFT+TA_BASELINE);
SetBkColor(metaDC,RGB(0xff,0xff,0xff));
SetBkMode(metaDC,OPAQUE);
hp_b = da_root.next;
for (d = 0; d < hp->n; d++)
{
if (mark.flag && (hp_b->smarked + hp_b->tmarked) == 0)
{
}
else
{
coord = bond_cut (hp_b->x, hp_b->y, hp_b->tx, hp_b->ty, 15);
x = coord->x;
y = coord->y;
tx = coord->tx;
ty = coord->ty;
if (!hp_b->bond)
{
MoveToEx (metaDC, x*size_factor/2,y*size_factor/2,dummy);
LineTo(metaDC,tx*size_factor/2,ty*size_factor/2);
}
if (hp_b->bond == 5)
{
points[0].x=x*size_factor/2;
points[0].y=y*size_factor/2;
points[1].x=(int) (tx - 0.1 * (ty - y))*size_factor/2;
points[1].y=(int) (ty + 0.1 * (tx - x))*size_factor/2;
points[2].x=(int) (tx + 0.1 * (ty - y))*size_factor/2;
points[2].y=(int) (ty - 0.1 * (tx - x))*size_factor/2;
Polygon(metaDC,points,3);
}
if (hp_b->bond == 6)
{
for (i = 0; i < 10; i++)
{
MoveToEx(metaDC,
(int) ((x + 0.1 * i * (tx - x) -
0.01 * (ty - y) * i)*size_factor/2),
(int) ((y + 0.1 * i * (ty - y) +
0.01 * (tx - x) * i)*size_factor/2),dummy);
LineTo(metaDC,
(int) ((x + 0.1 * i * (tx - x) +
0.01 * (ty - y) * i)*size_factor/2),
(int) ((y + 0.1 * i * (ty - y) -
0.01 * (tx - x) * i)*size_factor/2));
}
}
if (hp_b->bond == 7)
{
coord = multi_bonds (x, y, tx, ty, 2*mb_dist);
Arc(metaDC,(int)(coord->x*size_factor/2),(int)(coord->ty*size_factor/2),
(int)((x+0.25*(tx-x))*size_factor/2),
(int)((y+0.25*(ty-y))*size_factor/2),
(int)(coord->x*size_factor/2),(int)(coord->y*size_factor/2),
(int)((x+0.25*(tx-x))*size_factor/2),
(int)((y+0.25*(ty-y))*size_factor/2));
coord = multi_bonds (tx, ty, x, y, 2*mb_dist);
Arc(metaDC,(int)(coord->x*size_factor/2),(int)(coord->ty*size_factor/2),
(int)((x+0.5*(tx-x))*size_factor/2),
(int)((y+0.5*(ty-y))*size_factor/2),
(int)(coord->x*size_factor/2),(int)(coord->y*size_factor/2),
(int)((x+0.5*(tx-x))*size_factor/2),
(int)((y+0.5*(ty-y))*size_factor/2));
coord = multi_bonds (x, y, tx, ty, 2*mb_dist);
Arc(metaDC,(int)(coord->x*size_factor/2),(int)(coord->ty*size_factor/2),
(int)((x+0.75*(tx-x))*size_factor/2),
(int)((y+0.75*(ty-y))*size_factor/2),
(int)(coord->x*size_factor/2),(int)(coord->y*size_factor/2),
(int)((x+0.75*(tx-x))*size_factor/2),
(int)((y+0.75*(ty-y))*size_factor/2));
coord = multi_bonds (tx, ty, x, y, 2*mb_dist);
Arc(metaDC,(int)(coord->x*size_factor/2),(int)(coord->ty*size_factor/2),
(int)((x+1.*(tx-x))*size_factor/2),
(int)((y+1.*(ty-y))*size_factor/2),
(int)(coord->x*size_factor/2),(int)(coord->y*size_factor/2),
(int)((x+1.*(tx-x))*size_factor/2),
(int)((y+1.*(ty-y))*size_factor/2));
}
if (hp_b->bond == 8)
{
MoveToEx (metaDC, x*size_factor/2,y*size_factor/2,dummy);
LineTo(metaDC,tx*size_factor/2,ty*size_factor/2);
points[0].x=(int) (x + 0.8 * (tx - x))*size_factor/2;
points[0].y=(int) (y + 0.8 * (ty - y))*size_factor/2;
points[1].x=(int) (x + 0.8 * (tx - x) + 0.1 * (ty - y))*size_factor/2;
points[1].y=(int) (y + 0.8 * (ty - y) - 0.1 * (tx - x))*size_factor/2;
points[2].x=(int) (tx*size_factor/2);
points[2].y=(int) (ty*size_factor/2);
Polygon(metaDC,points,3);
}
if (hp_b->bond == 9)
{
MoveToEx (metaDC, x*size_factor/2,y*size_factor/2,dummy);
LineTo(metaDC,tx*size_factor/2,ty*size_factor/2);
points[0].x= (int) (tx*size_factor/2);
points[0].y= (int) (ty*size_factor/2);
points[1].x= (int) ((x + 0.8 * (tx - x) + 0.1 * (ty - y))*size_factor/2);
points[1].y= (int) ((y + 0.8 * (ty - y) - 0.1 * (tx - x))*size_factor/2);
points[2].x= (int) ((x + 0.8 * (tx - x) - 0.1 * (ty - y))*size_factor/2);
points[2].y= (int) ((y + 0.8 * (ty - y) + 0.1 * (tx - x))*size_factor/2);
Polygon(metaDC,points,3);
}
if (hp_b->bond == 11)
{
w=calc_vector(x-tx,y-ty);
Ellipse(metaDC, (x-w)*size_factor/2,
(y-w)*size_factor/2,
(x+w)*size_factor/2,
(y+w)*size_factor/2);
}
if (hp_b->bond == 10)
{
SelectObject(metaDC,widepen);
MoveToEx (metaDC, x*size_factor/2,y*size_factor/2,dummy);
LineTo(metaDC,tx*size_factor/2,ty*size_factor/2);
SelectObject(metaDC,pen);
}
if (hp_b->bond == 12)
{
SelectObject(metaDC,dottedpen);
MoveToEx (metaDC, x*size_factor/2,y*size_factor/2,dummy);
LineTo(metaDC,tx*size_factor/2,ty*size_factor/2);
SelectObject(metaDC,pen);
}
if (hp_b->bond == 13)
{
SelectObject(metaDC,whitepen);
MoveToEx (metaDC, x*size_factor/2,y*size_factor/2,dummy);
LineTo(metaDC,tx*size_factor/2,ty*size_factor/2);
SelectObject(metaDC,pen);
MoveToEx (metaDC, x*size_factor/2,y*size_factor/2,dummy);
LineTo(metaDC,tx*size_factor/2,ty*size_factor/2);
}
if (hp_b->bond == 4)
{
coord = center_double_bond (x, y, tx, ty, db_dist);
MoveToEx (metaDC, coord->x*size_factor/2,coord->y*size_factor/2,dummy);
LineTo(metaDC,coord->tx*size_factor/2,coord->ty*size_factor/2);
coord++;
MoveToEx (metaDC, coord->x*size_factor/2,coord->y*size_factor/2,dummy);
LineTo(metaDC,coord->tx*size_factor/2,coord->ty*size_factor/2);
}
if (hp_b->bond == 1 || hp_b->bond == 3)
{
coord = multi_bonds (x, y, tx, ty, mb_dist);
MoveToEx (metaDC, x*size_factor/2,y*size_factor/2,dummy);
LineTo(metaDC,tx*size_factor/2,ty*size_factor/2);
MoveToEx (metaDC, coord->x*size_factor/2,coord->y*size_factor/2,dummy);
LineTo(metaDC,coord->tx*size_factor/2,coord->ty*size_factor/2);
}
if (hp_b->bond == 2 || hp_b->bond == 3)
{
coord = multi_bonds (tx, ty, x, y, mb_dist);
MoveToEx (metaDC, x*size_factor/2,y*size_factor/2,dummy);
LineTo(metaDC,tx*size_factor/2,ty*size_factor/2);
MoveToEx (metaDC, coord->x*size_factor/2,coord->y*size_factor/2,dummy);
LineTo(metaDC,coord->tx*size_factor/2,coord->ty*size_factor/2);
}
if (hp_b->bond == 14)
{
coord = multi_bonds (x, y, tx, ty, mb_dist);
MoveToEx (metaDC, x*size_factor/2,y*size_factor/2,dummy);
LineTo(metaDC,tx*size_factor/2,ty*size_factor/2);
SelectObject(metaDC,dashedpen);
MoveToEx (metaDC, coord->x*size_factor/2,coord->y*size_factor/2,dummy);
LineTo(metaDC,coord->tx*size_factor/2,coord->ty*size_factor/2);
SelectObject(metaDC,pen);
}
if (hp_b->bond == 15)
{
coord = multi_bonds (tx, ty, x, y, mb_dist);
MoveToEx (metaDC, x*size_factor/2,y*size_factor/2,dummy);
LineTo(metaDC,tx*size_factor/2,ty*size_factor/2);
SelectObject(metaDC,dashedpen);
MoveToEx (metaDC, coord->x*size_factor/2,coord->y*size_factor/2,dummy);
LineTo(metaDC,coord->tx*size_factor/2,coord->ty*size_factor/2);
SelectObject(metaDC,pen);
}
if (hp_b->bond == 16)
{
coord = center_double_bond (x, y, tx, ty, db_dist);
x = coord->x;
y = coord->y;
tx = coord->tx;
ty = coord->ty;
coord++;
for (i = 0; i < 10; i++){
MoveToEx (metaDC,(int) (x+0.1*i*(tx-x)*size_factor/2),
(int)(y+0.1*i*(ty-y)*size_factor/2),dummy);
LineTo(metaDC,
(int)(coord->x+0.1*i*(coord->tx-coord->x)*size_factor/2),
(int)(coord->y+0.1*i*(coord->ty-coord->y)*size_factor/2));
}
}
}
hp_b = hp_b->next;
}
ha = 9 * fzoom;
ha = 9 *size_factor;
hp_a = dac_root.next;
for (d = 0; d < hp->nc; d++)
{
if (mark.flag && hp_a->marked == 0)
{
}
else
{
switch (hp_a->direct)
{
case Middle_Text:
chl = 0;
SetTextAlign(metaDC,TA_CENTER+TA_BOTTOM);
break;
case Left_Text:
chl = 9 * fzoom;
SetTextAlign(metaDC,TA_LEFT+TA_BOTTOM);
break;
case Right_Text:
chl = -9 * fzoom;
SetTextAlign(metaDC,TA_RIGHT+TA_BOTTOM);
break;
default:
fprintf (stderr, "undefined text direction in emf output\n");
rval = 3;
chl=0;
;;
}
nsub = 0;
nsup = 0;
for (i = 0; i < (int)strlen (hp_a->c); ++i)
if (hp_a->c[i] == '\\')
hp_a->c[i] = ' ';
if (!strpbrk (hp_a->c, "@_^|#"))
{ /*no sub- or superscripts */
xpos = hp_a->x * fzoom;
csize = fontsize * fzoom * 1.4;
SelectObject(metaDC,normalfont);
TextOutA(metaDC,(int)((hp_a->x)*size_factor/2),(int)((hp_a->y+25)*size_factor/2),
hp_a->c,(int)strlen(hp_a->c));
}
else
{ /* special formatting needed, every character becomes a separate entity */
l = (int)strlen (hp_a->c);
l = 0;
for (i = 0; i < (int)strlen (hp_a->c); i++)
{
switch (hp_a->c[i])
{
case '@':
break;
case '_':
case '^':
/* l -= .5; ??*/
break;
default:
l++;
}
}
fzoom=size_factor;
xpos = hp_a->x * size_factor - chl;
if (hp_a->direct == Right_Text) xpos=xpos-12*(l-2);
csize = fontsize * size_factor * 1.4;
shifted=0;
for (i = 0; i < (int)strlen (hp_a->c); i++)
{
offset = 0;
SelectObject(metaDC,normalfont);
csize = fontsize * fzoom * 1.4;
if (shifted != 0)
{
if (hp_a->c[i] == '}')
{
shifted = 0;
i++;
if (i >= (int)strlen (hp_a->c))
break;
}
else
{
offset = shifted;
}
}
if (hp_a->c[i] == '_')
{
if (chl >= 0)
csize = csize / 2;
offset = ha / 2;
nsub = nsub + 1;
if (nsub == 1)
{
if (nsup > 0)
xpos = savedpos;
else
savedpos = xpos;
}
nsup = 0;
}
if (hp_a->c[i] == '^')
{
offset = -ha / 2;
nsup = nsup + 1;
if (nsup == 1)
{
if (nsub > 0)
xpos = savedpos;
else
savedpos = xpos;
}
nsub = 0;
}
if (offset != 0)
{
SelectObject(metaDC,smallfont);
/* if (chl < 0)
xpos = xpos - csize / 2;
else
xpos = xpos - 20;*/
if (hp_a->direct==Right_Text)
xpos=xpos-10;
if (shifted == 0)
{
i++;
if (hp_a->c[i] == '{')
{
shifted = offset;
i++;
}
}
if (i >= (int)strlen (hp_a->c))
break;
if (hp_a->c[i] != '-' && hp_a->c[i] != '+')
offset = offset * 2;
}
else
{ /*reset sub- and superscript counters */
nsub = 0;
nsup = 0;
}
if (hp_a->c[i] == '@')
{
SelectObject(metaDC,symbolfont);
if (offset !=0) SelectObject(metaDC,smallsymbolfont);
i++;
}
if (hp_a->c[i] == '|')
{
SelectObject(metaDC,italicfont);
if (offset!=0) SelectObject(metaDC,smallitalicfont);
/* csize = csize / 2; */
i++;
}
if (hp_a->c[i] == '#')
{
SelectObject(metaDC,boldfont);
if (offset!=0) SelectObject(metaDC,smallboldfont);
i++;
}
sprintf(tmpstring,"%c",hp_a->c[i]);
TextOutA(metaDC,(int)((xpos-10+abs(offset/2))/2),
(int)((hp_a->y+25)*size_factor/2),
tmpstring,(int)strlen(tmpstring));
xpos = xpos + 20;
if (zoom_factor < 2)
xpos = xpos + 10;
} /*for i */
} /* normal or special formatting */
for (i = 0; i < (int)strlen (hp_a->c); ++i)
if (hp_a->c[i] == ' ')
hp_a->c[i] = '\\';
} /* if within current set*/
hp_a = hp_a->next;
} /* for all labels */
hp_sp = sp_root.next;
for (d = 0; d < hp->nsp; d++)
{
if (mark.flag == 1 && hp_sp->marked == 0)
{
}
else
{
points[0].x=hp_sp->x0 *size_factor/2;
points[0].y=hp_sp->y0 *size_factor/2;
points[1].x=hp_sp->x1 *size_factor/2;
points[1].y=hp_sp->y1 *size_factor/2;
points[2].x=hp_sp->x2 *size_factor/2;
points[2].y=hp_sp->y2 *size_factor/2;
points[3].x=hp_sp->x3 *size_factor/2;
points[3].y=hp_sp->y3 *size_factor/2;
switch (hp_sp->type)
{
case 0:
case 1:
case 2:
PolyBezier(metaDC,points,4);
break;
;;
case -2:
SelectObject(metaDC,dashedpen);
PolyBezier(metaDC,points,4);
SelectObject(metaDC,pen);
break;
;;
case -1:
SelectObject(metaDC,fill);
PolyBezier(metaDC,points,4);
SelectObject(metaDC,pen);
}
if (hp_sp->type > 0)
{
xbase =
0.7 * 0.7 * 0.7 * (double) hp_sp->x3 + 3. * 0.7 * 0.7 * (1. -
0.7)
* (double) hp_sp->x2 + 3. * 0.7 * (1. - 0.7) * (1. -
0.7) *
(double) hp_sp->x1 + (1. - 0.7) * (1. - 0.7) * (1. -
0.7) *
hp_sp->x0;
ybase =
0.7 * 0.7 * 0.7 * (double) hp_sp->y3 + 3. * 0.7 * 0.7 * (1. -
0.7)
* (double) hp_sp->y2 + 3. * 0.7 * (1. - 0.7) * (1. -
0.7) *
(double) hp_sp->y1 + (1. - 0.7) * (1. - 0.7) * (1. -
0.7) *
hp_sp->y0;
xlen = hp_sp->x3 - xbase;
ylen = hp_sp->y3 - ybase;
if (xlen != 0)
xlen = (int) copysign (50., xlen);
if (ylen != 0)
ylen = (int) copysign (50., ylen);
xside = xbase + 0.15 * ylen;
yside = ybase - 0.15 * xlen;
if (hp_sp->type == 1)
{
xend = xbase - 0.15 * ylen;
yend = ybase + 0.15 * xlen;
x =
(xside - hp_sp->x0) * (xside - hp_sp->x0) + (yside -
hp_sp->y0) *
(yside - hp_sp->y0);
tx =
(xend - hp_sp->x0) * (xend - hp_sp->x0) + (yend -
hp_sp->y0) *
(yend - hp_sp->y0);
if (tx > x)
{
xside = xend;
yside = yend;
}
xend = xbase; /*on baseline */
yend = ybase;
}
else
{
xend = xbase - 0.15 * ylen;
yend = ybase + 0.15 * xlen;
}
SelectObject(metaDC,fill);
points[0].x=hp_sp->x3*size_factor/2;
points[0].y=hp_sp->y3*size_factor/2;
points[1].x=xside*size_factor/2;
points[1].y=yside*size_factor/2;
points[2].x=xend*size_factor/2;
points[2].y=yend*size_factor/2;
Polygon(metaDC,points,3);
SelectObject(metaDC,pen);
}
}
hp_sp = hp_sp->next;
}
mfh=CloseEnhMetaFile(metaDC);
DeleteEnhMetaFile(mfh);
DeleteDC(metaDC);
return (0);
}
#endif
int
export_bitmap (char *filename)
/* exports the current drawing to an X11 bitmap file */
{
int x, y, w, h;
struct data *hp_b;
struct dc *hp_a;
struct spline *hp_sp;
int d;
int retval;
char xfile[512];
Pixmap buffer;
GdkPixmap *bitmap;
GdkGC *bitmapgc;
if (mark.flag && mark.w != 0 && mark.h != 0)
{
x = mark.x * size_factor + 3;
y = mark.y * size_factor + 3;
w = mark.w * size_factor - 6;
h = mark.h * size_factor - 6;
}
else
{
/* get true extents of drawing*/
x = 10000;
y = 10000;
w = 0;
h = 0;
hp_b = da_root.next;
for (d = 0; d < hp->n; d++)
{
w = MAX (w, hp_b->x);
w = MAX (w, hp_b->tx);
h = MAX (h, hp_b->y);
h = MAX (h, hp_b->ty);
x = MIN (x, hp_b->x);
x = MIN (x, hp_b->tx);
y = MIN (y, hp_b->y);
y = MIN (y, hp_b->ty);
hp_b = hp_b->next;
}
hp_a = dac_root.next;
for (d = 0; d < hp->nc; d++)
{
w = MAX (w, hp_a->x);
if (hp_a->direct > -2)
w = MAX (w, hp_a->x + (int)strlen (hp_a->c) * (6 + 2 * size_factor));
h = MAX (h, hp_a->y + 8);
x = MIN (x, hp_a->x);
if (hp_a->direct < 0)
x = MIN (x, hp_a->x - (int)strlen (hp_a->c) * (6 + 2 * size_factor));
y = MIN (y, hp_a->y - 8);
hp_a = hp_a->next;
}
hp_sp = sp_root.next;
for (d = 0; d < hp->nsp; d++)
{
w = MAX (w, hp_sp->x0);
h = MAX (h, hp_sp->y0);
w = MAX (w, hp_sp->x1);
h = MAX (h, hp_sp->y1);
w = MAX (w, hp_sp->x2);
h = MAX (h, hp_sp->y2);
w = MAX (w, hp_sp->x3);
h = MAX (h, hp_sp->y3);
x = MIN (x, hp_sp->x0);
y = MIN (y, hp_sp->y0);
x = MIN (x, hp_sp->x1);
y = MIN (y, hp_sp->y1);
x = MIN (x, hp_sp->x2);
y = MIN (y, hp_sp->y2);
x = MIN (x, hp_sp->x3);
y = MIN (y, hp_sp->y3);
hp_sp = hp_sp->next;
}
x = (int) (x * size_factor * 0.9);
y = (int) (y * size_factor * 0.9);
w = (int) (w * size_factor * 1.1 - x);
h = (int) (h * size_factor * 1.1 - y);
if (x < 0)
x = 0;
if (y < 0)
y = 0;
}
bitmap = gdk_pixmap_new (drawing_area->window, 1, 1, 1);
bitmapgc = gdk_gc_new (bitmap);
buffer = XCreatePixmap (GDK_WINDOW_XDISPLAY(picture), GDK_WINDOW_XWINDOW(picture),
(unsigned int)w, (unsigned int)h, 1);
XCopyPlane (GDK_WINDOW_XDISPLAY(picture), GDK_WINDOW_XWINDOW(picture), buffer,
GDK_GC_XGC(bitmapgc), x, y, (unsigned int)w, (unsigned int)h, 0, 0, 1);
if ((int)strlen (filename))
{
snprintf (xfile,512, "%s", filename);
retval = XWriteBitmapFile (GDK_DISPLAY (), xfile, buffer,
(unsigned int)w, (unsigned int)h, -1, -1);
gdk_pixmap_unref (bitmap);
gdk_gc_unref (bitmapgc);
XFreePixmap (GDK_DISPLAY (), buffer);
return (retval);
}
return (0);
}
void
xfig_line (FILE * fp, int x, int y, int tx, int ty)
/* writes a single line bond in XFig notation */
{
fprintf (fp, "%i %i %i %i %i %i %i %i %i %.3f %i %i %i %i %i %i\n",
figline.object, figline.sub_type, figline.line_style,
figline.thickness, figline.pen_color, figline.fill_color,
figline.depth, figline.pen_style, figline.area_fill,
figline.style_val, figline.join_style, figline.cap_style,
figline.radius, figline.forward_arrow, figline.backward_arrow,
figline.npoints);
fprintf (fp, "%i %i %i %i\n", x, y, tx, ty);
}
void
xfig_wedge (FILE * fp, int x, int y, int tx, int ty, int factor, int latex)
/* writes a wedge definition in XFig notation */
{
struct data *hpc;
struct xy_co *coord;
int d, x1, y1, x2, y2;
int bond_already_tuned;
float area;
x1 = tx - (int) (0.1 * (float) (ty - y));
y1 = ty + (int) (0.1 * (float) (tx - x));
x2 = tx + (int) (0.1 * (float) (ty - y));
y2 = ty - (int) (0.1 * (float) (tx - x));
hpc = da_root.next;
bond_already_tuned = 0;
for (d = 0; d < hp->n; d++)
{
if (hpc->bond == 10)
{
if (
(abs (hpc->x * factor - tx) < 3
&& abs (hpc->y * factor - ty) < 3)
|| (abs (hpc->tx * factor - tx) < 3
&& abs (hpc->ty * factor - ty) < 3))
{
coord =
center_double_bond (hpc->x, hpc->y, hpc->tx, hpc->ty, db_dist);
if (abs (hpc->x * factor - tx) < 3
&& abs (hpc->y * factor - ty) < 3)
{
x1 = coord->x * factor;
y1 = coord->y * factor;
coord++;
x2 = coord->x * factor;
y2 = coord->y * factor;
}
else
{
x1 = coord->tx * factor;
y1 = coord->ty * factor;
coord++;
x2 = coord->tx * factor;
y2 = coord->ty * factor;
}
area = 0.5 * abs (x * (y1 - y2)
+ x1 * (y2 - y) + x2 * (y - y1));
if (fabs (area) < 76. * factor)
{
x1 = tx - (int) (0.05 * (float) (ty - y));
y1 = ty + (int) (0.05 * (float) (tx - x));
x2 = tx + (int) (0.05 * (float) (ty - y));
y2 = ty - (int) (0.05 * (float) (tx - x));
}
else bond_already_tuned = 1;
}
}
if (hpc->bond == 0 && !bond_already_tuned) {
if ((abs (hpc->x * factor - tx) < 3 && abs (hpc->y * factor - ty) < 3)
||(abs (hpc->tx * factor - tx) < 3 && abs (hpc->ty * factor - ty) < 3))
/* let the wedge smooth along a another bond */
{
coord = intersect(x,y,x1,y1,hpc->x*factor,hpc->y*factor,
hpc->tx*factor,hpc->ty*factor);
coord->tx = coord->x;
coord->ty = coord->y;
coord = intersect(x,y,x2,y2,hpc->x*factor,hpc->y*factor,
hpc->tx*factor,hpc->ty*factor);
x1 = coord->tx;
y1 = coord->ty;
x2 = coord->x;
y2 = coord->y;
area = 0.5 * abs (x * (y1 - y2)
+ x1 * (y2 - y) + x2 * (y - y1));
if (fabs (area) > 3300. * factor || fabs(area) < 1750. * factor)
{
x1 = tx - (int) (0.1 * (float) (ty - y));
y1 = ty + (int) (0.1 * (float) (tx - x));
x2 = tx + (int) (0.1 * (float) (ty - y));
y2 = ty - (int) (0.1 * (float) (tx - x));
}
}
}
hpc = hpc->next;
}
if (!latex)
{
fprintf (fp, "%i %i %i %i %i %i %i %i %i %f %i %i %i %i %i %i\n",
figline.object, figline.sub_type, figline.line_style,
figline.thickness, figline.pen_color, figline.fill_color,
figline.depth, figline.pen_style, figline.area_fill + 21,
figline.style_val, figline.join_style, figline.cap_style,
figline.radius, figline.forward_arrow, figline.backward_arrow,
figline.npoints + 1);
fprintf (fp, "%i %i %i %i %i %i\n", x, y, x1, y1, x2, y2);
}
else
{
for (d = 0; d < 10; d++)
xfig_line (fp, x, y, x1 + d * (x2 - x1) / 10,
y1 + d * (y2 - y1) / 10);
}
}
void
xfig_wiggly (FILE * fp, int x, int y, int tx, int ty)
/* writes a wavy bond in XFig notation */
{
int arccode = 5;
int arctype = 1;
int direction = 1;
float xlen, ylen, veclen, boxlen;
int boxcorx, boxcory;
int i;
float center_x, center_y;
int xstart, ystart, xmid, ymid, xend, yend;
xlen = (float)(tx - x);
ylen = (float)(ty - y);
veclen = (float)calc_vector (abs (tx - x), abs (ty - y));
boxlen = 0.2 * veclen;
boxcorx = (int) ((1. - xlen / veclen) * boxlen / 2);
boxcory = (int) ((1. - ylen / veclen) * boxlen / 2);
for (i = 0; i < 5; i++)
{
direction = abs (direction - 1);
center_x = x + (0.2 * i + .1) * xlen;
center_y = y + (0.2 * i + .1) * ylen;
xstart = (int) (x + 0.2 * i * xlen);
ystart = (int) (y + 0.2 * i * ylen);
xmid = (int) (center_x - boxcorx * pow (-1, (double)i));
ymid = (int) (center_y - boxcory * pow (-1, (double)i));
if (x > tx)
{
xmid = (int) (center_x + boxcorx * pow (-1, (double)i));
ymid = (int) (center_y + boxcory * pow (-1, (double)i));
}
xend = (int) (x + 0.2 * (i + 1) * xlen);
yend = (int) (y + 0.2 * (i + 1) * ylen);
fprintf (fp,
"%i %i %i %i %i %i %i %i %i %f %i %i %i %i %f %f %i %i %i %i %i %i\n",
arccode, arctype, figline.line_style, figline.thickness,
figline.pen_color, figline.fill_color, figline.depth,
figline.pen_style, figline.area_fill, figline.style_val,
figline.cap_style, direction, figline.forward_arrow,
figline.backward_arrow, center_x, center_y, xstart, ystart,
xmid, ymid, xend, yend);
}
}
void
xfig_arrow (FILE * fp, int x, int y, int tx, int ty, int type, int latex)
/* writes an arrow in XFig notation */
{
float xlen, ylen;
float headfact;
int xbase, ybase, xside, yside, xend, yend;
int i;
float veclen;
xlen = (float)(tx - x);
ylen = (float)(ty - y);
headfact = 0.8;
xbase = x + headfact * xlen;
ybase = y + headfact * ylen;
if (select_char (tx,ty,1) != NULL){
veclen = (float)calc_vector(tx-x,ty-y);
xbase = x+headfact*xlen-10*xlen/veclen;
ybase = y+headfact*ylen-10*ylen/veclen;
}
xside = (int) (xbase + 0.05 * ylen);
yside = (int) (ybase - 0.05 * xlen);
xend = (int) (xbase - type * (0.05 * ylen)); /*type=0 (half arrow) ends on baseline, */
yend = (int) (ybase + type * (0.05 * xlen)); /*type=1 is a symmetrical arrowhead */
if (type == 1)
{
/* symmetrical arrow */
fprintf (fp, "%i %i %i %i %i %i %i %i %i %f %i %i %i %i %i %i\n",
figline.object, figline.sub_type, figline.line_style,
figline.thickness, figline.pen_color, figline.fill_color,
figline.depth, figline.pen_style, figline.area_fill,
figline.style_val, figline.join_style, figline.cap_style,
figline.radius, figline.forward_arrow + 1,
figline.backward_arrow, figline.npoints);
fprintf (fp, "%i %i %f %f %f\n", /* arrow attributes */
1, /* arrow_type (triangle, as before) */
1, /* arrow_style (1 == filled) */
2.00, /* arrow_thickness (1/80inch) */
72.00, /* arrow_width (fig units (?) ) */
114.00 /* arrow_height (fig units) */
);
fprintf (fp, "%i %i %i %i\n", x, y, tx, ty);
}
else
{
/* half arrow */
/* the line */
fprintf (fp, "%i %i %i %i %i %i %i %i %i %f %i %i %i %i %i %i\n",
figline.object, figline.sub_type, figline.line_style,
figline.thickness, figline.pen_color, figline.fill_color,
figline.depth, figline.pen_style, figline.area_fill,
figline.style_val, figline.join_style, figline.cap_style,
figline.radius, figline.forward_arrow, figline.backward_arrow,
figline.npoints);
fprintf (fp, "%i %i %i %i\n", x, y, tx, ty);
/* and the arrowhead - a filled polyline */
if (!latex)
{
fprintf (fp, "%i %i %i %i %i %i %i %i %i %f %i %i %i %i %i %i\n",
figline.object, figline.sub_type, figline.line_style,
figline.thickness, figline.pen_color, figline.fill_color,
figline.depth, figline.pen_style, figline.area_fill + 21,
figline.style_val, figline.join_style, figline.cap_style,
figline.radius, figline.forward_arrow,
figline.backward_arrow, figline.npoints + 1);
fprintf (fp, "%i %i %i %i %i %i\n", tx, ty, xside, yside, xend,
yend);
}
else
{
for (i = 0; i < 10; i++)
xfig_line (fp, tx, ty, xend + i * (xside - xend) / 10,
yend + i * (yside - yend) / 10);
}
}
}
void
xfig_circle (FILE * fp, int x, int y, int tx, int ty)
{
int radius;
float start_ang = 0.;
int direction = 1;
radius = calc_vector (abs (tx - x), abs (ty - y));
fprintf (fp, "1 3 %i %i %i %i %i %i %i %.4f %i %.4f %i %i %i %i %i %i %i %i\n",
figline.line_style,
figline.thickness, figline.pen_color, figline.fill_color,
figline.depth, figline.pen_style, figline.area_fill,
figline.style_val, direction,
start_ang, x, y, radius, radius, tx, ty, tx, ty);
}
void
xfig_spline (FILE * fp, int x0, int y0, int x1, int y1, int x2, int y2,
int x3, int y3, int type, int latex)
/* draws a spline curve, optionally with full of half arrowhead */
{
int xlen, ylen, xbase, ybase, flag;
double px0, py0, px1, py1;
int i;
double t;
double dist;
int xside, yside, xend, yend;
figline.npoints = 21;
if (type == -2)
{
figline.line_style = 2;
figline.style_val = 4;
}
if (type == -1)
{
figline.area_fill = 20;
}
/* if (type == 1)*/
/* figline.npoints = 15;*/
/* the line */
fprintf (fp, "%i %i %i %i %i %i %i %i %i %f %i %i %i %i %i %i\n",
figline.object, figline.sub_type, figline.line_style,
figline.thickness, figline.pen_color, figline.fill_color,
figline.depth, figline.pen_style, figline.area_fill,
figline.style_val, figline.join_style, figline.cap_style,
figline.radius, figline.forward_arrow, figline.backward_arrow,
figline.npoints);
fprintf (fp, "%i %i\n", x0, y0);
px0 = (double)x0;
py0 = (double)y0;
xbase = 0;
ybase = 0;
flag = 0;
for (i = 0; i < figline.npoints -1 ; i++)
{
t = (float) i / (figline.npoints -2 );
px1 =
t * t * t * (double) x3 + 3. * t * t * (1. - t) * (double) x2 +
3. * t * (1. - t) * (1. - t) * (double) x1 + (1. - t) * (1. -
t) * (1. -
t) *
px0;
py1 =
t * t * t * (double) y3 + 3. * t * t * (1. - t) * (double) y2 +
3. * t * (1. - t) * (1. - t) * (double) y1 + (1. - t) * (1. -
t) * (1. -
t) *
py0;
fprintf (fp, "%i %i\n", (int) px1, (int) py1);
if (type >= 0) {
dist = (x3-px1) * (x3-px1) + (y3-py1) * (y3-py1) ;
if (( flag == 0) && ( i == 18 || (i >= 15 && dist < 30000.) ) )
{
xbase = (int)px1;
ybase = (int)py1;
if (dist >30000.) {
xbase += (x3-xbase)/2;
ybase += (y3-ybase)/2;
}
flag = 1;
}
}
}
figline.line_style = 0;
figline.style_val = 0;
figline.area_fill = -1;
figline.npoints = 2;
if (type <= 0)
return;
xlen = x3 - xbase;
ylen = y3 - ybase;
if (xlen != 0)
xlen = (int) copysign (50., (double)xlen);
if (ylen != 0)
ylen = (int) copysign (50., (double)ylen);
xside = (int) (xbase + 0.5 * ylen);
yside = (int) (ybase - 0.5 * xlen);
if (type == 1)
{
xend = (int) (xbase - 0.5 * ylen);
yend = (int) (ybase + 0.5 * xlen);
px0 = (double)((xside - x0) * (xside - x0) + (yside - y0) * (yside - y0));
px1 = (double)((xend - x0) * (xend - x0) + (yend - y0) * (yend - y0));
if (px1 > px0)
{
xside = xend;
yside = yend;
}
xend = xbase; /*on baseline */
yend = ybase;
}
else
{
xend = (int) (xbase - 0.5 * ylen);
yend = (int) (ybase + 0.5 * xlen);
}
/* add the arrowhead - a filled polyline */
if (!latex)
{
fprintf (fp, "%i %i %i %i %i %i %i %i %i %f %i %i %i %i %i %i\n",
figline.object, figline.sub_type, figline.line_style,
figline.thickness, figline.pen_color, figline.fill_color,
figline.depth, figline.pen_style, figline.area_fill + 21,
figline.style_val, figline.join_style, figline.cap_style,
figline.radius, figline.forward_arrow, figline.backward_arrow,
figline.npoints + 1);
fprintf (fp, "%i %i %i %i %i %i\n", (int) x3, (int) y3, xside, yside,
xend, yend);
}
else
{
for (i = 0; i < 10; i++)
xfig_line (fp, x3, y3, xend + i * (xside - xend) / 10,
yend + i * (yside - yend) / 10);
}
}
int
exfig (FILE * fp, int latex_flag)
/* export the current molecule in the format of Brian Smith' XFig program */
{
struct data *hp_b;
struct dc *hp_a;
struct spline *hp_sp;
struct xy_co *coord;
int i;
float l;
int d, x, y, tx, ty;
int n;
#ifdef GTK2
int tw;
static PangoLayout *thelayout;
char cc[2];
#endif
int ulx, uly, lrx, lry;
int ha, chl = 0;
int fontsize = 12, fzoom = 10;
int xpos, offset, fontshrink;
int shifted = 0;
int nsub, nsup, savedpos;
int csize;
char symbol[30];
int rval = 0;
float charscale; /* scale textlength, width according to zoom factor */
int len;
float step;
const int myfontheight[7]={8,8,9,14,12,14,24};
#ifdef GTK2
setlocale(LC_NUMERIC,"C");
#endif
savedpos = 0;
switch (zoom_factor)
{
case 0:
fontsize = 8; /*8 */
fzoom = 9; /*6,4 */
charscale = 0.5;
break;
case 1:
fontsize = 10; /*6? */
fzoom = 9; /*5? */
charscale = 0.75;
break;
case 2:
fontsize = 12; /*9? */
fzoom = 11; /*7? */
charscale = 1.0;
break;
case 3:
fontsize = 16; /*12? */
fzoom = 12; /*12,10? */
charscale = 1.25;
break;
case 4:
fontsize = 18;
fzoom = 13;
charscale = 1.3;
break;
default:
charscale = 1.;
fprintf (stderr, "no figfont parameters for zoom factor %d\n",
zoom_factor);
rval = 2;
}
if (!fprintf (fp, "#FIG 3.2\n"))
return (1);
fprintf (fp, "Portrait\n");
fprintf (fp, "Center\n");
fprintf (fp, "Metric\n");
fprintf (fp, "A4\n");
fprintf (fp, "100.00\n");
fprintf (fp, "Single\n");
fprintf (fp, "0\n");
fprintf (fp, "# generated by Chemtool " VERSION "\n");
fprintf (fp, "1200 2\n");
figline.object = 2;
figline.sub_type = 1;
figline.line_style = 0;
figline.thickness = 2;
figline.pen_color = 0;
figline.fill_color = 7;
figline.depth = 100;
figline.pen_style = 0;
figline.area_fill = -1;
figline.style_val = 0.000;
figline.join_style = 0;
figline.cap_style = 0;
figline.radius = -1;
figline.forward_arrow = 0;
figline.backward_arrow = 0;
figline.npoints = 2;
hp_b = da_root.next;
for (d = 0; d < hp->n; d++)
{
if (mark.flag && (hp_b->smarked + hp_b->tmarked) == 0)
{
}
else
{
figline.pen_color = hp_b->color;
figline.fill_color = hp_b->color;
coord = bond_cut (hp_b->x, hp_b->y, hp_b->tx, hp_b->ty, 12);
if(hp_b->bond==11) coord = bond_cut (hp_b->x, hp_b->y, hp_b->tx, hp_b->ty, 0);
#if 0
if(hp_b->bond==5 || hp_b->bond==6) coord = bond_cut (hp_b->x, hp_b->y, hp_b->tx, hp_b->ty, 15);
#endif
x = coord->x * fzoom;
y = coord->y * fzoom;
tx = coord->tx * fzoom;
ty = coord->ty * fzoom;
#if 1
if ( !use_whiteout) {
i=has_label(hp_b->x,hp_b->y);
if (i>=0) {
int ox=x;
x += (1.*fzoom*(i+1)/calc_vector(abs(tx-x),abs(ty-y))) *(tx-x);
y += (1.*fzoom*(i+1)/calc_vector(abs(tx-ox),abs(ty-y))) *(ty-y);
}
i=has_label(hp_b->tx,hp_b->ty);
if (i>=0) {
int otx=tx;
tx -= (1.*fzoom*(i+1)/calc_vector(abs(tx-x),abs(ty-y))) *(tx-x);
ty -= (1.*fzoom*(i+1)/calc_vector(abs(otx-x),abs(ty-y))) *(ty-y);
}
}
#endif
if (!hp_b->bond)
xfig_line (fp, x, y, tx, ty);
if (hp_b->bond == 5)
{
xfig_wedge (fp, x, y, tx, ty, fzoom, latex_flag);
}
if (hp_b->bond == 6)
{
len=(int) (calc_vector(abs(tx-x),abs(ty-y))/(8.*fzoom));
if (len <8 ) len=8;
step=1./len;
for (i = 1; i < len; i=i+1)
xfig_line (fp, (int) (x + step * i * (tx - x) - 0.01 * (ty - y) * i),
(int) (y + step * i * (ty - y) + 0.01 * (tx - x) * i),
(int) (x + step * i * (tx - x) + 0.01 * (ty - y) * i),
(int) (y + step * i * (ty - y) - 0.01 * (tx - x) * i));
}
if (hp_b->bond == 7)
xfig_wiggly (fp, x, y, tx, ty);
if (hp_b->bond == 8)
xfig_arrow (fp, x, y, tx, ty, 0, latex_flag);
if (hp_b->bond == 9)
xfig_arrow (fp, x, y, tx, ty, 1, latex_flag);
if (hp_b->bond == 11)
xfig_circle (fp, x, y, tx, ty);
if (hp_b->bond == 10)
{
figline.thickness = 6; /* 4 ? */
xfig_line (fp, x, y, tx, ty);
figline.thickness = 2; /* 1 ? */
}
if (hp_b->bond == 12)
{
figline.line_style = 2;
figline.style_val = 4;
xfig_line (fp, x, y, tx, ty);
figline.line_style = 0;
figline.style_val = 0;
}
if (hp_b->bond == 13)
{
figline.thickness = 6;
figline.pen_color = 7;
figline.depth = 85;
xfig_line (fp, x + (tx - x) / 4, y + (ty - y) / 4,
tx - (tx - x) / 4, ty - (ty - y) / 4);
figline.thickness = 2;
figline.pen_color = 0;
figline.depth = 80;
xfig_line (fp, x, y, tx, ty);
figline.depth = 100;
}
if (hp_b->bond == 4)
{
coord = center_double_bond (x, y, tx, ty, db_dist * fzoom);
xfig_line (fp, coord->x, coord->y, coord->tx, coord->ty);
coord++;
xfig_line (fp, coord->x, coord->y, coord->tx, coord->ty);
}
if (hp_b->bond == 1 || hp_b->bond == 3)
{
coord = multi_bonds (x, y, tx, ty, mb_dist * fzoom);
xfig_line (fp, x, y, tx, ty);
xfig_line (fp, coord->x, coord->y, coord->tx, coord->ty);
}
if (hp_b->bond == 2 || hp_b->bond == 3)
{
coord = multi_bonds (tx, ty, x, y, mb_dist * fzoom);
xfig_line (fp, x, y, tx, ty);
xfig_line (fp, coord->x, coord->y, coord->tx, coord->ty);
}
if (hp_b->bond == 14)
{
coord = multi_bonds (x, y, tx, ty, mb_dist * fzoom);
xfig_line (fp, x, y, tx, ty);
figline.line_style = 1;
figline.style_val = 2.;
xfig_line (fp, coord->x, coord->y, coord->tx, coord->ty);
figline.line_style = 0;
figline.style_val = 0.;
}
if (hp_b->bond == 15)
{
coord = multi_bonds (tx, ty, x, y, mb_dist * fzoom);
xfig_line (fp, x, y, tx, ty);
figline.line_style = 1;
figline.style_val = 2.;
xfig_line (fp, coord->x, coord->y, coord->tx, coord->ty);
figline.line_style = 0;
figline.style_val = 0.;
}
if (hp_b->bond == 16)
{
coord = center_double_bond (x, y, tx, ty, db_dist * fzoom);
x = coord->x;
y = coord->y;
tx = coord->tx;
ty = coord->ty;
coord++;
for (i = 0; i < 10; i++)
xfig_line (fp, (int) (x + 0.1 * i * (tx - x)),
(int) (y + 0.1 * i * (ty - y)),
(int) (coord->x + 0.1 * i * (coord->tx - coord->x)),
(int) (coord->y + 0.1 * i * (coord->ty - coord->y)));
}
if (hp_b->bond == 18)
{
xfig_line (fp, x, y, tx, ty);
coord = center_double_bond (x, y, tx, ty, (db_dist+1) * fzoom);
xfig_line (fp, coord->x, coord->y, coord->tx, coord->ty);
coord++;
xfig_line (fp, coord->x, coord->y, coord->tx, coord->ty);
}
if (hp_b->bond == 19)
{
int tmpx1,tmpx2,tmpy1,tmpy2,tmptx1,tmptx2,tmpty1,tmpty2;
coord = center_double_bond (x, y, tx, ty, (db_dist+2) * fzoom);
tmpx1=coord->x;
tmpy1=coord->y;
tmptx1=coord->tx;
tmpty1=coord->ty;
coord++;
tmpx2=coord->x;
tmpy2=coord->y;
tmptx2=coord->tx;
tmpty2=coord->ty;
coord = center_double_bond (tmpx1,tmpy1,tmptx1,tmpty1,(db_dist-1)*fzoom);
xfig_line (fp, coord->x, coord->y, coord->tx, coord->ty);
coord++;
xfig_line (fp, coord->x, coord->y, coord->tx, coord->ty);
coord = center_double_bond (tmpx2,tmpy2,tmptx2,tmpty2,(db_dist-1)*fzoom);
xfig_line (fp, coord->x, coord->y, coord->tx, coord->ty);
coord++;
xfig_line (fp, coord->x, coord->y, coord->tx, coord->ty);
}
/* hp_b = hp_b->next;*/
}
hp_b = hp_b->next;
}
figtext.object = 4;
figtext.sub_type = 0;
figtext.color = 0;
figtext.depth = 90;
figtext.pen_style = 0;
figtext.font = 16; /*16=helvetica*,12=courier */
figtext.font_size = fontsize;
figtext.angle = 0.000;
if (!latex_flag)
figtext.font_flags = 4; /*6?? messes up bounding box*/
else
figtext.font_flags = 6;
figtext.height = 180. *charscale;
figtext.length = 170. *charscale;
hp_a = dac_root.next;
for (d = 0; d < hp->nc; d++)
{
if (mark.flag && hp_a->marked == 0)
{
}
else
{
fontsize=hp_a->size;
if (zoom_factor <2) fontsize-= 2-zoom_factor;
if (zoom_factor >2) fontsize+= zoom_factor-2;
if (fontsize <0) fontsize=0;
if (fontsize >6) fontsize=6;
switch (fontsize)
{
case 0:
figtext.font_size = 8; /*8 */
break;
case 1:
figtext.font_size = 10; /*6? */
break;
case 2:
figtext.font_size = 12; /*9? */
break;
case 3:
figtext.font_size = 16; /*12? */
break;
case 4:
figtext.font_size = 18;
break;
case 5:
figtext.font_size = 20;
break;
case 6:
figtext.font_size = 24;
break;
default:
fprintf (stderr, "no figfont parameters for fontsize %d\n",
fontsize);
rval = 2;
}
/* fzoom = size_factor * 16. ;*/ /* 75dpi screen to 1200dpi FIG */
#ifdef GTK2
if (!thelayout) thelayout = gtk_widget_create_pango_layout(drawing_area,"X");
pango_layout_set_text(thelayout, "X", -1);
pango_layout_set_font_description(thelayout,symbfont[fontsize]);
pango_layout_get_pixel_size(thelayout, NULL, &ha);
ha = ha/100 *fzoom;
#else
ha=fzoom * gdk_char_height(font[fontsize],(gchar)'X');
#endif
ha=(int)(fzoom/2. * myfontheight[fontsize]);
figtext.height = 180. *charscale;
figtext.length = 170. *charscale;
figtext.color = hp_a->color;
if (hp_a->font == 0)
figtext.font = 16; /* Helvetica */
else
figtext.font = 0; /* Times */
figtext.sub_type = abs (hp_a->direct);
switch (hp_a->direct)
{
case Middle_Text:
chl = 0;
break;
case Left_Text:
chl = 9 * fzoom;
break;
case Right_Text:
chl = -9 * fzoom;
break;
default:
fprintf (stderr, "undefined text direction in xfig output\n");
rval = 3;
;;
}
nsub = 0;
nsup = 0;
for (i = 0; i < (int)strlen (hp_a->c); ++i)
if (hp_a->c[i] == '\\')
hp_a->c[i] = ' ';
if (!strpbrk (hp_a->c, "@_^|#"))
{ /*no sub- or superscripts */
xpos = hp_a->x * fzoom;
csize = (int) (fontsize * fzoom /* * 1.4*/);
if (chl < 0)
xpos -= (int)strlen (hp_a->c) * csize;
if (chl == 0)
xpos -= (int)strlen (hp_a->c) * csize / 2;
ulx = xpos;
if (chl > 0)
ulx = xpos - csize / 2;
/* if (chl == 0) ulx = xpos+ csize/2; */
if (chl < 0)
ulx = xpos + csize;
uly = hp_a->y * fzoom - ha;
lrx = xpos + (int)strlen (hp_a->c) * csize - csize / 2;
if (chl == 0) lrx += csize/2;
if (chl < 0)
lrx = lrx + csize;
lry = hp_a->y * fzoom + ha;
/*whiteout box*/
if (use_whiteout == 1) fprintf (fp, " 6 %i %i %i %i\n", ulx, uly, lrx, lry);
if (use_whiteout == 1 && !latex_flag)
{
fprintf (fp, " 2 2 0 1 7 7 95 0 20 1 0 0 5 0 0 5\n");
fprintf (fp, "%i %i\n", ulx, uly);
fprintf (fp, "%i %i\n", lrx, uly);
fprintf (fp, "%i %i\n", lrx, lry);
fprintf (fp, "%i %i\n", ulx, lry);
fprintf (fp, "%i %i\n", ulx, uly);
}
if (latex_flag)
{
int ii,jj;
char latexstr[255];
jj=0;
for (ii=0;ii<(int)strlen(hp_a->c);ii++){
if (hp_a->c[ii] == '°' ){
latexstr[jj++]='\0';
strcat(latexstr,"$^{\\\\circ}$");
jj += 10;
continue;
}
if (hp_a->c[ii] == (char)169 ){
latexstr[jj++]='\0';
strcat(latexstr,"$\\\\copyright$");
jj += 12;
continue;
}
if (hp_a->c[ii] == (char)174 ){
latexstr[jj++]='\0';
strcat(latexstr,"$\\\\textregistered$");
jj += 17;
continue;
}
if (hp_a->c[ii] == (char)177 ){
latexstr[jj++]='\0';
strcat(latexstr,"$\\\\pm$");
jj += 5;
continue;
}
if (hp_a->c[ii]=='%' || hp_a->c[ii]=='$') {
latexstr[jj++]='\\';
latexstr[jj++]='\\';
}
latexstr[jj++]=hp_a->c[ii];
}
latexstr[jj]='\0';
fprintf (fp,
"%i %i %i %i %i %i %d %.4f %i %f %f %i %i %s\\001\n",
figtext.object, figtext.sub_type, figtext.color,
figtext.depth, figtext.pen_style, figtext.font,
figtext.font_size, figtext.angle,
figtext.font_flags, figtext.height,
figtext.length * (int)strlen (latexstr),
hp_a->x * fzoom - chl, hp_a->y * fzoom + ha,
latexstr);
}
else
{
//{
float tlen=0.;
int xxx;
int cw;
#ifdef GTK2
gchar *c;
c=g_convert(hp_a->c,-1,"ISO8859-1","UTF-8",NULL,NULL,NULL);
if (!c) c=g_strdup(hp_a->c);
#else
char *c = strdup(hp_a->c);
#endif
for (xxx=0;xxx<strlen(hp_a->c);xxx++){
#ifdef GTK2
gchar *cx;
cx=g_locale_to_utf8(hp_a->c,-1,NULL,NULL,NULL);
if (!cx) cx = g_convert(hp_a->c,-1,"UTF-8","ISO8859-1",NULL,NULL,NULL);
if (!cx) {
fprintf(stderr,"invalid character cx in chemtool file\n");
return 1;
}
if (!thelayout) thelayout = gtk_widget_create_pango_layout(drawing_area,cx);
pango_layout_set_text(thelayout, cx, -1);
pango_layout_set_font_description(thelayout,font[fontsize]);
pango_layout_get_pixel_size(thelayout, &cw, NULL);
tlen+=1.25*cw;
#else
cw=gdk_char_width(font[fontsize],(gchar)hp_a->c[xxx]);
tlen+=15.*cw;
if (hp_a->c[xxx]==' ') tlen+=12.*cw;
#endif
}
//fprintf(stderr,"text #%s#, len_alt %f, len_neu %f\n",
//hp_a->c, figtext.length*(int)strlen(hp_a->c), tlen);
//}
fprintf (fp,
"%i %i %i %i %i %i %d %.4f %i %f %f %i %i %s\\001\n",
figtext.object, figtext.sub_type, figtext.color,
figtext.depth, figtext.pen_style, figtext.font,
figtext.font_size, figtext.angle,
figtext.font_flags, figtext.height,
// figtext.length * (int)strlen (hp_a->c),
tlen,
(int)(hp_a->x * fzoom - chl ),
hp_a->y * fzoom + ha,
c);
}
if (use_whiteout==1) fprintf (fp, "-6\n"); /* close block (around whiteout and label) */
}
else
{ /* special formatting needed, every character becomes a separate entity */
figtext.sub_type = 1; /* have xfig center characters at the calculated position */
l = 0;
#ifdef GTK2
if (!thelayout) thelayout = gtk_widget_create_pango_layout(drawing_area,hp_a->c);
pango_layout_set_font_description(thelayout,font[fontsize]);
n = (int) g_utf8_strlen(hp_a->c,-1);
#else
n = (int)strlen (hp_a->c);
#endif
for (i = 0; i < (int)strlen (hp_a->c); i++)
{
switch (hp_a->c[i])
{
case '@':
i++;
if (hp_a->c[i]=='}' || hp_a->c[i]=='{' ) i++;
#ifdef GTK2
cc[0]=hp_a->c[i];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,symbfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
l+= tw*fzoom;
#else
l+=gdk_char_width(symbfont[fontsize],hp_a->c[i])*fzoom;
#endif
break;
case '#':
i++;
if (hp_a->c[i]=='}' || hp_a->c[i]=='{' ) i++;
#ifdef GTK2
cc[0]=hp_a->c[i];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,boldfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
l+= tw*fzoom;
#else
l+=gdk_char_width(boldfont[fontsize],hp_a->c[i])*fzoom;
#endif
break;
case '|':
i++;
if (hp_a->c[i]=='}' || hp_a->c[i]=='{' ) i++;
#ifdef GTK2
cc[0]=hp_a->c[i];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,slfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
l+=tw*fzoom;
#else
l+=gdk_char_width(slfont[fontsize],hp_a->c[i])*fzoom;
#endif
break;
case '}':
case '{':
break;
case '_':
nsub=1;
i++;
if (hp_a->c[i]=='}' || hp_a->c[i]=='{' ) i++;
#ifdef GTK2
cc[0]=hp_a->c[i];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,smallfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
l+=tw*fzoom;
#else
l+=gdk_char_width(smallfont[fontsize],hp_a->c[i])*fzoom;
#endif
break;
case '^':
nsup=1;
i++;
if (hp_a->c[i]=='}' || hp_a->c[i]=='{' ) i++;
#ifdef GTK2
cc[0]=hp_a->c[i];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,smallfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
l+=tw*fzoom;
#else
l+=gdk_char_width(smallfont[fontsize],hp_a->c[i])*fzoom;
#endif
break;
default:
#ifdef GTK2
cc[0]=hp_a->c[i];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,font[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
l+=tw*fzoom;
#else
l+=gdk_char_width(font[fontsize],hp_a->c[i])*fzoom;
#endif
}
}
xpos = hp_a->x * fzoom ;
#ifdef GTK2
cc[0]=hp_a->c[0];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,font[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
csize= tw *fzoom*2;
#else
csize = gdk_char_width(font[fontsize],hp_a->c[0])*fzoom*2;
#endif
if (chl < 0) {
xpos = hp_a->x * fzoom -l + csize/2;
}
if (chl == 0)
xpos = hp_a->x * fzoom - l / 2;
/* glue text into compound for easier editing in xfig */
ulx = xpos -csize/2;
uly = hp_a->y * fzoom - ha;
lrx = xpos + l ;
if (chl < 0)
lrx = xpos + (l - 1);
lry = hp_a->y * fzoom + ha;
if (nsup != 0) uly -= ha; /* height adjustment for */
if (nsub != 0) lry += ha; /* sub- and superscript */
fprintf (fp, " 6 %i %i %i %i\n", ulx, uly, lrx, lry);
/*whiteout box*/
if (use_whiteout == 1 && !latex_flag)
{
fprintf (fp, " 2 2 0 1 7 7 95 0 20 1 0 0 5 0 0 5\n");
fprintf (fp, "%i %i\n", ulx, uly);
fprintf (fp, "%i %i\n", lrx, uly);
fprintf (fp, "%i %i\n", lrx, lry);
fprintf (fp, "%i %i\n", ulx, lry);
fprintf (fp, "%i %i\n", ulx, uly);
}
nsub=nsup=0;
for (i = 0; i < (int)strlen (hp_a->c); i++)
{
offset = 0;
fontshrink = 0;
if (hp_a->font == 0)
figtext.font = 16; /*Helvetica */
else
figtext.font = 0; /* Times */
#ifdef GTK2
cc[0]=hp_a->c[i];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,font[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
/*
if (cc[0]=='C') csize=161;
else if (cc[0]=='H') csize=145;
else
*/
csize= 1+ tw *fzoom;
#else
csize = (1+gdk_char_width(font[fontsize],hp_a->c[i])) * fzoom;
#endif
if (shifted != 0)
{
if (hp_a->c[i] == '}')
{
shifted = 0;
offset = 0;
i++;
if (i >= n) break;
#ifdef GTK2
cc[0]=hp_a->c[i];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,font[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
csize= 1+ tw *fzoom;
#else
csize = (1+gdk_char_width(font[fontsize],hp_a->c[i])) * fzoom;
#endif
}
else
{
offset = shifted;
#ifdef GTK2
cc[0]=hp_a->c[i];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,smallfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
csize= 1+ tw *fzoom;
#else
csize = (1+gdk_char_width(smallfont[fontsize],hp_a->c[i])) * fzoom;
#endif
}
}
if (hp_a->c[i] == '_')
{
#ifdef GTK2
cc[0]=hp_a->c[i+1];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,smallfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
csize= 1+ tw *fzoom;
#else
csize = (1+gdk_char_width(smallfont[fontsize],hp_a->c[i+1])) * fzoom;
#endif
offset = ha / 2;
nsub = nsub + 1;
if (nsub == 1)
{
if (nsup > 0)
xpos = savedpos;
else
savedpos = xpos;
}
nsup = 0;
}
if (hp_a->c[i] == '^')
{
offset = -ha;
/* offset = -ha / 2;*/
#ifdef GTK2
cc[0]=hp_a->c[i+1];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,smallfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
csize= 1+ tw *fzoom;
#else
csize = (1+gdk_char_width(smallfont[fontsize],hp_a->c[i+1])) * fzoom;
#endif
nsup = nsup + 1;
if (nsup == 1)
{
if (nsub > 0)
xpos = savedpos;
else
savedpos = xpos;
}
nsub = 0;
}
if (offset != 0)
{
if (shifted == 0)
{
i++;
if (hp_a->c[i] == '{')
{
shifted = offset;
i++;
#ifdef GTK2
cc[0]=hp_a->c[i];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,smallfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
csize= 1+ tw *fzoom;
#else
csize = (1+gdk_char_width(smallfont[fontsize],hp_a->c[i])) * fzoom;
#endif
}
}
if (i >= (int)strlen (hp_a->c))
break;
if (hp_a->c[i] != '-' && hp_a->c[i] != '+')
fontshrink = 4;
offset = offset * 2;
/* xpos -= csize*.75;*/
xpos -= csize*.35;
}
else
{ /*reset sub- and superscript counters */
nsub = 0;
nsup = 0;
}
if (hp_a->c[i] == '@')
{
figtext.font = 32;
#ifdef GTK2
cc[0]=hp_a->c[i+1];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,symbfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
csize= 1+ tw *fzoom;
#else
csize = (1+gdk_char_width(symbfont[fontsize],hp_a->c[i+1])) * fzoom;
#endif
i++;
}
if (hp_a->c[i] == '|')
{
if (figtext.font <16)
figtext.font = 1; /* Times Italic */
else
figtext.font = 17; /* Helvetica Oblique */
#ifdef GTK2
cc[0]=hp_a->c[i+1];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,slfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
csize= 1+ tw *fzoom;
#else
csize = (1+2*gdk_char_width(slfont[fontsize],hp_a->c[i+1])) * fzoom;
#endif
xpos-= csize;
i++;
}
if (hp_a->c[i] == '#')
{
if (figtext.font < 16)
figtext.font = 2 ; /* Times Bold */
else
figtext.font = 18; /* Helvetica Bold */
#ifdef GTK2
cc[0]=hp_a->c[i+1];
cc[1]='\0';
pango_layout_set_text(thelayout, cc, -1);
pango_layout_set_font_description(thelayout,boldfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, NULL);
csize= 1+ tw *fzoom;
#else
csize = (1+gdk_char_width(boldfont[fontsize],hp_a->c[i+1])) * fzoom;
#endif
i++;
}
if (figtext.font_size-fontshrink <8) csize *=0.8;
if (hp_a->c[i] == '(' || hp_a->c[i] == ')' ) xpos -= csize;
if (hp_a->c[i] == 'i' || hp_a->c[i] == 'l' ) xpos -= csize;
if (latex_flag)
{
if (figtext.font == 32 /* use TeX names for symbols */
|| (unsigned char) hp_a->c[i] > 128 || hp_a->c[i]=='%' || hp_a->c[i]=='$')
{
switch ((unsigned char) hp_a->c[i])
{
case 'a':
strcpy (symbol, "$\\\\alpha$");
break;
case 'b':
strcpy (symbol, "$\\\\beta$");
break;
case 'c':
strcpy (symbol, "$\\\\chi$");
break;
case 'd':
strcpy (symbol, "$\\\\delta$");
break;
case 'e':
strcpy (symbol, "$\\\\varepsilon$");
break;
case 'f':
strcpy (symbol, "$\\\\phi$");
break;
case 'g':
strcpy (symbol, "$\\\\gamma$");
break;
case 'h':
strcpy (symbol, "$\\\\eta$");
break;
case 'i':
strcpy (symbol, "$\\\\iota$");
break;
case 'j':
strcpy (symbol, "$\\\\varphi$");
break;
case 'k':
strcpy (symbol, "$\\\\kappa$");
break;
case 'l':
strcpy (symbol, "$\\\\lambda$");
break;
case 'm':
strcpy (symbol, "$\\\\mu$");
break;
case 'n':
strcpy (symbol, "$\\\\nu$");
break;
case 'p':
strcpy (symbol, "$\\\\pi$");
break;
case 'q':
strcpy (symbol, "$\\\\theta$");
break;
case 'r':
strcpy (symbol, "$\\\\rho$");
break;
case 's':
strcpy (symbol, "$\\\\sigma$");
break;
case 't':
strcpy (symbol, "$\\\\tau$");
break;
case 'u':
strcpy (symbol, "$\\\\upsilon$");
break;
case 'v':
strcpy (symbol, "$\\\\varpi$");
break;
case 'w':
strcpy (symbol, "$\\\\omega$");
break;
case 'x':
strcpy (symbol, "$\\\\xi$");
break;
case 'y':
strcpy (symbol, "$\\\\psi$");
break;
case 'z':
strcpy (symbol, "$\\\\zeta$");
break;
case 'C':
strcpy (symbol, "X");
break;
case 'D':
strcpy (symbol, "$\\\\Delta$");
break;
case 'F':
strcpy (symbol, "$\\\\Phi$");
break;
case 'G':
strcpy (symbol, "$\\\\Gamma$");
break;
case 'J':
strcpy (symbol, "$\\\\vartheta$");
break;
case 'L':
strcpy (symbol, "$\\\\Lambda$");
break;
case 'P':
strcpy (symbol, "$\\\\Pi$");
break;
case 'Q':
strcpy (symbol, "$\\\\Theta$");
break;
case 'R':
strcpy (symbol, "P");
break;
case 'S':
strcpy (symbol, "$\\\\Sigma$");
break;
case 'U':
strcpy (symbol, "$\\\\Upsilon$");
break;
case 'V':
strcpy (symbol, "$\\\\varsigma$");
break;
case 'W':
strcpy (symbol, "$\\\\Omega$");
break;
case 'X':
strcpy (symbol, "$\\\\Xi$");
break;
case 'Y':
strcpy (symbol, "$\\\\Psi$");
break;
case (unsigned char) 173:
strcpy (symbol, "$\\\\uparrow$");
break;
case (unsigned char) 175:
strcpy (symbol, "$\\\\downarrow$");
break;
case (unsigned char) 174:
#if 0
strcpy (symbol,
"$\\\\bigcirc\\\\hspace{-1.5ex}R$");
#else
strcpy (symbol,
"$\\\\textregistered$");
#endif
break;
case '%':
strcpy (symbol, "\\\\%");
break;
case '$':
strcpy (symbol, "\\\\$");
break;
case (unsigned char) 176:
strcpy(symbol,
"$^{\\\\circ}$");
break;
case (unsigned char) 177:
strcpy(symbol,
"$\\\\pm$");
break;
case (unsigned char) 169:
strcpy(symbol,
"$\\\\copyright$");
break;
default:
fprintf (stderr, "no translation for %d\n",
(unsigned char) hp_a->c[i]);
symbol[0] = hp_a->c[i];
symbol[1] = '\0';
break;
}
fprintf (fp,
"%i %i %i %i %i %i %d %.4f %i %f %f %i %i %s \\001\n",
figtext.object, figtext.sub_type,
figtext.color, figtext.depth,
figtext.pen_style, figtext.font,
figtext.font_size - fontshrink,
figtext.angle, figtext.font_flags,
figtext.height, figtext.length,
xpos,
hp_a->y * fzoom + ha + offset, symbol);
}
else
{
fprintf (fp,
"%i %i %i %i %i %i %d %.4f %i %f %f %i %i %c\\001\n",
figtext.object, figtext.sub_type,
figtext.color, figtext.depth,
figtext.pen_style, figtext.font,
figtext.font_size - fontshrink,
figtext.angle, figtext.font_flags,
figtext.height, figtext.length,
xpos,
hp_a->y * fzoom + ha + offset, hp_a->c[i]);
}
}
else
{ /* not in LaTeX mode */
fprintf (fp,
"%i %i %i %i %i %i %d %.4f %i %f %f %i %i %c\\001\n",
figtext.object, figtext.sub_type,
figtext.color, figtext.depth,
figtext.pen_style, figtext.font,
figtext.font_size - fontshrink, figtext.angle,
figtext.font_flags, figtext.height,
(double)csize*2, xpos,
hp_a->y * fzoom + ha + offset, hp_a->c[i]);
}
if (hp_a->c[i] == '(' || hp_a->c[i] == ')' ) xpos += csize;
if (hp_a->c[i] == 'l' || hp_a->c[i] == 'i' ) xpos += csize;
xpos = (int)(xpos + csize *1.1) ;
} /*for i */
fprintf (fp, "-6\n"); /* close this compound */
}
#ifdef GTK2
n = (int) g_utf8_strlen(hp_a->c,-1);
#else
n = (int)strlen (hp_a->c);
#endif
for (i = 0; i < n; ++i)
if (hp_a->c[i] == ' ')
hp_a->c[i] = '\\';
}
hp_a = hp_a->next;
}
figline.pen_color = 0; /* reset after linedrawing */
hp_sp = sp_root.next;
for (d = 0; d < hp->nsp; d++)
{
if (mark.flag == 1 && hp_sp->marked == 0)
{
}
else
{
figline.pen_color=hp_sp->color;
figline.fill_color=hp_sp->color;
xfig_spline (fp, hp_sp->x0 * fzoom, hp_sp->y0 * fzoom,
hp_sp->x1 * fzoom, hp_sp->y1 * fzoom,
hp_sp->x2 * fzoom, hp_sp->y2 * fzoom,
hp_sp->x3 * fzoom, hp_sp->y3 * fzoom,
hp_sp->type, latex_flag);
}
hp_sp = hp_sp->next;
}
return (rval);
}
int
export_xfig (char *filename)
/* initiate exporting of the current molecule in plain XFig format */
{
FILE *xfile;
int rval;
if ((int)strlen (filename))
{
xfile = fopen (filename, "w");
if (!xfile)
return (1);
rval = exfig (xfile, 0);
if (fclose (xfile) != 0)
{
perror ("could not close fig file");
return (1);
}
return (rval);
}
return (1);
}
int
export_latex_pic (char *filename, float scale)
/* export molecule as a pictex file by writing a temporary XFig file and
postprocessing that with fig2dev */
{
char com[255];
FILE *xfile;
int rval;
if (figversion == 0)
return (1); /* cannot export without fig2dev */
if ((int)strlen (filename))
{
snprintf (com,255, "fig2dev -Lpictex -m %f > %s", scale, filename);
xfile = popen (com, "w");
if (!xfile)
return (1);
rval = exfig (xfile, 1);
if (pclose (xfile) != 0)
return (1);
return (rval);
}
else
return (1);
}
int
export_ps_pic (char *filename, float scale)
/* export molecule as a postscript file by writing a temporary XFig file and
postprocessing that with fig2dev */
{
char com[255];
FILE *xfile;
int rval;
char *epso[4] = {" ","-A","-T","-C"};
char intl[3];
#ifdef GTK2
setlocale (LC_NUMERIC,"C");
#endif
if (figversion == 0)
return (1); /* cannot export without fig2dev */
if (use_intlchars)
strcpy(intl,"-j");
else
strcpy(intl,"");
if ((int)strlen (filename))
{
if (figversion == 1)
snprintf (com,255, "fig2dev %s -Lps -m %f > %s", intl, scale, filename);
else if (figversion == 2)
snprintf (com,255, "fig2dev %s -L eps -m %f > %s", intl, scale, filename);
else
snprintf (com,255, "fig2dev %s -L eps %s -m %f -g \\%s> %s", intl,epso[epsoption], scale, bghexcolor, filename);
xfile = popen (com, "w");
if (!xfile)
return (1);
rval = exfig (xfile, 0);
if (rval != 0)
return (rval);
rval=pclose(xfile);
if (rval != 0)
return (1);
else
return (rval);
}
else
return (1);
}
int
export_png_pic (char *filename, float scale)
/* export molecule as a png file by writing a temporary XFig file and
postprocessing that with fig2dev */
{
char com[255];
FILE *xfile;
int rval;
char intl[3];
#ifdef GTK2
setlocale (LC_NUMERIC,"C");
#endif
if (figversion == 0)
return (1); /* cannot export without fig2dev */
if (use_intlchars)
strcpy(intl,"-j");
else
strcpy(intl,"");
if ((int)strlen (filename))
{
if (figversion == 1)
snprintf (com,255, "fig2dev %s -Lpng -m %f > %s", intl, scale, filename);
else
snprintf (com,255, "fig2dev %s -L png -S 4 -F -m %f > %s", intl, scale, filename);
xfile = popen (com, "w");
if (!xfile)
return (1);
rval = exfig (xfile, 0);
if (rval != 0)
return (rval);
rval=pclose(xfile);
if (rval != 0)
return (1);
else
return (rval);
}
else
return (1);
}
int
print_ps_pic (char *filename)
/* Print molecule to a postscript printer by creating an XFig datastream and
postprocessing that with fig2dev */
{
char com[255];
int rval;
FILE *xfile;
char intl[3];
#ifdef GTK2
setlocale (LC_NUMERIC,"C");
#endif
if (figversion == 0)
return (1); /* cannot print without fig2dev */
if (use_intlchars)
strcpy(intl,"-j");
else
strcpy(intl,"");
if (figversion == 1)
snprintf (com,255, "fig2dev %s -L ps -z %s -P %s -e -m %f | %s%s",
intl,paper[papersize], orientation[orient], printscale,
printcommand[printcmd], queuename);
else
snprintf (com,255, "fig2dev %s -L ps -z %s %s -e -m %f | %s%s",
intl,paper[papersize], orientation[orient], printscale,
printcommand[printcmd], queuename);
xfile = popen (com, "w");
if (!xfile)
return (1);
rval = exfig (xfile, 0);
if (rval != 0)
return (rval);
rval=pclose(xfile);
if (rval != 0)
return (1);
else
return (rval);
}
int
export_fw (char *filename)
/* save file and postprocess it with cht */
{
char com[255];
char xfile[512];
int rval;
FILE *chtpipe;
FILE *fp;
int fd;
if ((int)strlen (filename))
{
strcpy (xfile, "/tmp/chtXXXXXX");
/*@ignore@ splint does not recognize mkstemp */
fd = mkstemp (xfile);
/*@end@*/
if (fd == -1)
return 1;
snprintf (com,255, "cht %s", xfile);
fp = fdopen (fd, "w");
save_mol (fp, mark.flag);
fclose (fp);
chtpipe = popen (com, "r");
if (!chtpipe) return (1);
rval = fscanf (chtpipe, "%20s %20s %20s %64s", formula, weight, eweight,
compos);
rval = pclose (chtpipe);
unlink (xfile);
return (rval);
}
else
return (1);
}
int
readrc ()
{
FILE *fp;
int i;
char key[20], value[100];
char line[80];
gchar *filename;
char *epso[4] = { "None","EPSI","TIFFm","TIFFc" };
filename = g_malloc (PATH_MAX + 1);
filename =
strncat (strncpy (filename, g_get_home_dir (), PATH_MAX), "/.chemtoolrc",
PATH_MAX);
fp = fopen (filename, "r");
if (!fp)
{
g_free (filename);
return 1;
}
else
{
while (!feof (fp))
{
if (fgets (line, (int)sizeof (line), fp)) {
i = sscanf (line, "%s %s", key, value);
if (i < 2)
continue;
if (!strcmp (key, "orientation"))
{
if (!strcmp (value, "portrait"))
orient = 0;
else
orient = 1;
}
if (!strcmp (key, "papersize"))
{
for (i = 0; i < 11; i++)
if (!strcmp (value, paper[i]))
papersize = i;
}
if (!strcmp (key, "printcommand"))
{
for (i = 0; i < (int)strlen (value); i++)
if (value[i] == '\\')
value[i] = ' ';
for (i = 0; i < 2; i++)
if (!strcmp (value, printcommand[i]))
printcmd = i;
}
if (!strcmp (key, "printer"))
strcpy (queuename, value);
if (!strcmp (key, "printscale"))
printscale = atof (value);
if (!strcmp (key, "epsoption"))
for (i = 0; i < 4; i++) {
if (!strcmp (value, epso[i]))
epsoption = i;
}
if (!strcmp (key, "whiteout"))
use_whiteout = atoi (value);
if (!strcmp (key, "intlchars"))
use_intlchars = atoi (value);
if (!strcmp (key, "datadir"))
strcpy (datadir, value);
if (!strcmp (key, "extension"))
strcpy (datamask, value);
if (!strcmp (key, "bondlength")){
bondlen_mm= atof(value);
if (bondlen_mm != 0 && bondlen_mm != 10.668) size_factor*=bondlen_mm/10.668;
}
if (!strcmp (key, "double_separation")){
db_dist = atoi(value);
if (db_dist <= 0 || db_dist >100) db_dist=4;
mb_dist = (int) ( ( (float)db_dist )* 2.5 );
}
if (!strcmp (key, "background")){
i=sscanf(value,"(%d,%d,%d)",&bgred,&bggreen,&bgblue);
if (i<3) bgred=bggreen=bgblue=65535;
}
}
}
fclose (fp);
g_free (filename);
return 0;
}
}
int
writerc ()
{
FILE *fp;
char *pcomm[3] = { "lpr\\-P", "lp\\-d", "kprinter -d"};
char *ori[2] = { "portrait", "landscape" };
char *epso[4] = { "None","EPSI","TIFFm","TIFFc" };
gchar *filename;
filename = g_malloc (PATH_MAX + 1);
filename =
strncat (strncpy (filename, g_get_home_dir (), PATH_MAX), "/.chemtoolrc",
PATH_MAX);
fp = fopen (filename, "w");
if (!fp)
{
g_free (filename);
return 1;
}
else
{
fprintf (fp, "datadir %s\n", datadir);
fprintf (fp, "extension %s\n", datamask);
fprintf (fp, "papersize %s\n", paper[papersize]);
fprintf (fp, "orientation %s\n", ori[orient]);
fprintf (fp, "printscale %f\n", printscale);
fprintf (fp, "printcommand %s\n", pcomm[printcmd]);
fprintf (fp, "printer %s\n", queuename);
fprintf (fp, "bondlength %6.4f\n", bondlen_mm);
fprintf (fp, "double_separation %d\n", db_dist);
fprintf (fp, "epsoption %s\n", epso[epsoption]);
fprintf (fp, "whiteout %d\n", use_whiteout);
fprintf (fp, "intlchars %d\n", use_intlchars);
fprintf (fp, "background (%d,%d,%d)\n", bgred,bggreen,bgblue);
fclose (fp);
g_free (filename);
return 0;
}
}
void
check_fig2dev ()
{
char cmd[20];
FILE *xfile;
float version;
float ref=3.2;
int pl;
int rval;
#ifdef GTK2
setlocale (LC_NUMERIC,"C");
#endif
snprintf (cmd,20, "fig2dev -V");
xfile = popen (cmd, "r");
rval = fscanf (xfile, "%*s %*s %f %*s %d", &version, &pl);
rval = pclose (xfile);
if (rval != 0)
figversion = 0; /* fig2dev not found */
else
{
if (version < ref || (version == ref && pl < 3))
figversion = 1; /* "old" fig2dev, needs -Lps */
else
figversion = 2; /* new fig2dev, knows -L eps */
if (version > ref || (version == ref && pl >3))
figversion = 3; /* 3.2.4 can generate previews in eps file */
}
}
void
check_babel ()
{
char cmd[20];
char data[80];
FILE *xfile;
/* float version;*/
int rval;
int start=0,stop=0;
int obmajor=0,obminor=0,obrel=0;
babelin=-1;
babelout=-1;
memset(data,'\0',80);
snprintf (cmd,20, "babel 2>/dev/null");
xfile = popen (cmd, "r");
if (!xfile)return;
if (!fgets (data,80,xfile)){
pclose(xfile);
return;
}
if (!strncmp(data,"Open",4)) { /* OpenBabel 1.x */
strcpy(babeloutp,"--");
sscanf(data,"%*s %*s %d.%d.%d",&obmajor,&obminor,&obrel);
if (obmajor*10000+obminor*10+obrel >= 11001) {
rval=pclose(xfile);
snprintf(cmd,20,"babel -H");
xfile = popen (cmd, "r");
}
} else if (!strncmp(data,"No output",9)) { /* OpenBabel 2.x */
strcpy(babeloutp,"--");
rval=pclose(xfile);
snprintf(cmd,20,"babel -H");
xfile = popen (cmd, "r");
}
else /* original babel 1.6 */
strcpy(babeloutp,"CON");
while (!feof(xfile)) {
if (fgets (data,80,xfile)) {
if (!strncmp(data,"Currently",9)|| !strncmp(data,"The following",13)) {
start=1;
break;
}
}
}
babelin=-1;
inmode=NULL;
intype=NULL;
babelout=-1;
outmode=NULL;
outtype=NULL;
if (start==1){
while (!feof(xfile)){
(void)fgets (data, 80, xfile);
if (!strncmp(data,"Currently",9)|| !strncmp(data,"See further",11)) {
stop=1;
babelin--;
babelout--;
break;
}else if (strstr(data,"Write-only")==NULL) {
babelin++;
inmode = realloc (inmode, (babelin + 1) * sizeof (char *));
inmode[babelin] = malloc (9 * sizeof (char));
intype = realloc (intype, (babelin + 1) * sizeof (char *));
intype[babelin] = malloc (39 * sizeof (char));
sscanf(data,"%s -- %36[a-zA-Z0-9 -]",inmode[babelin],intype[babelin]);
}
if (strstr(data,"Read-only")==NULL) {
babelout++;
outmode = realloc (outmode, (babelout + 1) * sizeof (char *));
outmode[babelout] = malloc (10 * sizeof (char));
outtype = realloc (outtype, (babelout + 1) * sizeof (char *));
outtype[babelout] = malloc (39 * sizeof (char));
sscanf(data,"%s -- %36[a-zA-Z0-9 -]",outmode[babelout],outtype[babelout]);
}
}
}
rval = pclose (xfile);
if (rval != 0 && babelin <=0 )
fprintf(stderr,"Consider installing Babel/OpenBabel for file format conversions...\n");
#if 0
else
{
for (start=0;start<=babelin;start++)
fprintf(stderr,"BABEL input %s : %s\n",inmode[start],intype[start]);
for (start=0;start<=babelout;start++)
fprintf(stderr,"BABEL output %s : %s\n",outmode[start],outtype[start]);
}
#endif
}
int
export_sxd (char *filename)
/* export molecule as a pictex file by writing a temporary XFig file and
postprocessing that with fig2sxd */
{
char com[255];
FILE *xfile;
int rval;
if (have_fig2sxd == 0)
return (1); /* cannot export without fig2sxd */
if ((int)strlen (filename))
{
snprintf (com,255, "fig2sxd - %s", filename);
xfile = popen (com, "w");
if (!xfile)
return (1);
rval = exfig (xfile, 1);
if (pclose (xfile) < 0)
return (1);
return (rval);
}
else
return (1);
}
void
check_fig2sxd ()
{
char cmd[20];
FILE *xfile;
char myname[10];
have_fig2sxd = 0;
snprintf (cmd,20, "fig2sxd 2>&1");
xfile = popen (cmd, "r");
if (!xfile) return;
fscanf (xfile, "%s", myname);
pclose (xfile);
if (!strncmp(myname,"fig2sxd",7)) have_fig2sxd = 1;
}
int
export_babel (char *filename)
/* export molecule by writing a temporary molfile and
postprocessing that with (open)babel, adding explicit hydrogens
if necessary */
{
char com[255];
FILE *xfile;
int rval;
if ((int)strlen (filename))
{
snprintf (com,255, "babel -h -imol %s -o%s %s", babeloutp, babel, filename);
xfile = popen (com, "w");
if (!xfile)
return (1);
rval = export_mdl_mol (xfile, 1);
if (pclose (xfile) < 0)
return (1);
return (rval);
}
else
return (1);
}
syntax highlighted by Code2HTML, v. 0.9.1