204 lines
5.4 KiB
C
204 lines
5.4 KiB
C
/* touchingtypes.c --
|
||
*
|
||
* *********************************************************************
|
||
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
||
* * Permission to use, copy, modify, and distribute this *
|
||
* * software and its documentation for any purpose and without *
|
||
* * fee is hereby granted, provided that the above copyright *
|
||
* * notice appear in all copies. The University of California *
|
||
* * makes no representations about the suitability of this *
|
||
* * software for any purpose. It is provided "as is" without *
|
||
* * express or implied warranty. Export of this software outside *
|
||
* * of the United States of America may require an export license. *
|
||
* *********************************************************************
|
||
* Lawrence Livermore National Laboratory
|
||
* All rights reserved.
|
||
*
|
||
* Function to return mask of all tiletypes touching a given point.
|
||
*/
|
||
|
||
#ifndef lint
|
||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/utils/touchtypes.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||
#endif /* not lint */
|
||
|
||
#include <stdio.h>
|
||
|
||
#include "utils/magic.h"
|
||
#include "utils/geometry.h"
|
||
#include "utils/geofast.h"
|
||
#include "tiles/tile.h"
|
||
#include "utils/hash.h"
|
||
#include "database/database.h"
|
||
|
||
/* ----------------------- Structs local to this file ------------------- */
|
||
|
||
typedef struct touchingfuncparms
|
||
{
|
||
Point tfp_point;
|
||
TileTypeBitMask tfp_types;
|
||
} TouchingFuncParms;
|
||
|
||
|
||
/*
|
||
* ----------------------------------------------------------------------------
|
||
*
|
||
* TouchingTypes --
|
||
*
|
||
* Generate mask of all types touching or covering a given point.
|
||
*
|
||
* Results:
|
||
* Mask of all types touching or covering a given point in cellUse or
|
||
* expanded subcell. If an unexpanded subcell is
|
||
* covering or touching point TT_SUBCELL is included in the result as
|
||
* well.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
TileTypeBitMask
|
||
TouchingTypes(cellUse, expansionMask, point)
|
||
CellUse *cellUse;
|
||
int expansionMask;
|
||
Point *point;
|
||
{
|
||
int touchingTypesFunc();
|
||
int touchingSubcellsFunc();
|
||
TouchingFuncParms parms;
|
||
|
||
/* Search unit radius rectangle around point for paint tiles
|
||
* (in cellUse or subcells expanded in cmd window) containing or
|
||
* touching point
|
||
*/
|
||
{
|
||
SearchContext scx;
|
||
|
||
scx.scx_area.r_ll = *point;
|
||
scx.scx_area.r_ur = *point;
|
||
scx.scx_area.r_ll.p_x -= 1;
|
||
scx.scx_area.r_ll.p_y -= 1;
|
||
scx.scx_area.r_ur.p_x += 1;
|
||
scx.scx_area.r_ur.p_y += 1;
|
||
|
||
scx.scx_trans = GeoIdentityTransform;
|
||
scx.scx_use = cellUse;
|
||
|
||
parms.tfp_point = *point;
|
||
TTMaskZero(&(parms.tfp_types));
|
||
|
||
DBTreeSrTiles(
|
||
&scx,
|
||
&DBAllButSpaceAndDRCBits,
|
||
expansionMask,
|
||
touchingTypesFunc,
|
||
(ClientData) &parms);
|
||
}
|
||
|
||
/* Now check for presence of unexpanded subcells */
|
||
{
|
||
SearchContext scx;
|
||
|
||
scx.scx_area.r_ll = *point;
|
||
scx.scx_area.r_ur = *point;
|
||
scx.scx_area.r_ll.p_x -= 1;
|
||
scx.scx_area.r_ll.p_y -= 1;
|
||
scx.scx_area.r_ur.p_x += 1;
|
||
scx.scx_area.r_ur.p_y += 1;
|
||
|
||
scx.scx_trans = GeoIdentityTransform;
|
||
scx.scx_use = cellUse;
|
||
|
||
DBTreeSrCells(
|
||
&scx,
|
||
expansionMask,
|
||
touchingSubcellsFunc,
|
||
(ClientData) &parms);
|
||
}
|
||
|
||
return(parms.tfp_types);
|
||
}
|
||
|
||
|
||
/*
|
||
* ---------------------------------------------------------------------
|
||
*
|
||
* touchingTypesFunc --
|
||
*
|
||
* Called by DBTreeSrTiles on behalf of touchingTypes above, to check if
|
||
* tile touches point.
|
||
*
|
||
* Results:
|
||
* Returns 0 to continue search.
|
||
*
|
||
* Side effects:
|
||
* Sets tile type in mask if tile touches point.
|
||
*
|
||
* ---------------------------------------------------------------------
|
||
*/
|
||
|
||
int
|
||
touchingTypesFunc(tile, cxp)
|
||
Tile *tile;
|
||
TreeContext *cxp;
|
||
{
|
||
SearchContext *scx = cxp->tc_scx;
|
||
Rect r, rDest;
|
||
TouchingFuncParms *parms = (TouchingFuncParms *) (cxp->tc_filter->tf_arg);
|
||
|
||
/* Transform to result coordinates */
|
||
TITORECT(tile, &r);
|
||
GEOCLIP(&r, &scx->scx_area);
|
||
GEOTRANSRECT(&scx->scx_trans, &r, &rDest);
|
||
|
||
if(GEO_ENCLOSE(&(parms->tfp_point), &rDest))
|
||
TTMaskSetType(&(parms->tfp_types),TiGetType(tile));
|
||
|
||
/* return 0 to continue search */
|
||
return(0);
|
||
}
|
||
|
||
|
||
/*
|
||
* ---------------------------------------------------------------------
|
||
*
|
||
* touchingSubcellsFunc --
|
||
*
|
||
* Called by DBTreeSrCells on behalf of touchingTypes above, to check if
|
||
* subcell touches point.
|
||
*
|
||
* Results:
|
||
* Returns 0 if subcell doesn't touch point (to continue search)
|
||
* Returns 1 on match (to terminate search)
|
||
*
|
||
* Side effects:
|
||
* Sets TT_SUBCELL in mask if subcell touches point.
|
||
*
|
||
* ---------------------------------------------------------------------
|
||
*/
|
||
|
||
int
|
||
touchingSubcellsFunc(scx, cdarg)
|
||
SearchContext *scx;
|
||
ClientData cdarg;
|
||
{
|
||
Rect r, rDest;
|
||
TouchingFuncParms *parms = (TouchingFuncParms *) cdarg;
|
||
|
||
/* Transform bounding box to result coordinates */
|
||
r = scx->scx_use->cu_def->cd_bbox;
|
||
GEOTRANSRECT(&scx->scx_trans, &r, &rDest);
|
||
|
||
if(GEO_ENCLOSE(&(parms->tfp_point), &rDest))
|
||
{
|
||
/* touching subcell found, mark in types mask, and terminate search */
|
||
TTMaskSetType(&(parms->tfp_types),TT_SUBCELL);
|
||
return 1; /* 1 = abort search */
|
||
}
|
||
else
|
||
{
|
||
/* subcell doesn't touch point after all, continue search */
|
||
return 0; /* 0 = continue search */
|
||
}
|
||
}
|