Changeset 94 for trunk/src/helpers/gpih.c
- Timestamp:
- Aug 5, 2001, 6:32:52 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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 }
Note:
See TracChangeset
for help on using the changeset viewer.