OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [libgui/] [src/] [tclwinfont.c] - Blame information for rev 1770

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* tclwinfont.c -- Tcl routine to let the user choose a font on Windows.
2
   Copyright (C) 1997 Cygnus Solutions.
3
   Written by Ian Lance Taylor <ian@cygnus.com>.
4
 
5
   This file provides a Tcl command which may be used to let the user
6
   select a font on Windows.  */
7
 
8
#ifdef _WIN32
9
 
10
#include <windows.h>
11
 
12
#include <tcl.h>
13
#include <tk.h>
14
 
15
#include "guitcl.h"
16
 
17
/* FIXME: We need to dig into the Tk window implementation internals
18
   to convert a Tk Windows to an HWND.  */
19
 
20
#include <tkWinInt.h>
21
 
22
/* FIXME: We grovel around in the Tk internal font structures.  */
23
 
24
#include <tkInt.h>
25
#include <tkFont.h>
26
 
27
/* This file defines a single Tcl command.
28
 
29
   ide_win_choose_font OPTIONS
30
       Choose a font on Windows.  This opens a modal dialog box to
31
       permit the user to choose a font.  This returns a string naming
32
       the new font, or the empty string if the user did not choose a
33
       font.
34
 
35
       Supported options:
36
           -default FONT
37
               FONT is the name of a font to use to initialize the
38
               default choice in the dialog box.
39
           -parent WINDOW
40
               Set the parent window of the dialog box.  The dialog
41
               box is modal with respect to this window.  The default
42
               is the main window.
43
 
44
   FIXME: The current implementation only supports choosing a screen
45
   font.  To permit choosing printer fonts, we would need to have a
46
   device context for the printer.
47
 
48
   */
49
 
50
/* Implement the ide_win_choose_font procedure.  */
51
 
52
static int
53
win_choose_font (ClientData cd, Tcl_Interp *interp, int argc, char **argv)
54
{
55
  char *deffont;
56
  Tk_Window parent;
57
  int i, oldMode;
58
  CHOOSEFONT cf;
59
  LOGFONT lf;
60
  HDC hdc;
61
  HFONT hfont;
62
  char facebuf[LF_FACESIZE];
63
  TEXTMETRIC tm;
64
  int pointsize;
65
  char *s;
66
  Tcl_DString resultStr;             /* used to translate result in UTF8 in Tcl/Tk8.1 */
67
  deffont = NULL;
68
  parent = Tk_MainWindow (interp);
69
 
70
  for (i = 1; i < argc; i += 2)
71
    {
72
      if (i + 1 >= argc)
73
        {
74
          Tcl_ResetResult (interp);
75
          Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
76
                                  "value for \"", argv[i], "\" missing",
77
                                  (char *) NULL);
78
          return TCL_ERROR;
79
        }
80
 
81
      if (strcmp (argv[i], "-default") == 0)
82
        deffont = argv[i + 1];
83
      else if (strcmp (argv[i], "-parent") == 0)
84
        {
85
          parent = Tk_NameToWindow (interp, argv[i + 1],
86
                                    Tk_MainWindow (interp));
87
          if (parent == NULL)
88
            return TCL_ERROR;
89
        }
90
      else
91
        {
92
          Tcl_ResetResult (interp);
93
          Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
94
                                  "unknown option \"", argv[i], "\"",
95
                                  (char *) NULL);
96
          return TCL_ERROR;
97
        }
98
    }
99
 
100
  memset (&cf, 0, sizeof (CHOOSEFONT));
101
  cf.lStructSize = sizeof (CHOOSEFONT);
102
 
103
  if (Tk_WindowId (parent) == None)
104
    Tk_MakeWindowExist (parent);
105
  cf.hwndOwner = Tk_GetHWND (Tk_WindowId (parent));
106
 
107
  cf.lpLogFont = &lf;
108
  cf.Flags = CF_SCREENFONTS | CF_FORCEFONTEXIST;
109
 
110
  memset (&lf, 0, sizeof (LOGFONT));
111
 
112
  if (deffont != NULL)
113
    {
114
      Tk_Font tkfont;
115
      const TkFontAttributes *fa;
116
 
117
      tkfont = Tk_GetFont (interp, parent, deffont);
118
      if (tkfont == NULL)
119
        return TCL_ERROR;
120
 
121
      cf.Flags |= CF_INITTOLOGFONTSTRUCT;
122
 
123
      /* In order to initialize LOGFONT, we need to extract the real
124
         font attributes from the Tk internal font information.  */
125
      fa = &((TkFont *) tkfont)->fa;
126
 
127
      /* This code is taken from TkpGetFontFromAttributes.  It
128
         converts a TkFontAttributes structure into a LOGFONT
129
         structure.  */
130
#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
131
      lf.lfHeight = - fa->size;
132
#else
133
      lf.lfHeight = - fa->pointsize;
134
#endif
135
      if (lf.lfHeight < 0)
136
        lf.lfHeight = MulDiv (lf.lfHeight,
137
                              254 * WidthOfScreen (Tk_Screen (parent)),
138
                              720 * WidthMMOfScreen (Tk_Screen (parent)));
139
      lf.lfWeight = fa->weight == TK_FW_NORMAL ? FW_NORMAL : FW_BOLD;
140
      lf.lfItalic = fa->slant;
141
      lf.lfUnderline = fa->underline;
142
      lf.lfStrikeOut = fa->overstrike;
143
      lf.lfCharSet = DEFAULT_CHARSET;
144
      lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
145
      lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
146
      lf.lfQuality = DEFAULT_QUALITY;
147
      lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
148
      if (fa->family == NULL)
149
        lf.lfFaceName[0] = '\0';
150
      else
151
        strncpy (lf.lfFaceName, fa->family, sizeof (lf.lfFaceName));
152
 
153
      Tk_FreeFont (tkfont);
154
    }
155
 
156
  oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
157
  if (! ChooseFont (&cf))
158
    {
159
      DWORD code;
160
 
161
      code = CommDlgExtendedError ();
162
      if (code == 0)
163
        {
164
          /* The user pressed cancel.  */
165
          Tcl_ResetResult (interp);
166
          return TCL_OK;
167
        }
168
      else
169
        {
170
          char buf[200];
171
 
172
          sprintf (buf, "Windows common dialog error 0x%lx", (unsigned long) code);
173
          Tcl_ResetResult (interp);
174
          #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
175
            Tcl_ExternalToUtfDString(NULL, buf, -1, &resultStr);
176
          #else
177
            Tcl_InitDString(&resultStr);
178
            Tcl_DStingAppend(&resultStr, buf, -1);
179
          #endif
180
          Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
181
                                  Tcl_DStringValue(&resultStr),
182
                                  (char *) NULL);
183
          Tcl_DStringFree(&resultStr);
184
          return TCL_ERROR;
185
        }
186
    }
187
  Tcl_SetServiceMode(oldMode);
188
  /* We now have a LOGFONT structure.  We store it into a device
189
     context, and then extract enough information to build a Tk font
190
     specification.  With luck, when Tk interprets the font
191
     specification it will wind up with the font that the user expects
192
     to see.  Some of this code is taken from AllocFont.  */
193
 
194
  hfont = CreateFontIndirect (&lf);
195
  if (hfont == NULL)
196
    {
197
      /* This should be impossible.  */
198
      #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
199
        Tcl_ExternalToUtfDString(NULL, "CreateFontIndirect failed on chosen font", -1, &resultStr);
200
      #else
201
        Tcl_InitDString(&resultStr);
202
        Tcl_DStingAppend(&resultStr, "CreateFontIndirect failed on chosen font", -1);
203
      #endif
204
      Tcl_SetResult (interp, Tcl_DStringValue(&resultStr), TCL_STATIC);
205
      Tcl_DStringFree(&resultStr);
206
      return TCL_ERROR;
207
    }
208
 
209
  hdc = GetDC (cf.hwndOwner);
210
  hfont = SelectObject (hdc, hfont);
211
  GetTextFace (hdc, sizeof (facebuf), facebuf);
212
  GetTextMetrics (hdc, &tm);
213
 
214
  Tcl_ResetResult (interp);
215
 
216
#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
217
  Tcl_ExternalToUtfDString(NULL, facebuf, -1, &resultStr);
218
#else
219
  Tcl_InitDString(&resultStr);
220
  Tcl_DStingAppend(&resultStr,facebuf,-1);
221
#endif
222
 
223
  if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp),
224
                                Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) {
225
    Tcl_DStringFree(&resultStr);
226
    return TCL_ERROR;
227
  }
228
 
229
  Tcl_DStringFree(&resultStr);
230
 
231
  pointsize = MulDiv (tm.tmHeight - tm.tmInternalLeading,
232
                      720 * WidthMMOfScreen (Tk_Screen (parent)),
233
                      254 * WidthOfScreen (Tk_Screen (parent)));
234
 
235
  if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp),
236
                                Tcl_NewIntObj (pointsize)) != TCL_OK) {
237
     return TCL_ERROR;
238
  }
239
 
240
   if (tm.tmWeight > FW_MEDIUM)
241
    s = "bold";
242
  else
243
    s = "normal";
244
 
245
#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
246
  Tcl_ExternalToUtfDString(NULL, s, -1, &resultStr);
247
#else
248
  Tcl_InitDString(&resultStr);
249
  Tcl_DStingAppend(&resultStr, s, -1);
250
#endif
251
 
252
  if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp),
253
                                Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) {
254
    Tcl_DStringFree(&resultStr);
255
    return TCL_ERROR;
256
  }
257
 
258
  Tcl_DStringFree(&resultStr);
259
 
260
  if (tm.tmItalic)
261
    s = "italic";
262
  else
263
    s = "roman";
264
 
265
#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
266
  Tcl_ExternalToUtfDString(NULL, s, -1, &resultStr);
267
#else
268
  Tcl_InitDString(&resultStr);
269
  Tcl_DStingAppend(&resultStr, s, -1);
270
#endif
271
 
272
  if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp),
273
                                Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) {
274
    Tcl_DStringFree(&resultStr);
275
    return TCL_ERROR;
276
  }
277
  Tcl_DStringFree(&resultStr);
278
 
279
  if (tm.tmUnderlined)
280
    {
281
      #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
282
        Tcl_ExternalToUtfDString(NULL, "underline", -1, &resultStr);
283
      #else
284
        Tcl_InitDString(&resultStr);
285
        Tcl_DStingAppend(&resultStr,"underline",-1);
286
      #endif
287
      if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp),
288
                                    Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1))
289
          != TCL_OK) {
290
        Tcl_DStringFree(&resultStr);
291
        return TCL_ERROR;
292
      }
293
      Tcl_DStringFree(&resultStr);
294
    }
295
 
296
  if (tm.tmStruckOut)
297
    {
298
      #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
299
        Tcl_ExternalToUtfDString(NULL, "overstrike", -1, &resultStr);
300
      #else
301
        Tcl_InitDString(&resultStr);
302
        Tcl_DStingAppend(&resultStr, "overstrike", -1);
303
      #endif
304
      if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp),
305
                                    Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1))
306
          != TCL_OK) {
307
        Tcl_DStringFree(&resultStr);
308
        return TCL_ERROR;
309
      }
310
      Tcl_DStringFree(&resultStr);
311
    }
312
 
313
  hfont = SelectObject (hdc, hfont);
314
  ReleaseDC (cf.hwndOwner, hdc);
315
  DeleteObject (hfont);
316
 
317
  return TCL_OK;
318
}
319
 
320
/* Create the Tcl command.  */
321
 
322
int
323
ide_create_win_choose_font_command (Tcl_Interp *interp)
324
{
325
  if (Tcl_CreateCommand (interp, "ide_win_choose_font", win_choose_font,
326
                         NULL, NULL) == NULL)
327
    return TCL_ERROR;
328
  return TCL_OK;
329
}
330
 
331
#endif /* _WIN32 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.