home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / stk-3.002 / stk-3 / STk-3.1 / Tk / win / tkWinFont.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-08  |  16.7 KB  |  730 lines

  1. /* 
  2.  * tkWinFont.c --
  3.  *
  4.  *    This file contains the Xlib emulation routines relating to
  5.  *    creating and manipulating fonts.
  6.  *
  7.  * Copyright (c) 1995 Sun Microsystems, Inc.
  8.  * Copyright (c) 1994 Software Research Associates, Inc. 
  9.  *
  10.  * See the file "license.terms" for information on usage and redistribution
  11.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12.  *
  13.  * SCCS: @(#) tkWinFont.c 1.8 96/04/05 15:21:22
  14.  */
  15.  
  16. #include "tkWinInt.h"
  17.  
  18. /*
  19.  * Forward declarations for functions used in this file.
  20.  */
  21.  
  22. static int        NameToFont _ANSI_ARGS_((_Xconst char *name,
  23.                 LOGFONT *logfont));
  24. static int        XNameToFont _ANSI_ARGS_((_Xconst char *name,
  25.                 LOGFONT *logfont));
  26.  
  27. /*
  28.  *----------------------------------------------------------------------
  29.  *
  30.  * NameToFont --
  31.  *
  32.  *    Converts a three part font name into a logical font
  33.  *    description.  Font name is of the form:
  34.  *        "Family point_size style_list"
  35.  *    Style_list contains a list of one or more attributes:
  36.  *        normal, bold, italic, underline, strikeout
  37.  *
  38.  * Results:
  39.  *    Returns false if the font name was syntactically invalid,
  40.  *    else true.  Sets the fields of the passed in LOGFONT.
  41.  *
  42.  * Side effects:
  43.  *    None.
  44.  *
  45.  *----------------------------------------------------------------------
  46.  */
  47.  
  48. static int
  49. NameToFont(name, logfont)
  50.     _Xconst char *name;
  51.     LOGFONT *logfont;
  52. {
  53.     int argc, argc2;
  54.     char **argv, **argv2;
  55.     int nameLen, i, pointSize = 0;
  56.     Tcl_Interp *dummy = Tcl_CreateInterp();
  57.  
  58.     if (Tcl_SplitList(dummy, (char *) name, &argc, &argv) != TCL_OK) {
  59.     goto nomatch;
  60.     }
  61.     if (argc != 3) {
  62.     ckfree((char *) argv);
  63.     goto nomatch;
  64.     }
  65.  
  66.     memset(logfont, '\0', sizeof(LOGFONT));
  67.  
  68.     /*
  69.      * Determine the font family name.
  70.      */
  71.  
  72.     nameLen = strlen(argv[0]);
  73.     if (nameLen > LF_FACESIZE) {
  74.     nameLen = LF_FACESIZE;
  75.     }
  76.     strncpy(logfont->lfFaceName, argv[0], nameLen);
  77.  
  78.     /*
  79.      * Check the character set.
  80.      */
  81.  
  82.     logfont->lfCharSet = ANSI_CHARSET;
  83.     if (stricmp(logfont->lfFaceName, "Symbol") == 0) {
  84.     logfont->lfCharSet = SYMBOL_CHARSET;
  85.     } else if (stricmp(logfont->lfFaceName, "WingDings") == 0) {
  86.     logfont->lfCharSet = SYMBOL_CHARSET;
  87.     }
  88.     
  89.     /*
  90.      * Determine the font size.
  91.      */
  92.  
  93.     if (Tcl_GetInt(dummy, argv[1], &pointSize) != TCL_OK) {
  94.     ckfree((char *) argv);
  95.     goto nomatch;
  96.     }
  97.     logfont->lfHeight = -pointSize;
  98.  
  99.     /*
  100.      * Apply any style modifiers.
  101.      */
  102.     
  103.     if (Tcl_SplitList(dummy, (char *) argv[2], &argc2, &argv2) != TCL_OK) {
  104.     ckfree((char*) argv);
  105.     goto nomatch;
  106.     }
  107.     for (i = 0; i < argc2; i++) {
  108.     if (stricmp(argv2[i], "normal") == 0) {
  109.         logfont->lfWeight = FW_NORMAL;
  110.     } else if (stricmp(argv2[i], "bold") == 0) {
  111.         logfont->lfWeight = FW_BOLD;
  112.     } else if (stricmp(argv2[i], "medium") == 0) {
  113.         logfont->lfWeight = FW_MEDIUM;
  114.     } else if (stricmp(argv2[i], "heavy") == 0) {
  115.         logfont->lfWeight = FW_HEAVY;
  116.     } else if (stricmp(argv2[i], "thin") == 0) {
  117.         logfont->lfWeight = FW_THIN;
  118.     } else if (stricmp(argv2[i], "extralight") == 0) {
  119.         logfont->lfWeight = FW_EXTRALIGHT;
  120.     } else if (stricmp(argv2[i], "light") == 0) {
  121.         logfont->lfWeight = FW_LIGHT;
  122.     } else if (stricmp(argv2[i], "semibold") == 0) {
  123.         logfont->lfWeight = FW_SEMIBOLD;
  124.     } else if (stricmp(argv2[i], "extrabold") == 0) {
  125.         logfont->lfWeight = FW_EXTRABOLD;
  126.     } else if (stricmp(argv2[i], "italic") == 0) {
  127.         logfont->lfItalic = TRUE;
  128.     } else if (stricmp(argv2[i], "oblique") == 0) {
  129.         logfont->lfOrientation = 3600 - 150; /* 15 degree forward slant */
  130.     } else if (stricmp(argv2[i], "underline") == 0) {
  131.         logfont->lfUnderline = TRUE;
  132.     } else if (stricmp(argv2[i], "strikeout") == 0) {
  133.         logfont->lfStrikeOut = TRUE;
  134.     } else {
  135.         /* ignore for now */
  136.     }
  137.     }
  138.  
  139.     ckfree((char *) argv);
  140.     ckfree((char *) argv2);
  141.     return True;
  142.  
  143.     nomatch:
  144.     Tcl_DeleteInterp(dummy);
  145.     return False;
  146. }
  147.  
  148. /*
  149.  *----------------------------------------------------------------------
  150.  *
  151.  * XNameToFont --
  152.  *
  153.  *    This function constructs a logical font description from an
  154.  *    X font name.  This code only handles font names with all 13
  155.  *    parts, although a part can be '*'.
  156.  *
  157.  * Results:
  158.  *    Returns false if the font name was syntactically invalid,
  159.  *    else true.  Sets the fields of the passed in LOGFONT.
  160.  *
  161.  * Side effects:
  162.  *    None.
  163.  *
  164.  *----------------------------------------------------------------------
  165.  */
  166.  
  167. static int
  168. XNameToFont(name, logfont)
  169.     _Xconst char *name;
  170.     LOGFONT *logfont;
  171. {
  172.     const char *head, *tail;
  173.     const char *field[13];
  174.     int flen[13];
  175.     int i, len, parsefields;
  176.  
  177.     /*
  178.      * Valid font name patterns must have a leading '-' or '*'.
  179.      */
  180.  
  181.     head = tail = name;
  182.     if (*tail == '-') {
  183.     head++; tail++;
  184.     } else if (*tail != '*') {
  185.     return FALSE;
  186.     }
  187.  
  188.     /*
  189.      * Identify field boundaries.  Stores a pointer to the beginning
  190.      * of each field in field[i], and the length of the field in flen[i].
  191.      * Fields are separated by dashes.  Each '*' becomes a field by itself.
  192.      */
  193.  
  194.     i = 0;
  195.     while (*tail != '\0' && i < 12) {
  196.     if (*tail == '-') {
  197.         flen[i] = tail - head;
  198.         field[i] = head;
  199.         tail++;
  200.         head = tail;
  201.         i++;
  202.     } else if (*tail == '*') {
  203.         len = tail - head;
  204.         if (len > 0) {
  205.         flen[i] = tail - head;
  206.         field[i] = head;
  207.         } else {
  208.         flen[i] = 1;
  209.         field[i] = head;
  210.         tail++;
  211.         if (*tail == '-') {
  212.             tail++;
  213.         }
  214.         }
  215.         head = tail;
  216.         i++;
  217.     } else {
  218.         tail++;
  219.     }
  220.     }
  221.  
  222.     /*
  223.      * We handle the last field as a special case, since it may contain
  224.      * an emedded hyphen.
  225.      */
  226.  
  227.     flen[i] = strlen(head);
  228.     field[i] = head;
  229.  
  230.     /*
  231.      * Bail if we don't have all of the fields.
  232.      */
  233.  
  234.     if (i != 12) {
  235.     return FALSE;
  236.     } 
  237.  
  238.     /*
  239.      * Now fill in the logical font description from the fields we have
  240.      * identified.
  241.      */
  242.  
  243.     memset(logfont, '\0', sizeof(LOGFONT));
  244.  
  245.     /*
  246.      * Field 1: Foundry.  Skip.
  247.      */
  248.  
  249.     /*
  250.      * Field 2: Font Family.
  251.      */
  252.  
  253.     i = 1;
  254.     if (!(flen[i] == 0 ||
  255.       (flen[i] == 1 && (field[i][0] == '*' || field[i][0] == '?'))))
  256.     {
  257.     len = (flen[i] < LF_FACESIZE) ? flen[i] : LF_FACESIZE - 1;
  258.     strncpy(logfont->lfFaceName, field[i], len);
  259.  
  260.     /*
  261.      * Need to handle Symbol and WingDings specially.
  262.      */
  263.  
  264.     if (stricmp(logfont->lfFaceName, "Symbol") == 0) {
  265.         logfont->lfCharSet = SYMBOL_CHARSET;
  266.     } else if (stricmp(logfont->lfFaceName, "WingDings") == 0) {
  267.         logfont->lfCharSet = SYMBOL_CHARSET;
  268.     }
  269.     }
  270.  
  271.     /*
  272.      * Field 3: Weight.  Default is medium.
  273.      */
  274.  
  275.     i = 2;
  276.     if ((flen[i] > 0) && (strnicmp(field[i], "bold", flen[i]) == 0)) {
  277.     logfont->lfWeight = FW_BOLD;
  278.     } else {
  279.     logfont->lfWeight = FW_MEDIUM;
  280.     }
  281.         
  282.     /*
  283.      * Field 4: Slant.  Default is Roman.
  284.      */
  285.     
  286.     i = 3;
  287.     if (!(flen[i] == 0 ||
  288.       (flen[i] == 1 && (field[i][0] == '*' || field[i][0] == '?'))))
  289.     {
  290.     if (strnicmp(field[i], "r", flen[i]) == 0) {
  291.         /* Roman.  Don't do anything */
  292.     } else if (strnicmp(field[i], "i", flen[i]) == 0) {
  293.         /* Italic */
  294.         logfont->lfItalic = TRUE;
  295.     } else if (strnicmp(field[i], "o", flen[i]) == 0) {
  296.         /* Oblique */
  297.         logfont->lfOrientation = 3600 - 150; /* 15 degree slant forward */
  298.     } else if (strnicmp(field[i], "ri", flen[i]) == 0) {
  299.         /* Reverse Italic */
  300.         logfont->lfOrientation = 300;        /* 30 degree slant backward */
  301.     } else if (strnicmp(field[i], "ro", flen[i]) == 0) {
  302.         /* Reverse Oblique */
  303.         logfont->lfOrientation = 150;        /* 30 degree slant backward */
  304.     } else if (strnicmp(field[i], "ot", flen[i]) == 0) {
  305.         /* Other */
  306.     } else {
  307.         return FALSE;
  308.     }
  309.     }
  310.  
  311.     /*
  312.      * Field 5 & 6: Set Width & Blank.  Skip.
  313.      */
  314.  
  315.     /*
  316.      * Field 7: Pixels.  Use this as the points if no points set.
  317.      */
  318.  
  319.     i = 6;
  320.     if (!(flen[i] == 0 ||
  321.       (flen[i] == 1 && (field[i][0] == '*' || field[i][0] == '?'))))
  322.     {
  323.     logfont->lfHeight = -atoi(field[i]);
  324.     }
  325.  
  326.     /*
  327.      * Field 8: Points in tenths of a point.
  328.      */
  329.  
  330.     i = 7;
  331.     if (!(flen[i] == 0 ||
  332.       (flen[i] == 1 && (field[i][0] == '*' || field[i][0] == '?'))))
  333.     {
  334.     logfont->lfHeight = -(atoi(field[i]) / 10);
  335.     }
  336.  
  337.     /*
  338.      * Field 9: Horizontal Resolution in DPI.  Skip.
  339.      * Field 10: Vertical Resolution in DPI.  Skip.
  340.      */
  341.  
  342.     /*
  343.      * Field 11: Spacing.
  344.      */
  345.  
  346.     i = 10;
  347.     if (!(flen[i] == 0 ||
  348.       (flen[i] == 1 && (field[i][0] == '*' || field[i][0] == '?'))))
  349.     {
  350.     if (flen[i] != 1) {
  351.         return FALSE;
  352.     }
  353.     if (field[i][0] == 'p' || field[i][0] == 'P') {
  354.         logfont->lfPitchAndFamily |= VARIABLE_PITCH;
  355.     } else if (field[i][0] == 'm' || field[i][0] == 'm' ||
  356.            field[i][0] == 'c' || field[i][0] == 'c')
  357.     {
  358.         logfont->lfPitchAndFamily |= FIXED_PITCH;
  359.     } else {
  360.         return FALSE;
  361.     }
  362.     }
  363.  
  364.     /*
  365.      * Field 12: Average Width.
  366.      */
  367.  
  368.     i = 11;
  369.     if (!(flen[i] == 0 ||
  370.       (flen[i] == 1 && (field[i][0] == '*' || field[i][0] == '?'))))
  371.     {
  372.     logfont->lfWidth = (atoi(field[i]) / 10);
  373.     }
  374.  
  375.     /*
  376.      * Field 13: Character Set.  Skip.
  377.      */
  378.  
  379.     return TRUE;
  380. }
  381.  
  382. /*
  383.  *----------------------------------------------------------------------
  384.  *
  385.  * XLoadFont --
  386.  *
  387.  *    Get the font handle for the specified font.
  388.  *
  389.  * Results:
  390.  *    Returns the font handle.
  391.  *
  392.  * Side effects:
  393.  *    None.
  394.  *
  395.  *----------------------------------------------------------------------
  396.  */
  397.  
  398. Font
  399. XLoadFont(display, name)
  400.     Display* display;
  401.     _Xconst char* name;
  402. {
  403.     HFONT font;
  404.     LOGFONT logfont;
  405.  
  406.     if (((name[0] == '-') || (name[0] == '*'))
  407.         && XNameToFont(name, &logfont)) {
  408.     font = CreateFontIndirect(&logfont);
  409.     } else if (NameToFont(name, &logfont)) {
  410.     font = CreateFontIndirect(&logfont);
  411.     } else {
  412.     int object = SYSTEM_FONT;
  413.  
  414.     if (stricmp(name, "system") == 0) {
  415.         object = SYSTEM_FONT;
  416.     } else if (stricmp(name, "systemfixed") == 0) {
  417.         object = SYSTEM_FIXED_FONT;
  418.     } else if (stricmp(name, "ansi") == 0) {
  419.         object = ANSI_VAR_FONT;
  420.     } else if (stricmp(name, "ansifixed") == 0) {
  421.         object = ANSI_FIXED_FONT;
  422.     } else if (stricmp(name, "device") == 0) {
  423.         object = DEVICE_DEFAULT_FONT;
  424.     } else if (stricmp(name, "oemfixed") == 0) {
  425.         object = OEM_FIXED_FONT;
  426.     }
  427.     font = GetStockObject(object);
  428.     }
  429.     if (font == NULL) {
  430.     font = GetStockObject(SYSTEM_FONT);
  431.     }
  432.     return (Font) font;
  433. }
  434.  
  435. /*
  436.  *----------------------------------------------------------------------
  437.  *
  438.  * XQueryFont --
  439.  *
  440.  *    Retrieve information about the specified font.
  441.  *
  442.  * Results:
  443.  *    Returns a newly allocated XFontStruct.
  444.  *
  445.  * Side effects:
  446.  *    None.
  447.  *
  448.  *----------------------------------------------------------------------
  449.  */
  450.  
  451. XFontStruct *
  452. XQueryFont(display, font_ID)
  453.     Display* display;
  454.     XID font_ID;
  455. {
  456.     XFontStruct *fontPtr = (XFontStruct *) ckalloc(sizeof(XFontStruct));
  457.     HFONT oldFont;
  458.     HDC dc;
  459.     TEXTMETRIC tm;
  460.     XCharStruct bounds;
  461.  
  462.     if (!fontPtr) {
  463.     return NULL;
  464.     }
  465.     
  466.     fontPtr->fid = font_ID;
  467.  
  468.     dc = GetDC(NULL);
  469.     oldFont = SelectObject(dc, (HFONT) fontPtr->fid);
  470.  
  471.     /*
  472.      * Determine the font metrics and store the values into the appropriate
  473.      * X data structures.
  474.      */
  475.  
  476.     if (GetTextMetrics(dc, &tm)) {
  477.     fontPtr->direction = FontLeftToRight;
  478.     fontPtr->min_byte1 = 0;
  479.     fontPtr->max_byte1 = 0;
  480.     fontPtr->min_char_or_byte2 = tm.tmFirstChar;
  481.     fontPtr->max_char_or_byte2 = tm.tmLastChar;
  482.     fontPtr->all_chars_exist = True;
  483.     fontPtr->default_char = tm.tmDefaultChar;
  484.     fontPtr->n_properties = 0;
  485.     fontPtr->properties = NULL;
  486.     bounds.lbearing = 0;
  487.     bounds.rbearing = tm.tmMaxCharWidth;
  488.     bounds.width = tm.tmMaxCharWidth;
  489.     bounds.ascent = tm.tmAscent;
  490.     bounds.descent = tm.tmDescent;
  491.     bounds.attributes = 0;
  492.     fontPtr->min_bounds = bounds;
  493.     fontPtr->max_bounds = bounds;
  494.     fontPtr->ascent = tm.tmAscent;
  495.     fontPtr->descent = tm.tmDescent;
  496.  
  497.     /*
  498.      * If the font is not fixed pitch, then we need to construct
  499.      * the per_char array.
  500.      */
  501.  
  502.     if (tm.tmAveCharWidth != tm.tmMaxCharWidth) {
  503.         int i;
  504.         int nchars = tm.tmLastChar - tm.tmFirstChar + 1;
  505.         int minWidth = 30000;
  506.  
  507.         fontPtr->per_char =
  508.         (XCharStruct *)ckalloc(sizeof(XCharStruct) * nchars);
  509.  
  510.         if (tm.tmPitchAndFamily & TMPF_TRUETYPE) {
  511.         ABC *chars = (ABC*)ckalloc(sizeof(ABC) * nchars);
  512.  
  513.         GetCharABCWidths(dc, tm.tmFirstChar, tm.tmLastChar, chars);
  514.         for (i = 0; i < nchars; i++) {
  515.             fontPtr->per_char[i].ascent = tm.tmAscent;
  516.             fontPtr->per_char[i].descent = tm.tmDescent;
  517.             fontPtr->per_char[i].attributes = 0;
  518.             fontPtr->per_char[i].lbearing = chars[i].abcA;
  519.             fontPtr->per_char[i].rbearing = chars[i].abcA
  520.             + chars[i].abcB;
  521.             fontPtr->per_char[i].width = chars[i].abcA + chars[i].abcB
  522.             + chars[i].abcC;
  523.         }
  524.         ckfree((char *)chars);
  525.         } else {
  526.         int *chars = (int *)ckalloc(sizeof(int) * nchars);
  527.  
  528.         GetCharWidth(dc, tm.tmFirstChar, tm.tmLastChar, chars);
  529.  
  530.         for (i = 0; i < nchars ; i++ ) {
  531.             fontPtr->per_char[i] = bounds;
  532.             fontPtr->per_char[i].width = chars[i];
  533.             if (minWidth > chars[i]) {
  534.             minWidth = chars[i];
  535.             }
  536.         }
  537.         ckfree((char *)chars);
  538.         }
  539.         fontPtr->min_bounds.width = minWidth;
  540.     } else {
  541.         fontPtr->per_char = NULL;
  542.     }
  543.     } else {
  544.     ckfree((char *)fontPtr);
  545.     fontPtr = NULL;
  546.     }    
  547.  
  548.     SelectObject(dc, oldFont);
  549.     ReleaseDC(NULL, dc);
  550.     
  551.     return fontPtr;
  552. }
  553.  
  554. /*
  555.  *----------------------------------------------------------------------
  556.  *
  557.  * XLoadQueryFont --
  558.  *
  559.  *    Finds the closest available Windows font for the specified
  560.  *    font name.
  561.  *
  562.  * Results:
  563.  *    Allocates and returns an XFontStruct containing a description
  564.  *    of the matching font.
  565.  *
  566.  * Side effects:
  567.  *    None.
  568.  *
  569.  *----------------------------------------------------------------------
  570.  */
  571.  
  572. XFontStruct *
  573. XLoadQueryFont(display, name)
  574.     Display* display;
  575.     _Xconst char* name;
  576. {
  577.     Font font;
  578.     font = XLoadFont(display, name);
  579.     return XQueryFont(display, font);
  580. }
  581.  
  582. /*
  583.  *----------------------------------------------------------------------
  584.  *
  585.  * XFreeFont --
  586.  *
  587.  *    Releases resources associated with the specified font.
  588.  *
  589.  * Results:
  590.  *    None.
  591.  *
  592.  * Side effects:
  593.  *    Frees the memory referenced by font_struct.
  594.  *
  595.  *----------------------------------------------------------------------
  596.  */
  597.  
  598. void
  599. XFreeFont(display, font_struct)
  600.     Display* display;
  601.     XFontStruct* font_struct;
  602. {
  603.     DeleteObject((HFONT)font_struct->fid);
  604.     if (font_struct->per_char != NULL) {
  605.     ckfree((char *) font_struct->per_char);
  606.     }
  607.     ckfree((char *) font_struct);
  608. }
  609.  
  610. /*
  611.  *----------------------------------------------------------------------
  612.  *
  613.  * XTextExtents --
  614.  *
  615.  *    Compute the width of an 8-bit character string.
  616.  *
  617.  * Results:
  618.  *    Returns the computed width of the specified string.
  619.  *
  620.  * Side effects:
  621.  *    None.
  622.  *
  623.  *----------------------------------------------------------------------
  624.  */
  625.  
  626. int
  627. XTextWidth(font_struct, string, count)
  628.     XFontStruct* font_struct;
  629.     _Xconst char* string;
  630.     int count;
  631. {
  632.     TEXTMETRIC tm;
  633.     int width;
  634.     SIZE size;
  635.     HFONT oldFont;
  636.     HDC dc;
  637.  
  638.     dc = GetDC(NULL);
  639.     oldFont = SelectObject(dc, (HFONT)font_struct->fid);
  640.  
  641.     GetTextExtentPoint(dc, string, count, &size);
  642.     GetTextMetrics(dc, &tm);
  643.     size.cx -= tm.tmOverhang;
  644.  
  645.     SelectObject(dc, oldFont);
  646.     ReleaseDC(NULL, dc);
  647.  
  648.     return size.cx;
  649. }
  650.  
  651. /*
  652.  *----------------------------------------------------------------------
  653.  *
  654.  * XTextExtents --
  655.  *
  656.  *    Compute the bounding box for a string.
  657.  *
  658.  * Results:
  659.  *    Sets the direction_return, ascent_return, descent_return, and
  660.  *    overall_return values as defined by Xlib.
  661.  *
  662.  * Side effects:
  663.  *    None.
  664.  *
  665.  *----------------------------------------------------------------------
  666.  */
  667.  
  668. void
  669. XTextExtents(font_struct, string, nchars, direction_return,
  670.     font_ascent_return, font_descent_return, overall_return)
  671.     XFontStruct* font_struct;
  672.     _Xconst char* string;
  673.     int nchars;
  674.     int* direction_return;
  675.     int* font_ascent_return;
  676.     int* font_descent_return;
  677.     XCharStruct* overall_return;
  678. {
  679.     HDC dc;
  680.     HFONT oldFont;
  681.     TEXTMETRIC tm;
  682.     SIZE size;
  683.  
  684.     *direction_return = font_struct->direction;
  685.     *font_ascent_return = font_struct->ascent;
  686.     *font_descent_return = font_struct->descent;
  687.  
  688.     dc = GetDC(NULL);
  689.     oldFont = SelectObject(dc, (HFONT)font_struct->fid);
  690.  
  691.     GetTextMetrics(dc, &tm);
  692.     overall_return->ascent = tm.tmAscent;
  693.     overall_return->descent = tm.tmDescent;
  694.     GetTextExtentPoint(dc, string, nchars, &size);
  695.     overall_return->width = size.cx;
  696.     overall_return->lbearing = 0;
  697.     overall_return->rbearing = overall_return->width - tm.tmOverhang;
  698.  
  699.     SelectObject(dc, oldFont);
  700.     ReleaseDC(NULL, dc);
  701. }
  702.  
  703.  
  704. /*
  705.  *----------------------------------------------------------------------
  706.  *
  707.  * XGetFontProperty --
  708.  *
  709.  *    Called to get font properties.  Since font properties are not
  710.  *    supported under Windows, this function is a no-op.
  711.  *
  712.  * Results:
  713.  *    Always returns false
  714.  *
  715.  * Side effects:
  716.  *    None.
  717.  *
  718.  *----------------------------------------------------------------------
  719.  */
  720.  
  721. Bool
  722. XGetFontProperty(font_struct, atom, value_return)
  723.     XFontStruct* font_struct;
  724.     Atom atom;
  725.     unsigned long* value_return;
  726. {
  727.     return False;
  728. }
  729.  
  730.