📄 imagemap.cpp
字号:
/*____________________________________________________________________________*\
Copyright (c) 1997-2003 John Roy, Holger Zimmermann. All rights reserved.
These sources, libraries and applications are
FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
as long as the following conditions are adhered to.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHORS OR ITS CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*____________________________________________________________________________*|
*
* $Source: /cvsroot/pi3web/Pi3Web_200/Source/HTTP/ImageMap.cpp,v $
* $Date: 2003/05/13 18:42:03 $
*
Description:
ImageMap handler module.
\*____________________________________________________________________________*/
/* $SourceTop:$ */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "Pi3API.h"
#include "PIString.h"
#define D { cerr << __FILE__ << ": " << __LINE__ << endl; }
/*____________________________________________________________________________*\
*
Description:
\*____________________________________________________________________________*/
#define NUM_VERTICES 50
class Vertice
{
public:
int iX;
int iY;
Vertice()
: iX( -1 ), iY( -1 )
{};
};
/*____________________________________________________________________________*\
*
Description:
Documentation
\*____________________________________________________________________________*/
#if 0
/*
** HTML documentation for this handler
*/
/*___+++HTMLDOC_BEGIN+++___*/
Name:
ImageMap
Description:
Handle server-side image maps, this version only supports circles,
rectangles and defaults.
<!--
Options:
<H5>Overview</H5>
<TABLE BORDER=1>
<TH>Option
<TH>Default
<TH>Values
<TH>Short Description
<TH>Example(s)
<TR>
<TD>Pi3Expression
<TD>+
<TD>A Pi3Expression
<TD>Expression to place in debug log
<TD>Pi3Expression="$c/* value of Content-Type */"
</TABLE>
<STRONG>-</STRONG> in the <IT>default</IT> indicates no default<BR>
<STRONG>+</STRONG> in the <IT>default</IT> indicates the field is mandatory<BR>
<H4>Description of Options</H4>
<H5>
Pi3Expression
</H5>
Pi3Expression to write in the debug log.
-->
Phase:
HANDLE
Returns:
PIAPI_COMPLETED
Note:
Example:
<PRE>
<Object>
Name ImageMap
Class ImageMapClass
</Object>
<Object>
...
Handle ImageMap
...
</Object>
</PRE>
/*___+++HTMLDOC_END+++___*/
#endif
/*____________________________________________________________________________*\
*
Description:
\*____________________________________________________________________________*/
struct _ImageMap
{
int xxx;
};
typedef struct _ImageMap ImageMap;
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int ImageMap_fnParameter( void *pData, const char *pVar, const char *pVal,
const char *pWhere )
{
PIObject *pObject = (PIObject *)pData;
ImageMap *pImageMap = (ImageMap *)PIObject_getUserData( pObject );
(void)pImageMap;
assert( pVar );
assert( pVal );
#if 0
if ( !PIUtil_stricmp( pVar, "Variable1" ) )
{
xxx = pVal;
}
#endif
if ( 1 )
{
}
else
{
/* ---
Configuration error
--- */
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "ImageMap: %sUnknown directive '%s'.", pWhere, pVar );
return 0;
};
return 1;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int ImageMap_init( ImageMap *pImageMap, PIObject *pObject, int iArgc,
const char *ppArgv[] )
{
int iRet = PIObject_readParameters( pObject, iArgc, ppArgv,
ImageMap_fnParameter, pObject );
/* --- set defaults --- */
if ( iRet )
{
#if 0
pImageMap->xxx = "yyy"
#endif
};
return iRet;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int ImageMap_onClassLoad( PIClass_LoadAction eLoad, void * )
{
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int ImageMap_constructor( PIObject *pObj,
int iArgc, const char *ppArgv[] )
{
ImageMap *pImageMap = (ImageMap *)PIUtil_malloc( sizeof( ImageMap ) );
PIObject_setUserData( pObj, pImageMap );
if ( !ImageMap_init( pImageMap, pObj, iArgc, ppArgv ) )
{
return PIAPI_ERROR;
};
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int ImageMap_copyConstructor( PIObject *o, int i, const char *a[] )
{
return PIAPI_ERROR;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
#define TS(x) #x
static int Internal_redirect( PIHTTP &tPIHTTP, const char *pDefault )
{
const char *pPort = HTTPUtil_getHostPort(&tPIHTTP);
const char *pHost = HTTPUtil_getHostName(&tPIHTTP);
const char *pURI = (const char *)PIDB_lookup( tPIHTTP.pRequestDB,
PIDBTYPE_STRING, KEY_HTTP_URI, 0 );
assert( pURI );
const char *pKeySize = (const char *)PIDB_lookup( tPIHTTP.pConnectionDB,
PIDBTYPE_STRING, KEY_HTTPS_KEYSIZE, 0 );
if ( !pHost ) { pHost = ""; };
const char *pProtocol = 0;
/* --- the new location --- */
PIString sLocation;
/*
** Get protocol
*/
if ( !PIUtil_strncmpi( pDefault, "https://", 8 ) )
{
pProtocol = "https://";
pDefault = &( pDefault[8] );
if ( !pKeySize ) pKeySize = "foo";
}
else if ( !PIUtil_strncmpi( pDefault, "http://", 7 ) )
{
pProtocol = "http://";
pDefault = &( pDefault[7] );
if ( pKeySize ) pKeySize = 0;
}
else
{
pProtocol = pKeySize ? "https://" : "http://";
};
assert( pProtocol );
sLocation.Concatenate( pProtocol );
sLocation.Concatenate( pHost );
/*
** Get port
*/
enum { PORT_SIZE=15 };
char szPort[PORT_SIZE+1];
int iDefaultPort = pKeySize ? HTTPS_DEFAULT_PORT : HTTP_DEFAULT_PORT;
if ( *pDefault == ':' )
{
pDefault = &( pDefault[1] );
sprintf( szPort, "%d", atoi( pDefault ) );
pPort = szPort;
for( ; isdigit( *pDefault ); pDefault++ );
}
else if ( !pPort )
{
sprintf( szPort, "%d", iDefaultPort );
pPort = szPort;
};
if ( atoi( pPort ) != iDefaultPort )
{
sLocation.Concatenate( ':' );
sLocation.Concatenate( pPort );
};
/*
** Get URL path
*/
if ( *pDefault != '/' )
{
/* --- just filename provided - use old URI path --- */
int i = strlen( pURI ) - 1;
for( ; i>=0 && pURI[i]!='/'; i-- );
if ( i>0 )
{
PIString sTmp( pURI, i );
sLocation.Concatenate( sTmp );
};
sLocation.Concatenate( '/' );
};
sLocation.Concatenate( pDefault );
PIDB_add( tPIHTTP.pResponseDB, PIDBTYPE_RFC822, KEY_HTTP_LOCATION,
(void *)(const char *)sLocation, 0 );
return HTTPUtil_doHTTPError( &tPIHTTP, ST_PERMANENTREDIRECT );
}
#undef TS
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
static int Internal_isRect( Vertice &tI, Vertice aV[], int iNumVert )
{
/* --- vertices are two diagonal points --- */
assert( iNumVert == 2 );
if ( iNumVert < 2 ) return 0;
/* --- get min and max x --- */
int iX1, iX2;
if ( aV[0].iX < aV[1].iX )
{ iX1 = aV[0].iX; iX2 = aV[1].iX; }
else
{ iX1 = aV[1].iX; iX2 = aV[0].iX; }
/* --- Vertices are within x? --- */
if ( ( tI.iX < iX1 ) || ( tI.iX > iX2 ) )
{ /* out of x range */ return 0; };
/* --- get min and max y --- */
int iY1, iY2;
if ( aV[0].iY < aV[1].iY )
{ iY1 = aV[0].iY; iY2 = aV[1].iY; }
else
{ iY1 = aV[1].iY; iY2 = aV[0].iY; }
/* --- Vertices are within x? --- */
if ( ( tI.iY < iY1 ) || ( tI.iY > iY2 ) )
{ /* out of y range */ return 0; };
return 1;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
static int Internal_isCircle( Vertice &tI, Vertice aV[], int iNumVert )
{
/* --- vertices are the center and a point on the circle --- */
assert( iNumVert == 2 );
if ( iNumVert < 2 ) return 0;
/* --- get square of length of point on circle from center --- */
int iRadiusSquare = ( ( aV[0].iX - aV[1].iX ) * ( aV[0].iX - aV[1].iX ) ) +
( ( aV[0].iY - aV[1].iY ) * ( aV[0].iY - aV[1].iY ) );
/* --- get square of length of given point from center --- */
int iGivenSquare = ( ( aV[0].iX - tI.iX ) * ( aV[0].iX - tI.iX ) ) +
( ( aV[0].iY - tI.iY ) * ( aV[0].iY - tI.iY ) );
/* ---
The given point is within the circle if the square of its length
from the circle center is less than or equal to that of the
point on the circle
--- */
if ( iGivenSquare <= iRadiusSquare )
{ return 1; };
/* --- not in circle --- */
return 0;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
static int Internal_isPolygon( Vertice &tI, Vertice aV[], int iNumVert )
{
/* DotProduct = PP1*PP2 = (P1.x - P.x)*(P2.y-P.y) - (P1.y - P.y)*(P2.x - P.x) */
/* The sign of the angle between PP1 and PP2 is the "circulation" */
int i, result = 0;
double p;
for (i = 0; i < iNumVert - 1; i++)
{
p = (aV[i].iX - tI.iX)*(aV[i+1].iY - tI.iY)
- (aV[i].iY - tI.iY)*(aV[i+1].iX - tI.iX);
if ( (aV[i].iY < tI.iY) && (aV[i+1].iY >= tI.iY) && (p > 0) ) result++;
if ( (aV[i].iY >= tI.iY) && (aV[i+1].iY < tI.iY) && (p < 0) ) result--;
}
return result;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
static int Internal_isEllipse( Vertice &tI, Vertice aV[], int iNumVert )
{
/* --- vertices describe the outer rectangle --- */
assert( iNumVert == 2 );
if ( iNumVert < 2 ) return 0;
/* --- calculate [a,b], [u,v] --- */
double a, b, u, v;
a = (aV[1].iX - aV[0].iX) / 2;
b = (aV[1].iY - aV[0].iY) / 2;
u = aV[0].iX + a;
v = aV[0].iY + b;
/* --- no division by zero for special case a = 0 --- */
if ( a == 0 ) return 0;
/* --- No negative argument for SQRT (see below) --- */
/* --- abbreviate when x > a or y > b --- */
if ( fabs(tI.iX - u) > a ) return 0;
if ( fabs(tI.iY - v) > b ) return 0;
/* --- x
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -