/* File: drawdisp.c * Author: Richard Durbin (rd@sanger.ac.uk) * Copyright (C) J Thierry-Mieg and R Durbin, 1995 * ------------------------------------------------------------------- * Acedb is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt * ------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (MRC LMB, UK) rd@sanger.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr * * Description: to provide postscript output for the graph package * Exported functions: graphPS(), graphPrint() * HISTORY: * Last edited: May 6 10:43 2003 (edgrif) * Created: Sat May 22 08:30:44 1995 (rd) * $Id: drawdisp.c,v 1.16 2003/05/06 13:13:41 edgrif Exp $ *------------------------------------------------------------------- */ #include #include #include #include #include #include static int MAGIC = 28426847 ; static BOOL isInitialised = FALSE ; static KEY _Point, _Rectangle, _Circle, _Polygon, _Contains, _Draw ; static KEY _Scale, _Bounds, _Shape, _Foreground, _Background ; static void drawInitialise (void) { lexaddkey ("Point", &_Point, 0) ; lexaddkey ("Draw", &_Draw, 0) ; lexaddkey ("Rectangle", &_Rectangle, 0) ; lexaddkey ("Polygon", &_Polygon, 0) ; lexaddkey ("Circle", &_Circle, 0) ; lexaddkey ("Contains", &_Contains, 0) ; lexaddkey ("Scale", &_Scale, 0) ; lexaddkey ("Bounds", &_Bounds, 0) ; lexaddkey ("Shape", &_Shape, 0) ; lexaddkey ("Foreground", &_Foreground, 0) ; lexaddkey ("Background", &_Background, 0) ; } /*************************/ typedef struct LOOKSTUFF { int magic; /* == MAGIC */ KEY key ; /* for the Drawing object */ Array segs ; /* array of SEG's indexed by box */ Array boxIndex ; /* array of indices in segs */ float scale ; /* coord->pixel factor */ float x0, y0 ; /* in pixels */ STORE_HANDLE handle ; int activeBox ; char imageFileName[256] ; } *LOOK ; typedef struct { KEY key ; KEY tag ; /* tag2 tag in Drawing obj */ KEY fg, bg ; } SEG ; LOOK lookGet (char *name) { LOOK look ; if (!graphAssFind (&MAGIC, &look)) messcrash ("graph not found in drawing%s()", name) ; if (look->magic != MAGIC) messcrash ("%s received a wrong pointer",name) ; return look ; } #define X2P(z) (((z)-look->x0)*look->scale) #define Y2P(z) (((z)-look->y0)*look->scale) /*************************/ static void drawDestroy (void) { handleDestroy (lookGet("Destroy")->handle) ; } static void drawPick (int box_unused, double x_unused, double y_unused, int modifier_unused) ; static void drawDraw (void) ; static BOOL drawConvert (LOOK look) ; static MENUOPT drawMenu[] = { { graphDestroy, "Quit" }, { graphPrint, "Print" }, { help, "Help" }, { graphBoxInfoWrite, "Box info" }, { 0, 0 } } ; BOOL imageDisplay (KEY key, KEY from, BOOL isOldGraph, void *unused) { LOOK look = 0 ; if (!isInitialised) drawInitialise () ; /* from here assume key support #Image model */ /* ignore isOldGraph */ { STORE_HANDLE handle = handleCreate() ; look = (LOOK) handleAlloc (0, handle, sizeof (struct LOOKSTUFF)) ; look->handle = handle ; } look->magic = MAGIC; look->key = key ; look->segs = arrayHandleCreate (32, SEG, look->handle) ; look->boxIndex = arrayHandleCreate (32, int, look->handle) ; displayCreate ("DtImage"); graphRegister (DESTROY, drawDestroy) ; graphRegister (PICK, drawPick) ; graphMenu (drawMenu) ; graphAssociate (&MAGIC, look) ; if (!drawConvert (look)) goto abort ; drawDraw () ; return TRUE ; abort: if (look) handleDestroy (look->handle) ; return FALSE ; } /**************************************/ static BOOL drawConvert (LOOK look) { OBJ obj = bsCreate (look->key) ; float bx0, by0, bx1, by1 ; Array flat ; int i ; SEG *seg ; char *fileName = 0 ; #define ABORT(z) { messout ("Can't draw %s: %s", name(look->key), z) ; \ return FALSE ; } if (!obj) ABORT("can't open object") ; if (!bsGetData (obj, _Scale, _Float, &look->scale)) ABORT("no Scale") ; if (!(bsGetData (obj, _Bounds, _Float, &bx0) && bsGetData (obj, _bsRight, _Float, &by0) && bsGetData (obj, _bsRight, _Float, &bx1) && bsGetData (obj, _bsRight, _Float, &by1))) ABORT("no Bounds") ; look->x0 = bx0 * look->scale ; look->y0 = by0 * look->scale ; graphPixelBounds (look->scale*(bx1-bx0), look->scale*(by1-by0)) ; arrayMax(look->segs) = 1 ; /* don't use seg 0 */ if (bsFindTag (obj, _File) && bsPushObj (obj) && bsFindTag (obj, str2tag("GIF")) && bsGetData (obj, str2tag("File_name"), _Text, &fileName)) { strncpy (look->imageFileName, fileName, 255) ; } bsGoto (obj,0) ; flat = arrayCreate (128, BSunit) ; if (bsFindTag (obj, _Contains) && bsFlatten (obj, 2, flat)) for (i = 0 ; i < arrayMax(flat) ; i += 2) { if (class(arr(flat, i+1, BSunit).k)) { seg = arrayp(look->segs, arrayMax(look->segs), SEG) ; seg->tag = arr(flat, i, BSunit).k ; seg->key = arr(flat, i+1, BSunit).k ; bsGoto (obj, 0) ; if (bsFindKey (obj, seg->tag, seg->key) && bsPushObj (obj) && bsFindTag (obj, _Foreground) && bsGetKeyTags (obj, _bsRight, &seg->fg)) ; else seg->fg = BLACK ; bsGoto (obj, 0) ; if (bsFindKey (obj, seg->tag, seg->key) && bsPushObj (obj) && bsFindTag (obj, _Background) && bsGetKeyTags (obj, _bsRight, &seg->bg)) ; else seg->bg = TRANSPARENT ; bsGoto (obj, 0) ; } } return TRUE ; } /*************************************/ static void drawSelect (LOOK look, int box, BOOL on) { int i = arr(look->boxIndex, box, int) ; SEG *seg = arrp (look->segs, i, SEG) ; if (!i) return ; if (on) graphBoxDraw (box, CYAN, seg->bg) ; else graphBoxDraw (box, seg->fg, seg->bg) ; } /*************************************/ static void drawPick (int box_unused, double x_unused, double y_unused, int modifier_unused) { LOOK look = lookGet ("Pick") ; int i ; int box = graphBoxAt (graphEventX, graphEventY, 0, 0) ; if (box && box == look->activeBox && (i = arr(look->boxIndex, box, int))) display (arrp(look->segs,i,SEG)->key, look->key, 0) ; else { if (look->activeBox) drawSelect (look, look->activeBox, FALSE) ; look->activeBox = box ; if (look->activeBox) drawSelect (look, look->activeBox, TRUE) ; } } /*************************************/ static void drawDraw (void) { LOOK look = lookGet ("Draw") ; int box, i ; SEG *seg ; OBJ obj ; KEY type ; static Array units = 0, coords = 0 ; float x0, x1, y0, y1 ; FILE *fil = 0 ; arrayMax(look->boxIndex) = 0 ; graphClear () ; graphPointsize (10.0) ; if (*look->imageFileName && (fil = filopen (look->imageFileName,"","r"))) graphGIFread (fil, 0, 0) ; if (fil) filclose (fil) ; obj = bsCreate (look->key) ; if (obj) for (i = 1 ; i < arrayMax (look->segs) ; ++i) { seg = arrp(look->segs, i, SEG) ; bsGoto (obj, 0) ; if (!bsFindKey (obj, seg->tag, seg->key) || !bsPushObj (obj) || !bsFindTag (obj, _Shape) || !bsGetKeyTags (obj, _bsRight, &type)) continue ; box = 0 ; if (type == _Point) { if (bsGetData (obj, _bsRight, _Float, &x0) && bsGetData (obj, _bsRight, _Float, &y0)) { box = graphBoxStart() ; graphPoint (X2P(x0), Y2P(y0)) ; graphBoxEnd() ; } } else if (type == _Rectangle) { if (bsGetData (obj, _bsRight, _Float, &x0) && bsGetData (obj, _bsRight, _Float, &y0) && bsGetData (obj, _bsRight, _Float, &x1) && bsGetData (obj, _bsRight, _Float, &y1)) { box = graphBoxStart() ; graphRectangle (X2P(x0), Y2P(y0), X2P(x1), Y2P(y1)) ; graphBoxEnd() ; } } else if (type == _Circle) { if (bsGetData (obj, _bsRight, _Float, &x0) && bsGetData (obj, _bsRight, _Float, &y0) && bsGetData (obj, _bsRight, _Float, &y1)) { box = graphBoxStart() ; graphCircle (X2P(x0), Y2P(y0), Y2P(y1)) ; graphBoxEnd() ; graphBoxDraw(box, BLACK, TRANSPARENT) ; } } else if (type == _Polygon) { units = arrayReCreate (units, 32, BSunit) ; coords = arrayReCreate (coords, 32, float) ; if (bsFlatten (obj, 2, units)) { int j ; for (j = 0 ; j < arrayMax (units) ; j += 2) { array(coords, j, float) = X2P(arr(units, j, BSunit).f) ; array(coords, j+1, float) = Y2P(arr(units, j+1, BSunit).f) ; } box = graphBoxStart() ; graphPolygon (coords) ; graphBoxEnd() ; graphBoxDraw(box, BLACK, TRANSPARENT) ; } } if (box) { array(look->boxIndex, box, int) = i ; graphBoxInfo (box, seg->key, 0) ; graphBoxDraw (box, seg->fg, seg->bg) ; } } bsDestroy (obj) ; look->activeBox = 0 ; graphRedraw () ; } /********************* end of file ******************/