Annotation of pmsdk/samples/bio/biopaint.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.