type xatom (* X interned atom *)
type xwin (* X window identifier *)
-type xfont (* opaque type for xft font structure *)
-type xfontpatt (* opaque type for fontconfig font pattern structure *)
+type xfont (* opaque type for custom font caching structure *)
+type xftfont (* opaque type for xft font structure *)
(* X event definitions *)
type xevent =
}
type glyph = {
- font: xfont;
+ font: xftfont;
index: int;
rune: int;
width: int;
let (font_cache : font option array) = Array.make 8 None
let glyph_cache = Hashtbl.create 127
-
-(*
-let unbox = function
-| Some v -> v
-| None -> failwith "Expected some got none"
-
-let load_match font rune i =
- Printf.printf "load_match %d %d\n" rune i;
- (match font_cache.(i) with
- | Some f -> font_unload f;
- | None -> ());
- let fmatch = (font_match font rune) in
- Array.set font_cache i (Some fmatch);
- font_glyph fmatch rune
-
-let rec get_cache_glyph font rune i =
- if i < 8 then
- match font_cache.(i) with
- | None ->
- load_match font rune i
- | Some f ->
- if font_hasglyph f rune then
- font_glyph f rune
- else
- get_cache_glyph font rune (i + 1)
- else
- load_match font rune 7
-
-let clear_font_cache () =
- print_endline "clearing cache";
- let clear_entry i f = match f with
- | Some f -> (if i > 0 then (font_unload f)); None
- | None -> None
- in Array.mapi clear_entry font_cache
-
-let rec get_font_glyph font rune =
- match font_cache.(0) with
- | None ->
- print_endline "changing root font";
- Array.set font_cache 0 (Some font);
- font_glyph font rune
- | Some f ->
- if f != font then
- (clear_font_cache (); get_font_glyph font rune)
- else
- get_cache_glyph font rune 0
-*)
-
-
-
-
let cache_update rune glyph =
Hashtbl.replace glyph_cache rune glyph;
glyph
let get_glyph (font : font) rune =
try
- let glyph = Hashtbl.find glyph_cache rune in
- if (glyph.font != font.font) then
- cache_update rune glyph
- else
- glyph
+ Hashtbl.find glyph_cache rune
with Not_found ->
cache_update rune (font_glyph font rune)
FcFontSet* set;
FcPattern* pattern;
} base;
- XftFont* cache[FontCacheSize];
+ struct {
+ XftFont* font;
+ uint32_t unicodep;
+ } cache[FontCacheSize];
int ncached;
} XFont;
Val_int(font->base.match->ascent + font->base.match->descent)));
}
-/*
-CAMLprim value x11_font_unload(value font) {
- CAMLparam1(font);
- XftFontClose(X.display, (XftFont*)Field(font,0));
- CAMLreturn(Val_unit);
-}
-
-CAMLprim value x11_font_match(value font, value rune) {
- CAMLparam2(font, rune);
-
- FcResult result;
- XftFont* xftfont = (XftFont*)Field(font,0);
-
- FcFontSet* fcsets[] = { FcFontSort(0, xftfont->pattern, 1, 0, &result) };
- FcPattern* fcpattern = FcPatternDuplicate(xftfont->pattern);
- FcCharSet* fccharset = FcCharSetCreate();
-
- FcCharSetAddChar(fccharset, rune);
- FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
- FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
- FcConfigSubstitute(0, fcpattern, FcMatchPattern);
- FcDefaultSubstitute(fcpattern);
-
- FcPattern* fcmatch = FcFontSetMatch(0, fcsets, 1, fcpattern, &result);
- XftFont* newfont = XftFontOpenPattern(X.display, fcmatch);
- //FcPatternPrint(newfont->pattern);
- fprintf(stderr,"loading match\n");
-
- FcFontSetDestroy(fcsets[0]);
- FcPatternDestroy(fcpattern);
- FcCharSetDestroy(fccharset);
- FcPatternDestroy(fcmatch);
-
- CAMLreturn( mkvariant(0, 2, newfont, Field(font,1)) );
-}
-
-CAMLprim value x11_font_hasglyph(value font, value rune) {
- CAMLparam2(font, rune);
- XftFont* xfont = (XftFont*)Field(font, 0);
- int val = XftCharIndex(X.display, xfont, Int_val(rune));
- CAMLreturn( Val_int(val > 0) );
-}
-*/
-
void get_glyph(XFont* font, XftGlyphFontSpec* spec, uint32_t rune) {
/* if the rune is in the base font, set it and return */
FT_UInt glyphidx = XftCharIndex(X.display, font->base.match, rune);
}
/* Otherwise check the cache */
for (int f = 0; f < font->ncached; f++) {
- glyphidx = XftCharIndex(X.display, font->cache[f], rune);
+ glyphidx = XftCharIndex(X.display, font->cache[f].font, rune);
/* Fond a suitable font or found a default font */
- //if (glyphidx || (!glyphidx && font->cache[f]->unicodep == rune)) {
- if (glyphidx) {
- spec->font = font->cache[f];
+ if (glyphidx || (!glyphidx && font->cache[f].unicodep == rune)) {
+ spec->font = font->cache[f].font;
spec->glyph = glyphidx;
return;
}
/* add the font to the cache and use it */
if (font->ncached >= FontCacheSize) {
font->ncached = FontCacheSize - 1;
- XftFontClose(X.display, font->cache[font->ncached]);
+ XftFontClose(X.display, font->cache[font->ncached].font);
}
- font->cache[font->ncached] = XftFontOpenPattern(X.display, fontmatch);
- spec->glyph = XftCharIndex(X.display, font->cache[font->ncached], rune);
- spec->font = font->cache[font->ncached];
+ font->cache[font->ncached].font = XftFontOpenPattern(X.display, fontmatch);
+ font->cache[font->ncached].unicodep = rune;
+ spec->glyph = XftCharIndex(X.display, font->cache[font->ncached].font, rune);
+ spec->font = font->cache[font->ncached].font;
font->ncached++;
FcPatternDestroy(fcpattern);
FcCharSetDestroy(fccharset);