~ubuntu-branches/ubuntu/karmic/python-scipy/karmic

« back to all changes in this revision

Viewing changes to Lib/xplt/src/play/win/getdc.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T. Chen (new)
  • Date: 2005-03-16 02:15:29 UTC
  • Revision ID: james.westby@ubuntu.com-20050316021529-xrjlowsejs0cijig
Tags: upstream-0.3.2
ImportĀ upstreamĀ versionĀ 0.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * getdc.c -- $Id: getdc.c,v 1.1 2003/03/08 15:26:49 travo Exp $
 
3
 * get a DC to draw into a window
 
4
 *
 
5
 * Copyright (c) 1999.  See accompanying LEGAL file for details.
 
6
 */
 
7
 
 
8
#include "playw.h"
 
9
#include "pstdlib.h"
 
10
 
 
11
/* WARNING
 
12
 * implementations of p_txwidth and p_txheight assume
 
13
 * that p_font will be called afterwards
 
14
 */
 
15
static HDC wp_font(p_win *w, int font, int pixsize, int orient);
 
16
static void w_font(p_scr *s, HDC dc, int font, int pixsize, int orient);
 
17
 
 
18
void
 
19
p_font(p_win *w, int font, int pixsize, int orient)
 
20
{
 
21
  wp_font(w, font, pixsize, orient);
 
22
}
 
23
 
 
24
static HDC
 
25
wp_font(p_win *w, int font, int pixsize, int orient)
 
26
{
 
27
  HDC dc = w_getdc(w, 0);
 
28
  if (dc) {
 
29
    if (!w->s->does_rotext) {
 
30
      w->orient = orient;
 
31
      orient = 0;
 
32
    }
 
33
    if (w->font!=font || w->pixsize!=pixsize) {
 
34
      w_font(w->s, dc, font, pixsize, orient);
 
35
      w->font = font;
 
36
      w->pixsize = pixsize;
 
37
      w->s->font_win = w;
 
38
    }
 
39
  }
 
40
  return dc;
 
41
}
 
42
 
 
43
static void
 
44
w_font(p_scr *s, HDC dc, int font, int pixsize, int orient)
 
45
{
 
46
  int face = ((unsigned int)(font&0x1c))>>2;
 
47
 
 
48
  if (face >= 5) {
 
49
    SelectObject(dc, s->gui_font);
 
50
 
 
51
  } else {
 
52
    int i, j;
 
53
 
 
54
    for (i=j=0 ; i<W_FONTS_CACHED && s->font_cache[i].hfont ; i++) {
 
55
      j = s->font_order[i];
 
56
      if (s->font_cache[j].font==font &&
 
57
          s->font_cache[j].pixsize==pixsize &&
 
58
          s->font_cache[j].orient==orient) {
 
59
        /* install cached font and make it most recently used */
 
60
        for (; i>0 ; i--) s->font_order[i] = s->font_order[i-1];
 
61
        s->font_order[0] = j;
 
62
        SelectObject(dc, s->font_cache[j].hfont);
 
63
        return;
 
64
      }
 
65
    }
 
66
    if (i<W_FONTS_CACHED) j = i++;
 
67
 
 
68
    {
 
69
      static DWORD families[5] = {
 
70
        FF_MODERN|FIXED_PITCH, FF_ROMAN|VARIABLE_PITCH,
 
71
        FF_SWISS|VARIABLE_PITCH, VARIABLE_PITCH, FF_ROMAN|VARIABLE_PITCH };
 
72
      /* note: my MS Windows box does not have Helvetica -- is Arial
 
73
       *       equivalent? -- hopefully substitution will be reasonable */
 
74
      static char *names[5] = { "Courier", "Times New Roman", "Helvetica",
 
75
                               "Symbol", "Century Schoolbook" };
 
76
      static int angles[4] = { 0, 900, 1800, 2700 };
 
77
      int ang = angles[orient];
 
78
      int weight = (font&P_BOLD)? FW_BOLD : FW_NORMAL;
 
79
      DWORD charset = ((font&P_SYMBOL)!=P_SYMBOL)? ANSI_CHARSET:SYMBOL_CHARSET;
 
80
      HFONT hfont = CreateFont(pixsize, 0, ang, ang, weight,
 
81
                              (font&P_ITALIC)!=0, 0, 0, charset,
 
82
                              OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
 
83
                              PROOF_QUALITY, families[face], names[face]);
 
84
      HFONT fold = s->font_cache[j].hfont;
 
85
      for (i-- ; i>0 ; i--)
 
86
        s->font_order[i] = s->font_order[i-1];
 
87
      s->font_order[0] = j;
 
88
      s->font_cache[j].hfont = hfont;
 
89
      s->font_cache[j].font = font;
 
90
      s->font_cache[j].pixsize = pixsize;
 
91
      s->font_cache[j].orient = orient;
 
92
      if (fold) DeleteObject(fold);
 
93
      SelectObject(dc, hfont);
 
94
    }
 
95
  }
 
96
}
 
97
 
 
98
int
 
99
p_txheight(p_scr *s, int font, int pixsize, int *baseline)
 
100
{
 
101
  int height = pixsize;
 
102
  int base = pixsize;
 
103
  if (!p_signalling) {
 
104
    HFONT orig = 0;
 
105
    HDC dc;
 
106
    TEXTMETRIC tm;
 
107
    if (s->font_win) {
 
108
      dc = wp_font(s->font_win, font, pixsize, s->font_win->orient);
 
109
    } else {
 
110
      dc = GetDC(0);
 
111
      orig = dc? SelectObject(dc, GetStockObject(ANSI_FIXED_FONT)) : 0;
 
112
      w_font(s, dc, font, pixsize, 0);
 
113
    }
 
114
    if (dc && GetTextMetrics(dc, &tm)) {
 
115
      base = tm.tmAscent;
 
116
      height = tm.tmHeight + 1;
 
117
    }
 
118
    if (orig) SelectObject(dc, orig);
 
119
  } else {
 
120
    p_abort();
 
121
  }
 
122
  if (baseline) *baseline = base;
 
123
  return height;
 
124
}
 
125
 
 
126
int
 
127
p_txwidth(p_scr *s, const char *text, int n, int font, int pixsize)
 
128
{
 
129
  int width = pixsize;
 
130
  if (!p_signalling) {
 
131
    HFONT orig = 0;
 
132
    HDC dc;
 
133
    SIZE sz;
 
134
    if (s->font_win) {
 
135
      dc = wp_font(s->font_win, font, pixsize, s->font_win->orient);
 
136
    } else {
 
137
      dc = GetDC(0);
 
138
      orig = dc? SelectObject(dc, GetStockObject(ANSI_FIXED_FONT)) : 0;
 
139
      w_font(s, dc, font, pixsize, 0);
 
140
    }
 
141
    if (dc && GetTextExtentPoint32(dc, text, n, &sz))
 
142
      width = sz.cx;
 
143
    else
 
144
      width = n*(pixsize*3/5);
 
145
    if (orig) SelectObject(dc, orig);
 
146
  } else {
 
147
    p_abort();
 
148
  }
 
149
  return width;
 
150
}
 
151
 
 
152
void
 
153
p_pen(p_win *w, int width, int type)
 
154
{
 
155
  if (p_signalling) {
 
156
    p_abort();
 
157
  } else {
 
158
    if (width<1) width = 1;
 
159
    else if (width>100) width = 100;
 
160
    if (w->pen_width!=width || w->pen_type!=type) {
 
161
      w->pen_width = width;
 
162
      w->pen_type = type;
 
163
      w->pen = 0;
 
164
    }
 
165
  }
 
166
}
 
167
 
 
168
void
 
169
p_color(p_win *w, unsigned long color)
 
170
{
 
171
  if (p_signalling) p_abort(), color = w->color;
 
172
  if (w->color != color) {
 
173
    int de_xor = (w->color == P_XOR);
 
174
    w->color = color;
 
175
    if (de_xor || color==P_XOR) {
 
176
      if (w->dc)
 
177
        SetROP2(w->dc, de_xor? R2_COPYPEN : R2_NOT);  /* or R2_XORPEN */
 
178
    }
 
179
  }
 
180
}
 
181
 
 
182
COLORREF
 
183
w_color(p_win *w, unsigned long color)
 
184
{
 
185
  if (w->parent) w = w->parent;
 
186
  if (!P_IS_RGB(color)) {
 
187
    return w->pixels[color];
 
188
  } else {
 
189
    unsigned int r = P_R(color);
 
190
    unsigned int g = P_G(color);
 
191
    unsigned int b = P_B(color);
 
192
    if (w->w && !w->menu && w->s->sys_pal) {
 
193
      if (!w->rgb_mode) {
 
194
        p_palette(w, p_595, 225);
 
195
        w->rgb_mode = 1;
 
196
      }
 
197
      /* must be consistent with p_palette in pals.c */
 
198
      r = (r+32)>>6;
 
199
      g = (g+16)>>5;
 
200
      b = (b+32)>>6;
 
201
      g += b+(b<<3);
 
202
      return PALETTEINDEX(w->s->sys_offset+r+g+(g<<2));  /* r+5*g+45*b */
 
203
    } else {
 
204
      return RGB(r, g, b);
 
205
    }
 
206
  }
 
207
}
 
208
 
 
209
HDC
 
210
w_getdc(p_win *w, int flags)
 
211
{
 
212
  HDC dc = w->dc;
 
213
  if (p_signalling) p_abort(), dc = 0;
 
214
  if (dc) {
 
215
    if (flags) {
 
216
      COLORREF color = (flags&7)? w_color(w, w->color) : 0;
 
217
 
 
218
      if ((flags & 1) && (w->font_color!=w->color)) {
 
219
        /* text */
 
220
        w->font_color = w->color;
 
221
        SetTextColor(dc, color);
 
222
      }
 
223
 
 
224
      if (flags & 2) {
 
225
        /* pen */
 
226
        HPEN pen = 0;
 
227
        if (!w->pen || (w->pen_color != w->color)) {
 
228
          int width = w->pen_width;
 
229
#ifdef USE_GEOMETRIC_PEN
 
230
          /* NOTE: geometric pen is way to slow for practical use */
 
231
          int type = w->pen_type;
 
232
          static DWORD styles[8] = {
 
233
            PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT, 0, 0, 0 };
 
234
          DWORD ltype = w->s->does_linetypes? styles[type&7] : PS_SOLID;
 
235
          DWORD cap = (type&P_SQUARE)? PS_ENDCAP_SQUARE : PS_ENDCAP_ROUND;
 
236
          DWORD join = (type&P_SQUARE)? PS_JOIN_MITER : PS_JOIN_ROUND;
 
237
          LOGBRUSH brush;
 
238
          brush.lbStyle = BS_SOLID;
 
239
          brush.lbColor = color;
 
240
          brush.lbHatch = 0;
 
241
          pen = ExtCreatePen(PS_GEOMETRIC | ltype | cap | join,
 
242
                             width, &brush, 0, 0);
 
243
#else
 
244
          /* downside of cosmetic pen is always round endcaps and joins,
 
245
           * so P_SQUARE type modifier is ignored
 
246
           * -- go for high performance instead */
 
247
          pen = CreatePen(PS_SOLID, width, color);
 
248
#endif
 
249
          if (!pen) return 0;
 
250
          w->pen = pen;
 
251
          w->pen_color = w->color;
 
252
        } else if (w->pbflag&1) {
 
253
          /* null pen has been installed */
 
254
          pen = w->pen;
 
255
        }
 
256
        if (pen) {
 
257
          pen = SelectObject(dc, pen);
 
258
          if (pen) DeleteObject(pen);
 
259
          w->pbflag &= ~1;
 
260
        }
 
261
      }
 
262
 
 
263
      if (flags & 4) {
 
264
        /* brush */
 
265
        HBRUSH b = 0;
 
266
        if (!w->brush || (w->brush_color != w->color)) {
 
267
          b = CreateSolidBrush(color);
 
268
          if (!b) return 0;
 
269
          w->brush = b;
 
270
          w->brush_color = w->color;
 
271
        } else if (w->pbflag&2) {
 
272
          b = w->brush;
 
273
        }
 
274
        if (b) {
 
275
          b = SelectObject(dc, b);
 
276
          if (b) DeleteObject(b);
 
277
          w->pbflag &= ~2;
 
278
        }
 
279
      }
 
280
 
 
281
      if (flags & 8) {
 
282
        /* install null pen */
 
283
        HPEN pen = CreatePen(PS_NULL, 0, 0);
 
284
        if (pen) {
 
285
          pen = SelectObject(dc, pen);
 
286
          if (pen && pen==w->pen) w->pbflag |= 1;
 
287
        }
 
288
      }
 
289
 
 
290
      if (flags & 16) {
 
291
        /* install null brush */
 
292
        HBRUSH b = SelectObject(dc, GetStockObject(NULL_BRUSH));
 
293
        if (b && b==w->brush) w->pbflag |= 2;
 
294
      }
 
295
    }
 
296
  }
 
297
  return dc;
 
298
}