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

Misc updates.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.