1 /* ftxfont.c -- FreeType font driver on X (without using XFT).
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H13PRO009
7 This file is part of GNU Emacs.
9 GNU Emacs is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs; see the file COPYING. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA. */
29 #include "dispextern.h"
32 #include "blockinput.h"
33 #include "character.h"
38 /* FTX font driver. */
40 static Lisp_Object Qftx
;
42 /* Prototypes for helper function. */
43 static int ftxfont_create_gcs
P_ ((FRAME_PTR
, GC
*,
44 unsigned long, unsigned long));
45 static int ftxfont_draw_bitmap
P_ ((FRAME_PTR
, GC
*, struct font
*, unsigned,
46 int, int, XPoint
*, int, int *n
));
47 static void ftxfont_draw_backgrond
P_ ((FRAME_PTR
, struct font
*, GC
,
49 static Font ftxfont_default_fid
P_ ((FRAME_PTR
));
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. */
56 ftxfont_create_gcs (f
, gcs
, foreground
, background
)
59 unsigned long foreground
, background
;
65 colors
[0].pixel
= foreground
;
66 colors
[1].pixel
= background
;
69 XQueryColors (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), colors
, 2);
70 for (i
= 1; i
< 7; i
++)
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]))
77 xgcv
.foreground
= colors
[2].pixel
;
78 gcs
[i
- 1] = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
86 for (i
--; i
>= 0; i
--)
87 XFreeGC (FRAME_X_DISPLAY (f
), gcs
[i
]);
95 ftxfont_draw_bitmap (f
, gc
, font
, code
, x
, y
, p
, size
, n
)
104 struct font_bitmap bitmap
;
108 if (ftfont_driver
.get_bitmap (font
, code
, &bitmap
, size
> 0x100 ? 1 : 8) < 0)
110 for (i
= 0, b
= bitmap
.buffer
; i
< bitmap
.rows
;
111 i
++, b
+= bitmap
.pitch
)
115 for (j
= 0; j
< bitmap
.width
; j
++)
116 if (b
[j
/ 8] & (1 << (7 - (j
% 8))))
118 p
[n
[0]].x
= x
+ bitmap
.left
+ j
;
119 p
[n
[0]].y
= y
- bitmap
.top
+ i
;
122 XDrawPoints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
123 gc
[0], p
, size
, CoordModeOrigin
);
130 for (j
= 0; j
< bitmap
.width
; j
++)
132 int idx
= (b
[j
] >> 5) - 1;
136 XPoint
*pp
= p
+ size
* idx
;
138 pp
[n
[idx
]].x
= x
+ bitmap
.left
+ j
;
139 pp
[n
[idx
]].y
= y
- bitmap
.top
+ i
;
140 if (++(n
[idx
]) == 0x100)
142 XDrawPoints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
143 gc
[idx
], pp
, size
, CoordModeOrigin
);
151 if (ftfont_driver
.free_bitmap
)
152 ftfont_driver
.free_bitmap (font
, &bitmap
);
154 return bitmap
.advance
;
158 ftxfont_draw_backgrond (f
, font
, gc
, x
, y
, width
)
166 XGetGCValues (FRAME_X_DISPLAY (f
), gc
,
167 GCForeground
| GCBackground
, &xgcv
);
168 XSetForeground (FRAME_X_DISPLAY (f
), gc
, xgcv
.background
);
169 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
170 x
, y
- font
->ascent
, width
, y
+ font
->descent
);
171 XSetForeground (FRAME_X_DISPLAY (f
), gc
, xgcv
.foreground
);
174 /* Return the default Font ID on frame F. */
177 ftxfont_default_fid (f
)
180 static int fid_known
;
185 fid
= XLoadFont (FRAME_X_DISPLAY (f
), "fixed");
188 fid
= XLoadFont (FRAME_X_DISPLAY (f
), "*");
197 /* Prototypes for font-driver methods. */
198 static Lisp_Object ftxfont_list
P_ ((Lisp_Object
, Lisp_Object
));
199 static Lisp_Object ftxfont_match
P_ ((Lisp_Object
, Lisp_Object
));
200 static struct font
*ftxfont_open
P_ ((FRAME_PTR
, Lisp_Object
, int));
201 static void ftxfont_close
P_ ((FRAME_PTR
, struct font
*));
202 static int ftxfont_prepare_face (FRAME_PTR
, struct face
*);
203 static void ftxfont_done_face (FRAME_PTR
, struct face
*);
205 static int ftxfont_draw
P_ ((struct glyph_string
*, int, int, int, int, int));
207 struct font_driver ftxfont_driver
;
210 ftxfont_list (frame
, spec
)
214 Lisp_Object val
= ftfont_driver
.list (frame
, spec
);
220 for (i
= 0; i
< ASIZE (val
); i
++)
221 ASET (AREF (val
, i
), FONT_TYPE_INDEX
, Qftx
);
227 ftxfont_match (frame
, spec
)
231 Lisp_Object entity
= ftfont_driver
.match (frame
, spec
);
233 if (VECTORP (entity
))
234 ASET (entity
, FONT_TYPE_INDEX
, Qftx
);
239 ftxfont_open (f
, entity
, pixel_size
)
244 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
246 XFontStruct
*xfont
= malloc (sizeof (XFontStruct
));
250 font
= ftfont_driver
.open (f
, entity
, pixel_size
);
257 xfont
->fid
= ftxfont_default_fid (f
);
258 xfont
->ascent
= font
->ascent
;
259 xfont
->descent
= font
->descent
;
260 xfont
->max_bounds
.width
= font
->font
.size
;
261 xfont
->min_bounds
.width
= font
->min_width
;
262 font
->font
.font
= xfont
;
263 font
->driver
= &ftxfont_driver
;
267 /* Set global flag fonts_changed_p to non-zero if the font loaded
268 has a character with a smaller width than any other character
269 before, or if the font loaded has a smaller height than any other
270 font loaded before. If this happens, it will make a glyph matrix
271 reallocation necessary. */
272 if (dpyinfo
->n_fonts
== 1)
274 dpyinfo
->smallest_font_height
= font
->font
.height
;
275 dpyinfo
->smallest_char_width
= font
->min_width
;
280 if (dpyinfo
->smallest_font_height
> font
->font
.height
)
281 dpyinfo
->smallest_font_height
= font
->font
.height
, fonts_changed_p
|= 1;
282 if (dpyinfo
->smallest_char_width
> font
->min_width
)
283 dpyinfo
->smallest_char_width
= font
->min_width
, fonts_changed_p
|= 1;
290 ftxfont_close (f
, font
)
294 ftfont_driver
.close (f
, font
);
295 FRAME_X_DISPLAY_INFO (f
)->n_fonts
--;
299 ftxfont_prepare_face (f
, face
)
303 struct font
*font
= (struct font
*) face
->font_info
;
309 if (! font
->scalable
)
312 if (ftxfont_create_gcs (f
, gcs
, face
->foreground
, face
->background
) < 0)
313 /* Give up antialiasing. */
316 face
->extra
= malloc (sizeof (GC
) * 7);
319 for (i
= 0; i
< 6; i
++)
320 ((GC
*) face
->extra
)[i
] = gcs
[i
];
321 ((GC
*) face
->extra
)[i
] = face
->gc
;
326 ftxfont_done_face (f
, face
)
335 for (i
= 0; i
< 6; i
++)
336 XFreeGC (FRAME_X_DISPLAY (f
), ((GC
*) face
->extra
)[i
]);
344 ftxfont_draw (s
, from
, to
, x
, y
, with_background
)
345 struct glyph_string
*s
;
346 int from
, to
, x
, y
, with_background
;
349 struct face
*face
= s
->face
;
350 struct font
*font
= (struct font
*) face
->font_info
;
358 n
[0] = n
[1] = n
[2] = n
[3] = n
[4] = n
[5] = n
[6] = 0;
363 ftxfont_draw_backgrond (f
, font
, s
->gc
, x
, y
, s
->width
);
364 code
= alloca (sizeof (unsigned) * len
);
365 for (i
= 0; i
< len
; i
++)
366 code
[i
] = ((XCHAR2B_BYTE1 (s
->char2b
+ from
+ i
) << 8)
367 | XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
));
370 if (gcs
&& face
->gc
!= s
->gc
)
372 /* We are drawing for cursor or for mouse highlighting, and
373 can't use the prepared GCs. */
375 unsigned long mask
= GCForeground
| GCBackground
;
377 gcs
= alloca (sizeof (GC
) * 7);
378 XGetGCValues (FRAME_X_DISPLAY (f
), s
->gc
, mask
, &xgcv
);
379 if (ftxfont_create_gcs (f
, gcs
, xgcv
.foreground
, xgcv
.background
) < 0)
386 /* We are drawing with a bitmap font which doesn't use
388 for (i
= 0; i
< len
; i
++)
389 x
+= ftxfont_draw_bitmap (f
, &s
->gc
, font
, code
[i
], x
, y
,
392 XDrawPoints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
393 s
->gc
, p
, n
[0], CoordModeOrigin
);
397 /* We are drawing with a scalable font which use
399 for (i
= 0; i
< len
; i
++)
400 x
+= ftxfont_draw_bitmap (f
, gcs
, font
, code
[i
], x
, y
,
402 for (i
= 0; i
< 7; i
++)
404 XDrawPoints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
405 gcs
[i
], p
+ 0x100 * i
, n
[i
], CoordModeOrigin
);
406 if (face
->gc
!= s
->gc
)
407 for (i
= 0; i
< 6; i
++)
408 XFreeGC (FRAME_X_DISPLAY (f
), gcs
[i
]);
421 DEFSYM (Qftx
, "ftx");
423 ftxfont_driver
= ftfont_driver
;
424 ftxfont_driver
.type
= Qftx
;
425 ftxfont_driver
.list
= ftxfont_list
;
426 ftxfont_driver
.match
= ftxfont_match
;
427 ftxfont_driver
.open
= ftxfont_open
;
428 ftxfont_driver
.close
= ftxfont_close
;
429 ftxfont_driver
.prepare_face
= ftxfont_prepare_face
;
430 ftxfont_driver
.done_face
= ftxfont_done_face
;
431 ftxfont_driver
.draw
= ftxfont_draw
;
433 register_font_driver (&ftxfont_driver
, NULL
);
436 /* arch-tag: 59bd3469-5330-413f-b29d-1aa36492abe8
437 (do not change this comment) */