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
5
* Copyright (c) 1999. See accompanying LEGAL file for details.
12
* implementations of p_txwidth and p_txheight assume
13
* that p_font will be called afterwards
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);
19
p_font(p_win *w, int font, int pixsize, int orient)
21
wp_font(w, font, pixsize, orient);
25
wp_font(p_win *w, int font, int pixsize, int orient)
27
HDC dc = w_getdc(w, 0);
29
if (!w->s->does_rotext) {
33
if (w->font!=font || w->pixsize!=pixsize) {
34
w_font(w->s, dc, font, pixsize, orient);
44
w_font(p_scr *s, HDC dc, int font, int pixsize, int orient)
46
int face = ((unsigned int)(font&0x1c))>>2;
49
SelectObject(dc, s->gui_font);
54
for (i=j=0 ; i<W_FONTS_CACHED && s->font_cache[i].hfont ; 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];
62
SelectObject(dc, s->font_cache[j].hfont);
66
if (i<W_FONTS_CACHED) j = i++;
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;
86
s->font_order[i] = s->font_order[i-1];
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);
99
p_txheight(p_scr *s, int font, int pixsize, int *baseline)
101
int height = pixsize;
108
dc = wp_font(s->font_win, font, pixsize, s->font_win->orient);
111
orig = dc? SelectObject(dc, GetStockObject(ANSI_FIXED_FONT)) : 0;
112
w_font(s, dc, font, pixsize, 0);
114
if (dc && GetTextMetrics(dc, &tm)) {
116
height = tm.tmHeight + 1;
118
if (orig) SelectObject(dc, orig);
122
if (baseline) *baseline = base;
127
p_txwidth(p_scr *s, const char *text, int n, int font, int pixsize)
135
dc = wp_font(s->font_win, font, pixsize, s->font_win->orient);
138
orig = dc? SelectObject(dc, GetStockObject(ANSI_FIXED_FONT)) : 0;
139
w_font(s, dc, font, pixsize, 0);
141
if (dc && GetTextExtentPoint32(dc, text, n, &sz))
144
width = n*(pixsize*3/5);
145
if (orig) SelectObject(dc, orig);
153
p_pen(p_win *w, int width, int type)
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;
169
p_color(p_win *w, unsigned long color)
171
if (p_signalling) p_abort(), color = w->color;
172
if (w->color != color) {
173
int de_xor = (w->color == P_XOR);
175
if (de_xor || color==P_XOR) {
177
SetROP2(w->dc, de_xor? R2_COPYPEN : R2_NOT); /* or R2_XORPEN */
183
w_color(p_win *w, unsigned long color)
185
if (w->parent) w = w->parent;
186
if (!P_IS_RGB(color)) {
187
return w->pixels[color];
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) {
194
p_palette(w, p_595, 225);
197
/* must be consistent with p_palette in pals.c */
202
return PALETTEINDEX(w->s->sys_offset+r+g+(g<<2)); /* r+5*g+45*b */
210
w_getdc(p_win *w, int flags)
213
if (p_signalling) p_abort(), dc = 0;
216
COLORREF color = (flags&7)? w_color(w, w->color) : 0;
218
if ((flags & 1) && (w->font_color!=w->color)) {
220
w->font_color = w->color;
221
SetTextColor(dc, color);
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;
238
brush.lbStyle = BS_SOLID;
239
brush.lbColor = color;
241
pen = ExtCreatePen(PS_GEOMETRIC | ltype | cap | join,
242
width, &brush, 0, 0);
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);
251
w->pen_color = w->color;
252
} else if (w->pbflag&1) {
253
/* null pen has been installed */
257
pen = SelectObject(dc, pen);
258
if (pen) DeleteObject(pen);
266
if (!w->brush || (w->brush_color != w->color)) {
267
b = CreateSolidBrush(color);
270
w->brush_color = w->color;
271
} else if (w->pbflag&2) {
275
b = SelectObject(dc, b);
276
if (b) DeleteObject(b);
282
/* install null pen */
283
HPEN pen = CreatePen(PS_NULL, 0, 0);
285
pen = SelectObject(dc, pen);
286
if (pen && pen==w->pen) w->pbflag |= 1;
291
/* install null brush */
292
HBRUSH b = SelectObject(dc, GetStockObject(NULL_BRUSH));
293
if (b && b==w->brush) w->pbflag |= 2;