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

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: }

unix.superglobalmegacorp.com

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