167 lines
3.7 KiB
C++
167 lines
3.7 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#include "picture/pict.h"
|
|
#include "math/nmath.h"
|
|
|
|
using namespace GS;
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void Picture::LowLevelDrawLine(bool hq, float sx, float sy, float ex, float ey, float r, float g, float b, float a, const Rect <float> *clip_rect)
|
|
{
|
|
// Output validity.
|
|
if (!data || (pxformat.GetBpp() != 32) || pxformat.IsReal())
|
|
return;
|
|
|
|
// Clip primitive.
|
|
float dx = ex - sx, dy = ey - sy;
|
|
|
|
// Sub pixel correction.
|
|
if (Types::Abs(dy) > Types::Abs(dx))
|
|
{
|
|
float fsy = Math::Floor(sy);
|
|
if (dy)
|
|
sx -= dx * (sy - fsy) / dy; // Sub-pixel correction.
|
|
sy = fsy;
|
|
}
|
|
else
|
|
{
|
|
float fsx = Math::Floor(sx);
|
|
if (dx)
|
|
sy -= dy * (sx - fsx) / dx; // Sub-pixel correction.
|
|
sx = fsx;
|
|
}
|
|
|
|
// Clipping.
|
|
if (clip_rect)
|
|
{
|
|
//---------------------------------------------------------------
|
|
#define __SwapFloat(A, B) { float swp = A; A = B; B = swp; }
|
|
//---------------------------------------------------------------
|
|
|
|
if (dx)
|
|
{
|
|
// Flip line if it is going backward.
|
|
if (dx < 0)
|
|
{
|
|
__SwapFloat(sx, ex)
|
|
__SwapFloat(sy, ey)
|
|
dx = ex - sx; dy = ey - sy;
|
|
}
|
|
float idx = 1 / dx;
|
|
|
|
// Clip on X axis.
|
|
if (ex < clip_rect->sx)
|
|
return;
|
|
|
|
float kee = (clip_rect->ex - sx) * idx;
|
|
if (kee < 1)
|
|
{
|
|
ex = clip_rect->ex;
|
|
ey = dy * kee + sy;
|
|
}
|
|
|
|
if (sx > clip_rect->ex)
|
|
return;
|
|
|
|
float kss = (clip_rect->sx - sx) * idx;
|
|
if (kss > 0)
|
|
{
|
|
sx = clip_rect->sx;
|
|
sy += dy * kss;
|
|
}
|
|
dx = ex - sx; dy = ey - sy;
|
|
}
|
|
else
|
|
if ((sx < clip_rect->sx) || (sx > clip_rect->ex))
|
|
return;
|
|
|
|
if (dy)
|
|
{
|
|
// Flip line if it is going backward.
|
|
if (dy < 0)
|
|
{
|
|
__SwapFloat(sx, ex)
|
|
__SwapFloat(sy, ey)
|
|
dx = ex - sx; dy = ey - sy;
|
|
}
|
|
float idy = 1 / dy;
|
|
|
|
// Clip on Y axis.
|
|
if (ey < clip_rect->sy)
|
|
return;
|
|
|
|
float kee = (clip_rect->ey - sy) * idy;
|
|
if (kee < 1)
|
|
{
|
|
ey = clip_rect->ey;
|
|
ex = dx * kee + sx;
|
|
}
|
|
|
|
if (sy > clip_rect->ey)
|
|
return;
|
|
|
|
float kss = (clip_rect->sy - sy) * idy;
|
|
if (kss > 0)
|
|
{
|
|
sy = clip_rect->sy;
|
|
sx += dx * kss;
|
|
}
|
|
dx = ex - sx; dy = ey - sy;
|
|
}
|
|
else
|
|
if ((sy < clip_rect->sy) || (sy > clip_rect->ey))
|
|
return;
|
|
}
|
|
|
|
// Draw line.
|
|
if (Types::Abs(dy) > Types::Abs(dx))
|
|
{
|
|
if (dy < 0)
|
|
{
|
|
dy = -dy; dx = -dx;
|
|
float swp = ey;
|
|
ey = sy; sy = swp; sx = ex;
|
|
}
|
|
|
|
float slope = dy ? dx / dy : 0.f;
|
|
for (; sy < ey; sy += 1.f)
|
|
{
|
|
if (hq)
|
|
DrawPlotHQ(sx, sy, r, g, b, a);
|
|
else DrawPlot(sx, sy, r, g, b, a);
|
|
sx += slope;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (dx < 0)
|
|
{
|
|
dx = -dx; dy = -dy;
|
|
float swp = ex;
|
|
ex = sx; sx = swp; sy = ey;
|
|
}
|
|
|
|
float slope = dx ? dy / dx : 0.f;
|
|
for (; sx < ex; sx += 1.f)
|
|
{
|
|
if (hq)
|
|
DrawPlotHQ(sx, sy, r, g, b, a);
|
|
else DrawPlot(sx, sy, r, g, b, a);
|
|
sy += slope;
|
|
}
|
|
}
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
void Picture::DrawLine(float sx, float sy, float ex, float ey, float r, float g, float b, float a, const Rect <float> *clip_rect)
|
|
{ LowLevelDrawLine(false, sx, sy, ex, ey, r, g, b, a, clip_rect); }
|
|
void Picture::DrawLineHQ(float sx, float sy, float ex, float ey, float r, float g, float b, float a, const Rect <float> *clip_rect)
|
|
{ LowLevelDrawLine(true, sx, sy, ex, ey, r, g, b, a, clip_rect); }
|
|
//------------------------------------------------------------------------------
|