diff options
-rw-r--r-- | Build/source/texk/web2c/xetexdir/xetex-hz.ch | 7 | ||||
-rw-r--r-- | Build/source/texk/web2c/xetexdir/xetex.ch | 280 |
2 files changed, 215 insertions, 72 deletions
diff --git a/Build/source/texk/web2c/xetexdir/xetex-hz.ch b/Build/source/texk/web2c/xetexdir/xetex-hz.ch index b2951e6d216..bad79833e99 100644 --- a/Build/source/texk/web2c/xetexdir/xetex-hz.ch +++ b/Build/source/texk/web2c/xetexdir/xetex-hz.ch @@ -341,13 +341,6 @@ p, q: pointer; @z @x -@d is_native_word_node(#) == ((not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = native_word_node)) -@y -@d is_native_word_node(#) == ((not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = native_word_node)) -@d is_glyph_node(#) == ((not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = glyph_node)) -@z - -@x glue_node: @<Move right or output leaders@>; @y glue_node: @<Move right or output leaders@>; diff --git a/Build/source/texk/web2c/xetexdir/xetex.ch b/Build/source/texk/web2c/xetexdir/xetex.ch index a23ae00dad8..785166f4144 100644 --- a/Build/source/texk/web2c/xetexdir/xetex.ch +++ b/Build/source/texk/web2c/xetexdir/xetex.ch @@ -2,6 +2,7 @@ Part of the XeTeX typesetting system copyright (c) 1994-2008 by SIL International copyright (c) 2009-2012 by Jonathan Kew + copyright (c) 2012 by Khaled Hosny Written by Jonathan Kew @@ -66,8 +67,8 @@ authorization from the copyright holders. @d TeX_banner=='This is TeX, Version 3.1415926' {printed when \TeX\ starts} @# @d XeTeX_version=0 -@d XeTeX_revision==".9997" -@d XeTeX_version_string=='-0.9997.6' {current \XeTeX\ version} +@d XeTeX_revision==".9998" +@d XeTeX_version_string=='-0.9998' {current \XeTeX\ version} @# @d XeTeX_banner=='This is XeTeX, Version 3.1415926',eTeX_version_string,XeTeX_version_string {printed when \XeTeX\ starts} @@ -3778,6 +3779,7 @@ p:=list_ptr(this_box); @ Extra stuff for justifiable AAT text; need to merge runs of words and normal spaces. @d is_native_word_node(#) == ((not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = native_word_node)) +@d is_glyph_node(#) == ((not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = glyph_node)) @<Merge sequences of words using AAT fonts and inter-word spaces into single nodes@>= p := list_ptr(this_box); @@ -4132,6 +4134,15 @@ end; @z @x +@d accent_noad=over_noad+1 {|type| of a noad for accented subformulas} +@y +@d accent_noad=over_noad+1 {|type| of a noad for accented subformulas} +@d fixed_acc=1 {|subtype| for non growing math accents} +@d bottom_acc=2 {|subtype| for bottom math accents} +@d is_bottom_acc(#)==(subtype(#)=bottom_acc) or (subtype(#)=bottom_acc+fixed_acc) +@z + +@x procedure print_fam_and_char(@!p:pointer); {prints family and character} begin print_esc("fam"); print_int(fam(p)); print_char(" "); print_ASCII(qo(character(p))); @@ -4259,7 +4270,7 @@ macro capabilities. This seems a bit ugly, but it works. rval: scaled; begin f := fam_fnt(2 + size_code); - if is_ot_font(f) then + if is_ot_font(cur_f) then rval := get_native_mathsy_param(cur_f, #) else rval := mathsy(#); @@ -4308,7 +4319,7 @@ define_mathsy_accessor(axis_height)(22)(axis_height); rval: scaled; begin f := fam_fnt(3 + cur_size); - if is_ot_font(f) then + if is_ot_font(cur_f) then rval := get_native_mathex_param(cur_f, #) else rval := mathex(#); @@ -4732,7 +4743,8 @@ else if char_exists(cur_i) then end; if x<>null then begin if is_ot_font(f) then - if h<get_ot_math_constant(f, accentBaseHeight) then delta:=h@+else delta:=get_ot_math_constant(f, accentBaseHeight) + if is_bottom_acc(q) then delta:=0 + else if h<get_ot_math_constant(f, accentBaseHeight) then delta:=h@+else delta:=get_ot_math_constant(f, accentBaseHeight) else if h<x_height(f) then delta:=h@+else delta:=x_height(f); @z @@ -4740,6 +4752,9 @@ if x<>null then begin @x y:=char_box(f,c); shift_amount(y):=s+half(w-width(y)); + width(y):=0; p:=new_kern(-delta); link(p):=x; link(y):=p; + y:=vpack(y,natural); width(y):=width(x); + if height(y)<h then @<Make the height of box |y| equal to |h|@>; @y y:=char_box(f,c); if is_native_font(f) then begin @@ -4757,7 +4772,7 @@ if x<>null then begin wa:=get_ot_math_accent_pos(f,native_glyph(p)); if wa=@"7FFFFFFF then wa:=half(width(y)); p:=list_ptr(x); - if (p<>null) and (type(p)=whatsit_node) and (subtype(p)=glyph_node) and (link(p)=null) then begin + if (p<>null) and is_glyph_node(p) and (math_type(nucleus(q))=math_char) then begin w2:=get_ot_math_accent_pos(native_font(p), native_glyph(p)); if w2=@"7FFFFFFF then w:=half(w) else w:=w2; end else @@ -4765,35 +4780,49 @@ if x<>null then begin shift_amount(y):=s+w-wa; end else shift_amount(y):=s+half(w-width(y)); + width(y):=0; + if is_bottom_acc(q) then begin + link(x):=y; y:=vpack(x,natural); shift_amount(y):=-(h - height(y)); + end else begin + p:=new_kern(-delta); link(p):=x; link(y):=p; y:=vpack(y,natural); + if height(y)<h then @<Make the height of box |y| equal to |h|@>; + end; + width(y):=width(x); @z @x @ @<Switch to a larger accent if available and appropriate@>= @y @ @<Switch to a larger native-font accent if available and appropriate@>= - c:=native_glyph(p); - a:=0; - repeat - g:=get_ot_math_variant(f, c, a, addressof(w2), 1); - if (w2>0) and (w2<=w) then begin - native_glyph(p):=g; + if odd(subtype(q)) then {non growing accent} + set_native_glyph_metrics(p, 1) + else begin + c:=native_glyph(p); + a:=0; + repeat + g:=get_ot_math_variant(f, c, a, addressof(w2), 1); + if (w2>0) and (w2<=w) then begin + native_glyph(p):=g; + set_native_glyph_metrics(p, 1); + incr(a); + end; + until (w2<0) or (w2>=w); + 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, w, 1); + list_ptr(y):=p; + goto found; + end; + end else set_native_glyph_metrics(p, 1); - incr(a); - end; - until (w2<0) or (w2>=w); - 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, w, 1); - list_ptr(y):=p; - goto found; - end; - end else - set_native_glyph_metrics(p, 1); + end; found: width(y):=width(p); height(y):=height(p); depth(y):=depth(p); - if depth(y)<0 then depth(y):=0; + if is_bottom_acc(q) then begin + if height(y)<0 then height(y):=0 + end else if depth(y)<0 then depth(y):=0; @ @<Switch to a larger accent if available and appropriate@>= @z @@ -4877,6 +4906,7 @@ var delta:scaled; {offset between subscript and superscript} @!h1,@!h2:scaled; {height of original text-style symbol and possible replacement} @!n,@!g:integer; {potential variant index and glyph code} @!ot_assembly_ptr:void_pointer; +@!save_f:internal_font_number; begin if (subtype(q)=normal)and(cur_style<text_style) then subtype(q):=limits; delta:=0; @@ -4894,7 +4924,7 @@ if math_type(nucleus(q))=math_char then x:=clean_box(nucleus(q),cur_style); if is_ot_font(cur_f) then begin p:=list_ptr(x); - if (type(p)=whatsit_node) and (subtype(p)=glyph_node) then begin + if is_glyph_node(p) then begin if cur_style<text_style then begin {try to replace the operator glyph with a display-size variant, ensuring it is larger than the text size} @@ -4934,6 +4964,7 @@ found: {center vertically} math_type(nucleus(q)):=sub_box; info(nucleus(q)):=x; end; +save_f:=cur_f; if subtype(q)=limits then @<Construct a box with limits above and below it, skewed by |delta|@>; make_op:=delta; @@ -4941,6 +4972,13 @@ end; @z @x +@<Attach the limits to |y| and adjust |height(v)|, |depth(v)|...@>= +@y +@<Attach the limits to |y| and adjust |height(v)|, |depth(v)|...@>= +cur_f:=save_f; +@z + +@x character(nucleus(r)):=rem_byte(cur_i); fam(nucleus(r)):=fam(nucleus(q));@/ @y @@ -4987,6 +5025,78 @@ var p,@!x,@!y,@!z:pointer; {temporary registers for box construction} @!t:small_number; {subsidiary size code} begin p:=new_hlist(q); if is_char_node(p) then + begin shift_up:=0; shift_down:=0; + end +else begin z:=hpack(p,natural); + if cur_style<script_style then t:=script_size@+else t:=script_script_size; + shift_up:=height(z)-sup_drop(t); + shift_down:=depth(z)+sub_drop(t); + free_node(z,box_node_size); + end; +if math_type(supscr(q))=empty then + @<Construct a subscript box |x| when there is no superscript@> +else begin @<Construct a superscript box |x|@>; + if math_type(subscr(q))=empty then shift_amount(x):=-shift_up + else @<Construct a sub/superscript combination box |x|, with the + superscript offset by |delta|@>; + end; +if new_hlist(q)=null then new_hlist(q):=x +else begin p:=new_hlist(q); + while link(p)<>null do p:=link(p); + link(p):=x; + end; +end; + +@ When there is a subscript without a superscript, the top of the subscript +should not exceed the baseline plus four-fifths of the x-height. + +@<Construct a subscript box |x| when there is no superscript@>= +begin x:=clean_box(subscr(q),sub_style(cur_style)); +width(x):=width(x)+script_space; +if shift_down<sub1(cur_size) then shift_down:=sub1(cur_size); +clr:=height(x)-(abs(math_x_height(cur_size)*4) div 5); +if shift_down<clr then shift_down:=clr; +shift_amount(x):=shift_down; +end + +@ The bottom of a superscript should never descend below the baseline plus +one-fourth of the x-height. + +@<Construct a superscript box |x|@>= +begin x:=clean_box(supscr(q),sup_style(cur_style)); +width(x):=width(x)+script_space; +if odd(cur_style) then clr:=sup3(cur_size) +else if cur_style<text_style then clr:=sup1(cur_size) +else clr:=sup2(cur_size); +if shift_up<clr then shift_up:=clr; +clr:=depth(x)+(abs(math_x_height(cur_size)) div 4); +if shift_up<clr then shift_up:=clr; +end + +@ When both subscript and superscript are present, the subscript must be +separated from the superscript by at least four times |default_rule_thickness|. +If this condition would be violated, the subscript moves down, after which +both subscript and superscript move up so that the bottom of the superscript +is at least as high as the baseline plus four-fifths of the x-height. + +@<Construct a sub/superscript combination box |x|...@>= +begin y:=clean_box(subscr(q),sub_style(cur_style)); +width(y):=width(y)+script_space; +if shift_down<sub2(cur_size) then shift_down:=sub2(cur_size); +clr:=4*default_rule_thickness- + ((shift_up-depth(x))-(height(y)-shift_down)); +if clr>0 then + begin shift_down:=shift_down+clr; + clr:=(abs(math_x_height(cur_size)*4) div 5)-(shift_up-depth(x)); + if clr>0 then + begin shift_up:=shift_up+clr; + shift_down:=shift_down-clr; + end; + end; +shift_amount(x):=delta; {superscript is |delta| to the right of the subscript} +p:=new_kern((shift_up-depth(x))-(height(y)-shift_down)); link(x):=p; link(p):=y; +x:=vpack(x,natural); shift_amount(x):=shift_down; +end @y @ The purpose of |make_scripts(q,delta)| is to attach the subscript and/or superscript of noad |q| to the list that starts at |new_hlist(q)|, @@ -5001,46 +5111,80 @@ procedure make_scripts(@!q:pointer;@!delta:scaled); var p,@!x,@!y,@!z:pointer; {temporary registers for box construction} @!shift_up,@!shift_down,@!clr:scaled; {dimensions in the calculation} @!t:integer; {subsidiary size code} +@!save_f:internal_font_number; begin p:=new_hlist(q); -if is_char_node(p) or (p<>null and is_native_word_node(p)) then -@z +if is_char_node(p) or (p<>null and is_glyph_node(p)) then + begin shift_up:=0; shift_down:=0; + end +else begin z:=hpack(p,natural); + if cur_style<script_style then t:=script_size@+else t:=script_script_size; + shift_up:=height(z)-sup_drop(t); + shift_down:=depth(z)+sub_drop(t); + free_node(z,box_node_size); + end; +if math_type(supscr(q))=empty then + @<Construct a subscript box |x| when there is no superscript@> +else begin @<Construct a superscript box |x|@>; + if math_type(subscr(q))=empty then shift_amount(x):=-shift_up + else @<Construct a sub/superscript combination box |x|, with the + superscript offset by |delta|@>; + end; +if new_hlist(q)=null then new_hlist(q):=x +else begin p:=new_hlist(q); + while link(p)<>null do p:=link(p); + link(p):=x; + end; +end; -@x -clr:=height(x)-(abs(math_x_height(cur_size)*4) div 5); -@y +@ When there is a subscript without a superscript, the top of the subscript +should not exceed the baseline plus four-fifths of the x-height. + +@<Construct a subscript box |x| when there is no superscript@>= +begin +save_f:=cur_f; +x:=clean_box(subscr(q),sub_style(cur_style)); +cur_f:=save_f; +width(x):=width(x)+script_space; +if shift_down<sub1(cur_size) then shift_down:=sub1(cur_size); if is_ot_font(cur_f) then clr:=height(x)-get_ot_math_constant(cur_f, subscriptTopMax) else clr:=height(x)-(abs(math_x_height(cur_size)*4) div 5); -@z +if shift_down<clr then shift_down:=clr; +shift_amount(x):=shift_down; +end -@x -clr:=depth(x)+(abs(math_x_height(cur_size)) div 4); -@y +@ The bottom of a superscript should never descend below the baseline plus +one-fourth of the x-height. + +@<Construct a superscript box |x|@>= +begin +save_f:=cur_f; +x:=clean_box(supscr(q),sup_style(cur_style)); +cur_f:=save_f; +width(x):=width(x)+script_space; +if odd(cur_style) then clr:=sup3(cur_size) +else if cur_style<text_style then clr:=sup1(cur_size) +else clr:=sup2(cur_size); +if shift_up<clr then shift_up:=clr; if is_ot_font(cur_f) then clr:=depth(x)+get_ot_math_constant(cur_f, superscriptBottomMin) else clr:=depth(x)+(abs(math_x_height(cur_size)) div 4); -@z +if shift_up<clr then shift_up:=clr; +end + +@ When both subscript and superscript are present, the subscript must be +separated from the superscript by at least four times |default_rule_thickness|. +If this condition would be violated, the subscript moves down, after which +both subscript and superscript move up so that the bottom of the superscript +is at least as high as the baseline plus four-fifths of the x-height. -@x -@<Construct a sub/superscript combination box |x|...@>= -begin y:=clean_box(subscr(q),sub_style(cur_style)); -width(y):=width(y)+script_space; -if shift_down<sub2(cur_size) then shift_down:=sub2(cur_size); -clr:=4*default_rule_thickness- - ((shift_up-depth(x))-(height(y)-shift_down)); -if clr>0 then - begin shift_down:=shift_down+clr; - clr:=(abs(math_x_height(cur_size)*4) div 5)-(shift_up-depth(x)); - if clr>0 then - begin shift_up:=shift_up+clr; - shift_down:=shift_down-clr; - end; - end; -@y @<Construct a sub/superscript combination box |x|...@>= -begin y:=clean_box(subscr(q),sub_style(cur_style)); +begin +save_f:=cur_f; +y:=clean_box(subscr(q),sub_style(cur_style)); +cur_f:=save_f; width(y):=width(y)+script_space; if shift_down<sub2(cur_size) then shift_down:=sub2(cur_size); if is_ot_font(cur_f) then @@ -5058,6 +5202,10 @@ if clr>0 then shift_down:=shift_down-clr; end; end; +shift_amount(x):=delta; {superscript is |delta| to the right of the subscript} +p:=new_kern((shift_up-depth(x))-(height(y)-shift_down)); link(x):=p; link(p):=y; +x:=vpack(x,natural); shift_amount(x):=shift_down; +end @z @x @@ -5243,7 +5391,7 @@ max_hyph_char:=too_big_lang; @x @<Skip to node |hb|, putting letters into |hu| and |hc|@>; @y -if (not is_char_node(ha)) and (type(ha) = whatsit_node) and (subtype(ha) = native_word_node) then begin +if is_native_word_node(ha) then begin @<Check that nodes after |native_word| permit hyphenation; if not, |goto done1|@>; @<Prepare a |native_word_node| for hyphenation@>; end else begin @@ -5379,7 +5527,7 @@ if hyf_char>biggest_char then goto done1; @<Replace nodes |ha..hb| by a sequence of nodes...@>= @y @<Replace nodes |ha..hb| by a sequence of nodes...@>= -if (not is_char_node(ha)) and (type(ha) = whatsit_node) and (subtype(ha) = native_word_node) then begin +if is_native_word_node(ha) then begin @<Hyphenate the |native_word_node| at |ha|@>; end else begin @z @@ -5865,9 +6013,7 @@ collected: repeat if main_h = 0 then main_h := main_k; - if (not is_char_node(main_pp)) - and (type(main_pp)=whatsit_node) - and (subtype(main_pp)=native_word_node) + if is_native_word_node(main_pp) and (native_font(main_pp)=main_f) and (main_ppp<>main_pp) and (not is_char_node(main_ppp)) @@ -5940,9 +6086,7 @@ collected: end; if main_ppp<>main_pp then main_ppp:=link(main_ppp); end; - if (not is_char_node(main_pp)) - and (type(main_pp)=whatsit_node) - and (subtype(main_pp)=native_word_node) + if is_native_word_node(main_pp) and (native_font(main_pp)=main_f) and (main_ppp<>main_pp) and (not is_char_node(main_ppp)) @@ -6351,6 +6495,14 @@ if (cur_val>=var_code)and fam_in_range then fam(accent_chr(tail)):=cur_fam else fam(accent_chr(tail)):=(cur_val div 256) mod 16; @y if cur_chr=1 then begin + if scan_keyword("fixed") then + subtype(tail):=fixed_acc + else if scan_keyword("bottom") then begin + if scan_keyword("fixed") then + subtype(tail):=bottom_acc+fixed_acc + else + subtype(tail):=bottom_acc; + end; scan_math_class_int; c := set_class_field(cur_val); scan_math_fam_int; c := c + set_family_field(cur_val); scan_usv_num; cur_val := cur_val + c; @@ -7373,9 +7525,7 @@ begin end else if (type(pp) = disc_node) then begin ppp := link(pp); - if (ppp <> null) and (not is_char_node(ppp)) - and (type(ppp) = whatsit_node) - and (subtype(ppp) = native_word_node) + if (ppp <> null) and is_native_word_node(ppp) and (native_font(ppp) = native_font(p)) then begin pp := link(ppp); goto restart; |