/*
* functions for the graphic output of the pixmap
*/
#include <string.h>
#include "ct1.h"
#ifdef GTK2
PangoFontDescription *font[7], *smallfont[7], *symbfont[7],
*ssymbfont[7], *slfont[7],
*boldfont[7], *textfont[7];
#else
GdkFont *font[7], *smallfont[7], *symbfont[7],
*ssymbfont[7], *slfont[7],
*boldfont[7], *textfont[7];
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
void
CreatePix ()
/* initializes fonts, linestyles and factors */
{
float ztab[] = { 0.4, 0.6, 0.8, 1, 1.2 };
int ltab[] = { 0, 0, 2, 2, 2 };
/* int ftab[] = { 2, 3, 4, 5, 6 };*/
size_factor = ztab[zoom_factor];
if (bondlen_mm != 0 && bondlen_mm != 10.668) size_factor *= bondlen_mm/10.668;
head.pix_width = 1600;
head.pix_height = 1600;
Set_Line (ltab[zoom_factor]);
}
void
FreePix ()
/* erases the drawing area */
{
GdkRectangle update_rect;
int i;
gdk_draw_rectangle (picture,
background_gc,
TRUE, 0, 0,
(gint)drawing_area->allocation.width,
(gint)drawing_area->allocation.height);
if (gridtype==1) {
for (i=0+gridx;i<=(int)drawing_area->allocation.width;i=i+50)
gdk_draw_line (picture, drawing_area->style->bg_gc[GTK_STATE_INSENSITIVE],
(gint) (i * size_factor), (gint) (0),
(gint) (i * size_factor), (gint) (drawing_area->allocation.height));
for (i=0+gridy;i<=(int)drawing_area->allocation.height;i=i+50)
gdk_draw_line (picture, drawing_area->style->bg_gc[GTK_STATE_INSENSITIVE],
(gint) (0), (gint) (i*size_factor),
(gint) (drawing_area->allocation.width), (gint) (i * size_factor));
}
if (gridtype==2){
for (i=-2560+gridx;i<=5280;i=i+64){
gdk_draw_line (picture, drawing_area->style->bg_gc[GTK_STATE_INSENSITIVE],
(gint) (0+gridx), (gint) ((gridy+i)*size_factor),
(gint) (5500+gridx)*size_factor,
(gint) (3200+gridy+i) * size_factor);
gdk_draw_line (picture, drawing_area->style->bg_gc[GTK_STATE_INSENSITIVE],
(gint) (0+gridx), (gint) ((i+gridy)*size_factor),
(gint) (5500+gridx)*size_factor,
(gint) (-3200+gridy+i) * size_factor);
}
}
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
CopyPlane ()
/* updates the display with the contents of the background pixmap */
{
GdkRectangle update_rect;
gdk_draw_pixmap (drawing_area->window,
drawing_area->style->
fg_gc[GTK_WIDGET_STATE (drawing_area)], picture, 0, 0, 0,
0, head.pix_width, head.pix_height);
update_rect.x = 0;
update_rect.y = 0;
update_rect.width = (guint16)head.pix_width;
update_rect.height = (guint16)head.pix_height;
}
void
Display_Mol ()
/* calls the individual bond and text drawing functions to display the
picture */
{
struct data *hpc;
struct dc *hpc_c;
struct spline *hpc_sp;
int d,i;
char *c;
struct xy_co *coord;
int tmpx1,tmpx2,tmpy1,tmpy2,tmptx1,tmptx2,tmpty1,tmpty2;
GdkRectangle update_rect;
if (head.pix_width == 0 || head.pix_height == 0)
return;
gdk_draw_rectangle (picture,
background_gc,
TRUE, 0, 0, head.pix_width, head.pix_height);
if (gridtype==1) {
for (i=0+gridx;i<=head.pix_width;i=i+64)
gdk_draw_line (picture,drawing_area->style->bg_gc[GTK_STATE_INSENSITIVE],
(gint) (i * size_factor), (gint) (0),
(gint) (i * size_factor), (gint) (head.pix_height));
for (i=0+gridy;i<=head.pix_height;i=i+64)
gdk_draw_line (picture, drawing_area->style->bg_gc[GTK_STATE_INSENSITIVE],
(gint) (0), (gint) (i*size_factor),
(gint) (head.pix_width), (gint) (i * size_factor));
}
if (gridtype==2){
for (i=-2560+gridx;i<=6400;i=i+64){
gdk_draw_line (picture, drawing_area->style->bg_gc[GTK_STATE_INSENSITIVE],
(gint) (0+gridx), (gint) ((gridy+i)*size_factor),
(gint) (5500+gridx)*size_factor,
(gint) (3200+gridy+i) * size_factor);
gdk_draw_line (picture, drawing_area->style->bg_gc[GTK_STATE_INSENSITIVE],
(gint) (0+gridx), (gint) ((i+gridy)*size_factor),
(gint) (5500+gridx)*size_factor,
(gint) (-3200+gridy+i) * size_factor);
}
}
hpc = da_root.next;
if (!hpc)
fprintf (stderr,
"Help - somebody ate my atoms (hp->n=%d, da_root.next NULL)!!!\n",
hp->n);
for (d = 0; d < hp->n; d++)
{
int x=hpc->x;
int y=hpc->y;
int tx=hpc->tx;
int ty=hpc->ty;
#if 1
if ( !use_whiteout) {
i=has_label(hpc->x,hpc->y);
if (i>=0) {
int ox=x;
x += (4.*size_factor*(i+1)/calc_vector(abs(tx-x),abs(ty-y))) *(tx-x);
y += (4.*size_factor*(i+1)/calc_vector(abs(tx-ox),abs(ty-y))) *(ty-y);
}
i=has_label(hpc->tx,hpc->ty);
if (i>=0) {
int otx=tx;
tx -= (4.*size_factor*(i+1)/calc_vector(abs(tx-x),abs(ty-y))) *(tx-x);
ty -= (4.*size_factor*(i+1)/calc_vector(abs(otx-x),abs(ty-y))) *(ty-y);
}
}
#endif
switch (hpc->bond)
{
case 0:
Drawline (x, y, tx, ty, hpc->smarked + hpc->tmarked,hpc->color); /*single */
break;
case 1:
{ /*leftdouble */
coord = multi_bonds (x, y, tx, ty, mb_dist);
Drawline (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
Drawline (hpc->x, hpc->y, hpc->tx, hpc->ty,
hpc->smarked + hpc->tmarked,hpc->color);
}
break;
case 2:
{ /*rightdouble */
coord = multi_bonds (tx, ty, x, y, mb_dist);
Drawline (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
Drawline (x, y, tx, ty,
hpc->smarked + hpc->tmarked,hpc->color);
}
break;
case 5:
DrawWedge (x, y, tx, ty,
hpc->smarked + hpc->tmarked, hpc->color);
break;
case 6:
DrawDashedWedge (x, y, tx, ty,
hpc->smarked + hpc->tmarked,hpc->color);
break;
case 7:
DrawWiggly (x, y, tx, ty,
hpc->smarked + hpc->tmarked,hpc->color);
break;
case 8:
DrawArrow (x, y, tx, ty, 1,
hpc->smarked + hpc->tmarked,hpc->color);
break;
case 9:
DrawArrow (x, y, tx, ty, 2,
hpc->smarked + hpc->tmarked,hpc->color);
break;
case 10:
DrawWide (x, y, tx, ty,
hpc->smarked + hpc->tmarked,hpc->color);
break;
case 11:
DrawCircle (x, y, tx, ty,
hpc->smarked + hpc->tmarked,hpc->color);
break;
case 12:
DrawDotted (x, y, tx, ty,
hpc->smarked + hpc->tmarked,hpc->color);
break;
case 13:
DrawAcross (x, y, tx, ty,
hpc->smarked + hpc->tmarked,hpc->color);
break;
case 4:
{ /*middouble */
coord = center_double_bond (x, y, tx, ty, db_dist);
Drawline (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
coord++;
Drawline (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
}
break;
case 3:
{ /*triple */
coord = multi_bonds (x, y, tx, ty, mb_dist);
Drawline (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
Drawline (x, y, tx, ty,
hpc->smarked + hpc->tmarked,hpc->color);
coord = multi_bonds (hpc->tx, hpc->ty, hpc->x, hpc->y, mb_dist);
Drawline (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
Drawline (x, y, tx, ty,
hpc->smarked + hpc->tmarked,hpc->color);
}
break;
case 14:
{ /*left partial double */
coord = multi_bonds (x, y, tx, ty, mb_dist);
DrawDashed (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
Drawline (x, y, tx, ty,
hpc->smarked + hpc->tmarked,hpc->color);
}
break;
case 15:
{ /*right partial double */
coord = multi_bonds (tx, ty, x, y, mb_dist);
DrawDashed (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
Drawline (x, y, tx, ty,
hpc->smarked + hpc->tmarked,hpc->color);
}
break;
case 16: /*zebra dashed single bond */
DrawStripe (x, y, tx, ty,
hpc->smarked + hpc->tmarked,hpc->color);
break;
case 18:
{ /*triple, equal lengths */
coord = center_double_bond (x, y, tx, ty, 2*db_dist);
Drawline (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
coord++;
Drawline (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
Drawline (x, y, tx, ty, hpc->smarked + hpc->tmarked,hpc->color); /*single */
}
break;
case 19:
{ /*quadruple */
coord = center_double_bond (x, y, tx, ty, db_dist+3);
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);
Drawline (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
coord++;
Drawline (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
coord = center_double_bond (tmpx2, tmpy2,tmptx2, tmpty2, db_dist);
Drawline (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
coord++;
Drawline (coord->x, coord->y, coord->tx, coord->ty,
hpc->smarked + hpc->tmarked,hpc->color);
}
break;
}
hpc = hpc->next;
if (!hpc)
{
fprintf (stderr,
"Help - somebody ate my atoms (d=%d,hp->n=%d)!!!\n", d,
hp->n);
hp->n = d;
continue;
}
}
hpc_c = dac_root.next;
for (d = 0; d < hp->nc; d++)
{
c = hpc_c->c;
Drawstring (hpc_c->x, hpc_c->y, c, hpc_c->direct, hpc_c->marked, hpc_c->color,hpc_c->font,hpc_c->size,0);
hpc_c = hpc_c->next;
}
hpc_sp = sp_root.next;
for (d = 0; d < hp->nsp; d++)
{
Drawspline (hpc_sp->x0, hpc_sp->y0, hpc_sp->x1, hpc_sp->y1,
hpc_sp->x2, hpc_sp->y2, hpc_sp->x3, hpc_sp->y3,
hpc_sp->type, hpc_sp->marked,hpc_sp->color);
hpc_sp = hpc_sp->next;
}
if (drawmode == 4 && addflag==1 && !xbmflag)
{
gdk_draw_rectangle (picture, mygc[2], TRUE, refx * size_factor - 1,
refy * size_factor - 1, 3, 3);
}
gdk_draw_pixmap (drawing_area->window,
drawing_area->style->
fg_gc[GTK_WIDGET_STATE (drawing_area)], picture, 0, 0, 0,
0, head.pix_width, head.pix_height);
update_rect.x = 0;
update_rect.y = 0;
update_rect.width = (guint16)head.pix_width;
update_rect.height = (guint16)head.pix_height;
gtk_widget_draw ((GtkWidget *) drawing_area, &update_rect);
}
void
draw_preview_bonds (x, y, tx, ty, b)
/* calls the individual bond functions to create the preview image */
int x, y, tx, ty, b;
{
struct xy_co *coord;
switch (b)
{
case 0:
Drawline (x, y, tx, ty, 0, 0); /*single */
break;
case 1:
{ /*leftdouble */
coord = multi_bonds (x, y, tx, ty, mb_dist);
Drawline (coord->x, coord->y, coord->tx, coord->ty, 0,0);
Drawline (x, y, tx, ty, 0, 0);
}
break;
case 2:
{ /*rightdouble */
coord = multi_bonds (tx, ty, x, y, mb_dist);
Drawline (coord->x, coord->y, coord->tx, coord->ty, 0,0);
Drawline (x, y, tx, ty, 0,0);
}
break;
case 5:
DrawWedge (x, y, tx, ty, 0, 0);
break;
case 6:
DrawDashedWedge (x, y, tx, ty, 0, 0);
break;
case 7:
DrawWiggly (x, y, tx, ty, 0, 0);
break;
case 8:
DrawArrow (x, y, tx, ty, 1, 0, 0);
break;
case 9:
DrawArrow (x, y, tx, ty, 2, 0, 0);
break;
case 10:
DrawWide (x, y, tx, ty, 0, 0);
break;
case 11:
DrawCircle (x, y, tx, ty, 0, 0);
break;
case 12:
DrawDotted (x, y, tx, ty, 0, 0);
break;
case 13:
DrawAcross (x, y, tx, ty, 0, 0);
break;
case 4:
{ /*middouble */
coord = center_double_bond (x, y, tx, ty, db_dist);
Drawline (coord->x, coord->y, coord->tx, coord->ty, 0, 0);
coord++;
Drawline (coord->x, coord->y, coord->tx, coord->ty, 0, 0);
}
break;
case 3:
{ /*triple */
coord = multi_bonds (x, y, tx, ty, mb_dist);
Drawline (coord->x, coord->y, coord->tx, coord->ty, 0, 0);
Drawline (x, y, tx, ty, 0, 0);
coord = multi_bonds (tx, ty, x, y, mb_dist);
Drawline (coord->x, coord->y, coord->tx, coord->ty, 0, 0);
Drawline (x, y, tx, ty, 0, 0);
}
break;
case 14:
{ /*left partial double */
coord = multi_bonds (x, y, tx, ty, mb_dist);
DrawDashed (coord->x, coord->y, coord->tx, coord->ty, 0, 0);
Drawline (x, y, tx, ty, 0, 0);
}
break;
case 15:
{ /*right partial double */
coord = multi_bonds (tx, ty, x, y, mb_dist);
DrawDashed (coord->x, coord->y, coord->tx, coord->ty, 0, 0);
Drawline (x, y, tx, ty, 0, 0);
}
break;
case 16: /*zebra dashed single bond */
DrawStripe (x, y, tx, ty, 0, 0);
break;
}
}
void
Drawline (int x, int y, int tx, int ty, int active, int color)
/* draws a single bond */
{
if ( xbmflag)
gdk_draw_line (picture, drawing_area->style->black_gc,
(gint) (x * size_factor), (gint) (y * size_factor),
(gint) (tx * size_factor), (gint) (ty * size_factor));
else if (active)
gdk_draw_line (picture, drawing_area->style->bg_gc[GTK_STATE_SELECTED],
(gint) (x * size_factor), (gint) (y * size_factor),
(gint) (tx * size_factor), (gint) (ty * size_factor));
else
gdk_draw_line (picture, mygc[color],
(gint) (x * size_factor), (gint) (y * size_factor),
(gint) (tx * size_factor), (gint) (ty * size_factor));
}
void
DrawAcross (int x, int y, int tx, int ty, int active,int color)
/* draws a single bond on a white background */
{
gint npoints = 4;
GdkPoint mypoints[4];
struct xy_co *coord;
GdkGC *thegc;
thegc = background_gc;
coord = center_double_bond (x, y, tx, ty, 6);
mypoints[0].x = (coord->x + (coord->tx - coord->x) / 4) * size_factor;
mypoints[0].y = (coord->y + (coord->ty - coord->y) / 4) * size_factor;
mypoints[1].x = (coord->tx - (coord->tx - coord->x) / 4) * size_factor;
mypoints[1].y = (coord->ty - (coord->ty - coord->y) / 4) * size_factor;
coord++;
mypoints[2].x = (coord->tx - (coord->tx - coord->x) / 4) * size_factor;
mypoints[2].y = (coord->ty - (coord->ty - coord->y) / 4) * size_factor;
mypoints[3].x = (coord->x + (coord->tx - coord->x) / 4) * size_factor;
mypoints[3].y = (coord->y + (coord->ty - coord->y) / 4) * size_factor;
gdk_draw_polygon (picture, thegc, TRUE, (GdkPoint *) mypoints,
(gint) npoints);
if (xbmflag)
thegc=drawing_area->style->black_gc;
else if (active)
thegc=drawing_area->style->bg_gc[GTK_STATE_SELECTED];
else
thegc=mygc[color];
gdk_draw_line (picture, thegc,
(gint) (x * size_factor), (gint) (y * size_factor),
(gint) (tx * size_factor), (gint) (ty * size_factor));
}
void
DrawDashed (int x, int y, int tx, int ty, int active,int color)
/* draws a dashed bond */
{
GdkGC *thegc;
GdkSegment mypoints[6];
int xlen, ylen, i;
gint nsegments = 6;
xlen = tx - x;
ylen = ty - y;
for (i = 0; i < nsegments; i++)
{
mypoints[i].x1 = (gint16) ((x + 2 * i * 0.09 * xlen) * size_factor);
mypoints[i].y1 = (gint16) ((y + 2 * i * 0.09 * ylen) * size_factor);
mypoints[i].x2 = (gint16) ((x + (2 * i + 1) * 0.09 * xlen) * size_factor);
mypoints[i].y2 = (gint16) ((y + (2 * i + 1) * 0.09 * ylen) * size_factor);
}
if (xbmflag)
thegc= drawing_area->style->black_gc;
else if (active)
thegc=drawing_area->style->bg_gc[GTK_STATE_SELECTED];
else
thegc=mygc[color];
gdk_draw_segments (picture,
thegc,
(GdkSegment *) mypoints, (gint) nsegments);
}
void
DrawDotted (int x, int y, int tx, int ty, int active, int color)
/* draws a dotted bond */
{
GdkGC *thegc;
GdkPoint mypoints[100];
int xlen, ylen, i;
gint npoints ;
int len;
float step;
xlen = tx - x;
ylen = ty - y;
len=(int) rint(calc_vector(abs(xlen),abs(ylen))/6.3);
step = 1./len;
npoints=len;
if (npoints>99)npoints=99;
for (i = 0; i < npoints; i++)
{
mypoints[i].x = (gint16) ((x + i * step * xlen) * size_factor);
mypoints[i].y = (gint16) ((y + i * step * ylen) * size_factor);
}
if (xbmflag)
thegc= drawing_area->style->black_gc;
else if (active)
thegc=drawing_area->style->bg_gc[GTK_STATE_SELECTED];
else
thegc=mygc[color];
gdk_draw_points (picture, thegc,
(GdkPoint *) mypoints, (gint) npoints);
}
void
DrawWide (int x, int y, int tx, int ty, int active,int color)
/* draws a wide single bond */
{
gint npoints = 4;
GdkPoint mypoints[4];
struct xy_co *coord;
GdkGC *thegc;
if (xbmflag)
thegc = drawing_area->style->black_gc;
else if (active)
thegc = drawing_area->style->bg_gc[GTK_STATE_SELECTED];
else
thegc=mygc[color];
coord = center_double_bond (x, y, tx, ty, 6);
mypoints[0].x = (gint16) (coord->x * size_factor);
mypoints[0].y = (gint16) (coord->y * size_factor);
mypoints[1].x = (gint16) (coord->tx * size_factor);
mypoints[1].y = (gint16) (coord->ty * size_factor);
coord++;
mypoints[2].x = (gint16) (coord->tx * size_factor);
mypoints[2].y = (gint16) (coord->ty * size_factor);
mypoints[3].x = (gint16) (coord->x * size_factor);
mypoints[3].y = (gint16) (coord->y * size_factor);
gdk_draw_polygon (picture, thegc, TRUE, (GdkPoint *) mypoints,
(gint) npoints);
}
void
DrawStripe (int x, int y, int tx, int ty, int active, int color)
/* draws a striped single bond */
{
int i;
GdkPoint mypoints[4];
struct xy_co *coord;
GdkGC *thegc;
if (xbmflag)
thegc = drawing_area->style->black_gc;
else if (active)
thegc = drawing_area->style->bg_gc[GTK_STATE_SELECTED];
else
thegc=mygc[color];
coord = center_double_bond (x, y, tx, ty, 4);
mypoints[0].x = (gint16) (coord->x * size_factor);
mypoints[0].y = (gint16) (coord->y * size_factor);
mypoints[1].x = (gint16) (coord->tx * size_factor);
mypoints[1].y = (gint16) (coord->ty * size_factor);
coord++;
mypoints[2].x = (gint16) (coord->x * size_factor);
mypoints[2].y = (gint16) (coord->y * size_factor);
mypoints[3].x = (gint16) (coord->tx * size_factor);
mypoints[3].y = (gint16) (coord->ty * size_factor);
for (i = 0; i < 10; i++)
{
gdk_draw_line (picture, thegc,
mypoints[0].x + i * (mypoints[1].x - mypoints[0].x) / 10,
mypoints[0].y + i * (mypoints[1].y - mypoints[0].y) / 10,
mypoints[2].x + i * (mypoints[3].x - mypoints[2].x) / 10,
mypoints[2].y + i * (mypoints[3].y -
mypoints[2].y) / 10);
}
}
void
DrawCircle (int x, int y, int tx, int ty, int active,int color)
/* draws a circle of radius (tx/ty)-(x/y) around (x/y) */
{
GdkGC *thegc;
int topleftx, toplefty;
int radius;
if (xbmflag)
thegc = drawing_area->style->black_gc;
else if (active )
thegc = drawing_area->style->bg_gc[GTK_STATE_SELECTED];
else
thegc=mygc[color];
radius = calc_vector (abs (tx - x), abs (ty - y)) * size_factor;
topleftx = x * size_factor - radius;
toplefty = y * size_factor - radius;
gdk_draw_arc (picture, thegc, FALSE, topleftx, toplefty, 2 * radius,
2 * radius, 0, 360 * 64);
if (drawmode == 3 && !xbmflag)
{
thegc = drawing_area->style->bg_gc[GTK_STATE_SELECTED];
gdk_draw_rectangle (picture, thegc, TRUE, x * size_factor - 1,
y * size_factor - 1, 3, 3);
gdk_draw_rectangle (picture, thegc, TRUE, tx * size_factor - 1,
ty * size_factor - 1, 3, 3);
}
}
void
DrawWiggly (int x, int y, int tx, int ty, int active, int color)
/* draws a wavy line */
{
gint ax, ay, width, height, angle1, angle2;
int narcs, veclen, boxlen;
int i, xlen, ylen, ang;
int boxcorx, boxcory;
GdkGC *thegc;
if (xbmflag)
thegc = drawing_area->style->black_gc;
else if (active)
thegc = drawing_area->style->bg_gc[GTK_STATE_SELECTED];
else
thegc=mygc[color];
narcs = 5;
xlen = tx - x;
ylen = ty - y;
veclen = calc_vector (abs (tx - x), abs (ty - y));
ang = (int)
(180. +
asin (copysign ((float) ylen / (float) veclen, (double) (xlen * -ylen) )) * 180. /
3.14159);
boxlen = (int) (0.2 * veclen);
boxcorx = (int) ((1. - (float) xlen / (float) veclen) * boxlen / 2);
boxcory = (int) ((1. - (float) ylen / (float) veclen) * boxlen / 2);
for (i = 0; i < narcs; ++i)
{
ax = (gint)((x + 0.2 * i * xlen - boxcorx) * size_factor);
ay = (gint)((y + 0.2 * i * ylen - boxcory) * size_factor);
width = boxlen * size_factor;
height = boxlen * size_factor;
angle1 = ang * 64;
angle2 = (gint) (-180 * 64 * pow (-1, (double)i));
if (x > tx)
angle2 *= -1;
gdk_draw_arc (picture, thegc, FALSE, ax, ay, width, height, angle1,
angle2);
}
}
void
DrawArrow (int x, int y, int tx, int ty, int head, int active, int color)
/* draws an arrow with either full or one-sided arrowhead */
{
int xlen, ylen, xbase, ybase;
gint npoints;
float veclen, headfact, scalefact;
GdkPoint mypoints[3];
GdkGC *thegc;
if (xbmflag)
thegc = drawing_area->style->black_gc;
else if (active)
thegc = drawing_area->style->bg_gc[GTK_STATE_SELECTED];
else
thegc= mygc[color];
xlen = tx - x;
ylen = ty - y;
veclen = sqrt ((double)(xlen * xlen + ylen * ylen));
scalefact=64./veclen; /* keep arrowhead size constant (64=std length)*/
/* headfact = 1. - 20. / veclen;*/
headfact = 0.8;
xbase = x + headfact * xlen*scalefact;
ybase = y + headfact * ylen*scalefact;
xbase = (int) (tx - 0.2 *xlen*scalefact);
ybase = (int) (ty - 0.2 *ylen*scalefact);
mypoints[0].x = tx * size_factor;
mypoints[0].y = ty * size_factor;
if (select_char (tx,ty,1) != NULL){
xbase = x+headfact*xlen-12*xlen/veclen;
ybase = y+headfact*ylen-12*ylen/veclen;
mypoints[0].x = (gint16) ((tx-12*xlen/veclen)*size_factor);
mypoints[0].y = (gint16) ((ty-12*ylen/veclen)*size_factor);
}
mypoints[1].x = (gint16) ((xbase + 0.1 * ylen) * size_factor);
mypoints[1].y = (gint16) ((ybase - 0.1 * xlen) * size_factor);
mypoints[1].x = (gint16) ((xbase + 0.1 * ylen*scalefact) * size_factor);
mypoints[1].y = (gint16) ((ybase - 0.1 * xlen*scalefact) * size_factor);
if (head == 1)
{
mypoints[2].x = (gint16) (xbase * size_factor); /*on baseline */
mypoints[2].y = (gint16) (ybase * size_factor);
}
else
{
mypoints[2].x = (gint16) ((xbase - 0.1 * ylen) * size_factor);
mypoints[2].y = (gint16) ((ybase + 0.1 * xlen) * size_factor);
mypoints[2].x = (gint16) ((xbase - 0.1 * ylen*scalefact) * size_factor);
mypoints[2].y = (gint16) ((ybase + 0.1 * xlen*scalefact) * size_factor);
}
npoints = 3;
gdk_draw_line (picture, thegc, x * size_factor, y * size_factor,
tx * size_factor, ty * size_factor);
gdk_draw_polygon (picture, thegc, TRUE, (GdkPoint *) mypoints,
(gint) npoints);
}
void
DrawDashedWedge (int x, int y, int tx, int ty, int active,int color)
/* draws the dashed wedge for a bond behind the image plane */
{
int i, xlen, ylen;
GdkGC *thegc;
int len;
float step,factor;
if (xbmflag)
thegc = drawing_area->style->black_gc;
else if (active)
thegc = drawing_area->style->bg_gc[GTK_STATE_SELECTED];
else
thegc= mygc[color];
xlen = tx - x;
ylen = ty - y;
len=(int) rint(calc_vector(abs(xlen),abs(ylen))/8.);
if (len<8) len=8;
step = 1./len;
factor=0.0125;
if (len>20) factor= 0.00125;
if (len==8) {
factor =0.03;
}
for (i = 1; i < len; i++)
gdk_draw_line (picture, thegc,
(x + step * i * xlen - factor * ylen * i) * size_factor,
(y + step * i * ylen + factor * xlen * i) * size_factor,
(x + step * i * xlen + factor * ylen * i) * size_factor,
(y + step * i * ylen - factor * xlen * i) * size_factor);
}
void
DrawWedge (int x, int y, int tx, int ty, int active, int color)
/* draws the wedge-shaped single bond 'pointing towards the viewer' */
{
int xlen, ylen;
gint npoints;
GdkPoint mypoints[3];
GdkGC *thegc;
struct data *hpc;
struct xy_co *coord;
int d;
float area;
if (xbmflag)
thegc = drawing_area->style->black_gc;
else if (active)
thegc = drawing_area->style->bg_gc[GTK_STATE_SELECTED];
else
thegc = mygc[color];
xlen = tx - x;
ylen = ty - y;
float c=1.;
if (xlen*xlen+ylen*ylen <=1000.) c=2.;
mypoints[0].x = (gint16) (x * size_factor);
mypoints[0].y = (gint16) (y * size_factor);
mypoints[1].x = (gint16) ((tx - 0.1 *c * ylen) * size_factor);
mypoints[1].y = (gint16) ((ty + 0.1 *c* xlen) * size_factor);
mypoints[2].x = (gint16) ((tx + 0.1 *c* ylen) * size_factor);
mypoints[2].y = (gint16) ((ty - 0.1 *c* xlen) * size_factor);
hpc = da_root.next;
for (d = 0; d < hp->n; d++)
{
if (hpc->bond == 10)
{
if ((abs (hpc->x - tx) < 3 && abs (hpc->y - ty) < 3)
|| (abs (hpc->tx - tx) < 3 && abs (hpc->ty - ty) < 3))
{
coord =
center_double_bond (hpc->x, hpc->y, hpc->tx, hpc->ty, 6);
if (abs (hpc->x - tx) < 3 && abs (hpc->y - ty) < 3)
{
mypoints[1].x = (gint16) (coord->x * size_factor);
mypoints[1].y = (gint16) (coord->y * size_factor);
coord++;
mypoints[2].x = (gint16) (coord->x * size_factor);
mypoints[2].y = (gint16) (coord->y * size_factor);
}
else
{
mypoints[1].x = (gint16) (coord->tx * size_factor);
mypoints[1].y = (gint16) (coord->ty * size_factor);
coord++;
mypoints[2].x = (gint16) (coord->tx * size_factor);
mypoints[2].y = (gint16) (coord->ty * size_factor);
}
area =
0.5 * abs (mypoints[0].x * (mypoints[1].y - mypoints[2].y) +
mypoints[1].x * (mypoints[2].y - mypoints[0].y) +
mypoints[2].x * (mypoints[0].y - mypoints[1].y));
if (fabs (area) < 76. * size_factor)
{
mypoints[1].x = (gint16) ((tx - 0.05 * ylen) * size_factor);
mypoints[1].y = (gint16) ((ty + 0.05 * xlen) * size_factor);
mypoints[2].x = (gint16) ((tx + 0.05 * ylen) * size_factor);
mypoints[2].y = (gint16) ((ty - 0.05 * xlen) * size_factor);
}
}
}
hpc = hpc->next;
}
npoints = 3;
gdk_draw_polygon (picture, thegc, TRUE, (GdkPoint *) mypoints,
(gint) npoints);
}
void
Drawspline (int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3,
int type, int active, int color)
/* draws a spline curve, optionally with full of half arrowhead */
{
int xlen, ylen, xbase, ybase;
double px0, py0, px1, py1;
int i;
double t;
gint npoints;
GdkPoint mypoints[21];
GdkGC *thegc;
if (xbmflag)
thegc = drawing_area->style->black_gc;
else if (active)
thegc = drawing_area->style->bg_gc[GTK_STATE_SELECTED];
else
thegc = mygc[color];
if (drawmode == 3 && !xbmflag)
{
gdk_draw_rectangle (picture, thegc, TRUE, x0 * size_factor - 1,
y0 * size_factor - 1, 3, 3);
gdk_draw_rectangle (picture, thegc, TRUE, x1 * size_factor - 1,
y1 * size_factor - 1, 3, 3);
gdk_draw_rectangle (picture, thegc, TRUE, x2 * size_factor - 1,
y2 * size_factor - 1, 3, 3);
gdk_draw_rectangle (picture, thegc, TRUE, x3 * size_factor - 1,
y3 * size_factor - 1, 3, 3);
}
px0 = (double)x0;
py0 = (double)y0;
for (i = 0; i < 21; i++)
{
t = (float) i / 20.;
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;
mypoints[i].x = (gint16) (px1 * size_factor);
mypoints[i].y = (gint16) (py1 * size_factor);
}
npoints = 21;
if (type >= 0) {
/* move end of last line segment back a bit to keep it from protruding
beneath the arrowhead */
xbase= mypoints[20].x;
ybase= mypoints[20].y;
mypoints[20].x = mypoints[20].x - (gint16) ( 0.03*(mypoints[20].x-mypoints[19].x));
mypoints[20].y = mypoints[20].y - (gint16) (0.03*(mypoints[20].y-mypoints[19].y));
gdk_draw_lines (picture, thegc, mypoints, npoints);
mypoints[20].x=xbase;
mypoints[20].y=ybase;
}
if (type == -1)
gdk_draw_polygon (picture, thegc, TRUE, mypoints, npoints);
if (type == -2)
gdk_draw_points (picture, thegc, mypoints, npoints);
if (type <= 0)
return;
for (i=0;i<4;i++){ /* find acceptable arrowhead length */
xlen = mypoints[20].x - mypoints[19-i].x;
ylen = mypoints[20].y - mypoints[19-i].y;
xbase = mypoints[19-i].x;
ybase = mypoints[19-i].y;
if (xlen*xlen+ylen*ylen >200 *size_factor*size_factor) break;
}
if (xlen*xlen+ylen*ylen >400 *size_factor*size_factor) {
xlen -= (mypoints[20].x - mypoints[19].x)/2;
ylen -= (mypoints[20].y - mypoints[19].y)/2;
xbase = mypoints[19].x +(mypoints[20].x - mypoints[19].x)/2 ;
ybase = mypoints[19].y +(mypoints[20].y - mypoints[19].y)/2 ;
}
if (xlen != 0)
xlen = (int) copysign (10. * size_factor, (double)xlen);
if (ylen != 0)
ylen = (int) copysign (10. * size_factor, (double)ylen);
/* tip of arrow at original endpoint of last line */
mypoints[0].x = mypoints[20].x;
mypoints[0].y = mypoints[20].y;
/* calculate both possible positions for arrow side */
mypoints[1].x = (gint16) (xbase + 0.5 * ylen);
mypoints[1].y = (gint16) (ybase - 0.5 * xlen);
if (type == 1)
{
mypoints[2].x = (gint16) (xbase - 0.5 * ylen);
mypoints[2].y = (gint16) (ybase + 0.5 * xlen);
/* and choose the one facing outward (farther from the starting point) */
px0 = (double)
((mypoints[1].x - x0 * size_factor) * (mypoints[1].x -
x0 * size_factor) +
(mypoints[1].y - y0 * size_factor) * (mypoints[1].y -
y0 * size_factor));
px1 = (double)
((mypoints[2].x - x0 * size_factor) * (mypoints[2].x -
x0 * size_factor) +
(mypoints[2].y - y0 * size_factor) * (mypoints[2].y -
y0 * size_factor));
if (px0 < px1)
{
mypoints[1].x = mypoints[2].x;
mypoints[1].y = mypoints[2].y;
}
mypoints[2].x = (gint16)xbase; /*on baseline */
mypoints[2].y = (gint16)ybase;
}
else
{
mypoints[2].x = (gint16) (xbase - 0.5 * ylen); /* on opposite side of line */
mypoints[2].y = (gint16) (ybase + 0.5 * xlen);
}
npoints = 3;
gdk_draw_polygon (picture, thegc, TRUE, (GdkPoint *) mypoints,
(gint) npoints);
}
void
Drawstring (int x, int y, char *cc, int direct, int active, int thecolor, int serif_flag, int size, int preview)
/* draws a label with sub- and superscripting, symbols and text justification */
{
int ha, tw, a;
int nch, textl, chl, chr;
int d, hx, n;
int shiftall = 0;
int variance[MAXCL];
gchar *c;
#ifdef GTK2
int dummy;
gchar l[8];
gunichar hc, hl;
gunichar text[MAXCL];
gunichar symbol[MAXCL];
gunichar slanted[MAXCL];
gunichar bold[MAXCL];
static PangoLayout *thelayout;
#else
char *l, *hc, hl[2];
unsigned char text[MAXCL];
char symbol[MAXCL];
char slanted[MAXCL];
char bold[MAXCL];
#endif
GdkGC *thegc;
int save_x, sub_lastx, sup_lastx;
int fontsize;
fontsize=size;
if (zoom_factor <2) fontsize-=2-zoom_factor;
if (zoom_factor >2) fontsize+=zoom_factor-2;
if (fontsize<0 ) fontsize=curfontsize;
if (fontsize>6) fontsize=6;
if (preview) fontsize=0;
if (xbmflag)
thegc = drawing_area->style->black_gc;
else if (active)
thegc = drawing_area->style->bg_gc[GTK_STATE_SELECTED];
else
thegc = mygc[thecolor];
x = x * size_factor;
hx = x;
y = y * size_factor;
#ifdef GTK2
memset(l,0,8*sizeof(gchar));
c=g_locale_to_utf8(cc,-1,NULL,NULL,NULL);
if (!c) c=g_convert(cc,-1,"UTF-8","ISO8859-1",NULL,NULL,NULL);
if (!c) {
fprintf(stderr,"invalid character in chemtool file\n");
return;
}
if (!thelayout) thelayout = gtk_widget_create_pango_layout(drawing_area,"X");
pango_layout_set_font_description(thelayout,font[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &a);
pango_layout_set_text(thelayout, "x", -1);
pango_layout_set_font_description(thelayout,font[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &ha);
ha = ha/2;
n = (int) g_utf8_strlen(c,-1);
#else
c=cc;
a = gdk_char_height (font[fontsize], 'X');
ha = gdk_char_height (font[fontsize], 'x') / 2;
a += 6;
n = (int)strlen (c);
tw = gdk_char_width (font[fontsize], 'x') ;
#endif
#ifdef GTK2
for (d = 0; d < n; d++)
{
symbol[d] = FALSE;
slanted[d] = FALSE;
bold[d]=FALSE;
hc = g_utf8_get_char(c);
if (shiftall != 0)
{
if (hc == '}')
{
shiftall = 0;
if (!(c=g_utf8_next_char(c)))continue;
--n;
hc=g_utf8_get_char(c);
}
variance[d] = shiftall;
}
if (shiftall == 0)
{
if ((variance[d] = Extra_char (hc,ha)) != 0)
{
c=g_utf8_next_char(c);
if ((hc=g_utf8_get_char(c)))
{
--n;
if (hc == '{')
{
--n;
shiftall = variance[d];
c=g_utf8_next_char(c);
hc=g_utf8_get_char(c);
}
}
else
{
variance[d] = 0;
n=d;
continue;
}
}
}
text[d] = hc;
c = g_utf8_next_char(c);
if (text[d] == '@' && (hl=g_utf8_get_char(c)))
{
symbol[d] = TRUE;
text[d] = hl;
c = g_utf8_next_char(c);
--n;
}
else if (text[d] == '|' && (hl=g_utf8_get_char(c)))
{
slanted[d] = TRUE;
text[d] = hl;
c = g_utf8_next_char(c);
--n;
}
else if (text[d] == '#' && (hl=g_utf8_get_char(c)))
{
bold[d] = TRUE;
text[d] = hl;
c = g_utf8_next_char(c);
--n;
}
else if (text[d] == '\\' && (hl=g_utf8_get_char(c)))
{
text[d] = ' ';
}
}
#else
hc = c;
for (d = 0; d < n; d++)
{
symbol[d] = FALSE;
slanted[d] = FALSE;
bold[d]=FALSE;
if (shiftall != 0)
{
if (*hc == '}')
{
shiftall = 0;
if (*(hc + 1))
hc++;
--n;
}
variance[d] = shiftall;
}
if (shiftall == 0)
{
if ((variance[d] = Extra_char (*hc)) != 0)
{
if (*(hc + 1))
{
hc++;
--n;
if (*hc == '{')
{
shiftall = variance[d];
hc++;
--n;
}
}
else
{
variance[d] = 0;
}
}
}
text[d] = (unsigned char) *hc++;
if (text[d] == '@' && *hc)
{
symbol[d] = TRUE;
text[d] = (unsigned char) *hc++;
--n;
}
else if (text[d] == '|' && *hc)
{
slanted[d] = TRUE;
text[d] = (unsigned char) *hc++;
--n;
}
else if (text[d] == '#' && *hc)
{
bold[d] = TRUE;
text[d] = (unsigned char) *hc++;
--n;
}
else if (text[d] == '\\' && *hc)
{
text[d] = ' ';
}
}
#endif
nch = n;
if (nch > 0)
{
chl = 0;
chr = 0;
x = save_x = sub_lastx = sup_lastx = 0;
for (d = 0; d < nch; d++)
{
#ifdef GTK2
/* l = g_locale_to_utf8((const gchar*) &text[d],1,NULL,NULL,NULL); */
memset(l,0,8*sizeof(gchar));
g_unichar_to_utf8(text[d],l);
#endif
if (variance[d])
{
#ifdef GTK2
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,smallfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
#else
tw = gdk_char_width (smallfont[fontsize], (gchar)text[d]) + 2;
#endif
if (symbol[d])
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,ssymbfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
}
#else
tw = gdk_char_width (ssymbfont[fontsize], (gchar)text[d]);
#endif
if (variance[d] < 0)
{
if (save_x < x)
x = sub_lastx;
x = sub_lastx = x + tw;
}
else
{
if (save_x < x)
x = sup_lastx;
x = sup_lastx = x + tw;
}
}
else /* not sub- or superscripted */
{
#ifdef GTK2
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,font[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
#else
tw = 1 + gdk_char_width (font[fontsize], (gchar)text[d]);
#endif
if (symbol[d])
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,symbfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
}
#else
tw = gdk_char_width (symbfont[fontsize], (gchar)text[d]);
#endif
if (bold[d])
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,boldfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
}
#else
tw = gdk_char_width (boldfont[fontsize], (gchar)text[d]);
#endif
if (slanted[d])
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,slfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
}
#else
tw = 1 + gdk_char_width (slfont[fontsize], (gchar)text[d]);
#endif
if (save_x < x)
{
if (sub_lastx < sup_lastx)
x = sup_lastx;
else
x = sub_lastx;
}
x = save_x = sub_lastx = sup_lastx = x + tw;
chr = tw;
}
if (chl == 0)
chl = tw;
}
if (x != sub_lastx || x != sup_lastx) save_x+= tw; /* if the label ends with a sub/superscripted character, */
/* add its length to the current position (which is before */
/* the sub/superscript to allow vertical alignment of simultaneous */
/* sub- and superscripts */
textl = save_x;
switch (direct)
{
case 0:
hx = hx - chl / 2;
break;
case -1:
hx = hx - (textl - 1) / 2;
break;
case -2:
hx = hx + chr / 2 - (textl - 1);
break;
}
}
nch = n;
x = hx;
save_x = sub_lastx = sup_lastx = x;
for (d = 0; d < n; d++)
{
#ifdef GTK2
/* l = g_locale_to_utf8((const gchar*) &text[d],1,NULL,NULL,NULL);*/
memset(l,0,8*sizeof(gchar));
g_unichar_to_utf8(text[d], l);
#endif
if (variance[d])
{
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,smallfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
}
#else
tw = gdk_char_width (smallfont[fontsize], (gchar)text[d]) + 2;
#endif
if (symbol[d])
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,ssymbfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
}
#else
tw = gdk_char_width (ssymbfont[fontsize], (gchar)text[d]);
#endif
if (variance[d] < 0)
{
if (save_x < x)
x = sub_lastx;
sub_lastx = x + tw;
}
else
{
if (save_x < x)
x = sup_lastx;
sup_lastx = x + tw;
}
}
else
{ /* not sub- or superscripted */
#ifdef GTK2
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,font[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
#else
tw = 1 + gdk_char_width (font[fontsize], (gchar)text[d]);
#endif
if (symbol[d])
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,symbfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
}
#else
tw = gdk_char_width (symbfont[fontsize], (gchar)text[d]);
#endif
if (bold[d])
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,boldfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
}
#else
tw = gdk_char_width (boldfont[fontsize], (gchar)text[d]);
#endif
if (slanted[d])
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,slfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
}
#else
tw = 1 + gdk_char_width (slfont[fontsize], (gchar)text[d]);
#endif
if (save_x < x)
{
if (sub_lastx < sup_lastx)
x = sup_lastx;
else
x = sub_lastx;
}
save_x = sub_lastx = sup_lastx = x + tw;
}
/* erase a circular area slightly larger than the current character to
create some space around the label */
if (text[d] != 183) {
if (preview)
gdk_draw_arc (picture, drawing_area->style->white_gc, 1,
x - 5 * size_factor,
y - a + ha - 5 * size_factor + variance[d],
tw + 8 * size_factor, a + 10 * size_factor, 0, 360 * 64);
else
if (use_whiteout) gdk_draw_arc (picture, background_gc, 1,
x - 2 * size_factor,
y -a + ha + size_factor * variance[d],
tw + 8 * size_factor, a + 2 * size_factor, 0, 360 * 64);
x = x + tw;
}
}
n = nch;
x = hx;
#ifdef GTK2
y -= a ;
#endif
save_x = sub_lastx = sup_lastx = x;
for (d = 0; d < n; d++)
{
#ifdef GTK2
memset(l,0,8*sizeof(gchar));
/*#ifdef GTK2*/
/* l = g_locale_to_utf8((const gchar*) &text[d],1,NULL,NULL,NULL);*/
g_unichar_to_utf8(text[d],l);
if (symbol[d]) {
unsigned int unicodechar=text[d]+848;
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: /*centered dot*/ case 775: /* bullet */
unicodechar=8226;
break;
default:
break;
}
g_unichar_to_utf8((gunichar)unicodechar,l);
}
#else
hl[0] = (char)text[d];
hl[1] = 0;
l = &hl[0];
#endif
if (variance[d])
{
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,smallfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
}
#else
tw = gdk_char_width (smallfont[fontsize], (gchar)text[d]) + 2;
#endif
if (symbol[d])
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,ssymbfont[fontsize]);
pango_layout_get_pixel_size(thelayout, &tw, &dummy);
}
#else
tw = gdk_char_width (ssymbfont[fontsize], (gchar)text[d]);
#endif
if (variance[d] < 0)
{
if (save_x < x)
x = sub_lastx;
sub_lastx = x + tw;
}
else
{
if (save_x < x)
x = sup_lastx;
sup_lastx = x + tw;
}
if (symbol[d])
{
#ifdef GTK2
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,ssymbfont[fontsize]);
gdk_draw_layout(picture,background_gc,x,y+ha+variance[d],thelayout);
gdk_draw_layout(picture,thegc,x,y+ha+variance[d],thelayout);
#else
gdk_draw_text (picture, ssymbfont[fontsize],
background_gc, x,
y + ha + variance[d], l, (gint)strlen (l));
gdk_draw_text (picture, ssymbfont[fontsize], thegc, x,
y + ha + variance[d], l, (gint)strlen (l));
#endif
}
else
{
#ifdef GTK2
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,smallfont[fontsize]);
gdk_draw_layout(picture,background_gc,x,y+ha+variance[d],thelayout);
gdk_draw_layout(picture,thegc,x,y+ha+variance[d],thelayout);
#else
gdk_draw_text (picture, smallfont[fontsize],
background_gc, x,
y + ha + variance[d], l, (gint)strlen (l));
gdk_draw_text (picture, smallfont[fontsize], thegc, x,
y + ha + variance[d], l, (gint)strlen (l));
#endif
}
x = x + tw;
}
else /* not sub- or superscripted */
{
#ifdef GTK2
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,font[fontsize]);
pango_layout_get_pixel_size(thelayout,&tw,&dummy);
#else
tw = 1 + gdk_char_width (font[fontsize], (gchar)text[d]);
#endif
if (symbol[d])
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,symbfont[fontsize]);
pango_layout_get_pixel_size(thelayout,&tw,&dummy);
}
#else
tw = gdk_char_width (symbfont[fontsize], (gchar)text[d]);
#endif
if (bold[d])
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,boldfont[fontsize]);
pango_layout_get_pixel_size(thelayout,&tw,&dummy);
}
#else
tw = gdk_char_width (boldfont[fontsize], (gchar)text[d]);
#endif
if (slanted[d])
#ifdef GTK2
{
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,slfont[fontsize]);
pango_layout_get_pixel_size(thelayout,&tw,&dummy);
}
#else
tw = 1 + gdk_char_width (slfont[fontsize],(gchar) text[d]);
#endif
if (save_x < x)
{
if (sub_lastx < sup_lastx)
x = sup_lastx;
else
x = sub_lastx;
}
if (symbol[d])
{
#ifdef GTK2
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,symbfont[fontsize]);
gdk_draw_layout(picture,background_gc,x,y+ha,thelayout);
gdk_draw_layout(picture,thegc,x,y+ha,thelayout);
#else
gdk_draw_text (picture, symbfont[fontsize], background_gc,
x, y + ha, l, (gint)strlen (l));
gdk_draw_text (picture, symbfont[fontsize], thegc, x, y + ha, l,
(gint)strlen (l));
#endif
}
else if (bold[d])
{
#ifdef GTK2
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,boldfont[fontsize]);
gdk_draw_layout(picture,background_gc,x,y+ha,thelayout);
gdk_draw_layout(picture,thegc,x,y+ha,thelayout);
#else
gdk_draw_text (picture, boldfont[fontsize], background_gc,
x, y + ha, l, (gint)strlen (l));
gdk_draw_text (picture, boldfont[fontsize], thegc, x, y + ha, l, (gint)strlen (l));
#endif
}
else if (slanted[d])
{
#ifdef GTK2
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,slfont[fontsize]);
gdk_draw_layout(picture,background_gc,x,y+ha,thelayout);
gdk_draw_layout(picture,thegc,x,y+ha,thelayout);
#else
gdk_draw_text (picture, slfont[fontsize], background_gc,
x, y + ha, l, (gint)strlen (l));
gdk_draw_text (picture, slfont[fontsize], thegc, x, y + ha, l, (gint)strlen (l));
#endif
}
else if (serif_flag)
{
#ifdef GTK2
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,textfont[fontsize]);
gdk_draw_layout(picture,background_gc,x,y+ha,thelayout);
gdk_draw_layout(picture,thegc,x,y+ha,thelayout);
#else
gdk_draw_text (picture, textfont[fontsize], background_gc,
x, y + ha, l, (gint)strlen (l));
gdk_draw_text (picture, textfont[fontsize], thegc, x, y + ha, l, (gint)strlen (l));
#endif
}
else
{
#ifdef GTK2
pango_layout_set_text(thelayout,l,-1);
pango_layout_set_font_description(thelayout,font[fontsize]);
gdk_draw_layout(picture,background_gc,x,y+ha,thelayout);
gdk_draw_layout(picture,thegc,x,y+ha,thelayout);
#else
gdk_draw_text (picture, font[fontsize], background_gc,
x, y + ha, l, (gint)strlen (l));
gdk_draw_text (picture, font[fontsize], thegc, x, y + ha, l, (gint)strlen (l));
#endif
}
x = x + tw;
save_x = sub_lastx = sup_lastx = x;
}
}
}
#ifdef GTK2
int
Extra_char (gunichar c, int ha)
#else
int
Extra_char (char c)
#endif
/* process control characters for sub- and superscripting */
{
#ifndef GTK2
int ha = gdk_char_height (font[zoom_factor], 'x') / 2;
#endif
if (c == '_')
return (ha);
if (c == '^')
return (-ha);
return (0);
}
int
Load_Font ()
/* load the normal, subscript and symbol fonts for all zoom scales */
{
#ifdef GTK2
int i;
gchar *pangosymtype[]= {"Symbol 8", "Symbol 10", "Symbol 12", "Symbol 14",
"Symbol 18", "Symbol 20", "Symbol 24" };
gchar *pangossymtype[]= {"Symbol 8", "Symbol 8", "Symbol 10", "Symbol 12",
"Symbol 14", "Symbol 18", "Symbol 24" };
gchar *pangofntype[]= { "Helvetica 8", "Helvetica 10", "Helvetica 12",
"Helvetica 14", "Helvetica 17", "Helvetica 20",
"Helvetica 24"};
gchar *pangosfntype[]= { "Helvetica 8", "Helvetica 8", "Helvetica 10",
"Helvetica 12", "Helvetica 14", "Helvetica 14",
"Helvetica 20"};
gchar *pangosltype[]= { "Helvetica oblique 8", "Helvetica oblique 10",
"Helvetica oblique 12", "Helvetica oblique 14",
"Helvetica oblique 18", "Helvetica oblique 18",
"Helvetica oblique 24"};
gchar *pangobtype[]= { "Helvetica bold 8", "Helvetica bold 10",
"Helvetica bold 12", "Helvetica bold 14",
"Helvetica bold 18", "Helvetica bold 18",
"Helvetica bold 24"};
gchar *pangotexttype[]= { "Times 8", "Times 10",
"Times 12", "Times 14",
"Times 18", "Times 18",
"Times 24"};
for (i=0;i<7;i++){
font[i]=pango_font_description_from_string(pangofntype[i]);
symbfont[i]=pango_font_description_from_string(pangosymtype[i]);
ssymbfont[i]=pango_font_description_from_string(pangossymtype[i]);
smallfont[i]=pango_font_description_from_string(pangosfntype[i]);
slfont[i]=pango_font_description_from_string(pangosltype[i]);
boldfont[i]=pango_font_description_from_string(pangobtype[i]);
textfont[i]=pango_font_description_from_string(pangotexttype[i]);
}
#else
int i,fnt;
/* NB: entries 0 and 1 are used for preview only, the default font is 4(!) */
gchar *symtype75[] = { "*-symbol-*-*-8-*", "*-symbol-*-*-10-*",
"*-symbol-*-*-12-*", "*-symbol-*-*-14-*", "*-symbol-*-*-18-*",
"*-symbol-*-*-18-*", "*-symbol-*-*-24-*"
};
gchar *ssymtype75[] = { "*-symbol-*-*-8-*", "*-symbol-*-*-8-*",
"*-symbol-*-*-10-*", "*-symbol-*-*-12-*", "*-symbol-*-*-14-*",
"*-symbol-*-*-18-*", "*-symbol-*-*-24-*"
};
gchar *symtype100[] = { "*-symbol-*-*-11-*", "*-symbol-*-*-14-*",
"*-symbol-*-*-17-*", "*-symbol-*-*-20-*", "*-symbol-*-*-25-*",
"*-symbol-*-*-25-*", "*-symbol-*-*-34-*"
};
gchar *ssymtype100[] = { "*-symbol-*-*-11-*", "*-symbol-*-*-11-*",
"*-symbol-*-*-14-*", "*-symbol-*-*-17-*", "*-symbol-*-*-20-*",
"*-symbol-*-*-25-*", "*-symbol-*-*-34-*"
};
gchar *fntype75[] =
{ "*-helvetica-medium-r-normal--8-*", "*-helvetica-medium-r-normal--10-*",
"*-helvetica-medium-r-normal--12-*", "*-helvetica-medium-r-normal--14-*",
"*-helvetica-medium-r-normal--18-*",
"*-helvetica-medium-r-normal--18-*", "*-helvetica-medium-r-normal--24-*"
};
gchar *fntype100[] =
{ "*-helvetica-medium-r-normal--11-*", "*-helvetica-medium-r-normal--14-*",
"*-helvetica-medium-r-normal--17-*", "*-helvetica-medium-r-normal--20-*",
"*-helvetica-medium-r-normal--25-*",
"*-helvetica-medium-r-normal--25-*", "*-helvetica-medium-r-normal--34-*"
};
gchar *fallback[] = { "5x7", "6x10", "7x13", "9x15", "8x16",
"10x20", "12x24"
};
gchar *sfntype75[] =
{ "*-helvetica-medium-r-normal--8-*", "*-helvetica-medium-r-normal--8-*",
"*-helvetica-medium-r-normal--10-*", "*-helvetica-medium-r-normal--12-*",
"*-helvetica-bold-r-normal--14-*",
"*-helvetica-bold-r-normal--14-*", "*-helvetica-medium-r-normal--20-*"
};
gchar *sfntype100[] =
{ "*-helvetica-medium-r-normal--11-*", "*-helvetica-medium-r-normal--11-*",
"*-helvetica-medium-r-normal--14-*", "*-helvetica-medium-r-normal--17-*",
"*-helvetica-bold-r-normal--20-*",
"*-helvetica-bold-r-normal--20-*", "*-helvetica-medium-r-normal--25-*"
};
/* {"5x7", "5x7", "6x10", "8x13", "7x14",
"8x13bold", "10x20"};*/
gchar *sltype75[] =
{ "*-helvetica-medium-o-normal--8-*", "*-helvetica-medium-o-normal--10-*",
"*-helvetica-medium-o-normal--12-*", "*-helvetica-medium-o-normal--14-*",
"*-helvetica-medium-o-normal--18-*",
"*-helvetica-medium-o-normal--18-*", "*-helvetica-medium-o-normal--24-*"
};
gchar *sltype100[] =
{ "*-helvetica-medium-o-normal--11-*", "*-helvetica-medium-o-normal--14-*",
"*-helvetica-medium-o-normal--17-*", "*-helvetica-medium-o-normal--20-*",
"*-helvetica-medium-o-normal--25-*",
"*-helvetica-medium-o-normal--25-*", "*-helvetica-medium-o-normal--34-*"
};
gchar *btype75[] =
{ "*-helvetica-bold-r-normal--8-*", "*-helvetica-bold-r-normal--10-*",
"*-helvetica-bold-r-normal--12-*", "*-helvetica-bold-r-normal--14-*",
"*-helvetica-bold-r-normal--18-*",
"*-helvetica-bold-r-normal--18-*", "*-helvetica-bold-r-normal--24-*"
};
gchar *btype100[] =
{ "*-helvetica-bold-r-normal--11-*", "*-helvetica-bold-r-normal--14-*",
"*-helvetica-bold-r-normal--17-*", "*-helvetica-bold-r-normal--20-*",
"*-helvetica-bold-r-normal--25-*",
"*-helvetica-bold-r-normal--25-*", "*-helvetica-bold-r-normal--34-*"
};
gchar *texttype75[] =
{ "*-times-medium-r-normal--8-*", "*-times-medium-r-normal--10-*",
"*-times-medium-r-normal--12-*", "*-times-medium-r-normal--14-*",
"*-times-medium-r-normal--18-*",
"*-times-medium-r-normal--18-*", "*-times-medium-r-normal--24-*"
};
gchar *texttype100[] =
{ "*-times-medium-r-normal--11-*", "*-times-medium-r-normal--14-*",
"*-times-medium-r-normal--17-*", "*-times-medium-r-normal--20-*",
"*-times-medium-r-normal--25-*",
"*-times-medium-r-normal--25-*", "*-times-medium-r-normal--34-*"
};
for (i=0;i<7;i++) {
if (font[i])
gdk_font_unref (font[i]);
if (symbfont[i])
gdk_font_unref (symbfont[i]);
if (smallfont[i])
gdk_font_unref (smallfont[i]);
if (ssymbfont[i])
gdk_font_unref (ssymbfont[i]);
if (slfont[i])
gdk_font_unref (slfont[i]);
if (boldfont[i])
gdk_font_unref (boldfont[i]);
if (textfont[i])
gdk_font_unref (textfont[i]);
fnt=i;
if ((font[i] = gdk_font_load (fntype75[fnt])) == NULL)
if((font[i] = gdk_font_load (fntype100[fnt])) == NULL)
{
fprintf (stderr, "failed to load font %s !!!\n", fntype75[fnt]);
if ((font[i] = gdk_font_load (fallback[fnt])) == NULL)
return (0);
}
if ((symbfont[i] = gdk_font_load (symtype75[fnt])) == NULL)
if((symbfont[i] = gdk_font_load (symtype100[fnt])) == NULL)
{
fprintf (stderr, "Failed to load symbol font, using standard font\n");
symbfont[i] = font[i];
}
if ((ssymbfont[i] = gdk_font_load (ssymtype75[fnt])) == NULL)
if((ssymbfont[i] = gdk_font_load (ssymtype100[fnt])) == NULL)
ssymbfont[i] = font[i];
if ((smallfont[i] = gdk_font_load (sfntype75[fnt])) == NULL)
if ((smallfont[i] = gdk_font_load (sfntype100[fnt])) == NULL)
smallfont[i] = font[i];
if ((slfont[i] = gdk_font_load (sltype75[fnt])) == NULL)
if ((slfont[i] = gdk_font_load (sltype100[fnt])) == NULL)
slfont[i] = font[i];
if ((boldfont[i] = gdk_font_load (btype75[fnt])) == NULL)
if ((boldfont[i] = gdk_font_load (btype100[fnt])) == NULL)
boldfont[i] = font[i];
if ((textfont[i] = gdk_font_load (texttype75[fnt])) == NULL)
if ((textfont[i] = gdk_font_load (texttype100[fnt])) == NULL)
textfont[i] = font[i];
}
#endif
return (1);
}
void
Set_Line (int lsty)
/* define standard line attributes for bond drawing */
{
int i;
for (i=0; i<7; i++)
gdk_gc_set_line_attributes (mygc[i], lsty, 0,
GDK_CAP_BUTT, GDK_JOIN_MITER);
gdk_gc_set_line_attributes (background_gc, lsty, 0,
GDK_CAP_BUTT, GDK_JOIN_MITER);
gdk_gc_set_line_attributes (drawing_area->style->black_gc, lsty, 0,
GDK_CAP_BUTT, GDK_JOIN_MITER);
}
syntax highlighted by Code2HTML, v. 0.9.1