/* ----------------------------------------------------------------------------- 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 *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 *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 *clip_rect) { LowLevelDrawLine(true, sx, sy, ex, ey, r, g, b, a, clip_rect); } //------------------------------------------------------------------------------