Changeset 94
- Timestamp:
- Aug 5, 2001, 6:32:52 PM (24 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/helpers/dosh.h
r93 r94 164 164 165 165 APIRET XWPENTRY doshHasAudioCD(ULONG ulLogicalDrive, 166 HFILE hfDrive, 166 167 BOOL fMixedModeCD, 167 168 PBOOL pfAudio); … … 410 411 BOOL fWait, 411 412 PULONG pulSID, 412 PPID ppid); 413 PPID ppid, 414 PUSHORT pusReturn); 413 415 414 416 /******************************************************************** -
trunk/include/helpers/gpih.h
r93 r94 182 182 ********************************************************************/ 183 183 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 184 200 BOOL XWPENTRY gpihSplitPresFont(PSZ pszFontNameSize, 185 201 PULONG pulSize, … … 197 213 typedef VOID XWPENTRY GPIHUNLOCKLCIDS(VOID); 198 214 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; 199 219 200 220 LONG XWPENTRY gpihFindFont(HPS hps, -
trunk/src/helpers/dosh.c
r91 r94 373 373 * to cause problems with some device drivers for 374 374 * removeable disks. 375 * 376 *@@changed V0.9.14 (2001-08-03) [umoeller]: added extra fix for A: and B: 375 377 */ 376 378 … … 379 381 { 380 382 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 } 381 392 382 393 if (ulLogicalDrive) … … 395 406 parms.drive = (UCHAR)(ulLogicalDrive-1); 396 407 arc = doshDevIOCtl((HFILE)-1, 397 IOCTL_DISK, 398 DSK_BLOCKREMOVABLE, 408 IOCTL_DISK, // 0x08 409 DSK_BLOCKREMOVABLE, // 0x20 399 410 &parms, sizeof(parms), 400 411 &ucNonRemoveable, sizeof(ucNonRemoveable)); … … 471 482 472 483 arc = doshDevIOCtl((HFILE)-1, 473 IOCTL_DISK, 474 DSK_GETDEVICEPARAMS, 484 IOCTL_DISK, // 0x08 485 DSK_GETDEVICEPARAMS, // 0x63 475 486 &parms, sizeof(parms), 476 487 pdp, sizeof(BIOSPARAMETERBLOCK)); … … 520 531 521 532 APIRET doshHasAudioCD(ULONG ulLogicalDrive, 533 HFILE hfDrive, // in: DASD open 522 534 BOOL fMixedModeCD, 523 535 PBOOL pfAudio) … … 525 537 APIRET arc = NO_ERROR; 526 538 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]; 532 544 533 545 *pfAudio = FALSE; 534 546 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 570 558 { 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)))) 575 571 { 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++) 588 577 { 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)))) 594 591 { 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 608 595 { 609 if (trackdata.bFlags & 64)610 ulDataTracks++; 611 else596 ulAudioTracks++; 597 598 if (!fMixedModeCD) 612 599 { 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; 622 604 } 623 605 } 624 606 } 625 626 // _Pmpf((" got %d audio, %d data tracks",627 // ulAudioTracks, ulDataTracks));628 629 if (!ulDataTracks)630 *pfAudio = TRUE;631 607 } 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; 639 621 } 640 622 } 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 } 651 630 652 631 return (arc); … … 835 814 &fFixed); // V0.9.13 (2001-06-14) [umoeller] 836 815 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)); 839 818 840 819 if (!arc) … … 846 825 arc = doshQueryDiskParams(ulLogicalDrive, 847 826 &bpb); 848 //_Pmpf((" doshQueryDiskParams returned %d", arc));827 _Pmpf((" doshQueryDiskParams returned %d", arc)); 849 828 850 829 if ( (!arc) … … 852 831 ) 853 832 { 854 //_Pmpf((" --> is CD-ROM"));833 _Pmpf((" --> is CD-ROM")); 855 834 fCDROM = TRUE; 856 835 } 857 836 } 858 837 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) 866 871 ) 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); 868 885 } 869 886 … … 2649 2666 * 2650 2667 * 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. 2654 2676 * 2655 2677 * Returns the error code of DosStartSession. … … 2661 2683 *@@changed V0.9.1 (99-12-30) [umoeller]: queue was sometimes not closed. Fixed. 2662 2684 *@@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 2663 2687 */ 2664 2688 … … 2669 2693 BOOL fWait, // in: wait for termination? 2670 2694 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; 2674 2699 // queue stuff 2675 2700 const char *pcszQueueName = "\\queues\\xwphlpsw.que"; 2676 2701 HQUEUE hq = 0; 2677 2702 PID qpid = 0; 2678 STARTDATA SData;2679 CHAR szObjBuf[CCHMAXPATH];2680 2703 2681 2704 if (fWait) 2682 2705 { 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 ) 2725 2747 { 2748 // block on the termination queue, which is written 2749 // to when the subprocess ends 2726 2750 REQUESTDATA rqdata; 2727 ULONG DataLength= 0;2728 PULONG DataAddress;2751 ULONG cbData = 0; 2752 PULONG pulData = NULL; 2729 2753 BYTE elpri; 2730 2754 2731 2755 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 } 2740 2780 } 2741 2781 } -
trunk/src/helpers/gpih.c
r91 r94 325 325 * The specified rectangle is inclusive, that is, the top 326 326 * 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). 332 328 * 333 329 * Changes to the HPS: … … 343 339 VOID gpihBox(HPS hps, // in: presentation space for output 344 340 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) 346 342 { 347 343 POINTL ptl; … … 554 550 555 551 /* 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 594 BOOL 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 /* 556 808 *@@ gpihSplitPresFont: 557 809 * splits a presentation parameter font … … 746 998 747 999 /* 1000 *@@ gpihCreateFont: 1001 * 1002 *@@added V0.9.14 (2001-08-03) [umoeller] 1003 */ 1004 1005 LONG 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 /* 748 1027 *@@ gpihFindFont: 749 1028 * 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. 772 1034 * 773 1035 * To then use the font whose LCID has been returned by this … … 930 1192 PFONTMETRICS pFontMetrics) // out: font metrics of created font (optional) 931 1193 { 932 LONG lLCIDReturn = 0;933 ULONG ul = 0;934 1194 FATTRS FontAttrs; 935 1195 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)); 1125 1206 1126 1207 // _Pmpf((__FUNCTION__ ": returning lcid %d", lLCIDReturn)); 1127 1128 return (lLCIDReturn);1129 1208 } 1130 1209 … … 1249 1328 * 1250 1329 *@@added V0.9.0 [umoeller] 1330 *@@changed V0.9.14 (2001-08-03) [umoeller]: fixed bad rounding errors 1251 1331 */ 1252 1332 … … 1255 1335 { 1256 1336 SIZEF box; 1337 HDC hdc = GpiQueryDevice(hps); // get the HDC from the HPS 1257 1338 LONG alDevRes[2]; 1258 1339 DevQueryCaps(GpiQueryDevice(hps), // get the HDC from the HPS … … 1260 1341 2L, 1261 1342 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 1264 1356 return (GpiSetCharBox(hps, &box)); 1265 1357 } -
trunk/src/helpers/stringh.c
r91 r94 69 69 70 70 /* 71 *@@ str cpy:71 *@@ strhcpy: 72 72 * like strdup, but this one doesn't crash if string2 is NULL, 73 73 * but sets the first byte in string1 to \0 instead.
Note:
See TracChangeset
for help on using the changeset viewer.