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 */
|
|
}
|
|
}
|