Changeset 94


Ignore:
Timestamp:
Aug 5, 2001, 6:32:52 PM (24 years ago)
Author:
umoeller
Message:

Misc updates.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/helpers/dosh.h

    r93 r94  
    164164
    165165    APIRET XWPENTRY doshHasAudioCD(ULONG ulLogicalDrive,
     166                                   HFILE hfDrive,
    166167                                   BOOL fMixedModeCD,
    167168                                   PBOOL pfAudio);
     
    410411                                 BOOL fWait,
    411412                                 PULONG pulSID,
    412                                  PPID ppid);
     413                                 PPID ppid,
     414                                 PUSHORT pusReturn);
    413415
    414416    /********************************************************************
  • trunk/include/helpers/gpih.h

    r93 r94  
    182182     ********************************************************************/
    183183
     184    BOOL XWPENTRY gpihMatchFont(HPS hps,
     185                                LONG lSize,
     186                                BOOL fFamily,
     187                                const char *pcszName,
     188                                USHORT usFormat,
     189                                FATTRS *pfa,
     190                                PFONTMETRICS pFontMetrics);
     191    typedef BOOL XWPENTRY GPIHMATCHFONT(HPS hps,
     192                                        LONG lSize,
     193                                        BOOL fFamily,
     194                                        const char *pcszName,
     195                                        USHORT usFormat,
     196                                        FATTRS *pfa,
     197                                        PFONTMETRICS pFontMetrics);
     198    typedef GPIHMATCHFONT *PGPIHMATCHFONT;
     199
    184200    BOOL XWPENTRY gpihSplitPresFont(PSZ pszFontNameSize,
    185201                                    PULONG pulSize,
     
    197213    typedef VOID XWPENTRY GPIHUNLOCKLCIDS(VOID);
    198214    typedef GPIHUNLOCKLCIDS *PGPIHUNLOCKLCIDS;
     215
     216    LONG XWPENTRY gpihCreateFont(HPS hps, FATTRS *pfa);
     217    typedef LONG XWPENTRY GPIHCREATEFONT(HPS hps, FATTRS *pfa);
     218    typedef GPIHCREATEFONT *PGPIHCREATEFONT;
    199219
    200220    LONG XWPENTRY gpihFindFont(HPS hps,
  • trunk/src/helpers/dosh.c

    r91 r94  
    373373 *      to cause problems with some device drivers for
    374374 *      removeable disks.
     375 *
     376 *@@changed V0.9.14 (2001-08-03) [umoeller]: added extra fix for A: and B:
    375377 */
    376378
     
    379381{
    380382    APIRET arc = ERROR_INVALID_DRIVE;
     383
     384    if (    (ulLogicalDrive == 1)
     385         || (ulLogicalDrive == 2)
     386       )
     387    {
     388        // drive A: and B: can never be fixed V0.9.14 (2001-08-03) [umoeller]
     389        *pfFixed = FALSE;
     390        return NO_ERROR;
     391    }
    381392
    382393    if (ulLogicalDrive)
     
    395406        parms.drive = (UCHAR)(ulLogicalDrive-1);
    396407        arc = doshDevIOCtl((HFILE)-1,
    397                            IOCTL_DISK,
    398                            DSK_BLOCKREMOVABLE,
     408                           IOCTL_DISK,                  // 0x08
     409                           DSK_BLOCKREMOVABLE,          // 0x20
    399410                           &parms, sizeof(parms),
    400411                           &ucNonRemoveable, sizeof(ucNonRemoveable));
     
    471482
    472483        arc = doshDevIOCtl((HFILE)-1,
    473                            IOCTL_DISK,
    474                            DSK_GETDEVICEPARAMS,
     484                           IOCTL_DISK,                  // 0x08
     485                           DSK_GETDEVICEPARAMS,         // 0x63
    475486                           &parms, sizeof(parms),
    476487                           pdp,   sizeof(BIOSPARAMETERBLOCK));
     
    520531
    521532APIRET doshHasAudioCD(ULONG ulLogicalDrive,
     533                      HFILE hfDrive,            // in: DASD open
    522534                      BOOL fMixedModeCD,
    523535                      PBOOL pfAudio)
     
    525537    APIRET  arc = NO_ERROR;
    526538
    527     HFILE   hfDrive = 0;
    528     ULONG   ulTemp = 0;
    529 
    530     CHAR    szDrive[3] = "C:";
    531     szDrive[0] = 'A' + ulLogicalDrive - 1;
     539    ULONG ulAudioTracks = 0,
     540          ulDataTracks = 0;
     541
     542    CHAR cds1[4] = { 'C', 'D', '0', '1' };
     543    CHAR cds2[4];
    532544
    533545    *pfAudio = FALSE;
    534546
    535     arc = DosOpen(szDrive,   // "C:", "D:", ...
    536                   &hfDrive,
    537                   &ulTemp,
    538                   0,
    539                   FILE_NORMAL,
    540                   OPEN_ACTION_FAIL_IF_NEW
    541                          | OPEN_ACTION_OPEN_IF_EXISTS,
    542                   OPEN_FLAGS_DASD
    543                          | OPEN_FLAGS_FAIL_ON_ERROR
    544                          | OPEN_FLAGS_NOINHERIT     // V0.9.6 (2000-11-25) [pr]
    545               //            | OPEN_ACCESS_READONLY  // V0.9.13 (2001-06-14) [umoeller]
    546                          | OPEN_SHARE_DENYNONE,
    547                   NULL);
    548 
    549     // _Pmpf(("   DosOpen(OPEN_FLAGS_DASD) returned %d", arc));
    550 
    551     // this still returns NO_ERROR for audio CDs in a
    552     // CD-ROM drive...
    553     // however, the WPS then attempts to read in the
    554     // root directory for audio CDs, which produces
    555     // a "sector not found" error box...
    556 
    557     if (!arc && hfDrive)     // determined above
    558     {
    559         ULONG ulAudioTracks = 0,
    560               ulDataTracks = 0;
    561 
    562         CHAR cds1[4] = { 'C', 'D', '0', '1' };
    563         CHAR cds2[4];
    564         // check for proper driver signature
    565         if (!(arc = doshDevIOCtl(hfDrive,
    566                                  IOCTL_CDROMDISK,
    567                                  CDROMDISK_GETDRIVER,
    568                                  &cds1, sizeof(cds1),
    569                                  &cds2, sizeof(cds2))))
     547    // check for proper driver signature
     548    if (!(arc = doshDevIOCtl(hfDrive,
     549                             IOCTL_CDROMDISK,
     550                             CDROMDISK_GETDRIVER,
     551                             &cds1, sizeof(cds1),
     552                             &cds2, sizeof(cds2))))
     553    {
     554        if (memcmp(&cds1, &cds2, 4))
     555            // this is not a CD-ROM then:
     556            arc = NO_ERROR;
     557        else
    570558        {
    571             if (memcmp(&cds1, &cds2, 4))
    572                 // this is not a CD-ROM then:
    573                 arc = NO_ERROR;
    574             else
     559            struct {
     560                UCHAR   ucFirstTrack,
     561                        ucLastTrack;
     562                ULONG   ulLeadOut;
     563            } cdat;
     564
     565            // get track count
     566            if (!(arc = doshDevIOCtl(hfDrive,
     567                                     IOCTL_CDROMAUDIO,
     568                                     CDROMAUDIO_GETAUDIODISK,
     569                                     &cds1, sizeof(cds1),
     570                                     &cdat, sizeof(cdat))))
    575571            {
    576                 struct {
    577                     UCHAR   ucFirstTrack,
    578                             ucLastTrack;
    579                     ULONG   ulLeadOut;
    580                 } cdat;
    581 
    582                 // get track count
    583                 if (!(arc = doshDevIOCtl(hfDrive,
    584                                          IOCTL_CDROMAUDIO,
    585                                          CDROMAUDIO_GETAUDIODISK,
    586                                          &cds1, sizeof(cds1),
    587                                          &cdat, sizeof(cdat))))
     572                // still no error: build the audio TOC
     573                ULONG i;
     574                for (i = cdat.ucFirstTrack;
     575                     i <= cdat.ucLastTrack;
     576                     i++)
    588577                {
    589                     // still no error: build the audio TOC
    590                     ULONG i;
    591                     for (i = cdat.ucFirstTrack;
    592                          i <= cdat.ucLastTrack;
    593                          i++)
     578                    BYTE cdtp[5] =
     579                      { 'C', 'D', '0', '1', (UCHAR)i };
     580
     581                    struct {
     582                        ULONG   ulTrackAddress;
     583                        BYTE    bFlags;
     584                    } trackdata;
     585
     586                    if (!(arc = doshDevIOCtl(hfDrive,
     587                                             IOCTL_CDROMAUDIO,
     588                                             CDROMAUDIO_GETAUDIOTRACK,
     589                                             &cdtp, sizeof(cdtp),
     590                                             &trackdata, sizeof(trackdata))))
    594591                    {
    595                         BYTE cdtp[5] =
    596                           { 'C', 'D', '0', '1', (UCHAR)i };
    597 
    598                         struct {
    599                             ULONG   ulTrackAddress;
    600                             BYTE    bFlags;
    601                         } trackdata;
    602 
    603                         if (!(arc = doshDevIOCtl(hfDrive,
    604                                                  IOCTL_CDROMAUDIO,
    605                                                  CDROMAUDIO_GETAUDIOTRACK,
    606                                                  &cdtp, sizeof(cdtp),
    607                                                  &trackdata, sizeof(trackdata))))
     592                        if (trackdata.bFlags & 64)
     593                            ulDataTracks++;
     594                        else
    608595                        {
    609                             if (trackdata.bFlags & 64)
    610                                 ulDataTracks++;
    611                             else
     596                            ulAudioTracks++;
     597
     598                            if (!fMixedModeCD)
    612599                            {
    613                                 ulAudioTracks++;
    614 
    615                                 if (!fMixedModeCD)
    616                                 {
    617                                     // caller doesn't want mixed mode:
    618                                     // stop here
    619                                     ulDataTracks = 0;
    620                                     break;
    621                                 }
     600                                // caller doesn't want mixed mode:
     601                                // stop here
     602                                ulDataTracks = 0;
     603                                break;
    622604                            }
    623605                        }
    624606                    }
    625 
    626                     // _Pmpf(("   got %d audio, %d data tracks",
    627                     //             ulAudioTracks, ulDataTracks));
    628 
    629                     if (!ulDataTracks)
    630                         *pfAudio = TRUE;
    631607                }
    632                 else
    633                 {
    634                     // not audio disk:
    635                     // go on then
    636                     // _Pmpf(("   CDROMAUDIO_GETAUDIODISK returned %d", arc));
    637                     arc = NO_ERROR;
    638                 }
     608
     609                // _Pmpf(("   got %d audio, %d data tracks",
     610                //             ulAudioTracks, ulDataTracks));
     611
     612                if (!ulDataTracks)
     613                    *pfAudio = TRUE;
     614            }
     615            else
     616            {
     617                // not audio disk:
     618                // go on then
     619                // _Pmpf(("   CDROMAUDIO_GETAUDIODISK returned %d", arc));
     620                arc = NO_ERROR;
    639621            }
    640622        }
    641         else
    642         {
    643             // not CD-ROM: go on then
    644             // _Pmpf(("   CDROMDISK_GETDRIVER returned %d", arc));
    645             arc = NO_ERROR;
    646         }
    647     }
    648 
    649     if (hfDrive)
    650         DosClose(hfDrive);
     623    }
     624    else
     625    {
     626        // not CD-ROM: go on then
     627        // _Pmpf(("   CDROMDISK_GETDRIVER returned %d", arc));
     628        arc = NO_ERROR;
     629    }
    651630
    652631    return (arc);
     
    835814                          &fFixed);    // V0.9.13 (2001-06-14) [umoeller]
    836815
    837     // _Pmpf((__FUNCTION__ ": doshIsFixedDisk returned %d for disk %d", arc, ulLogicalDrive));
    838     // _Pmpf(("   fFixed is %d", fFixed));
     816    _Pmpf((__FUNCTION__ ": doshIsFixedDisk returned %d for disk %d", arc, ulLogicalDrive));
     817    _Pmpf(("   fFixed is %d", fFixed));
    839818
    840819    if (!arc)
     
    846825            arc = doshQueryDiskParams(ulLogicalDrive,
    847826                                      &bpb);
    848             // _Pmpf(("   doshQueryDiskParams returned %d", arc));
     827            _Pmpf(("   doshQueryDiskParams returned %d", arc));
    849828
    850829            if (    (!arc)
     
    852831               )
    853832            {
    854                 // _Pmpf(("   --> is CD-ROM"));
     833                _Pmpf(("   --> is CD-ROM"));
    855834                fCDROM = TRUE;
    856835            }
    857836        }
    858837
    859     if ((!arc) && (fCDROM))
    860     {
    861         BOOL fAudio;
    862         if (    (!(arc = doshHasAudioCD(ulLogicalDrive,
    863                                         ((fl & ASSERTFL_MIXEDMODECD) != 0),
    864                                         &fAudio)))
    865              && (fAudio)
     838    if (!arc)
     839    {
     840        HFILE hfDrive = NULLHANDLE;
     841
     842        ULONG   ulTemp = 0;
     843        CHAR    szDrive[3] = "C:";
     844        szDrive[0] = 'A' + ulLogicalDrive - 1;
     845
     846        arc = DosOpen(szDrive,   // "C:", "D:", ...
     847                      &hfDrive,
     848                      &ulTemp,
     849                      0,
     850                      FILE_NORMAL,
     851                      OPEN_ACTION_FAIL_IF_NEW
     852                             | OPEN_ACTION_OPEN_IF_EXISTS,
     853                      OPEN_FLAGS_DASD
     854                             | OPEN_FLAGS_FAIL_ON_ERROR
     855                             | OPEN_FLAGS_NOINHERIT     // V0.9.6 (2000-11-25) [pr]
     856                  //            | OPEN_ACCESS_READONLY  // V0.9.13 (2001-06-14) [umoeller]
     857                             | OPEN_SHARE_DENYNONE,
     858                      NULL);
     859
     860        // _Pmpf(("   DosOpen(OPEN_FLAGS_DASD) returned %d", arc));
     861
     862        // this still returns NO_ERROR for audio CDs in a
     863        // CD-ROM drive...
     864        // however, the WPS then attempts to read in the
     865        // root directory for audio CDs, which produces
     866        // a "sector not found" error box...
     867
     868        if (    (!arc)
     869             && (hfDrive)
     870             && (fCDROM)
    866871           )
    867             arc = ERROR_AUDIO_CD_ROM;       // special private error code (10000)
     872        {
     873            BOOL fAudio;
     874            if (    (!(arc = doshHasAudioCD(ulLogicalDrive,
     875                                            hfDrive,
     876                                            ((fl & ASSERTFL_MIXEDMODECD) != 0),
     877                                            &fAudio)))
     878                 && (fAudio)
     879               )
     880                arc = ERROR_AUDIO_CD_ROM;       // special private error code (10000)
     881        }
     882
     883        if (hfDrive)
     884            DosClose(hfDrive);
    868885    }
    869886
     
    26492666 *
    26502667 *      If (fWait), this function will create a termination queue
    2651  *      and not return until the child session has ended. Otherwise
    2652  *      the function will return immediately, and the SID/PID of
    2653  *      the child session can be found in *pulSID and *ppid.
     2668 *      and not return until the child session has ended. Be warned,
     2669 *      this blocks the calling thread.
     2670 *
     2671 *      Otherwise the function will return immediately.
     2672 *
     2673 *      The session and process IDs of the child session will be
     2674 *      written to *pulSID and *ppid. Of course, in "wait" mode,
     2675 *      these are no longer valid after this function returns.
    26542676 *
    26552677 *      Returns the error code of DosStartSession.
     
    26612683 *@@changed V0.9.1 (99-12-30) [umoeller]: queue was sometimes not closed. Fixed.
    26622684 *@@changed V0.9.3 (2000-05-03) [umoeller]: added fForeground
     2685 *@@changed V0.9.14 (2001-08-03) [umoeller]: fixed potential queue leak
     2686 *@@changed V0.9.14 (2001-08-03) [umoeller]: fixed memory leak in wait mode; added pusReturn to prototype
    26632687 */
    26642688
     
    26692693                             BOOL fWait,        // in: wait for termination?
    26702694                             PULONG pulSID,     // out: session ID (req.)
    2671                              PPID ppid)         // out: process ID (req.)
    2672 {
    2673     APIRET      arc;
     2695                             PPID ppid,         // out: process ID (req.)
     2696                             PUSHORT pusReturn) // out: in wait mode, session's return code (ptr can be NULL)
     2697{
     2698    APIRET      arc = NO_ERROR;
    26742699    // queue stuff
    26752700    const char  *pcszQueueName = "\\queues\\xwphlpsw.que";
    26762701    HQUEUE      hq = 0;
    26772702    PID         qpid = 0;
    2678     STARTDATA   SData;
    2679     CHAR        szObjBuf[CCHMAXPATH];
    26802703
    26812704    if (fWait)
    26822705    {
    2683         if ((arc = DosCreateQueue(&hq,
    2684                                   QUE_FIFO | QUE_CONVERT_ADDRESS,
    2685                                   (PSZ)pcszQueueName))
    2686                     != NO_ERROR)
    2687             return (arc);
    2688 
    2689         if ((arc = DosOpenQueue(&qpid, &hq, (PSZ)pcszQueueName)) != NO_ERROR)
    2690             return (arc);
    2691     }
    2692 
    2693     SData.Length  = sizeof(STARTDATA);
    2694     SData.Related = SSF_RELATED_CHILD; //INDEPENDENT;
    2695     SData.FgBg    = (fForeground) ? SSF_FGBG_FORE : SSF_FGBG_BACK;
    2696             // V0.9.3 (2000-05-03) [umoeller]
    2697     SData.TraceOpt = SSF_TRACEOPT_NONE;
    2698 
    2699     SData.PgmTitle = (PSZ)pcszPath;       // title for window
    2700     SData.PgmName = (PSZ)pcszPath;
    2701     SData.PgmInputs = (PSZ)pcszParams;
    2702 
    2703     SData.TermQ = (fWait) ? (PSZ)pcszQueueName : NULL;
    2704     SData.Environment = 0;
    2705     SData.InheritOpt = SSF_INHERTOPT_PARENT;
    2706     SData.SessionType = SSF_TYPE_DEFAULT;
    2707     SData.IconFile = 0;
    2708     SData.PgmHandle = 0;
    2709 
    2710     SData.PgmControl = usPgmCtl;
    2711 
    2712     SData.InitXPos  = 30;
    2713     SData.InitYPos  = 40;
    2714     SData.InitXSize = 200;
    2715     SData.InitYSize = 140;
    2716     SData.Reserved = 0;
    2717     SData.ObjectBuffer  = (CHAR*)&szObjBuf;
    2718     SData.ObjectBuffLen = (ULONG)sizeof(szObjBuf);
    2719 
    2720     arc = DosStartSession(&SData, pulSID, ppid);
    2721 
    2722     if (arc == NO_ERROR)
    2723     {
    2724         if (fWait)
     2706        if (!(arc = DosCreateQueue(&hq,
     2707                                   QUE_FIFO | QUE_CONVERT_ADDRESS,
     2708                                   (PSZ)pcszQueueName)))
     2709            arc = DosOpenQueue(&qpid, &hq, (PSZ)pcszQueueName);
     2710    }
     2711
     2712    if (!arc)    // V0.9.14 (2001-08-03) [umoeller]
     2713    {
     2714        STARTDATA   SData;
     2715        CHAR        szObjBuf[CCHMAXPATH];
     2716
     2717        SData.Length  = sizeof(STARTDATA);
     2718        SData.Related = SSF_RELATED_CHILD; //INDEPENDENT;
     2719        SData.FgBg    = (fForeground) ? SSF_FGBG_FORE : SSF_FGBG_BACK;
     2720                // V0.9.3 (2000-05-03) [umoeller]
     2721        SData.TraceOpt = SSF_TRACEOPT_NONE;
     2722
     2723        SData.PgmTitle = (PSZ)pcszPath;       // title for window
     2724        SData.PgmName = (PSZ)pcszPath;
     2725        SData.PgmInputs = (PSZ)pcszParams;
     2726
     2727        SData.TermQ = (fWait) ? (PSZ)pcszQueueName : NULL;
     2728        SData.Environment = 0;
     2729        SData.InheritOpt = SSF_INHERTOPT_PARENT;
     2730        SData.SessionType = SSF_TYPE_DEFAULT;
     2731        SData.IconFile = 0;
     2732        SData.PgmHandle = 0;
     2733
     2734        SData.PgmControl = usPgmCtl;
     2735
     2736        SData.InitXPos  = 30;
     2737        SData.InitYPos  = 40;
     2738        SData.InitXSize = 200;
     2739        SData.InitYSize = 140;
     2740        SData.Reserved = 0;
     2741        SData.ObjectBuffer  = szObjBuf;
     2742        SData.ObjectBuffLen = (ULONG)sizeof(szObjBuf);
     2743
     2744        if (    (!(arc = DosStartSession(&SData, pulSID, ppid)))
     2745             && (fWait)
     2746           )
    27252747        {
     2748            // block on the termination queue, which is written
     2749            // to when the subprocess ends
    27262750            REQUESTDATA rqdata;
    2727             ULONG       DataLength = 0;
    2728             PULONG      DataAddress;
     2751            ULONG       cbData = 0;
     2752            PULONG      pulData = NULL;
    27292753            BYTE        elpri;
    27302754
    27312755            rqdata.pid = qpid;
    2732             DosReadQueue(hq,                // in: queue handle
    2733                          &rqdata,           // out: pid and ulData
    2734                          &DataLength,       // out: size of data returned
    2735                          (PVOID*)&DataAddress, // out: data returned
    2736                          0,                 // in: remove first element in queue
    2737                          0,                 // in: wait for queue data (block thread)
    2738                          &elpri,            // out: element's priority
    2739                          0);                // in: event semaphore to be posted
     2756            if (!(arc = DosReadQueue(hq,                // in: queue handle
     2757                                     &rqdata,           // out: pid and ulData
     2758                                     &cbData,           // out: size of data returned
     2759                                     (PVOID*)&pulData,  // out: data returned
     2760                                     0,                 // in: remove first element in queue
     2761                                     0,                 // in: wait for queue data (block thread)
     2762                                     &elpri,            // out: element's priority
     2763                                     0)))               // in: event semaphore to be posted
     2764            {
     2765                if (!rqdata.ulData)
     2766                {
     2767                    // child session ended:
     2768                    // V0.9.14 (2001-08-03) [umoeller]
     2769
     2770                    // *pulSID = (*pulData) & 0xffff;
     2771                    if (pusReturn)
     2772                        *pusReturn = ((*pulData) >> 16) & 0xffff;
     2773
     2774                }
     2775                // else: continue looping
     2776
     2777                if (pulData)
     2778                    DosFreeMem(pulData);
     2779            }
    27402780        }
    27412781    }
  • trunk/src/helpers/gpih.c

    r91 r94  
    325325 *      The specified rectangle is inclusive, that is, the top
    326326 *      right corner specifies the top right pixel to be drawn.
    327  *      This is different from WinFillRect
    328  *      (see @GPI_rectangles).
    329  *
    330  *      If (lColor != -1), the HPS's current foreground color
    331  *      is changed to that color.
     327 *      This is different from WinFillRect (see @GPI_rectangles).
    332328 *
    333329 *      Changes to the HPS:
     
    343339VOID gpihBox(HPS hps,              // in: presentation space for output
    344340             LONG lControl,        // in: one of DRO_OUTLINE, DRO_FILL, DRO_OUTLINEFILL
    345              PRECTL prcl)          // in: rectangle to draw (exclusive)
     341             PRECTL prcl)          // in: rectangle to draw (inclusive)
    346342{
    347343    POINTL      ptl;
     
    554550
    555551/*
     552 *@@ gpihMatchFont:
     553 *      attempts to find a font matching the specified
     554 *      data and fills the specified FATTRS structure
     555 *      accordingly.
     556 *
     557 *      This function performs the insane "11-step process" to
     558 *      match a font, as described in the GPI reference.
     559 *
     560 *      This function can operate in two modes:
     561 *
     562 *      -- "Family" mode. In that case, specify the font family name
     563 *         with pszName and set fFamily to TRUE. This is useful for
     564 *         WYSIWYG text viewing if you need several font faces for
     565 *         the same family, such as Courier Bold, Bold Italics, etc.
     566 *         You can specify those attributes with usFormat then.
     567 *
     568 *      -- "Face" mode. In that case, specify the full font face name
     569 *         with pszName and set fFamily to FALSE. This is useful for
     570 *         font presentation parameters which use the "WarpSans Bold"
     571 *         format. In that case, set usFormat to 0.
     572 *
     573 *      Returns TRUE if a "true" match was found, FALSE
     574 *      otherwise. In both cases, *pfa receives data
     575 *      which will allow GpiCreateLogFont to work; however,
     576 *      if FALSE is returned, GpiCreateLogFont will most
     577 *      likely find the default font (System Proportional)
     578 *      only.
     579 *
     580 *      If (pFontMetrics != NULL), *pFontMetrics receives the
     581 *      FONTMETRICS of the font which was found. If an outline
     582 *      font has been found (instead of a bitmap font),
     583 *      FONTMETRICS.fsDefn will have the FM_DEFN_OUTLINE bit set.
     584 *
     585 *      This function was extracted from gpihFindFont with
     586 *      0.9.14 to allow for caching the font search results,
     587 *      which is most helpful for memory device contexts,
     588 *      where gpihFindFont can be inefficient.
     589 *
     590 *@@added V0.9.14 (2001-08-03) [umoeller]
     591 *@@changed V0.9.14 (2001-08-03) [umoeller]: fixed a few weirdos with outline fonts
     592 */
     593
     594BOOL gpihMatchFont(HPS hps,
     595                   LONG lSize,            // in: font point size
     596                   BOOL fFamily,          // in: if TRUE, pszName specifies font family;
     597                                          //     if FALSE, pszName specifies font face
     598                   const char *pcszName,  // in: font family or face name (without point size)
     599                   USHORT usFormat,       // in: none, one or several of:
     600                                          // -- FATTR_SEL_ITALIC
     601                                          // -- FATTR_SEL_UNDERSCORE (underline)
     602                                          // -- FATTR_SEL_BOLD
     603                                          // -- FATTR_SEL_STRIKEOUT
     604                                          // -- FATTR_SEL_OUTLINE (hollow)
     605                   FATTRS *pfa,           // out: font attributes if found
     606                   PFONTMETRICS pFontMetrics) // out: font metrics of created font (optional)
     607{
     608    // first find out how much memory we need to allocate
     609    // for the FONTMETRICS structures
     610    ULONG   ul = 0;
     611    LONG    lTemp = 0;
     612    LONG    cFonts = GpiQueryFonts(hps,
     613                                   QF_PUBLIC | QF_PRIVATE,
     614                                   NULL, // pszFaceName,
     615                                   &lTemp,
     616                                   sizeof(FONTMETRICS),
     617                                   NULL);
     618    PFONTMETRICS    pfm = (PFONTMETRICS)malloc(cFonts * sizeof(FONTMETRICS)),
     619                    pfm2 = pfm,
     620                    pfmFound = NULL;
     621
     622    BOOL            fQueriedDevice = FALSE;     // V0.9.14 (2001-08-01) [umoeller]
     623    LONG            alDevRes[2];            // device resolution
     624
     625    // _Pmpf(("gpihFindFont: enumerating for %s, %d points", pcszName, lSize));
     626
     627    GpiQueryFonts(hps,
     628                  QF_PUBLIC | QF_PRIVATE,
     629                  NULL, // pszFaceName,
     630                  &cFonts,
     631                  sizeof(FONTMETRICS),      // length of each metrics structure
     632                                            // -- _not_ total buffer size!
     633                  pfm);
     634
     635    // now we have an array of FONTMETRICS
     636    // for EVERY font that is installed on the system...
     637    // these things are completely unsorted, so there's
     638    // nothing we can rely on, we have to check them all.
     639
     640    // fill in some default values for FATTRS,
     641    // in case we don't find something better
     642    // in the loop below; these values will be
     643    // applied if
     644    // a)   an outline font has been found;
     645    // b)   bitmap fonts have been found, but
     646    //      none for the current device resolution
     647    //      exists;
     648    // c)   no font has been found at all.
     649    // In all cases, GpiCreateLogFont will do
     650    // a "close match" resolution (at the bottom).
     651    pfa->usRecordLength = sizeof(FATTRS);
     652    pfa->fsSelection = usFormat; // changed later if better font is found
     653    pfa->lMatch = 0L;             // closest match
     654    strcpy(pfa->szFacename, pcszName);
     655    pfa->idRegistry = 0;          // default registry
     656    pfa->usCodePage = 0;          // default codepage
     657    // the following two must be zero, or outline fonts
     658    // will not be found; if a bitmap font has been passed
     659    // to us, we'll modify these two fields later
     660    pfa->lMaxBaselineExt = 0;     // font size (height)
     661    pfa->lAveCharWidth = 0;       // font size (width)
     662    pfa->fsType = 0;              // default type
     663    pfa->fsFontUse = FATTR_FONTUSE_NOMIX;
     664
     665    // now go thru the array of FONTMETRICS
     666    // to check if we have a bitmap font
     667    // pszFaceName; the default WPS behavior
     668    // is that bitmap fonts appear to take
     669    // priority over outline fonts of the
     670    // same name, so we check these first
     671    pfm2 = pfm;
     672    for (ul = 0;
     673         ul < cFonts;
     674         ul++)
     675    {
     676        const char *pcszCompare = (fFamily)
     677                                     ? pfm2->szFamilyname
     678                                     : pfm2->szFacename;
     679
     680        /* _Pmpf(("  Checking font: %s (Fam: %s), %d, %d, %d",
     681               pcszCompare,
     682               pfm2->szFamilyname,
     683               pfm2->sNominalPointSize,
     684               pfm2->lMaxBaselineExt,
     685               pfm2->lAveCharWidth)); */
     686
     687        if (!strcmp(pcszCompare, pcszName))
     688        {
     689            /* _Pmpf(("  Found font %s; slope %d, usWeightClass %d",
     690                    pfm2->szFacename,
     691                    pfm2->sCharSlope,
     692                    pfm2->usWeightClass)); */
     693
     694            if ((pfm2->fsDefn & FM_DEFN_OUTLINE) == 0)
     695            {
     696                // image (bitmap) font:
     697                // check point size
     698                if (pfm2->sNominalPointSize == lSize * 10)
     699                {
     700                    // OK: check device resolutions, because
     701                    // normally, there are always several image
     702                    // fonts for different resolutions
     703                    // for bitmap fonts, there are normally two versions:
     704                    // one for low resolutions, one for high resolutions
     705                    if (!fQueriedDevice)
     706                    {
     707                        DevQueryCaps(GpiQueryDevice(hps),
     708                                     CAPS_HORIZONTAL_FONT_RES,
     709                                     2L,
     710                                     alDevRes);
     711                        fQueriedDevice = TRUE;
     712                    }
     713
     714                    if (    (pfm2->sXDeviceRes == alDevRes[0])
     715                         && (pfm2->sYDeviceRes == alDevRes[1])
     716                       )
     717                    {
     718                        // OK: use this for GpiCreateLogFont
     719                        pfa->lMaxBaselineExt = pfm2->lMaxBaselineExt;
     720                        pfa->lAveCharWidth = pfm2->lAveCharWidth;
     721                        // pfa->lMatch = pfm2->lMatch;
     722
     723                        pfmFound = pfm2;
     724                        break;
     725                    }
     726                }
     727            }
     728            else
     729                // outline font:
     730                if (pfmFound == NULL)
     731                {
     732                    // no bitmap font found yet:
     733
     734                    /*
     735                        #define FATTR_SEL_ITALIC               0x0001
     736                        #define FATTR_SEL_UNDERSCORE           0x0002
     737                        #define FATTR_SEL_OUTLINE              0x0008
     738                        #define FATTR_SEL_STRIKEOUT            0x0010
     739                        #define FATTR_SEL_BOLD                 0x0020
     740                     */
     741
     742                    if (    (!fFamily)          // face mode is OK always
     743                                                // V0.9.14 (2001-08-03) [umoeller]
     744                         || (    (    (    (usFormat & FATTR_SEL_BOLD)
     745                                        && (pfm2->usWeightClass == 7) // bold
     746                                      )
     747                                   || (    (!(usFormat & FATTR_SEL_BOLD))
     748                                        && (pfm2->usWeightClass == 5) // regular
     749                                      )
     750                                 )
     751                              && (    (    (usFormat & FATTR_SEL_ITALIC)
     752                                        && (pfm2->sCharSlope != 0) // italics
     753                                      )
     754                                   || (    (!(usFormat & FATTR_SEL_ITALIC))
     755                                        && (pfm2->sCharSlope == 0) // regular
     756                                      )
     757                                 )
     758                            )
     759                       )
     760                    {
     761                        // yes, we found a true font for that face:
     762                        pfmFound = pfm2;
     763
     764                        // use this exact font for GpiCreateLogFont
     765                        pfa->lMatch = pfm2->lMatch;
     766
     767                        // the following two might have been set
     768                        // for a bitmap font above
     769                        // V0.9.14 (2001-08-03) [umoeller]
     770                        pfa->lMaxBaselineExt = pfm2->lMaxBaselineExt;
     771                        pfa->lAveCharWidth = pfm2->lAveCharWidth;
     772
     773                        pfa->idRegistry = pfm2->idRegistry;
     774
     775                        // override NOMIX // V0.9.14 (2001-08-03) [umoeller]
     776                        pfa->fsFontUse = FATTR_FONTUSE_OUTLINE;
     777
     778                        // according to GPIREF, we must also specify
     779                        // the full face name... geese!
     780                        strcpy(pfa->szFacename, pfm2->szFacename);
     781                        // unset flag in FATTRS, because this would
     782                        // duplicate bold or italic
     783                        pfa->fsSelection = 0;
     784
     785                        // _Pmpf(("    --> using it"));
     786                        // but loop on, because we might have a bitmap
     787                        // font which should take priority
     788                    }
     789                }
     790        }
     791
     792        pfm2++;
     793    }
     794
     795    if (pfmFound)
     796        // FONTMETRICS found:
     797        // copy font metrics?
     798        if (pFontMetrics)
     799            memcpy(pFontMetrics, pfmFound, sizeof(FONTMETRICS));
     800
     801    // free the FONTMETRICS array
     802    free(pfm);
     803
     804    return (pfmFound != NULL);
     805}
     806
     807/*
    556808 *@@ gpihSplitPresFont:
    557809 *      splits a presentation parameter font
     
    746998
    747999/*
     1000 *@@ gpihCreateFont:
     1001 *
     1002 *@@added V0.9.14 (2001-08-03) [umoeller]
     1003 */
     1004
     1005LONG gpihCreateFont(HPS hps,
     1006                    FATTRS *pfa)
     1007{
     1008    LONG lLCIDReturn = 0;
     1009
     1010    if (gpihLockLCIDs())        // V0.9.9 (2001-04-01) [umoeller]
     1011    {
     1012        // new logical font ID: last used plus one
     1013        lLCIDReturn = gpihQueryNextFontID(hps);
     1014
     1015        GpiCreateLogFont(hps,
     1016                         NULL,  // don't create "logical font name" (STR8)
     1017                         lLCIDReturn,
     1018                         pfa);
     1019
     1020        gpihUnlockLCIDs();
     1021    }
     1022
     1023    return (lLCIDReturn);
     1024}
     1025
     1026/*
    7481027 *@@ gpihFindFont:
    7491028 *      this returns a new logical font ID (LCID) for the specified
    750  *      font by calling GpiCreateLogFont.
    751  *      This function performs the insane "11-step process" to
    752  *      match a font, as described in the GPI reference.
    753  *
    754  *      This function can operate in two modes:
    755  *
    756  *      -- "Family" mode. In that case, specify the font family name
    757  *         with pszName and set fFamily to TRUE. This is useful for
    758  *         WYSIWYG text viewing if you need several font faces for
    759  *         the same family, such as Courier Bold, Bold Italics, etc.
    760  *         You can specify those attributes with usFormat then.
    761  *
    762  *      -- "Face" mode. In that case, specify the full font face name
    763  *         with pszName and set fFamily to FALSE. This is useful for
    764  *         font presentation parameters which use the "WarpSans Bold"
    765  *         format. In that case, set usFormat to 0.
    766  *
    767  *      After the font has been created, if (pFontMetrics != NULL),
    768  *      *pFontMetrics receives the FONTMETRICS of the font which
    769  *      has been created. If an outline font has been created
    770  *      (instead of a bitmap font), FONTMETRICS.fsDefn will have
    771  *      the FM_DEFN_OUTLINE bit set.
     1029 *      font by calling gpihMatchFont first and then
     1030 *      GpiCreateLogFont to create a logical font from the
     1031 *      data returned.
     1032 *
     1033 *      See gpihMatchFont for additional explanations.
    7721034 *
    7731035 *      To then use the font whose LCID has been returned by this
     
    9301192                  PFONTMETRICS pFontMetrics) // out: font metrics of created font (optional)
    9311193{
    932     LONG    lLCIDReturn = 0;
    933     ULONG   ul = 0;
    9341194    FATTRS  FontAttrs;
    9351195
    936     // first find out how much memory we need to allocate
    937     // for the FONTMETRICS structures
    938     LONG    lTemp = 0;
    939     LONG    cFonts = GpiQueryFonts(hps,
    940                                    QF_PUBLIC | QF_PRIVATE,
    941                                    NULL, // pszFaceName,
    942                                    &lTemp,
    943                                    sizeof(FONTMETRICS),
    944                                    NULL);
    945     PFONTMETRICS    pfm = (PFONTMETRICS)malloc(cFonts * sizeof(FONTMETRICS)),
    946                     pfm2 = pfm,
    947                     pfmFound = NULL;
    948 
    949     BOOL            fQueriedDevice = FALSE;     // V0.9.14 (2001-08-01) [umoeller]
    950     LONG            alDevRes[2];            // device resolution
    951 
    952     // _Pmpf(("gpihFindFont: enumerating for %s, %d points", pszFaceName, lSize));
    953 
    954     GpiQueryFonts(hps,
    955                   QF_PUBLIC | QF_PRIVATE,
    956                   NULL, // pszFaceName,
    957                   &cFonts,
    958                   sizeof(FONTMETRICS),      // length of each metrics structure
    959                                             // -- _not_ total buffer size!
    960                   pfm);
    961 
    962     // now we have an array of FONTMETRICS
    963     // for EVERY font that is installed on the system...
    964     // these things are completely unsorted, so there's
    965     // nothing we can rely on, we have to check them all.
    966 
    967     // fill in some default values for FATTRS,
    968     // in case we don't find something better
    969     // in the loop below; these values will be
    970     // applied if
    971     // a)   an outline font has been found;
    972     // b)   bitmap fonts have been found, but
    973     //      none for the current device resolution
    974     //      exists;
    975     // c)   no font has been found at all.
    976     // In all cases, GpiCreateLogFont will do
    977     // a "close match" resolution (at the bottom).
    978     FontAttrs.usRecordLength = sizeof(FATTRS);
    979     FontAttrs.fsSelection = usFormat; // changed later if better font is found
    980     FontAttrs.lMatch = 0L;             // closest match
    981     strcpy(FontAttrs.szFacename, pcszName);
    982     FontAttrs.idRegistry = 0;          // default registry
    983     FontAttrs.usCodePage = 0;          // default codepage
    984     // the following two must be zero, or outline fonts
    985     // will not be found; if a bitmap font has been passed
    986     // to us, we'll modify these two fields later
    987     FontAttrs.lMaxBaselineExt = 0;     // font size (height)
    988     FontAttrs.lAveCharWidth = 0;       // font size (width)
    989     FontAttrs.fsType = 0;              // default type
    990     FontAttrs.fsFontUse = FATTR_FONTUSE_NOMIX;
    991 
    992     // now go thru the array of FONTMETRICS
    993     // to check if we have a bitmap font
    994     // pszFaceName; the default WPS behavior
    995     // is that bitmap fonts appear to take
    996     // priority over outline fonts of the
    997     // same name, so we check these first
    998     pfm2 = pfm;
    999     for (ul = 0;
    1000          ul < cFonts;
    1001          ul++)
    1002     {
    1003         /* _Pmpf(("  Checking font: %s (Fam: %s), %d, %d, %d",
    1004                pszFaceName,
    1005                pfm2->szFamilyname,
    1006                pfm2->sNominalPointSize,
    1007                pfm2->lMaxBaselineExt,
    1008                pfm2->lAveCharWidth)); */
    1009 
    1010         const char *pcszCompare = (fFamily)
    1011                                      ? pfm2->szFamilyname
    1012                                      : pfm2->szFacename;
    1013 
    1014         if (!strcmp(pcszCompare, pcszName))
    1015         {
    1016             /* _Pmpf(("  Found font %s; slope %d, usWeightClass %d",
    1017                     pfm2->szFacename,
    1018                     pfm2->sCharSlope,
    1019                     pfm2->usWeightClass)); */
    1020 
    1021             if ((pfm2->fsDefn & FM_DEFN_OUTLINE) == 0)
    1022             {
    1023                 // image (bitmap) font:
    1024                 // check point size
    1025                 if (pfm2->sNominalPointSize == lSize * 10)
    1026                 {
    1027                     // OK: check device resolutions, because
    1028                     // normally, there are always several image
    1029                     // fonts for different resolutions
    1030                     // for bitmap fonts, there are always two versions:
    1031                     // one for low resolutions, one for high resolutions
    1032                     if (!fQueriedDevice)
    1033                     {
    1034                         DevQueryCaps(GpiQueryDevice(hps),
    1035                                      CAPS_HORIZONTAL_FONT_RES,
    1036                                      2L,
    1037                                      alDevRes);
    1038                         fQueriedDevice = TRUE;
    1039                     }
    1040 
    1041                     if (    (pfm2->sXDeviceRes == alDevRes[0])
    1042                          && (pfm2->sYDeviceRes == alDevRes[1])
    1043                        )
    1044                     {
    1045                         // OK: use this for GpiCreateLogFont
    1046                         FontAttrs.lMaxBaselineExt = pfm2->lMaxBaselineExt;
    1047                         FontAttrs.lAveCharWidth = pfm2->lAveCharWidth;
    1048                         FontAttrs.lMatch = pfm2->lMatch;
    1049 
    1050                         pfmFound = pfm2;
    1051                         break;
    1052                     }
    1053                 }
    1054             }
    1055             else
    1056                 // outline font:
    1057                 if (pfmFound == NULL)
    1058                 {
    1059                     /*
    1060                         #define FATTR_SEL_ITALIC               0x0001
    1061                         #define FATTR_SEL_UNDERSCORE           0x0002
    1062                         #define FATTR_SEL_OUTLINE              0x0008
    1063                         #define FATTR_SEL_STRIKEOUT            0x0010
    1064                         #define FATTR_SEL_BOLD                 0x0020
    1065                      */
    1066                     // no bitmap font found yet:
    1067                     if (  (     (   (usFormat & FATTR_SEL_BOLD)
    1068                                  && (pfm2->usWeightClass == 7) // bold
    1069                                 )
    1070                             ||  (   (!(usFormat & FATTR_SEL_BOLD))
    1071                                  && (pfm2->usWeightClass == 5) // regular
    1072                                 )
    1073                            )
    1074                         && (    (   (usFormat & FATTR_SEL_ITALIC)
    1075                                  && (pfm2->sCharSlope != 0) // italics
    1076                                 )
    1077                             ||  (   (!(usFormat & FATTR_SEL_ITALIC))
    1078                                  && (pfm2->sCharSlope == 0) // regular
    1079                                 )
    1080                            )
    1081                        )
    1082                     {
    1083                         // yes, we found a true font for that face:
    1084                         pfmFound = pfm2;
    1085                         // use this exact font for GpiCreateLogFont
    1086                         FontAttrs.lMatch = pfm2->lMatch;
    1087                         // according to GPIREF, we must also specify
    1088                         // the full face name... Jesus!
    1089                         strcpy(FontAttrs.szFacename, pfm2->szFacename);
    1090                         // unset flag in FATTRS, because this would
    1091                         // duplicate bold or italic
    1092                         FontAttrs.fsSelection = 0;
    1093 
    1094                         // _Pmpf(("    --> using it"));
    1095                         // but loop on, because we might have a bitmap
    1096                         // font which should take priority
    1097                     }
    1098                 }
    1099         }
    1100 
    1101         pfm2++;
    1102     }
    1103 
    1104     if (pfmFound)
    1105         // FONTMETRICS found:
    1106         // copy font metrics?
    1107         if (pFontMetrics)
    1108             memcpy(pFontMetrics, pfmFound, sizeof(FONTMETRICS));
    1109 
    1110     // free the FONTMETRICS array
    1111     free(pfm);
    1112 
    1113     if (gpihLockLCIDs())        // V0.9.9 (2001-04-01) [umoeller]
    1114     {
    1115         // new logical font ID: last used plus one
    1116         lLCIDReturn = gpihQueryNextFontID(hps);
    1117 
    1118         GpiCreateLogFont(hps,
    1119                          NULL,  // don't create "logical font name" (STR8)
    1120                          lLCIDReturn,
    1121                          &FontAttrs);
    1122 
    1123         gpihUnlockLCIDs();
    1124     }
     1196    gpihMatchFont(hps,
     1197                  lSize,
     1198                  fFamily,
     1199                  pcszName,
     1200                  usFormat,
     1201                  &FontAttrs,
     1202                  pFontMetrics);
     1203
     1204    return (gpihCreateFont(hps,
     1205                           &FontAttrs));
    11251206
    11261207    // _Pmpf((__FUNCTION__ ": returning lcid %d", lLCIDReturn));
    1127 
    1128     return (lLCIDReturn);
    11291208}
    11301209
     
    12491328 *
    12501329 *@@added V0.9.0 [umoeller]
     1330 *@@changed V0.9.14 (2001-08-03) [umoeller]: fixed bad rounding errors
    12511331 */
    12521332
     
    12551335{
    12561336    SIZEF   box;
     1337    HDC     hdc = GpiQueryDevice(hps);       // get the HDC from the HPS
    12571338    LONG    alDevRes[2];
    12581339    DevQueryCaps(GpiQueryDevice(hps),       // get the HDC from the HPS
     
    12601341                 2L,
    12611342                 alDevRes);
    1262     box.cx = MAKEFIXED((lPointSize * alDevRes[0]) / 72, 0);
    1263     box.cy = MAKEFIXED((lPointSize * alDevRes[1]) / 72, 0);
     1343
     1344    // V0.9.14: this code didn't work... it produced rounding
     1345    // errors which set the font size different from what
     1346    // it should be according to the WPS font palette
     1347    /* box.cx = MAKEFIXED((lPointSize * alDevRes[0]) / 72, 0);
     1348    box.cy = MAKEFIXED((lPointSize * alDevRes[1]) / 72, 0); */
     1349
     1350    // V0.9.14 (2001-08-03) [umoeller]: now using this one
     1351    // instead
     1352    lPointSize *= 65536;
     1353    box.cx = (FIXED)(lPointSize / 72 * alDevRes[0]);
     1354    box.cy = (FIXED)(lPointSize / 72 * alDevRes[1]);
     1355
    12641356    return (GpiSetCharBox(hps, &box));
    12651357}
  • trunk/src/helpers/stringh.c

    r91 r94  
    6969
    7070/*
    71  *@@ strcpy:
     71 *@@ strhcpy:
    7272 *      like strdup, but this one doesn't crash if string2 is NULL,
    7373 *      but sets the first byte in string1 to \0 instead.
Note: See TracChangeset for help on using the changeset viewer.