diff options
| author | Kenichi Handa | 2006-07-28 12:44:45 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2006-07-28 12:44:45 +0000 |
| commit | 056360d007c86327ac5abfe0a44d9950d8c1f04a (patch) | |
| tree | 13716e11e1049ad8d971d9733c3f603b22962b7d /src | |
| parent | 1b4fe7abd255dbba6c50e82ca301149d02cd4abd (diff) | |
| download | emacs-056360d007c86327ac5abfe0a44d9950d8c1f04a.tar.gz emacs-056360d007c86327ac5abfe0a44d9950d8c1f04a.zip | |
(ftxfont_create_gcs): New function.
(ftxfont_draw_bitmap): Fix arg to ftfont_driver.get_bitmap.
(ftxfont_draw_backgrond): Fix filling region.
(ftxfont_default_fid): New function.
(ftxfont_open): Set xfotn->fid to the return value of
ftxfont_default_fid.
(ftxfont_prepare_face): Use ftxfont_create_gcs to create GCs.
(ftxfont_done_face): Free only GCs that are created by
ftxfont_create_gcs.
(ftxfont_draw): If face->gc != s->gc, create proper GCs.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ftxfont.c | 145 |
1 files changed, 111 insertions, 34 deletions
diff --git a/src/ftxfont.c b/src/ftxfont.c index 4e91bd50895..680c439e149 100644 --- a/src/ftxfont.c +++ b/src/ftxfont.c | |||
| @@ -40,10 +40,56 @@ Boston, MA 02110-1301, USA. */ | |||
| 40 | static Lisp_Object Qftx; | 40 | static Lisp_Object Qftx; |
| 41 | 41 | ||
| 42 | /* Prototypes for helper function. */ | 42 | /* Prototypes for helper function. */ |
| 43 | static int ftxfont_create_gcs P_ ((FRAME_PTR, GC *, | ||
| 44 | unsigned long, unsigned long)); | ||
| 43 | static int ftxfont_draw_bitmap P_ ((FRAME_PTR, GC *, struct font *, unsigned, | 45 | static int ftxfont_draw_bitmap P_ ((FRAME_PTR, GC *, struct font *, unsigned, |
| 44 | int, int, XPoint *, int, int *n)); | 46 | int, int, XPoint *, int, int *n)); |
| 45 | static void ftxfont_draw_backgrond P_ ((FRAME_PTR, struct font *, GC, | 47 | static void ftxfont_draw_backgrond P_ ((FRAME_PTR, struct font *, GC, |
| 46 | int, int, int)); | 48 | int, int, int)); |
| 49 | static Font ftxfont_default_fid P_ ((FRAME_PTR)); | ||
| 50 | |||
| 51 | /* Create 6 GCs for antialiasing by interpolating colors FOREGROUND | ||
| 52 | and BACKGROUND. GCS[0] is closest to BACKGROUND, and GCS[5] is | ||
| 53 | closest to FOREGROUND. */ | ||
| 54 | |||
| 55 | static int | ||
| 56 | ftxfont_create_gcs (f, gcs, foreground, background) | ||
| 57 | FRAME_PTR f; | ||
| 58 | GC *gcs; | ||
| 59 | unsigned long foreground, background; | ||
| 60 | { | ||
| 61 | XColor colors[3]; | ||
| 62 | XGCValues xgcv; | ||
| 63 | int i; | ||
| 64 | |||
| 65 | colors[0].pixel = foreground; | ||
| 66 | colors[1].pixel = background; | ||
| 67 | |||
| 68 | BLOCK_INPUT; | ||
| 69 | XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, 2); | ||
| 70 | for (i = 1; i < 7; i++) | ||
| 71 | { | ||
| 72 | colors[2].red = (colors[0].red * i + colors[1].red * (8 - i)) / 8; | ||
| 73 | colors[2].green = (colors[0].green * i + colors[1].green * (8 - i)) / 8; | ||
| 74 | colors[2].blue = (colors[0].blue * i + colors[1].blue * (8 - i)) / 8; | ||
| 75 | if (! x_alloc_nearest_color (f, FRAME_X_COLORMAP (f), &colors[2])) | ||
| 76 | break; | ||
| 77 | xgcv.foreground = colors[2].pixel; | ||
| 78 | gcs[i - 1] = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | ||
| 79 | GCForeground, &xgcv); | ||
| 80 | } | ||
| 81 | UNBLOCK_INPUT; | ||
| 82 | |||
| 83 | if (i < 7) | ||
| 84 | { | ||
| 85 | BLOCK_INPUT; | ||
| 86 | for (i--; i >= 0; i--) | ||
| 87 | XFreeGC (FRAME_X_DISPLAY (f), gcs[i]); | ||
| 88 | UNBLOCK_INPUT; | ||
| 89 | return -1; | ||
| 90 | } | ||
| 91 | return 0; | ||
| 92 | } | ||
| 47 | 93 | ||
| 48 | static int | 94 | static int |
| 49 | ftxfont_draw_bitmap (f, gc, font, code, x, y, p, size, n) | 95 | ftxfont_draw_bitmap (f, gc, font, code, x, y, p, size, n) |
| @@ -59,7 +105,7 @@ ftxfont_draw_bitmap (f, gc, font, code, x, y, p, size, n) | |||
| 59 | unsigned char *b; | 105 | unsigned char *b; |
| 60 | int i, j; | 106 | int i, j; |
| 61 | 107 | ||
| 62 | if (ftfont_driver.get_bitmap (font, code, &bitmap, 1) < 0) | 108 | if (ftfont_driver.get_bitmap (font, code, &bitmap, size > 0x100 ? 1 : 8) < 0) |
| 63 | return 0; | 109 | return 0; |
| 64 | for (i = 0, b = bitmap.buffer; i < bitmap.rows; | 110 | for (i = 0, b = bitmap.buffer; i < bitmap.rows; |
| 65 | i++, b += bitmap.pitch) | 111 | i++, b += bitmap.pitch) |
| @@ -121,10 +167,33 @@ ftxfont_draw_backgrond (f, font, gc, x, y, width) | |||
| 121 | GCForeground | GCBackground, &xgcv); | 167 | GCForeground | GCBackground, &xgcv); |
| 122 | XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.background); | 168 | XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.background); |
| 123 | XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, | 169 | XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, |
| 124 | x, y - font->ascent, width, font->font.height); | 170 | x, y - font->ascent, width, y + font->descent); |
| 125 | XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.foreground); | 171 | XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.foreground); |
| 126 | } | 172 | } |
| 127 | 173 | ||
| 174 | /* Return the default Font ID on frame F. */ | ||
| 175 | |||
| 176 | static Font | ||
| 177 | ftxfont_default_fid (f) | ||
| 178 | FRAME_PTR f; | ||
| 179 | { | ||
| 180 | static int fid_known; | ||
| 181 | static Font fid; | ||
| 182 | |||
| 183 | if (! fid_known) | ||
| 184 | { | ||
| 185 | fid = XLoadFont (FRAME_X_DISPLAY (f), "fixed"); | ||
| 186 | if (! fid) | ||
| 187 | { | ||
| 188 | fid = XLoadFont (FRAME_X_DISPLAY (f), "*"); | ||
| 189 | if (! fid) | ||
| 190 | abort (); | ||
| 191 | } | ||
| 192 | fid_known = 1; | ||
| 193 | } | ||
| 194 | return fid; | ||
| 195 | } | ||
| 196 | |||
| 128 | /* Prototypes for font-driver methods. */ | 197 | /* Prototypes for font-driver methods. */ |
| 129 | static Lisp_Object ftxfont_list P_ ((Lisp_Object, Lisp_Object)); | 198 | static Lisp_Object ftxfont_list P_ ((Lisp_Object, Lisp_Object)); |
| 130 | static struct font *ftxfont_open P_ ((FRAME_PTR, Lisp_Object, int)); | 199 | static struct font *ftxfont_open P_ ((FRAME_PTR, Lisp_Object, int)); |
| @@ -172,7 +241,7 @@ ftxfont_open (f, entity, pixel_size) | |||
| 172 | return NULL; | 241 | return NULL; |
| 173 | } | 242 | } |
| 174 | 243 | ||
| 175 | xfont->fid = FRAME_FONT (f)->fid; | 244 | xfont->fid = ftxfont_default_fid (f); |
| 176 | xfont->ascent = font->ascent; | 245 | xfont->ascent = font->ascent; |
| 177 | xfont->descent = font->descent; | 246 | xfont->descent = font->descent; |
| 178 | xfont->max_bounds.width = font->font.size; | 247 | xfont->max_bounds.width = font->font.size; |
| @@ -218,7 +287,8 @@ ftxfont_prepare_face (f, face) | |||
| 218 | FRAME_PTR f; | 287 | FRAME_PTR f; |
| 219 | struct face *face; | 288 | struct face *face; |
| 220 | { | 289 | { |
| 221 | GC gc[6]; | 290 | struct font *font = (struct font *) face->font_info; |
| 291 | GC gcs[6]; | ||
| 222 | XColor colors[3]; | 292 | XColor colors[3]; |
| 223 | XGCValues xgcv; | 293 | XGCValues xgcv; |
| 224 | unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures; | 294 | unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures; |
| @@ -226,32 +296,18 @@ ftxfont_prepare_face (f, face) | |||
| 226 | 296 | ||
| 227 | face->extra = NULL; | 297 | face->extra = NULL; |
| 228 | 298 | ||
| 229 | /* Here, we create 6 more GCs to simulate anti-aliasing. */ | 299 | if (! font->scalable) |
| 230 | BLOCK_INPUT; | 300 | return 0; |
| 231 | XGetGCValues (FRAME_X_DISPLAY (f), face->gc, mask, &xgcv); | 301 | |
| 232 | colors[0].pixel = face->foreground; | 302 | if (ftxfont_create_gcs (f, gcs, face->foreground, face->background) < 0) |
| 233 | colors[1].pixel = face->background; | 303 | /* Give up antialiasing. */ |
| 234 | XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, 2); | 304 | return 0; |
| 235 | for (i = 1; i < 7; i++) | ||
| 236 | { | ||
| 237 | colors[2].red = (colors[0].red * i + colors[1].red * (7 - i)) / 7; | ||
| 238 | colors[2].green = (colors[0].green * i + colors[1].green * (7 - i)) / 7; | ||
| 239 | colors[2].blue = (colors[0].blue * i + colors[1].blue * (7 - i)) / 7; | ||
| 240 | if (! x_alloc_nearest_color (f, FRAME_X_COLORMAP (f), &colors[2])) | ||
| 241 | break; | ||
| 242 | xgcv.foreground = colors[2].pixel; | ||
| 243 | gc[i - 1] = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | ||
| 244 | mask, &xgcv); | ||
| 245 | } | ||
| 246 | UNBLOCK_INPUT; | ||
| 247 | 305 | ||
| 248 | if (i < 7) | ||
| 249 | return -1; | ||
| 250 | face->extra = malloc (sizeof (GC) * 7); | 306 | face->extra = malloc (sizeof (GC) * 7); |
| 251 | if (! face->extra) | 307 | if (! face->extra) |
| 252 | return -1; | 308 | return -1; |
| 253 | for (i = 0; i < 6; i++) | 309 | for (i = 0; i < 6; i++) |
| 254 | ((GC *) face->extra)[i] = gc[i]; | 310 | ((GC *) face->extra)[i] = gcs[i]; |
| 255 | ((GC *) face->extra)[i] = face->gc; | 311 | ((GC *) face->extra)[i] = face->gc; |
| 256 | return 0; | 312 | return 0; |
| 257 | } | 313 | } |
| @@ -266,7 +322,7 @@ ftxfont_done_face (f, face) | |||
| 266 | int i; | 322 | int i; |
| 267 | 323 | ||
| 268 | BLOCK_INPUT; | 324 | BLOCK_INPUT; |
| 269 | for (i = 0; i < 7; i++) | 325 | for (i = 0; i < 6; i++) |
| 270 | XFreeGC (FRAME_X_DISPLAY (f), ((GC *) face->extra)[i]); | 326 | XFreeGC (FRAME_X_DISPLAY (f), ((GC *) face->extra)[i]); |
| 271 | UNBLOCK_INPUT; | 327 | UNBLOCK_INPUT; |
| 272 | free (face->extra); | 328 | free (face->extra); |
| @@ -281,12 +337,13 @@ ftxfont_draw (s, from, to, x, y, with_background) | |||
| 281 | { | 337 | { |
| 282 | FRAME_PTR f = s->f; | 338 | FRAME_PTR f = s->f; |
| 283 | struct face *face = s->face; | 339 | struct face *face = s->face; |
| 284 | struct font *font = (struct font *) face->font; | 340 | struct font *font = (struct font *) face->font_info; |
| 285 | XPoint p[0x700]; | 341 | XPoint p[0x700]; |
| 286 | int n[7]; | 342 | int n[7]; |
| 287 | unsigned *code; | 343 | unsigned *code; |
| 288 | int len = to - from; | 344 | int len = to - from; |
| 289 | int i; | 345 | int i; |
| 346 | GC *gcs; | ||
| 290 | 347 | ||
| 291 | n[0] = n[1] = n[2] = n[3] = n[4] = n[5] = n[6] = 0; | 348 | n[0] = n[1] = n[2] = n[3] = n[4] = n[5] = n[6] = 0; |
| 292 | 349 | ||
| @@ -299,26 +356,46 @@ ftxfont_draw (s, from, to, x, y, with_background) | |||
| 299 | code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8) | 356 | code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8) |
| 300 | | XCHAR2B_BYTE2 (s->char2b + from + i)); | 357 | | XCHAR2B_BYTE2 (s->char2b + from + i)); |
| 301 | 358 | ||
| 302 | if (! face->extra) | 359 | gcs = face->extra; |
| 360 | if (gcs && face->gc != s->gc) | ||
| 303 | { | 361 | { |
| 362 | /* We are drawing for cursor or for mouse highlighting, and | ||
| 363 | can't use the prepared GCs. */ | ||
| 364 | XGCValues xgcv; | ||
| 365 | unsigned long mask = GCForeground | GCBackground; | ||
| 366 | |||
| 367 | gcs = alloca (sizeof (GC) * 7); | ||
| 368 | XGetGCValues (FRAME_X_DISPLAY (f), s->gc, mask, &xgcv); | ||
| 369 | if (ftxfont_create_gcs (f, gcs, xgcv.foreground, xgcv.background) < 0) | ||
| 370 | gcs = NULL; | ||
| 371 | gcs[6] = s->gc; | ||
| 372 | } | ||
| 373 | |||
| 374 | if (! gcs) | ||
| 375 | { | ||
| 376 | /* We are drawing with a bitmap font which doesn't use | ||
| 377 | antialiasing. */ | ||
| 304 | for (i = 0; i < len; i++) | 378 | for (i = 0; i < len; i++) |
| 305 | x += ftxfont_draw_bitmap (f, &face->gc, font, code[i], x, y, | 379 | x += ftxfont_draw_bitmap (f, &s->gc, font, code[i], x, y, |
| 306 | p, 0x700, n); | 380 | p, 0x700, n); |
| 307 | if (n[0] > 0) | 381 | if (n[0] > 0) |
| 308 | XDrawPoints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 382 | XDrawPoints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 309 | face->gc, p, n[0], CoordModeOrigin); | 383 | s->gc, p, n[0], CoordModeOrigin); |
| 310 | } | 384 | } |
| 311 | else | 385 | else |
| 312 | { | 386 | { |
| 313 | GC *gc = face->extra; | 387 | /* We are drawing with a scalable font which use |
| 314 | 388 | antialiasing. */ | |
| 315 | for (i = 0; i < len; i++) | 389 | for (i = 0; i < len; i++) |
| 316 | x += ftxfont_draw_bitmap (f, &face->gc, font, code[i], x, y, | 390 | x += ftxfont_draw_bitmap (f, gcs, font, code[i], x, y, |
| 317 | p, 0x100, n); | 391 | p, 0x100, n); |
| 318 | for (i = 0; i < 7; i++) | 392 | for (i = 0; i < 7; i++) |
| 319 | if (n[i] > 0) | 393 | if (n[i] > 0) |
| 320 | XDrawPoints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 394 | XDrawPoints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 321 | gc[i], p + 0x100 * i, n[i], CoordModeOrigin); | 395 | gcs[i], p + 0x100 * i, n[i], CoordModeOrigin); |
| 396 | if (face->gc != s->gc) | ||
| 397 | for (i = 0; i < 6; i++) | ||
| 398 | XFreeGC (FRAME_X_DISPLAY (f), gcs[i]); | ||
| 322 | } | 399 | } |
| 323 | 400 | ||
| 324 | UNBLOCK_INPUT; | 401 | UNBLOCK_INPUT; |