Hi all, Currently XeTeX does not support extensible accents (just like TeX) which leads unicode-math to doing some ugly hacks to support \overbrace etc. The attached patch provides support for extensible accents (by adapting some commented out code and taking some inspirations from luatex implementation).
The output is nearly identical to luatex's except that luatex takes account of \delimiterfactor and \delimitershortfall when calculating the desired width of the accent, but luatex behaviour does not confirm to Office implementation nor \overbrace behaviour in plain tex, so I didn't follow it. The second patch does some cosmetic changes to better reflect the new job of build_opentype_assembly(). Both patches are to be applied after the previous ones. Regards, Khaled
--- f 2012-02-20 23:34:22.000000000 +0200
+++ xetex.ch 2012-02-20 23:34:26.000000000 +0200
@@ -4341,8 +4341,18 @@
type(p):=whatsit_node; subtype(p):=glyph_node;
native_font(p):=f; native_glyph(p):=g;
set_native_glyph_metrics(p, 1);
- link(p):=list_ptr(b); list_ptr(b):=p;
- height(b):=height(p); width(b):=width(p);
+ if type(b)=hlist_node then begin
+ q:=list_ptr(b);
+ if q=null then list_ptr(b):=p else begin
+ while link(q)<>null do q:=link(q);
+ link(q):=p;
+ if (height(b) < height(p)) then height(b):=height(p);
+ if (depth(b) < depth(p)) then depth(b):=depth(p);
+ end;
+ end else begin
+ link(p):=list_ptr(b); list_ptr(b):=p;
+ height(b):=height(p); width(b):=width(p);
+ end;
end;
procedure stack_glue_into_box(@!b:pointer;@!min,max:scaled);
@@ -4352,11 +4362,19 @@
width(q):=min;
stretch(q):=max-min;
p:=new_glue(q);
- link(p):=list_ptr(b); list_ptr(b):=p;
- height(b):=height(p); width(b):=width(p);
+ if type(b)=hlist_node then begin
+ q:=list_ptr(b);
+ if q=null then list_ptr(b):=p else begin
+ while link(q)<>null do q:=link(q);
+ link(q):=p;
+ end;
+ end else begin
+ link(p):=list_ptr(b); list_ptr(b):=p;
+ height(b):=height(p); width(b):=width(p);
+ end;
end;
-function build_opentype_assembly(@!f:internal_font_number;@!a:void_pointer;@!h:scaled):pointer;
+function build_opentype_assembly(@!f:internal_font_number;@!a:void_pointer;@!h:scaled;@!horiz:boolean):pointer;
{return a box with height at least |h|, using font |f|, with glyph assembly info from |a|}
var
b:pointer; {the box we're constructing}
@@ -4369,7 +4387,8 @@
nat,str:scaled; {natural height, stretch}
begin
b:=new_null_box;
- type(b):=vlist_node;
+ if horiz then type(b):=hlist_node
+ else type(b):=vlist_node;
{figure out how many repeats of each extender to use}
n:=-1;
@@ -4430,8 +4449,10 @@
{find natural height and total stretch of the box}
p:=list_ptr(b); nat:=0; str:=0;
while p<>null do begin
- if type(p)=whatsit_node then nat:=nat+height(p)+depth(p)
- else if type(p)=glue_node then begin
+ if type(p)=whatsit_node then begin
+ if horiz then nat:=nat+width(p)
+ else nat:=nat+height(p)+depth(p);
+ end else if type(p)=glue_node then begin
nat:=nat+width(glue_ptr(p));
str:=str+stretch(glue_ptr(p));
end;
@@ -4443,8 +4464,11 @@
if (h>nat) and (str>0) then begin
glue_order(b):=normal; glue_sign(b):=stretching;
glue_set(b):=unfloat((h-nat)/str);
- height(b):=nat+round(str*float(glue_set(b)));
- end else height(b):=nat;
+ if horiz then width(b):= nat+round(str*float(glue_set(b)))
+ else height(b):=nat+round(str*float(glue_set(b)));
+ end else
+ if horiz then width(b):=nat
+ else height(b):=nat;
build_opentype_assembly:=b;
end;
@@ -4487,7 +4511,7 @@
else begin
{for OT fonts, c is the glyph ID to use}
if ot_assembly_ptr<>nil then
- b:=build_opentype_assembly(f, ot_assembly_ptr, v)
+ b:=build_opentype_assembly(f, ot_assembly_ptr, v, 0)
else begin
b:=new_null_box; type(b):=vlist_node; list_ptr(b):=get_node(glyph_node_size);
type(list_ptr(b)):=whatsit_node; subtype(list_ptr(b)):=glyph_node;
@@ -4678,6 +4702,7 @@
@!h:scaled; {height of character being accented}
@!delta:scaled; {space to remove between accent and accentee}
@!w,@!wa,@!w2:scaled; {width of the accentee, not including sub/superscripts}
+@!ot_assembly_ptr:void_pointer;
begin fetch(accent_chr(q));
x:=null;
if is_native_font(cur_f) then
@@ -4738,19 +4763,17 @@
incr(a);
end;
until (w2<0) or (w2>=w);
-{
- |if (w2<0) then begin
+ if (w2<0) then begin
ot_assembly_ptr:=get_ot_assembly_ptr(f, c, 1);
if ot_assembly_ptr<>nil then begin
free_node(p,glyph_node_size);
- p:=build_opentype_assembly(cur_f, ot_assembly_ptr, w1);
+ p:=build_opentype_assembly(cur_f, ot_assembly_ptr, w, 1);
list_ptr(y):=p;
goto found;
end;
- end else|
-}
+ end else
set_native_glyph_metrics(p, 1);
-{found:}
+found:
width(y):=width(p); height(y):=height(p); depth(y):=depth(p);
if depth(y)<0 then depth(y):=0;
@@ -4874,7 +4897,7 @@
ot_assembly_ptr:=get_ot_assembly_ptr(cur_f, c, 0);
if ot_assembly_ptr<>nil then begin
free_node(p,glyph_node_size);
- p:=build_opentype_assembly(cur_f, ot_assembly_ptr, h1);
+ p:=build_opentype_assembly(cur_f, ot_assembly_ptr, h1, 0);
list_ptr(x):=p;
delta:=0;
goto found;
\input ifluatex.sty
\ifluatex
\input luaotfload.sty
\let\XeTeXmathaccent=\Umathaccent
\let\XeTeXmathcode=\Umathcode
\fi
\nopagenumbers
\font\xitsa="[xits-math.otf]" at 10pt \textfont0=\xitsa
\font\xitsb="[xits-math.otf]" at 7pt \scriptfont0=\xitsb
\font\xitsc="[xits-math.otf]" at 5pt \scriptscriptfont0=\xitsc
\XeTeXmathcode`x="7"0"1D465
$$
\XeTeXmathaccent "0 "0 "23DE {x}
$$
$$
\XeTeXmathaccent "0 "0 "23DE {xx}
$$
$$
\XeTeXmathaccent "0 "0 "23DE {xxx}
$$
$$
\XeTeXmathaccent "0 "0 "23DE {xxxx}
$$
$$
\XeTeXmathaccent "0 "0 "23DE {xxxxx}
$$
$$
\XeTeXmathaccent "0 "0 "23DE {xxxxxx}
$$
$$
\XeTeXmathaccent "0 "0 "23DE {xxxxxxx}
$$
$$
\XeTeXmathaccent "0 "0 "23DE {xxxxxxxx}
$$
$$
\XeTeXmathaccent "0 "0 "23DE {xxxxxxxxxxxxxxxx}
$$
\bye
accent_ext.pdf
Description: Adobe PDF document
--- ff 2012-02-21 00:18:08.000000000 +0200
+++ xetex.ch 2012-02-21 00:22:13.000000000 +0200
@@ -4374,17 +4374,17 @@
end;
end;
-function build_opentype_assembly(@!f:internal_font_number;@!a:void_pointer;@!h:scaled;@!horiz:boolean):pointer;
- {return a box with height at least |h|, using font |f|, with glyph assembly info from |a|}
+function build_opentype_assembly(@!f:internal_font_number;@!a:void_pointer;@!s:scaled;@!horiz:boolean):pointer;
+ {return a box with height/width at least |s|, using font |f|, with glyph assembly info from |a|}
var
b:pointer; {the box we're constructing}
n:integer; {the number of repetitions of each extender}
i,j:integer; {indexes}
g:integer; {glyph code}
p:pointer; {temp pointer}
- h_max,o,oo,prev_o,min_o:scaled;
+ s_max,o,oo,prev_o,min_o:scaled;
no_extenders: boolean;
- nat,str:scaled; {natural height, stretch}
+ nat,str:scaled; {natural size, stretch}
begin
b:=new_null_box;
if horiz then type(b):=hlist_node
@@ -4396,8 +4396,8 @@
min_o:=ot_min_connector_overlap(f);
repeat
n:=n+1;
- {calc max possible height with this number of extenders}
- h_max:=0;
+ {calc max possible size with this number of extenders}
+ s_max:=0;
prev_o:=0;
for i:=0 to ot_part_count(a)-1 do begin
if ot_part_is_extender(a, i) then begin
@@ -4406,18 +4406,18 @@
o:=ot_part_start_connector(f, a, i);
if min_o<o then o:=min_o;
if prev_o<o then o:=prev_o;
- h_max:=h_max-o+ot_part_full_advance(f, a, i);
+ s_max:=s_max-o+ot_part_full_advance(f, a, i);
prev_o:=ot_part_end_connector(f, a, i);
end
end else begin
o:=ot_part_start_connector(f, a, i);
if min_o<o then o:=min_o;
if prev_o<o then o:=prev_o;
- h_max:=h_max-o+ot_part_full_advance(f, a, i);
+ s_max:=s_max-o+ot_part_full_advance(f, a, i);
prev_o:=ot_part_end_connector(f, a, i);
end;
end;
- until (h_max>=h) or no_extenders;
+ until (s_max>=s) or no_extenders;
{assemble box using |n| copies of each extender,
with appropriate glue wherever an overlap occurs}
@@ -4446,7 +4446,7 @@
end;
end;
- {find natural height and total stretch of the box}
+ {find natural size and total stretch of the box}
p:=list_ptr(b); nat:=0; str:=0;
while p<>null do begin
if type(p)=whatsit_node then begin
@@ -4461,9 +4461,9 @@
{set glue so as to stretch the connections if needed}
depth(b):=0;
- if (h>nat) and (str>0) then begin
+ if (s>nat) and (str>0) then begin
glue_order(b):=normal; glue_sign(b):=stretching;
- glue_set(b):=unfloat((h-nat)/str);
+ glue_set(b):=unfloat((s-nat)/str);
if horiz then width(b):= nat+round(str*float(glue_set(b)))
else height(b):=nat+round(str*float(glue_set(b)));
end else
-------------------------------------------------- Subscriptions, Archive, and List information, etc.: http://tug.org/mailman/listinfo/xetex
