/* File: bump.c * Author: Jean Thierry-Mieg (mieg@mrc-lmb.cam.ac.uk) * Copyright (C) J Thierry-Mieg and R Durbin, 1992 * ------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (MRC LMB, UK) rd@mrc-lmb.cam.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (MRC LMB, UK) rd@mrc-lmb.cam.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr * * Description: ** Bumper (Cambridge traditional folklore) * Exported functions: ** bumpCreate, bumpDestroy ** bumpItem, bumpText, bumpTest, bumpAdd ** the BUMP structure is defined in wh/bump.h * HISTORY: * Last edited: Oct 5 15:58 1999 (fw) * Created: Thu Aug 20 10:34:55 1992 (mieg) *------------------------------------------------------------------- */ /* $Id: bump.c,v 1.15 2002/02/22 18:00:20 srk Exp $ */ #include "regular.h" #include "bump.h" #include "bump_.h" /************************************************************/ magic_t BUMP_MAGIC = "BUMP"; #define MINBUMP ((float)(-2000000000.0)) /************* bump package based on gmap text **************/ BUMP bumpCreate (int nCol, int minSpace) { int i ; BUMP bump; bump = (BUMP) messalloc (sizeof (struct BumpStruct)) ; bump->magic = &BUMP_MAGIC ; if (nCol < 1) nCol = 1 ; bump->n = nCol ; bump->bottom = (float*) messalloc (nCol*sizeof (float)) ; for (i = 0 ; i < nCol ; ++i) bump->bottom[i] = MINBUMP ; if (minSpace < 0) minSpace = 0 ; bump->minSpace = minSpace ; bump->sloppy = 0 ; bump->max = 0 ; return bump ; } BUMP bumpReCreate (BUMP bump, int nCol, int minSpace) { int i ; if (!bump) return bumpCreate(nCol, minSpace) ; if (bump->magic != &BUMP_MAGIC) messcrash ("bumpReCreate received corrupt bump->magic"); if (nCol < 1) nCol = 1 ; if (nCol != bump->n) { messfree (bump->bottom) ; bump->bottom = (float*) messalloc (nCol*sizeof (float)) ; bump->n = nCol ; } for (i = 0 ; i < nCol ; ++i) bump->bottom[i] = MINBUMP ; if (minSpace < 0) minSpace = 0 ; bump->minSpace = minSpace ; bump->sloppy = 0 ; bump->max = 0 ; return bump ; } /* bumpReCreate */ void uBumpDestroy (BUMP bump) { if (!bump) return ; if (bump->magic != &BUMP_MAGIC) messcrash ("bumpDestroy received corrupt bump->magic"); messfree (bump->bottom) ; messfree (bump) ; return; } /* bumpDestroy */ int bumpMax (BUMP bump) { if (!bump) return 0 ; if (bump->magic != &BUMP_MAGIC) messcrash ("bumpMax received corrupt bump->magic"); return bump->max ; } /* bumpMax */ float bumpSetSloppy( BUMP bump, float sloppy) { float old ; if (!bump) messcrash ("bumpSetSloppy received NULL bump"); if (bump->magic != &BUMP_MAGIC) messcrash ("bumpSetSloppy received corrupt bump->magic"); old = bump->sloppy; bump->sloppy = sloppy ; return old ; } /* void bumpText(BUMP bump, char *cp, float *x, float *y) { CHECKBUMP ; if (!cp || !*cp) return ; bumpItem(bump, strlen(cp), 1, &xs, &ys) ; } */ void bumpRegister (BUMP bump, int wid, float height, int *px, float *py) { int i = *px , j ; if (!bump) messcrash ("bumpRegister received NULL bump"); if (bump->magic != &BUMP_MAGIC) messcrash ("bumpRegister received corrupt bump->magic"); j = wid < bump->n ? wid : bump->n; if (bump->max < i + j - 1) bump->max = i + j - 1 ; while (j--) /* advance bump */ bump->bottom[i+j] = *py + height ; } /* mhmp 16/05/97 */ void asciiBumpItem (BUMP bump, int wid, float height, int *px, float *py) /* works by resetting x, y */ { int x = *px ; float ynew, y = *py ; if (bump->magic != &BUMP_MAGIC) messcrash ("asciiBumpItem received corrupt bump->magic"); if (bump->xAscii != 0) { if (bump->xAscii + wid + bump->xGapAscii > bump->n) { ynew = y + 1 ; x = 0 ; bump->xAscii = wid ; } else { ynew = y ; x = bump->xAscii + bump->xGapAscii ; bump->xAscii = x + wid ; } } else { if (x + wid > bump->n) { if ((y - bump->yAscii) < 1 && (int) y == (int) bump->yAscii) ynew = y + 1 ; else ynew = y ; x = 0 ; bump->xAscii = wid ; } else { if (y != bump->yAscii && (int) y == (int) bump->yAscii) ynew = y + 1 ; else ynew = y ; } } *px = x ; *py = ynew ; bump->yAscii = ynew ; } BOOL bumpAdd (BUMP bump, int wid, float height, int *px, float *py, BOOL doIt) /* works by resetting x, y */ { int i, j ; int x = *px ; float ynew, y = *py ; if (bump->magic != &BUMP_MAGIC) messcrash ("bumpAdd received corrupt bump->magic"); if (x + wid + bump->minSpace > bump->n) x = bump->n - wid - bump->minSpace ; if (x < 0) x = 0 ; if (wid > bump->n) /* prevent infinite loops */ wid = bump->n ; if (y <= MINBUMP) y = MINBUMP + 1 ; ynew = y ; while (TRUE) { for (i = x, j = wid ; i < bump->n ; ++i) /* always start at x */ { if (bump->bottom[i] > y + bump->sloppy) { j = wid ; ynew = y ; /* this line was missing in the old code */ } else { if (bump->bottom[i] > ynew) ynew = bump->bottom[i] ; if (!--j) /* have found a gap */ break ; } } if (!j) { if (doIt) { for (j = 0 ; j < wid ; j++) /* advance bump */ bump->bottom[i - j] = ynew+height ; if (bump->max < i + 1) bump->max = i + 1 ; } *px = i - wid + 1 ; *py = ynew ; return TRUE ; } y += 1 ; /* try next row down */ if (!doIt && bump->maxDy && y - *py > bump->maxDy) return FALSE ; } } /* abbreviate text, if vertical bump exceeds dy return accepted length */ int bumpText (BUMP bump, char *text, int *px, float *py, float dy, BOOL vertical) { int w, n, x = *px; float y = *py, h, old = bump->maxDy ; if (bump->magic != &BUMP_MAGIC) messcrash ("bumpText received corrupt bump->magic"); if (!text || !*text) return 0 ; n = strlen(text) ; bump->maxDy = dy ; while (TRUE) { x = *px ; y = *py ; /* try always from desired position */ if (vertical) /*like in the genetic map */ { w = n + 1 ; h = 1 ;} else /* like in pmap */ { w = 1 ; h = n + 1 ;} if (bumpAdd (bump, w, h, &x, &y, FALSE)) { /* success */ bump->maxDy = old ; bumpRegister(bump, w, h, &x, &y) ; *px = x ; *py = y ; return n ; } if (n > 7) { n = 7 ; continue ; } if (n > 3) { bump->maxDy = 2 * dy ; n = 3 ; continue ; } if (n > 1) { bump->maxDy = 3 * dy ; n = 1 ; continue ; } bump->maxDy = old ; return 0 ; /* failure */ } } /**************************************************/ /**************************************************/