/* Calculates |^ a/b ^| with mathamatically correct floor */ static int CeilDiv(int a,int b) { if (b>0) return FloorDiv(a-1,b)+1; else return FloorDiv(-a-1,-b)+1; }
/*---------------------------------------------------------------------------------------------- Set the value of this SilTime according to the information in psti. ----------------------------------------------------------------------------------------------*/ void SilTime::SetTimeInfo(const SilTimeInfo & sti, bool fUtc) { int dyear = sti.year + FloorDiv(sti.ymon - 1, kmonPerYear) - kyearBase; int mon = ModPos(sti.ymon - 1, kmonPerYear); // Calculate the day number. int64 day = (int64)365 * dyear + FloorDiv(dyear, 4) - FloorDiv(dyear, 100) + FloorDiv(dyear, 400) + g_rgyday[IsLeapYear(dyear + kyearBase)][mon] + sti.mday - 1; m_msec = day * kmsecPerDay + sti.hour * (int64)kmsecPerHour + sti.min * (int64)kmsecPerMin + sti.sec * (int64)kmsecPerSec + sti.msec; if (!fUtc) m_msec = g_tmm.ToUtc(m_msec); }
/*---------------------------------------------------------------------------------------------- Fill in the SilTimeInfo structure from this time. ----------------------------------------------------------------------------------------------*/ void SilTime::GetTimeInfo(SilTimeInfo * psti, bool fUtc) const { AssertPtr(psti); int dyear; int day; int msecDay; int yday; int64 msec = m_msec; if (!fUtc) msec = g_tmm.ToLcl(msec); // Decompose m_msec into which 400 year period it is in (relative to T0) and // the millisecond within the 400 year period. psti->year = (int)FloorDiv(msec, kmsecPerPeriod) * kyearPerPeriod + kyearBase; msec = ModPos(msec, kmsecPerPeriod); Assert(0 <= 0 && msec < kmsecPerPeriod); // Find the day within the 400 year period. day = (int)(msec / kmsecPerDay); Assert(0 <= day && day < kdayPerPeriod); // Get the time within the day. msecDay = (int)(msec - day * (int64)kmsecPerDay); Assert(0 <= msecDay && msecDay < kmsecPerDay); // Find the year within the 400 year period (dyear) and the day within that year (yday). Assert(0 <= day && day < 146097); dyear = YearFromDayInPeriod(day, &yday); Assert(0 <= dyear && dyear < 400); Assert(0 <= yday && (yday < 365 || yday == 365 && SilTime::IsLeapYear(dyear + kyearBase))); // Add dyear into the year. psti->year += dyear; // Find the month and day in the month. const int * prgday = g_rgyday[IsLeapYear(psti->year)]; for (psti->ymon = 1; yday >= prgday[psti->ymon]; psti->ymon++) ; psti->mday = yday - prgday[psti->ymon - 1] + 1; // Calculate the week day. // kdayMonday is used because T0 is a Monday. Note that kdayPerPeriod is divisible by 7 // so we don't have to adjust the day of the week. psti->wday = ModPos(day + kwdayMonday, kdayPerWeek); // Fill in the time. psti->hour = msecDay / kmsecPerHour; psti->min = (msecDay % kmsecPerHour) / kmsecPerMin; psti->sec = (msecDay % kmsecPerMin) / kmsecPerSec; psti->msec = msecDay % kmsecPerSec; }
/*---------------------------------------------------------------------------------------------- Set the value of this SilTime according to the information in psti. ----------------------------------------------------------------------------------------------*/ void SilTime::SetTimeInfo(const SilTimeInfo & sti, bool fUtc) { int dyear = sti.year + FloorDiv(sti.ymon - 1, kmonPerYear) - kyearBase; int mon = ModPos(sti.ymon - 1, kmonPerYear); // Calculate the day number. int64 day = (int64)365 * dyear + FloorDiv(dyear, 4) - FloorDiv(dyear, 100) + FloorDiv(dyear, 400) + g_rgyday[IsLeapYear(dyear + kyearBase)][mon] + sti.mday - 1; m_msec = day * kmsecPerDay + sti.hour * (int64)kmsecPerHour + sti.min * (int64)kmsecPerMin + sti.sec * (int64)kmsecPerSec + sti.msec; #if WIN32 if (!fUtc) m_msec = g_tmm.ToUtc(m_msec); #else // WIN32 if (!fUtc && (sti.year > 1970)) { m_msec *= kfttPerMsec; m_msec /= kfttPerSec; m_msec -= SECS_1601_TO_1970; time_t t = m_msec; struct tm *tm_lcl; tm_lcl = localtime(&t); int64 bias = tm_lcl->tm_gmtoff; m_msec += bias; m_msec += SECS_1601_TO_1970; m_msec *= kfttPerSec; m_msec /= kfttPerMsec; } #endif // WIN32 }
int cs_clipline(PSD psd,int *_x0, int *_y0, int *_x1, int *_y1, int *clip_first, int *clip_last) { int first,last, code; int x0,y0,x1,y1; int x,y; int dx,dy; int xmajor; int slope; int tempclipminx,tempclipminy,tempclipmaxx,tempclipmaxy; if (psd->doclip) { tempclipminx = psd->clipminx; tempclipminy = psd->clipminy; tempclipmaxx = psd->clipmaxx; tempclipmaxy = psd->clipmaxy; } else { tempclipminx = 0; tempclipminy = 0; tempclipmaxx = psd->xres - 1; tempclipmaxy = psd->yres - 1; } first = 0; last = 0; outcode(first,*_x0,*_y0); outcode(last,*_x1,*_y1); if ((first | last) == 0) { return CLIP_VISIBLE; /* Trivially accepted! */ } if ((first & last) != 0) { return CLIP_INVISIBLE; /* Trivially rejected! */ } x0=*_x0; y0=*_y0; x1=*_x1; y1=*_y1; dx = x1 - x0; dy = y1 - y0; xmajor = (abs(dx) > abs(dy)); slope = ((dx>=0) && (dy>=0)) || ((dx<0) && (dy<0)); for (;;) { code = first; if (first==0) code = last; if (code&OC_LEFT) { x = tempclipminx; if (xmajor) { y = *_y0 + FloorDiv(dy*(x - *_x0)*2 + dx, 2*dx); } else { if (slope) { y = *_y0 + CeilDiv(dy*((x - *_x0)*2 - 1), 2*dx); } else { y = *_y0 + FloorDiv(dy*((x - *_x0)*2 - 1), 2*dx); } } } else if (code&OC_RIGHT) { x = tempclipmaxx; if (xmajor) { y = *_y0 + FloorDiv(dy*(x - *_x0)*2 + dx, 2*dx); } else { if (slope) { y = *_y0 + CeilDiv(dy*((x - *_x0)*2 + 1), 2*dx)-1; } else { y = *_y0 + FloorDiv(dy*((x - *_x0)*2 + 1), 2*dx)+1; } } } else if (code&OC_TOP) { y = tempclipminy; if (xmajor) { if (slope) { x = *_x0 + CeilDiv(dx*((y - *_y0)*2 - 1), 2*dy); } else { x = *_x0 + FloorDiv(dx*((y - *_y0)*2 - 1), 2*dy); } } else { x = *_x0 + FloorDiv( dx*(y - *_y0)*2 + dy, 2*dy); } } else { /* OC_BOTTOM */ y = tempclipmaxy; if (xmajor) { if (slope) { x = *_x0 + CeilDiv(dx*((y - *_y0)*2 + 1), 2*dy)-1; } else { x = *_x0 + FloorDiv(dx*((y - *_y0)*2 + 1), 2*dy)+1; } } else { x = *_x0 + FloorDiv(dx*(y - *_y0)*2 + dy, 2*dy); } } if (first!=0) { x0 = x; y0 = y; outcode(first,x0,y0); *clip_first = 1; } else { x1 = x; y1 = y; last = code; outcode(last,x1,y1); *clip_last = 1; } if ((first & last) != 0) { return CLIP_INVISIBLE; /* Trivially rejected! */ } if ((first | last) == 0) { *_x0=x0; *_y0=y0; *_x1=x1; *_y1=y1; return CLIP_PARTIAL; /* Trivially accepted! */ } } }
static int _ggi_clip2d(ggi_visual *vis,int *_x0, int *_y0, int *_x1, int *_y1, int *clip_first, int *clip_last) { int first,last, code; int x0,y0,x1,y1; int x,y; int dx,dy; unsigned int absdx, absdy; int xmajor; int slope; int i; *clip_first = first = 0; *clip_last = last = 0; outcode(first,*_x0,*_y0); outcode(last,*_x1,*_y1); if ((first | last) == 0) { return 1; /* Trivially accepted! */ } if ((first & last) != 0) { return 0; /* Trivially rejected! */ } x0=*_x0; y0=*_y0; x1=*_x1; y1=*_y1; dx = x1 - x0; dy = y1 - y0; absdx = x0 < x1 ? x1 - x0 : x0 - x1; absdy = y0 < y1 ? y1 - y0 : y0 - y1; xmajor = absdx > absdy; slope = ((x1>=x0) && (y1>=y0)) || ((x1<x0) && (y1<y0)); if ((absdx > MAX_DIFF) || (absdy > MAX_DIFF)) { return _ggi_clip2d_3(vis, _x0, _y0, _x1, _y1, clip_first, clip_last); } for (i = 0; i < 4; i++) { code = first; if (first==0) code = last; if (code&OC_LEFT) { x = LIBGGI_GC(vis)->cliptl.x; if (xmajor) { y = *_y0 + FloorDiv(dy*(x - *_x0)*2 + dx, 2*dx); } else { if (slope) { y = *_y0 + CeilDiv(dy*((x - *_x0)*2 - 1), 2*dx); } else { y = *_y0 + FloorDiv(dy*((x - *_x0)*2 - 1), 2*dx); } } } else if (code&OC_RIGHT) { x = LIBGGI_GC(vis)->clipbr.x - 1; if (xmajor) { y = *_y0 + FloorDiv(dy*(x - *_x0)*2 + dx, 2*dx); } else { if (slope) { y = *_y0 + CeilDiv(dy*((x - *_x0)*2 + 1), 2*dx)-1; } else { y = *_y0 + FloorDiv(dy*((x - *_x0)*2 + 1), 2*dx)+1; } } } else if (code&OC_TOP) { y = LIBGGI_GC(vis)->cliptl.y; if (xmajor) { if (slope) { x = *_x0 + CeilDiv(dx*((y - *_y0)*2 - 1), 2*dy); } else { x = *_x0 + FloorDiv(dx*((y - *_y0)*2 - 1), 2*dy); } } else { x = *_x0 + FloorDiv( dx*(y - *_y0)*2 + dy, 2*dy); } } else { /* OC_BOTTOM */ LIB_ASSERT((code & OC_BOTTOM), "unknown outcode\n"); y = LIBGGI_GC(vis)->clipbr.y - 1; if (xmajor) { if (slope) { x = *_x0 + CeilDiv(dx*((y - *_y0)*2 + 1), 2*dy)-1; } else { x = *_x0 + FloorDiv(dx*((y - *_y0)*2 + 1), 2*dy)+1; } } else { x = *_x0 + FloorDiv(dx*(y - *_y0)*2 + dy, 2*dy); } } if (first!=0) { x0 = x; y0 = y; outcode(first,x0,y0); *clip_first = 1; } else { x1 = x; y1 = y; last = code; outcode(last,x1,y1); *clip_last = 1; } if ((first & last) != 0) { return 0; /* Trivially rejected! */ } if ((first | last) == 0) { *_x0=x0; *_y0=y0; *_x1=x1; *_y1=y1; return 1; /* Trivially accepted! */ } } return 0; /* Aieee! Failed to clip, clip whole line... */ }