📄 sitetran.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#define _TRANSITIONS_ON_
//#define _TESTING_TRANITIONS_
#ifdef _TESTING_TRANITIONS_
#define INITGUID // this must be befor pntypes
#endif
#include "hxtypes.h" // this must be before windows.h
#ifdef _WIN32
#include "windows.h"
#endif
#define PI 3.14159265358979323846
#define Root2 1.414213562
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
//#define NO_GRAPHICS
#include "hxcom.h"
#include "hxbuffer.h"
#include "hxassert.h"
#include "sitetran.h"
#include "region.h"
#include "poly.h"
#include "tranmat.h"
#include "hxstrutl.h"
//=======================================================================
//=======================================================================
// All Transistion effects
//=======================================================================
//=======================================================================
void CopyRegion(HXREGION* dstrgn, HXREGION* rgn)
{
if (dstrgn != rgn) /* don't want to copy to itself */
{
if (dstrgn->size < rgn->numRects)
{
if (dstrgn->rects)
{
HXBOX *prevRects = dstrgn->rects;
if (! (dstrgn->rects = (HXBOX *)
realloc((char *) dstrgn->rects,
(unsigned) rgn->numRects * (sizeof(HXBOX))))) {
free(prevRects);
return;
}
}
dstrgn->size = rgn->numRects;
}
dstrgn->numRects = rgn->numRects;
dstrgn->extents.x1 = rgn->extents.x1;
dstrgn->extents.y1 = rgn->extents.y1;
dstrgn->extents.x2 = rgn->extents.x2;
dstrgn->extents.y2 = rgn->extents.y2;
memcpy((char *) dstrgn->rects, (char *) rgn->rects, /* Flawfinder: ignore */
(int) (rgn->numRects * sizeof(HXBOX)));
}
}
HXREGION* InvertRGN(HXREGION* in, int x, int y, int x1, int y1)
{
HXREGION* retRGN = HXCreateRectRegion(x,y,x1 - x,y1 - y);
HXCombineRgn(retRGN, retRGN, in, HX_RGN_DIFF);
HXDestroyRegion(in);
return retRGN;
}
int CompareRects(const void *arg1, const void *arg2)
{
HXBOX* b1 = (HXBOX*)arg1;
HXBOX* b2 = (HXBOX*)arg2;
if (b1->y1 < b2->y1)
return -1;
if (b1->y1 != b2->y1)
return 1;
if (b1->x1 < b2->x1)
return -1;
if (b1->x1 != b2->x1)
return 1;
return 0;
}
HXREGION* MirrorHorizontal(HXREGION* in, int y)
{
int tmpY;
for (int i = 0; i < in->numRects; ++i)
{
in->rects[i].y1 = 2 * y - in->rects[i].y1;
in->rects[i].y2 = 2 * y - in->rects[i].y2;
if (in->rects[i].y2 < in->rects[i].y1)
{
tmpY = in->rects[i].y1;
in->rects[i].y1 = in->rects[i].y2;
in->rects[i].y2 = tmpY;
}
}
qsort((void*)in->rects, in->numRects, sizeof(HXBOX), CompareRects);
return in;
}
HXREGION* MirrorVertical(HXREGION* in, int x)
{
int tmpX;
for (int i = 0; i < in->numRects; ++i)
{
in->rects[i].x1 = 2 * x - in->rects[i].x1;
in->rects[i].x2 = 2 * x - in->rects[i].x2;
if (in->rects[i].x2 < in->rects[i].x1)
{
tmpX = in->rects[i].x1;
in->rects[i].x1 = in->rects[i].x2;
in->rects[i].x2 = tmpX;
}
if( in->rects[i].x1 != 0 )
in->rects[i].x1 = in->rects[i].x1 -1;
}
qsort((void*)in->rects, in->numRects, sizeof(HXBOX), CompareRects);
return in;
}
void MirrorHorizontal(tranLines* lines, int y)
{
for (int i = 0; i < lines->m_nLines; ++i)
{
lines->m_pLines[i].start.x = lines->m_pLines[i].start.x;
lines->m_pLines[i].start.y = 2 * y - lines->m_pLines[i].start.y;
lines->m_pLines[i].finish.x = lines->m_pLines[i].finish.x;
lines->m_pLines[i].finish.y = 2 * y - lines->m_pLines[i].finish.y;
}
}
void MirrorVertical(tranLines* lines, int x)
{
for (int i = 0; i < lines->m_nLines; ++i)
{
lines->m_pLines[i].start.x = 2 * x - lines->m_pLines[i].start.x;
lines->m_pLines[i].start.y = lines->m_pLines[i].start.y;
lines->m_pLines[i].finish.x = 2 * x - lines->m_pLines[i].finish.x;
lines->m_pLines[i].finish.y = lines->m_pLines[i].finish.y;
}
}
tranLines::tranLines()
{
m_nLines = 0;
m_pLines = NULL;
}
tranLines::~tranLines()
{
Destroy();
}
LineSegment::LineSegment(const LineSegment& ls)
{
*this = ls;
}
void LineSegment::operator=(const LineSegment& right)
{
start.x = right.start.x;
start.y = right.start.y;
finish.x = right.finish.x;
finish.y = right.finish.y;
}
// returns TRUE if the line is within the boundary, FALSE if it lies completely outside
BOOL LineSegment::Clip(int left, int top, int right, int bottom)
{
BOOL retVal = TRUE;
double slope;
// make sure our start is left of finish
if (start.x > finish.x)
{
int tmp = start.x;
start.x = finish.x;
finish.x = tmp;
tmp = start.y;
start.y = finish.y;
finish.y = tmp;
}
if (start.x > right || finish.x < left ||
(start.y < top && finish.y < top) ||
(start.y > bottom && finish.y > bottom))
{
retVal = FALSE;
goto LineSegment_Clip_End;
}
slope = ((double)(finish.y - start.y + 1) / (double)(finish.x - start.x + 1));
if (start.x < left)
{
start.y += int((left - start.x) * slope);
start.x = left;
}
if (start.y > bottom)
{
start.x -= int((start.y - bottom) / slope);
start.y = bottom;
}
if(start.y < top)
{
start.x += int((top - start.y) / slope);
start.y = top;
}
if (finish.x > right)
{
finish.y -= int((finish.x - right) * slope);
finish.x = right;
}
if (finish.y > bottom)
{
finish.x -= int((finish.y - bottom) / slope);
finish.y = bottom;
}
if(finish.y < top)
{
finish.x += int((top - finish.y) / slope);
finish.y = top;
}
if (start.x < left || start.x > right ||
start.y < top || start.y > bottom ||
finish.x < left || finish.x > right ||
finish.y < top || finish.y > bottom)
{
//XXXSMJ currently there's a case were the line can exist with only
// an endpoint on border. This means only one pixel of the line is
// inside the clipping region. For now, we'll say this sucker is
// clipped.
retVal = FALSE;
}
LineSegment_Clip_End:
return retVal;
}
tranLines* operator+(const tranLines& left, const tranLines& right)
{
tranLines* newLines = const_cast<tranLines*>(&left);
if (right.m_nLines)
{
newLines = new tranLines;
newLines->m_nLines = left.m_nLines + right.m_nLines;
newLines->m_pLines = new LineSegment[newLines->m_nLines];
if (!newLines->m_pLines)
{
newLines->m_nLines = 0;
}
else
{
int i,c;
for (i = 0, c = 0; i < left.m_nLines; ++i, ++c)
{
newLines->m_pLines[c] = left.m_pLines[i];
}
for (i = 0; i < right.m_nLines; ++i, ++c)
{
newLines->m_pLines[c] = right.m_pLines[i];
}
}
}
return newLines;
}
void tranLines::operator=(const tranLines& right)
{
Copy(right);
}
void tranLines::operator+=(const tranLines& right)
{
if (right.m_nLines)
{
tranLines* newLines = *this + right;
Copy(*newLines);
delete newLines;
}
}
void tranLines::operator+=(const LineSegment& right)
{
tranLines newLines;
newLines.m_nLines = 1;
newLines.m_pLines = new LineSegment[1];
if (!newLines.m_pLines)
{
newLines.m_nLines = 0;
}
else
{
*newLines.m_pLines = right;
}
*this += newLines;
}
tranLines::tranLines(const tranLines& tl)
{
m_nLines = 0;
m_pLines = NULL;
Copy(tl);
}
void tranLines::Copy(const tranLines& tl)
{
Destroy();
m_nLines = tl.m_nLines;
if (m_nLines)
{
m_pLines = new LineSegment[m_nLines];
for (int i = 0; i < m_nLines; ++i)
{
m_pLines[i] = tl.m_pLines[i];
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -