|
|
1.1.1.2 ! root 1: /* ! 2: biopaint.c - WM_PAINT processing and calendar conversion routines ! 3: ! 4: Created by Microsoft Corporation, 1989 ! 5: */ ! 6: #define INCL_WIN ! 7: #define INCL_GPI ! 8: #include <os2.h> ! 9: ! 10: #include "bio.h" ! 11: #include <math.h> ! 12: #include <stdio.h> ! 13: ! 14: /* Read-only global variables */ ! 15: extern double Born; ! 16: extern long Day, SelectDay; ! 17: extern BOOL bBorn; ! 18: extern FONTMETRICS tmFontInfo; ! 19: extern int LinesPerPage; ! 20: extern RECTL rclClient; ! 21: extern SHORT cxDateField; ! 22: ! 23: /* Read-only static variables */ ! 24: static double Cycle[] = { 23.0, 28.0, 33.0 }; ! 25: static char cDayOfWeek[] = "MTWTFSS"; ! 26: extern LONG Color[]; ! 27: ! 28: ! 29: 1.1 root 30: /* APPPaint() - Parent window WM_PAINT processing routine. 31: * 32: * Purpose: 1.1.1.2 ! root 33: * Routine to graph biorhythm cycles and tabulate dates. 1.1 root 34: * 35: * Arguments: 36: * hWnd - Handle of Window owning message 37: * message - Message itself 38: * mp1 - Extra message-dependent info 39: * mp2 - Extra message-dependent info 40: * 41: * Globals (static): 42: * Cycle[] - Array holding period for phy/emot/int: 23,28,33 43: * cDayOfWeek[] - Array of chars holding first letter of days of week. 44: * Color[] - Set of colored pens used to identify cycles. 45: * 46: * Globals (referenced): 1.1.1.2 ! root 47: * Born - Birthdate in julian days. Read from WIN.INI. ! 48: * SelectDay - Current day being tracked, day is highlighted. ! 49: * This is stored as the number of days from birthdate. ! 50: * Initialized to present day in WM_CREATE processing. 1.1 root 51: * Day - Day number from date born which is top line being 52: * displayed. Initially three days before SelectDay. 53: * bBorn - Boolean indicating whether valid birtdate entered or 1.1.1.2 ! root 54: * rclClient - Size of client area defined by WM_SIZE message 1.1 root 55: * LinesPerPage - Number of system font lines on client area, defined 56: * by WM_SIZE message handling 57: * tmFontInfo - Text Metric structure defined during WM_CREATE 58: * 59: * Description: 60: * Tabulates dates and graphs cycles. On color displays, weekends 61: * are written in red. The update rectangle is used to minimize 62: * repaint time of affected client area. 63: */ 1.1.1.2 ! root 64: VOID APIENTRY APPPaint( hWnd ) 1.1 root 65: HWND hWnd; 66: { 67: HPS hPS; 68: POINTL ptl; 69: int y, i; 70: int start, last; 71: char szDay[16]; 72: int Amplitude, offset; 73: int year, month; 74: double day; 75: RECTL rc, rcClip; 76: int DayOfWeek; 1.1.1.2 ! root 77: HRGN hrgnClip; ! 78: POINTL ptlTextBox[5]; 1.1 root 79: 80: hPS = WinBeginPaint( hWnd, NULL, &rcClip ); 81: 82: /* Erase client area */ 83: WinQueryWindowRect( hWnd, &rc ); 84: WinFillRect( hPS, &rc, CLR_WHITE ); 85: 86: /* Label parts of table and graph. */ 1.1.1.2 ! root 87: ptl.y = rclClient.yTop - tmFontInfo.lMaxBaselineExt + /* Top line */ 1.1 root 88: tmFontInfo.lMaxDescender; 89: ptl.x = 0; 1.1.1.2 ! root 90: GpiCharStringAt( hPS, &ptl, 7L, (PCH)" DATE" ); ! 91: ptl.x = cxDateField + tmFontInfo.lAveCharWidth; 1.1 root 92: GpiCharStringAt( hPS, &ptl, 3L, (PCH)"LOW" ); 1.1.1.2 ! root 93: GpiQueryTextBox( hPS, 4L, "HIGH", TXTBOX_COUNT, ptlTextBox ); ! 94: ptl.x = rclClient.xRight - ptlTextBox[TXTBOX_CONCAT].x - tmFontInfo.lAveCharWidth; 1.1 root 95: GpiCharStringAt( hPS, &ptl, 4L, (PCH)"HIGH" ); 96: 97: /* Underline labels from left to right across client area */ 1.1.1.2 ! root 98: ptl.y = rclClient.yTop - tmFontInfo.lMaxBaselineExt; 1.1 root 99: ptl.x = 0; 100: GpiMove( hPS, &ptl ); 1.1.1.2 ! root 101: ptl.x = rclClient.xRight; 1.1 root 102: GpiLine( hPS, &ptl ); 103: 104: /* Draw a vertical line separator between dates and cycles */ 1.1.1.2 ! root 105: ptl.y = rclClient.yTop; ! 106: ptl.x = cxDateField; 1.1 root 107: GpiMove( hPS, &ptl ); 1.1.1.2 ! root 108: ptl.y = rclClient.yBottom; 1.1 root 109: GpiLine( hPS, &ptl ); 110: 111: /* Draw a dotted vertical center line to reference cycles */ 112: GpiSetLineType( hPS, LINETYPE_DOT ); 1.1.1.2 ! root 113: ptl.x = (cxDateField + rclClient.xRight) / 2; 1.1 root 114: GpiMove( hPS, &ptl ); 1.1.1.2 ! root 115: ptl.y = rclClient.yTop; 1.1 root 116: GpiLine( hPS, &ptl ); 117: /* (Should not have to restore line type after EndPaint) */ 118: GpiSetLineType( hPS, LINETYPE_DEFAULT ); 119: 120: /* Update only the range of lines which fall into update rectangle */ 1.1.1.2 ! root 121: start = (int)((rclClient.yTop - rcClip.yTop) / tmFontInfo.lMaxBaselineExt); 1.1 root 122: if (start<1) 123: start = 1; 1.1.1.2 ! root 124: last = (int)((rclClient.yTop - rcClip.yBottom) / tmFontInfo.lMaxBaselineExt); 1.1 root 125: if (last>(LinesPerPage-1)) 126: last = LinesPerPage-1; 127: 128: /* Set clip rectangle to completely draw entire rectangle representing 129: each date affected. Start drawing one day before and after 130: (outside clip rectangle) so that cycle lines will connect correctly 131: with unaffected lines. */ 1.1.1.2 ! root 132: rcClip.yTop = rclClient.yTop - start*tmFontInfo.lMaxBaselineExt; 1.1 root 133: start--; 134: last++; 1.1.1.2 ! root 135: rcClip.yBottom = rclClient.yTop - last*tmFontInfo.lMaxBaselineExt + 1; 1.1 root 136: hrgnClip = GpiCreateRegion( hPS, 1L, &rcClip ); 1.1.1.2 ! root 137: GpiSetClipRegion( hPS, hrgnClip, &hrgnClip ); 1.1 root 138: 139: /* List days and date */ 140: for (y=start; y<=last; y++) { 141: /* Get the calendar date from julian day */ 142: calendar( Born+Day+y-1, &year, &month, &day ); 143: /* Get offset into days of the week initials array */ 144: DayOfWeek = (int)((LONG)(Born+Day+y) % 7); 145: /* Assemble each of the parts in a buffer */ 1.1.1.2 ! root 146: sprintf(szDay, " %02d-%02d-%02d", 1.1 root 147: month, (int)day, year - (trunc4((double)year / 100)*100) ); 148: /* If color available, draw weekends in red */ 149: if (DayOfWeek > 4) 150: GpiSetColor( hPS, CLR_RED ); 151: ptl.x = 0; 1.1.1.2 ! root 152: ptl.y = rclClient.yTop - ((y+1)*tmFontInfo.lMaxBaselineExt - ! 153: tmFontInfo.lMaxDescender); ! 154: GpiCharStringAt( hPS, &ptl, 1L, (PCH)&cDayOfWeek[DayOfWeek] ); ! 155: GpiQueryWidthTable( hPS, (LONG)'W', 1L, &ptl.x ); ! 156: GpiCharStringAt( hPS, &ptl, 9L, (PCH)szDay ); 1.1 root 157: GpiSetColor( hPS, CLR_BLACK ); 158: } 159: 160: /* Amplitude of sin wave is half client area minus space for dates */ 1.1.1.2 ! root 161: Amplitude = (int)((rclClient.xRight - cxDateField - tmFontInfo.lAveCharWidth) >> 1); 1.1 root 162: /* Move to right, make room for column of dates */ 1.1.1.2 ! root 163: offset = (int)(Amplitude + cxDateField + tmFontInfo.lAveCharWidth - (tmFontInfo.lAveCharWidth>>1)); 1.1 root 164: for (i=0; i<3 && bBorn; i++ ) { 165: GpiSetColor( hPS, Color[i] ); 166: for (y=start; y<=last; y++) { 167: ptl.x = (int)(sin( (y+Day-1)/Cycle[i]*2*3.14159 ) * Amplitude + offset); 1.1.1.2 ! root 168: ptl.y = rclClient.yTop - (y*tmFontInfo.lMaxBaselineExt + 1.1 root 169: tmFontInfo.lMaxBaselineExt/2); 170: if ((y+Day-1 > 0) && (y>start)) 171: GpiLine( hPS, &ptl ); 172: else 173: GpiMove( hPS, &ptl ); 174: } 175: } 176: 177: /* Draw highlight on selected day if visible. */ 178: if ((SelectDay >= Day) && (SelectDay - Day < LinesPerPage - 1)) { 1.1.1.2 ! root 179: rc.xRight = rclClient.xRight; ! 180: rc.xLeft = rclClient.xLeft; ! 181: rc.yTop = rclClient.yTop - (int)(SelectDay - Day + 1) * tmFontInfo.lMaxBaselineExt; 1.1 root 182: rc.yBottom = rc.yTop - tmFontInfo.lMaxBaselineExt + 1; 183: WinInvertRect( hPS, &rc ); 184: } 185: 186: WinEndPaint( hPS ); 187: 188: return; 189: } 190: 191: 192: /* julian() - Compute julian date from Gregorian calendar date. 193: * 194: * Purpose: 195: * Provide a standard time base. 196: * 197: * Arguments: 198: * year - Calendar year 199: * month - Calendar month 200: * day - Calendar day and fraction 201: * 202: * Return Value: 203: * double - Julian date converted 204: * 205: * Description: 206: * Convert Gregorian dates to Julian Days. Refer to Alamanac for 207: * Computers (1978), p. B2, Naval Observatory Pub. 208: * 209: * Limits: 210: * Valid between ~1900 and 2099. 211: * 212: */ 213: 214: double PASCAL julian (year, month, day) 215: int year, month; 216: double day; 217: { 218: double dj; 219: double fracDay, intDay; 220: 221: fracDay = modf(day, &intDay); 222: dj = (long)367*year - 7*(year + (month+9) / 12) / 4 + 275*month / 9 + 223: intDay + 1721013.5 + fracDay; 224: return dj; 225: } 226: 227: 228: /* calendar() - Compute Gregorian calendar date from julian date. 229: * 230: * Purpose: 231: * Provide a standard time base. 232: * 233: * Arguments: 234: * juldate - Julian date to convert 235: * year - Calendar year result 236: * month - Calendar month result 237: * day - Calendar day and fraction result 238: * 239: * Return Value: 240: * void 241: * 242: * Globals (modified): 243: * none 244: * 245: * Globals (referenced): 246: * none 247: * 248: * Description: 249: * Convert Julian Days to Gregorian date. Refer to Astronomical 250: * Formulae for Calculators (1979), p. 23, by Jean Meeus. 251: * 252: * Limits: 253: * Valid for positive Julian Day values. 254: * 255: */ 256: 257: void PASCAL calendar (juldate, year, month, day) 258: double juldate; 259: int *year; 260: int *month; 261: double *day; 262: { 263: long b, c, d, e, z, alf; 264: 265: juldate = juldate + 0.5; 266: z = trunc4(juldate); 267: alf = trunc4((z - 1867216.25)/36524.25); 268: b = z + 1 + alf - alf / 4 + 1524; 269: c = trunc4((b - 122.1)/365.25); 270: d = 365*c + c / 4; 271: e = trunc4((b - d)/30.6001); 272: *day = b - d - trunc4(30.6001*e) + juldate - z; 273: if (e > 13) 274: *month = (int)e - 13; 275: else 276: *month = (int)e - 1; 277: if (*month > 2) 278: *year = (int)c - 4716; 279: else 280: *year = (int)c - 4715; 281: } 282: 283: long PASCAL trunc4( dflValue ) 284: double dflValue; 285: { 286: double intValue; 287: modf(dflValue, &intValue); 288: return (long)intValue; 289: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.