/* m17n-X.c -- implementation of the GUI API on X Windows.
- Copyright (C) 2003, 2004
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H15PRO112
You should have received a copy of the GNU Lesser General Public
License along with the m17n library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
02111-1307, USA. */
#include "config.h"
#include "fontset.h"
#include "face.h"
-typedef struct _MFontX MFontX;
-
-struct _MFontX
-{
- /* Record a font of the smallest pixel size. */
- MFont core;
- /* Nth bit tells the existence of a font of size N + 5. So this is
- for 5..36 pixel size fonts. Usually this covers all sizes. */
- unsigned int size5_36;
- /* Fonts of (size < 5 || size > 36) are listed here (except for a
- scalable whose size is 0). */
- MFontX *next;
-};
-
-/* S must satisfy the condition (S >= 5 && S < 36). */
-
-#define SET_SIZE(FONTX, S) ((FONTX)->size5_36 |= (1 << ((S) - 5)))
-
-#define HAVE_SIZE(FONTX, S) ((FONTX)->size5_36 & (1 << ((S) - 5)))
-
typedef struct
{
/* Common header for the m17n object. */
/** List of available X-core fonts on the display. Keys are
registries and values are plists whose keys are families and
- values are pointers to MFontX. */
+ values are pointers to MFont. */
MPlist *font_list;
/** Nonzero means that <font_list> already contains all available
int alt_mask;
int super_mask;
int hyper_mask;
+ int altgr_mask;
Atom MULE_BASELINE_OFFSET;
Atom AVERAGE_WIDTH;
MPLIST_DO (plist, disp_info->font_list)
{
MPLIST_DO (pl, MPLIST_VAL (plist))
- {
- MFontX *fontx, *next;
-
- for (fontx = MPLIST_VAL (pl); fontx; fontx = next)
- {
- next = fontx->next;
- free (fontx);
- }
- }
+ free (MPLIST_VAL (pl));
M17N_OBJECT_UNREF (MPLIST_VAL (plist));
}
M17N_OBJECT_UNREF (disp_info->font_list);
KeyCode super_r = XKeysymToKeycode (display, XK_Super_R);
KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L);
KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R);
+#ifdef XK_XKB_KEYS
+ KeyCode altgr = XKeysymToKeycode (display, XK_ISO_Level3_Shift);
+#endif
int i, j;
mods = XGetModifierMapping (display);
disp_info->super_mask |= (1 << i);
else if (code == hyper_l || code == hyper_r)
disp_info->hyper_mask |= (1 << i);
+#ifdef XK_XKB_KEYS
+ else if (code == altgr)
+ disp_info->altgr_mask |= (1 << i);
+#endif
}
/* If meta keys are not in any modifier, use alt keys as meta
static void xfont_render (MDrawWindow, int, int, MGlyphString *,
MGlyph *, MGlyph *, int, MDrawRegion);
static int xfont_list (MFrame *, MPlist *, MFont *, int);
-
+static void xfont_list_family_names (MFrame *, MPlist *);
+static int xfont_check_capability (MRealizedFont *rfont, MSymbol capability);
static MFontDriver xfont_driver =
{ xfont_select, xfont_open,
xfont_find_metric, xfont_has_char, xfont_encode_char,
- xfont_render, xfont_list };
+ xfont_render, xfont_list, xfont_list_family_names, xfont_check_capability
+ };
static int
font_compare (const void *p1, const void *p2)
plist = mplist_get (font_list, registry);
if (plist)
return plist;
- plist = mplist ();
+ p = plist = mplist ();
mplist_add (font_list, registry, plist);
sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", msymbol_name (registry));
font_names = XListFonts (disp_info->display, pattern, 0x8000, &nfonts);
memcpy (names, font_names, sizeof (char *) * nfonts);
qsort (names, nfonts, sizeof (char *), font_compare);
MFONT_INIT (&font);
- for (i = 0, p = NULL; i < nfonts; i++)
+ for (i = 0; i < nfonts; i++)
if (mfont__parse_name_into_font (names[i], Mx, &font) == 0
- && (font.size >= 50 || font.property[MFONT_RESY] == 0))
+ && (font.size > 0 || font.property[MFONT_RESY] == 0))
{
MSymbol family = FONT_PROPERTY (&font, MFONT_FAMILY);
- MFontX *fontx, *fontx2;
+ MFont *fontx;
unsigned sizes[256];
int nsizes = 0;
- int size, smallest;
+ int limit;
+ int size, normal_size;
char *base_end;
int base_len;
int fields;
- if (p && MPLIST_KEY (p) != family)
- p = mplist_find_by_key (plist, family);
- if (! p)
- p = mplist_push (plist, family, NULL);
-
/* Calculate how many bytes to compare to detect fonts of the
same base name. */
for (base_end = names[i], fields = 0; *base_end; base_end++)
break;
base_len = base_end - names[i] + 1;
- size = smallest = font.size / 10;
+ size = font.size / 10;
sizes[nsizes++] = size;
- for (j = i + 1; j < nfonts && ! strncmp (names[i], names[j], base_len);
+ normal_size = (size >= 6 && size <= 29);
+ limit = (i + 256 < nfonts ? i + 256 : nfonts);
+ for (j = i + 1; j < limit && ! memcmp (names[i], names[j], base_len);
i = j++)
if (mfont__parse_name_into_font (names[j], Mx, &font) == 0
- && (font.size >= 50 || font.property[MFONT_RESY] == 0))
+ && (font.size > 0 || font.property[MFONT_RESY] == 0))
{
size = font.size / 10;
- if (size < smallest)
- smallest = size;
- if (nsizes < 256)
- sizes[nsizes++] = size;
+ sizes[nsizes++] = size;
+ normal_size |= (size >= 6 && size <= 29);
}
font.for_full_width = for_full_width;
font.type = MFONT_TYPE_OBJECT;
font.source = MFONT_SOURCE_X;
- MSTRUCT_CALLOC (fontx, MERROR_WIN);
- fontx->core = font;
- fontx->core.size = smallest * 10;
- fontx->next = MPLIST_VAL (p);
- MPLIST_VAL (p) = fontx;
- if (smallest > 0)
- for (j = 0; j < nsizes; j++)
+ if (normal_size)
+ {
+ MSTRUCT_CALLOC (fontx, MERROR_WIN);
+ *fontx = font;
+ fontx->multiple_sizes = 1;
+ fontx->size = 0;
+ for (j = 0; j < nsizes; j++)
+ if (sizes[j] >= 6 && sizes[j] <= 29)
+ fontx->size |= 1 << (sizes[j] - 6);
+ p = mplist_add (p, family, fontx);
+ }
+ for (j = 0; j < nsizes; j++)
+ if (sizes[j] < 6 || sizes[j] > 29)
{
- if (sizes[j] <= 36)
- {
- if (sizes[j] != smallest)
- SET_SIZE (fontx, sizes[j]);
- }
- else
- {
- MSTRUCT_CALLOC (fontx2, MERROR_WIN);
- fontx2->core = font;
- fontx2->core.size = sizes[j] * 10;
- fontx2->next = MPLIST_VAL (p);
- MPLIST_VAL (p) = fontx2;
- }
+ MSTRUCT_CALLOC (fontx, MERROR_WIN);
+ *fontx = font;
+ fontx->multiple_sizes = 0;
+ fontx->size = sizes[j] * 10;
+ if (sizes[j] == 0)
+ fontx->property[MFONT_RESY] = 0;
+ p = mplist_add (p, family, fontx);
}
}
XFreeFontNames (font_names);
static MRealizedFont *
xfont_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
{
- int size = spec->size;
+ int size;
MRealizedFontX *x_rfont;
char *name;
Display *display = FRAME_DISPLAY (frame);
XFontStruct *xfont;
- int mdebug_mask = MDEBUG_FONT;
+ int mdebug_flag = MDEBUG_FONT;
MFont this;
+ size = spec->size;
+ if (size)
+ {
+ int ratio = mfont_resize_ratio (font);
+
+ if (ratio != 100)
+ size = size * ratio / 100;
+ }
+ else
+ size = 120;
+
+ if (font->size)
+ {
+ /* non-scalable font */
+ if (font->multiple_sizes)
+ {
+ int i;
+
+ if (size < 60)
+ size = 60;
+ else if (size > 290)
+ size = 290;
+ for (i = size / 10 - 6; i >= 0; i--)
+ if (font->size & (1 << i))
+ break;
+ if (i == 0)
+ for (i = size / 10 - 5; i < 24; i++)
+ if (font->size & (1 << i))
+ break;
+ size = (i + 6) * 10;
+ }
+ else
+ size = font->size;
+ }
+
if (rfont)
{
for (; rfont; rfont = rfont->next)
}
this = *font;
+ this.multiple_sizes = 0;
this.size = size;
/* This never fail to generate a valid fontname. */
name = mfont_unparse_name (&this, Mx);
font->type = MFONT_TYPE_FAILURE;
return NULL;
}
- MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
- free (name);
M17N_OBJECT (x_rfont, close_xfont, MERROR_FONT_X);
x_rfont->display = display;
x_rfont->xfont = xfont;
MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
+ rfont->id = msymbol (name);
rfont->spec = this;
rfont->spec.type = MFONT_TYPE_REALIZED;
rfont->spec.source = MFONT_SOURCE_X;
rfont->baseline_offset
= (XGetFontProperty (xfont, disp_info->MULE_BASELINE_OFFSET, &value)
- ? (int) value : 0);
+ ? (int) (value << 6) : 0);
rfont->average_width
= (XGetFontProperty (xfont, disp_info->AVERAGE_WIDTH, &value)
- ? (int) value / 10 : 0);
+ ? (int) (value << 6) / 10 : 0);
}
- rfont->ascent = xfont->ascent + rfont->baseline_offset;
- rfont->descent = xfont->descent - rfont->baseline_offset;
- rfont->max_advance = xfont->max_bounds.width;
+ rfont->ascent = (xfont->ascent << 6) + rfont->baseline_offset;
+ rfont->descent = (xfont->descent << 6) - rfont->baseline_offset;
+ rfont->max_advance = xfont->max_bounds.width << 6;
+ rfont->x_ppem = rfont->y_ppem = size / 10;
rfont->fontp = xfont;
rfont->next = MPLIST_VAL (frame->realized_font_list);
MPLIST_VAL (frame->realized_font_list) = rfont;
+ MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
+ free (name);
return rfont;
}
MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
for (; g != gend; g++)
- {
- if (g->code == MCHAR_INVALID_CODE)
- {
- g->lbearing = xfont->max_bounds.lbearing;
- g->rbearing = xfont->max_bounds.rbearing;
- g->width = xfont->max_bounds.width;
- g->ascent = xfont->ascent;
- g->descent = xfont->descent;
- }
- else
- {
- int byte1 = g->code >> 8, byte2 = g->code & 0xFF;
- XCharStruct *pcm = NULL;
+ if (! g->g.measured)
+ {
+ if (g->g.code == MCHAR_INVALID_CODE)
+ {
+ g->g.lbearing = xfont->max_bounds.lbearing << 6;
+ g->g.rbearing = xfont->max_bounds.rbearing << 6;
+ g->g.xadv = xfont->max_bounds.width << 6;
+ g->g.ascent = xfont->ascent << 6;
+ g->g.descent = xfont->descent << 6;
+ }
+ else
+ {
+ int byte1 = g->g.code >> 8, byte2 = g->g.code & 0xFF;
+ XCharStruct *pcm = NULL;
- if (xfont->per_char != NULL)
- {
- if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
- {
- if (byte1 == 0
- && byte2 >= xfont->min_char_or_byte2
- && byte2 <= xfont->max_char_or_byte2)
- pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
- }
- else
- {
- if (byte1 >= xfont->min_byte1
- && byte1 <= xfont->max_byte1
- && byte2 >= xfont->min_char_or_byte2
- && byte2 <= xfont->max_char_or_byte2)
- {
- pcm = (xfont->per_char
- + ((xfont->max_char_or_byte2
- - xfont->min_char_or_byte2 + 1)
- * (byte1 - xfont->min_byte1))
- + (byte2 - xfont->min_char_or_byte2));
- }
- }
- }
+ if (xfont->per_char != NULL)
+ {
+ if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
+ {
+ if (byte1 == 0
+ && byte2 >= xfont->min_char_or_byte2
+ && byte2 <= xfont->max_char_or_byte2)
+ pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
+ }
+ else
+ {
+ if (byte1 >= xfont->min_byte1
+ && byte1 <= xfont->max_byte1
+ && byte2 >= xfont->min_char_or_byte2
+ && byte2 <= xfont->max_char_or_byte2)
+ {
+ pcm = (xfont->per_char
+ + ((xfont->max_char_or_byte2
+ - xfont->min_char_or_byte2 + 1)
+ * (byte1 - xfont->min_byte1))
+ + (byte2 - xfont->min_char_or_byte2));
+ }
+ }
+ }
- if (pcm)
- {
- g->lbearing = pcm->lbearing;
- g->rbearing = pcm->rbearing;
- g->width = pcm->width;
- g->ascent = pcm->ascent;
- g->descent = pcm->descent;
- }
- else
- {
- /* If the per_char pointer is null, all glyphs between
- the first and last character indexes inclusive have
- the same information, as given by both min_bounds and
- max_bounds. */
- g->lbearing = 0;
- g->rbearing = xfont->max_bounds.width;
- g->width = xfont->max_bounds.width;
- g->ascent = xfont->ascent;
- g->descent = xfont->descent;
- }
- }
- g->ascent += rfont->baseline_offset;
- g->descent -= rfont->baseline_offset;
- }
+ if (pcm)
+ {
+ g->g.lbearing = pcm->lbearing << 6;
+ g->g.rbearing = pcm->rbearing << 6;
+ g->g.xadv = pcm->width << 6;
+ g->g.ascent = pcm->ascent << 6;
+ g->g.descent = pcm->descent << 6;
+ }
+ else
+ {
+ /* If the per_char pointer is null, all glyphs between
+ the first and last character indexes inclusive have
+ the same information, as given by both min_bounds and
+ max_bounds. */
+ g->g.lbearing = 0;
+ g->g.rbearing = xfont->max_bounds.width << 6;
+ g->g.xadv = xfont->max_bounds.width << 6;
+ g->g.ascent = xfont->ascent << 6;
+ g->g.descent = xfont->descent << 6;
+ }
+ }
+ g->g.yadv = 0;
+ g->g.ascent += rfont->baseline_offset;
+ g->g.descent -= rfont->baseline_offset;
+ g->g.measured = 1;
+ }
}
rfont = (MRealizedFont *) font;
else if (font->type == MFONT_TYPE_OBJECT)
{
- int size = spec->size;
-
for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
rfont = rfont->next)
- if (rfont->font == font && rfont->spec.size == size)
+ if (rfont->font == font)
break;
if (! rfont)
{
if (from == to)
return;
- baseline_offset = rface->rfont->baseline_offset;
+ baseline_offset = rface->rfont->baseline_offset >> 6;
if (region)
gc = set_region (rface->frame, gc, region);
XSetFont (display, gc, ((XFontStruct *) rface->rfont->fontp)->fid);
code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
for (i = 0, g = from; g < to; i++, g++)
{
- code[i].byte1 = g->code >> 8;
- code[i].byte2 = g->code & 0xFF;
+ code[i].byte1 = g->g.code >> 8;
+ code[i].byte2 = g->g.code & 0xFF;
}
g = from;
while (g < to)
{
if (g->type == GLYPH_PAD)
- x += g++->width;
+ x += g++->g.xadv;
else if (g->type == GLYPH_SPACE)
for (; g < to && g->type == GLYPH_SPACE; g++)
- x += g->width;
+ x += g->g.xadv;
else if (! g->rface->rfont)
{
- if ((g->c >= 0x200B && g->c <= 0x200F)
- || (g->c >= 0x202A && g->c <= 0x202E))
- x += g++->width;
+ if ((g->g.c >= 0x200B && g->g.c <= 0x200F)
+ || (g->g.c >= 0x202A && g->g.c <= 0x202E))
+ x += g++->g.xadv;
else
{
/* As a font is not found for this character, draw an
empty box. */
- int box_width = g->width;
+ int box_width = g->g.xadv;
int box_height = gstring->ascent + gstring->descent;
if (box_width > 4)
box_height -= 2;
XDrawRectangle (display, (Window) win, gc,
x, y - gstring->ascent, box_width, box_height);
- x += g++->width;
+ x += g++->g.xadv;
}
}
- else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
+ else if (g->g.xoff != 0 || g->g.yoff != 0 || g->right_padding)
{
XDrawString16 (display, (Window) win, gc,
- x + g->xoff, y + g->yoff - baseline_offset,
+ x + g->g.xoff, y + g->g.yoff - baseline_offset,
code + (g - from), 1);
- x += g->width;
+ x += g->g.xadv;
g++;
}
else
int code_idx = g - from;
for (i = 0;
- g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
+ g < to && g->type == GLYPH_CHAR && g->g.xoff == 0 && g->g.yoff == 0;
i++, g++)
- x += g->width;
+ x += g->g.xadv;
XDrawString16 (display, (Window) win, gc,
orig_x, y - baseline_offset, code + code_idx, i);
}
int size = font ? font->size : 0;
MPlist *pl, *p;
int num = 0;
- int mdebug_mask = MDEBUG_FONT;
+ int mdebug_flag = MDEBUG_FONT;
MDEBUG_PRINT2 (" [X-FONT] listing %s-%s...",
family ? msymbol_name (family) : "*",
xfont_registry_list (frame, registry);
MPLIST_DO (pl, disp_info->font_list)
+ if (registry == Mnil || registry == MPLIST_KEY (pl))
+ {
+ MPLIST_DO (p, MPLIST_VAL (pl))
+ if (family == Mnil || family == MPLIST_KEY (p))
+ {
+ MFont *fontx = MPLIST_VAL (p);
+
+ if (! font || (mfont__match_p (fontx, font, MFONT_REGISTRY)))
+ {
+ if (fontx->size != 0 && size)
+ {
+ if (fontx->multiple_sizes)
+ {
+ if (size < 60 || size > 290
+ || ! (fontx->size & (1 << (size / 10 - 6))))
+ continue;
+ }
+ else if (fontx->size != size)
+ continue;
+ }
+ mplist_push (plist, MPLIST_KEY (p), fontx);
+ num++;
+ if (maxnum > 0 && maxnum == num)
+ goto done;
+ }
+ }
+ }
+
+ done:
+ MDEBUG_PRINT1 (" %d found\n", num);
+ return num;
+}
+
+static void
+xfont_list_family_names (MFrame *frame, MPlist *plist)
+{
+ MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
+ char **font_names;
+ int i, nfonts;
+ MSymbol last_family = Mnil;
+
+ font_names = XListFonts (disp_info->display,
+ "-*-*-*-*-*-*-*-*-*-*-*-*-*-*", 0x8000, &nfonts);
+ for (i = 0; i < nfonts; i++)
{
- if (registry != Mnil && registry != MPLIST_KEY (pl))
+ MSymbol family;
+ char foundry[256], fam[256];
+ MPlist *p;
+
+ if (sscanf (font_names[i], "-%s-%s-", foundry, fam) < 2)
continue;
- MPLIST_DO (p, MPLIST_VAL (pl))
- {
- MFontX *fontx;
+ family = msymbol (fam);
+ if (family == last_family)
+ continue;
+ last_family = family;
- if (family != Mnil && family != MPLIST_KEY (p))
- continue;
- for (fontx = MPLIST_VAL (p); fontx; fontx = fontx->next)
- if (! font
- || (mfont__match_p (&fontx->core, font, MFONT_REGISTRY)))
- {
- if (fontx->core.size == size
- || fontx->core.size == 0)
- {
- mplist_push (plist, MPLIST_KEY (p), fontx);
- num++;
- }
- else if (size == 0
- || (size <= 360 && HAVE_SIZE (fontx, (size / 10))))
- {
- unsigned size5_36 = fontx->size5_36;
- MFontX *fontx2;
- int i;
+ MPLIST_DO (p, plist)
+ {
+ MSymbol sym = MPLIST_SYMBOL (p);
- fontx->size5_36 = 0;
- for (i = fontx->core.size / 10; i <= 36; i++)
- if (size5_36 & (1 << (i - 5)))
- {
- MSTRUCT_CALLOC (fontx2, MERROR_WIN);
- fontx2->core = fontx->core;
- fontx2->core.size = i * 10;
- fontx2->next = fontx->next;
- fontx->next = fontx2;
- fontx = fontx2;
- if ((size == 0 || size == fontx->core.size)
- && (maxnum == 0 || num < maxnum))
- {
- mplist_push (plist, MPLIST_KEY (p), fontx);
- num++;
- }
- }
- }
- if (maxnum > 0 && maxnum == num)
- break;
- }
- if (maxnum > 0 && maxnum == num)
+ if (sym == family)
break;
+ if (strcmp (MSYMBOL_NAME (sym), fam) > 0)
+ {
+ mplist_push (p, Msymbol, family);
+ break;
+ }
}
- if (maxnum > 0 && maxnum == num)
- break;
+ if (MPLIST_TAIL_P (p))
+ mplist_push (p, Msymbol, family);
}
+ if (font_names)
+ XFreeFontNames (font_names);
+}
- MDEBUG_PRINT1 (" %d found\n", num);
- return num;
+static int
+xfont_check_capability (MRealizedFont *rfont, MSymbol capability)
+{
+ /* Currently X font driver doesn't support any capability. */
+ return -1;
}
\f
typedef struct
{
M17NObject control;
+ FT_Face ft_face; /* This must be the 2nd member. */
Display *display;
XftFont *font_aa;
XftFont *font_no_aa;
- FT_Face ft_face;
/* Pointer to MRealizedFontFT */
void *info;
} MRealizedFontXft;
static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int);
static void xft_render (MDrawWindow, int, int, MGlyphString *,
MGlyph *, MGlyph *, int, MDrawRegion);
-
-MFontDriver xft_driver =
+static int xft_check_capability (MRealizedFont *rfont, MSymbol capability);
+static int xft_check_otf (MFLTFont *font, MFLTOtfSpec *spec);
+static int xft_drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
+ MFLTGlyphString *in, int from, int to,
+ MFLTGlyphString *out,
+ MFLTGlyphAdjustment *adjustment);
+static int xft_try_otf (MFLTFont *font, MFLTOtfSpec *spec,
+ MFLTGlyphString *in, int from, int to);
+static int xft_iterate_otf_feature (struct _MFLTFont *font, MFLTOtfSpec *spec,
+ int from, int to, unsigned char *table);
+
+
+static MFontDriver xft_driver =
{ NULL, xft_open,
- xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL };
+ xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL, NULL,
+ xft_check_capability, NULL, NULL, xft_check_otf, xft_drive_otf, xft_try_otf,
+#ifdef HAVE_OTF
+ xft_iterate_otf_feature
+#endif /* HAVE_OTF */
+ };
static void
close_xft (void *object)
FT_Face ft_face;
MRealizedFontXft *rfont_xft;
FcBool anti_alias = FRAME_DEVICE (frame)->depth > 1 ? FcTrue : FcFalse;
- double size = font->size ? font->size : spec->size;
+ int size;
XftFont *xft_font;
int ascent, descent, max_advance, average_width, baseline_offset;
+ if (font->size)
+ /* non-scalable font */
+ size = font->size;
+ else if (spec->size)
+ {
+ int ratio = mfont_resize_ratio (font);
+
+ size = ratio == 100 ? spec->size : spec->size * ratio / 100;
+ }
+ else
+ size = 120;
+
if (rfont)
{
MRealizedFont *save = NULL;
rfont_xft->info = rfont->info;
M17N_OBJECT_REF (rfont->info);
MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
+ rfont->id = font->file;
rfont->spec = *spec;
+ rfont->spec.size = size;
rfont->frame = frame;
rfont->font = font;
rfont->driver = &xft_driver;
rfont->max_advance = max_advance;
rfont->average_width = average_width;
rfont->baseline_offset = baseline_offset;
+ rfont->x_ppem = ft_face->size->metrics.x_ppem;
+ rfont->y_ppem = ft_face->size->metrics.y_ppem;
rfont->fontp = xft_font;
rfont->next = MPLIST_VAL (frame->realized_font_list);
MPLIST_VAL (frame->realized_font_list) = rfont;
MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
for (; g != gend; g++)
- {
- if (g->code == MCHAR_INVALID_CODE)
- {
- g->lbearing = 0;
- g->rbearing = xft_font->max_advance_width;
- g->width = g->rbearing;
- g->ascent = xft_font->ascent;
- g->descent = xft_font->descent;
- }
- else
- {
- XGlyphInfo extents;
-
- XftGlyphExtents (display, xft_font, &g->code, 1, &extents);
- g->lbearing = - extents.x;
- g->rbearing = extents.width - extents.x;
- g->width = extents.xOff;
- g->ascent = extents.y;
- g->descent = extents.height - extents.y;
- }
- }
+ if (! g->g.measured)
+ {
+ if (g->g.code == MCHAR_INVALID_CODE)
+ {
+ g->g.lbearing = 0;
+ g->g.rbearing = xft_font->max_advance_width << 6;
+ g->g.xadv = g->g.rbearing << 6;
+ g->g.ascent = xft_font->ascent << 6;
+ g->g.descent = xft_font->descent << 6;
+ }
+ else
+ {
+ XGlyphInfo extents;
+
+ XftGlyphExtents (display, xft_font, &g->g.code, 1, &extents);
+ g->g.lbearing = (- extents.x) << 6;
+ g->g.rbearing = (extents.width - extents.x) << 6;
+ g->g.xadv = extents.xOff << 6;
+ g->g.ascent = extents.y << 6;
+ g->g.descent = (extents.height - extents.y) << 6;
+ }
+ g->g.yadv = 0;
+ g->g.measured = 1;
+ }
}
static int
XftDrawChange (xft_draw, (Drawable) win);
XftDrawSetClip (xft_draw, (Region) region);
- y -= rfont->baseline_offset;
+ y -= rfont->baseline_offset >> 6;
glyphs = alloca (sizeof (FT_UInt) * (to - from));
- for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width)
+ for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->g.xadv)
{
- if (g->xoff == 0 && g->yoff == 0 && !g->left_padding && !g->right_padding)
- glyphs[nglyphs++] = g->code;
+ if (! g->g.adjusted && !g->left_padding && !g->right_padding)
+ glyphs[nglyphs++] = g->g.code;
else
{
if (nglyphs > 0)
last_x, y, glyphs, nglyphs);
nglyphs = 0;
XftDrawGlyphs (xft_draw, xft_color, xft_font,
- x + g->xoff, y + g->yoff, (FT_UInt *) &g->code, 1);
- last_x = x + g->width;
+ x + g->g.xoff, y + g->g.yoff, (FT_UInt *) &g->g.code, 1);
+ last_x = x + g->g.xadv;
}
}
if (nglyphs > 0)
XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
}
+static int
+xft_check_capability (MRealizedFont *rfont, MSymbol capability)
+{
+ MRealizedFontXft *rfont_xft = rfont->info;
+ int result;
+
+ rfont->info = rfont_xft->info;
+ result = mfont__ft_driver.check_capability (rfont, capability);
+ rfont->info = rfont_xft;
+ return result;
+}
+
+static int
+xft_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
+{
+ MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
+ MRealizedFontXft *rfont_xft = rfont->info;
+ int result;
+
+ rfont->info = rfont_xft->info;
+ result = mfont__ft_driver.check_otf (font, spec);
+ rfont->info = rfont_xft;
+ return result;
+}
+
+static int
+xft_drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
+ MFLTGlyphString *in, int from, int to,
+ MFLTGlyphString *out,
+ MFLTGlyphAdjustment *adjustment)
+{
+ MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
+ MRealizedFontXft *rfont_xft = rfont->info;
+ int result;
+
+ rfont->info = rfont_xft->info;
+ result = mfont__ft_driver.drive_otf (font, spec, in, from, to, out,
+ adjustment);
+ rfont->info = rfont_xft;
+ return result;
+}
+
+static int
+xft_try_otf (MFLTFont *font, MFLTOtfSpec *spec,
+ MFLTGlyphString *in, int from, int to)
+{
+ return xft_drive_otf (font, spec, in, from, to, NULL, NULL);
+}
+
+#ifdef HAVE_OTF
+
+static int
+xft_iterate_otf_feature (struct _MFLTFont *font, MFLTOtfSpec *spec,
+ int from, int to, unsigned char *table)
+{
+ MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
+ MRealizedFontXft *rfont_xft = rfont->info;
+ int result;
+
+ rfont->info = rfont_xft->info;
+ result = mfont__ft_driver.iterate_otf_feature (font, spec, from, to, table);
+ rfont->info = rfont_xft;
+ return result;
+}
+#endif /* HAVE_OTF */
+
#endif /* HAVE_XFT2 */
\f
for (; from < to; from++)
{
XDrawRectangle (display, (Window) win, gc,
- x, y - gstring->ascent + 1, from->width - 1,
+ x, y - gstring->ascent + 1, from->g.xadv - 1,
gstring->ascent + gstring->descent - 2);
- x += from->width;
+ x += from->g.xadv;
}
}
int x0, x1;
if (g->left_padding)
- x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
+ x0 = x + box->outer_hmargin, x1 = x + g->g.xadv - 1;
else
- x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
+ x0 = x, x1 = x + g->g.xadv - box->outer_hmargin - 1;
/* Draw the top side. */
for (i = 0; i < box->width; i++)
{
XRectangle rect;
XClipBox (region, &rect);
- fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
+ fprintf (mdebug__output, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
}
default: event_name = "unknown";
}
- fprintf (stderr, "%s: %s\n", win_name, event_name);
+ fprintf (mdebug__output, "%s: %s\n", win_name, event_name);
}
#endif
int len;
char buf[512];
KeySym keysym;
- MSymbol key = Mnil;
+ MSymbol key;
*modifiers = 0;
if (event->xany.type != KeyPress
len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
if (len > 1)
return Mnil;
- if (len == 1)
+ if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
+ return Mnil;
+#ifdef XK_XKB_KEYS
+ if ((keysym & 0xff00) == 0xfe00)
+ return Mnil;
+#endif
+ if (len == 1 && keysym >= XK_space && keysym <= XK_asciitilde)
{
int c = keysym;
- if (c < XK_space || c > XK_asciitilde)
- c = buf[0];
- if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
- *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
- if (((XKeyEvent *) event)->state & ControlMask)
- {
- if (c >= 'a' && c <= 'z')
- c += 'A' - 'a';
- if (c >= ' ' && c < 127)
- *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
- }
key = minput__char_to_key (c);
+ if (c == ' ' && ((XKeyEvent *) event)->state & ShiftMask)
+ *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
}
- else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
- return Mnil;
- if (key == Mnil)
+ else
{
char *str = XKeysymToString (keysym);
key = msymbol (str);
if (((XKeyEvent *) event)->state & ShiftMask)
*modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
- if (((XKeyEvent *) event)->state & ControlMask)
- *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
}
+ if (((XKeyEvent *) event)->state & ControlMask)
+ *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
if (((XKeyEvent *) event)->state & disp_info->meta_mask)
*modifiers |= MINPUT_KEY_META_MODIFIER;
if (((XKeyEvent *) event)->state & disp_info->alt_mask)
*modifiers |= MINPUT_KEY_SUPER_MODIFIER;
if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
*modifiers |= MINPUT_KEY_HYPER_MODIFIER;
-
+#ifdef XK_XKB_KEYS
+ if (((XKeyEvent *) event)->state & disp_info->altgr_mask)
+ *modifiers |= MINPUT_KEY_ALTGR_MODIFIER;
+#endif
return key;
}
for (i = 0; i <= GC_INVERSE; i++)
{
XGetGCValues (display, info->gc[i], valuemask, &values);
- fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
+ fprintf (mdebug__output, "GC%d: fore/#%lX back/#%lX", i,
values.foreground, values.background);
- fprintf (stderr, "\n");
+ fprintf (mdebug__output, "\n");
}
}
#ifdef HAVE_XFT2
xft_driver.select = mfont__ft_driver.select;
xft_driver.list = mfont__ft_driver.list;
+ xft_driver.list_family_names = mfont__ft_driver.list_family_names;
#endif
Mxim = msymbol ("xim");
mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
#endif /* HAVE_FREETYPE */
if (use_xfont || MPLIST_TAIL_P (frame->font_driver_list))
- mplist_push (frame->font_driver_list, Mx, &xfont_driver);
+ mplist_add (frame->font_driver_list, Mx, &xfont_driver);
frame->realized_font_list = device->realized_font_list;
frame->realized_face_list = device->realized_face_list;
/*** @addtogroup m17nInputMethodWin */
/*** @{ */
-
+/*=*/
/***en
@brief Input method driver for XIM.
MInputDriver minput_xim_driver =
{ xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
xim_filter, xim_lookup, NULL };
-
+/*=*/
/*** @} */
-
+/*=*/
#else /* not HAVE_X11 */
int device_open () { return -1; }