diff options
Diffstat (limited to 'Build/source/texk/web2c/xetexdir/xetex-new.ch')
-rw-r--r-- | Build/source/texk/web2c/xetexdir/xetex-new.ch | 432 |
1 files changed, 243 insertions, 189 deletions
diff --git a/Build/source/texk/web2c/xetexdir/xetex-new.ch b/Build/source/texk/web2c/xetexdir/xetex-new.ch index 7f76fbdcd6b..66cc3f57c14 100644 --- a/Build/source/texk/web2c/xetexdir/xetex-new.ch +++ b/Build/source/texk/web2c/xetexdir/xetex-new.ch @@ -55,8 +55,8 @@ @d eTeX_version_string=='-2.2' {current \eTeX\ version} @d XeTeX_version=0 -@d XeTeX_revision==".995" -@d XeTeX_version_string=='-0.995' {current \eTeX\ version} +@d XeTeX_revision==".996" +@d XeTeX_version_string=='-0.996' {current \XeTeX\ version} @z @x @@ -1164,14 +1164,6 @@ else begin print_esc("scriptscriptfont"); @d saving_hyph_codes==int_par(saving_hyph_codes_code) @d XeTeX_linebreak_locale==int_par(XeTeX_linebreak_locale_code) @d XeTeX_linebreak_penalty==int_par(XeTeX_linebreak_penalty_code) - -@ @<Global...@>= -xetex_del_code_base:integer; { a hack, because WEB defined constants don't make it through to C } - -@ @<Set init...@>= -xetex_del_code_base:=del_code_base; - -@ New sections slipped in above here. @z @x @@ -1197,7 +1189,6 @@ del_code("."):=0; {this null delimiter is used in error recovery} @y for k:=0 to number_chars-1 do del_code(k):=-1; del_code("."):=0; {this null delimiter is used in error recovery} -set_del_code1(".",0); @z @x @@ -1295,6 +1286,13 @@ else begin k:=str_start_macro(s); l:=str_start_macro(s+1)-k; @z @x +primitive("delimiter",delim_num,0);@/ +@y +primitive("delimiter",delim_num,0);@/ +primitive("XeTeXdelimiter",delim_num,1);@/ +@z + +@x primitive("mathaccent",math_accent,0);@/ @y primitive("mathaccent",math_accent,0);@/ @@ -1306,18 +1304,32 @@ primitive("mathchar",math_char_num,0);@/ @!@:math_char_}{\.{\\mathchar} primitive@> @y primitive("mathchar",math_char_num,0);@/ -primitive("XeTeXmathchar",math_char_num,1);@/ -primitive("XeTeXextmathchar",math_char_num,2);@/ +primitive("XeTeXmathcharnum",math_char_num,1);@/ +primitive("XeTeXmathchar",math_char_num,2);@/ @!@:math_char_}{\.{\\mathchar} primitive@> @z @x +primitive("radical",radical,0);@/ +@y +primitive("radical",radical,0);@/ +primitive("XeTeXradical",radical,1);@/ +@z + +@x primitive("relax",relax,256); {cf.\ |scan_file_name|} @y primitive("relax",relax,too_big_char); {cf.\ |scan_file_name|} @z @x +delim_num: print_esc("delimiter"); +@y +delim_num: if chr_code=1 then print_esc("XeTeXdelimiter") + else print_esc("delimiter"); +@z + +@x end_cs_name: if chr_code = 10 then print_esc("endmubyte") else print_esc("endcsname"); @y @@ -1334,20 +1346,27 @@ math_accent: if chr_code=1 then print_esc("XeTeXmathaccent") @x math_char_num: print_esc("mathchar"); @y -math_char_num: if chr_code=2 then print_esc("XeTeXextmathchar") - else if chr_code=1 then print_esc("XeTeXmathchar") +math_char_num: if chr_code=2 then print_esc("XeTeXmathchar") + else if chr_code=1 then print_esc("XeTeXmathcharnum") else print_esc("mathchar"); @z @x +radical: print_esc("radical"); +@y +radical: if chr_code=1 then print_esc("XeTeXradical") else print_esc("radical"); +@z + +@x @* \[19] Saving and restoring equivalents. @y @* \[19] Saving and restoring equivalents. @z -@x +-- based on Omega; not needed with new xetex delimiter coding + x @ The |eq_define| and |eq_word_define| routines take care of local definitions. -@y + y @# procedure eq_word_define1(@!p:pointer;@!w:integer); label exit; @@ -1364,11 +1383,11 @@ assign_trace(p,"into")@;@/ exit:end; @ The |eq_define| and |eq_word_define| routines take care of local definitions. -@z + z -@x + x @ Subroutine |save_for_after| puts a token on the stack for save-keeping. -@y + y @# procedure geq_word_define1(@!p:pointer;@!w:integer); {global |eq_word_define1|} begin assign_trace(p,"globally changing")@;@/ @@ -1378,7 +1397,7 @@ assign_trace(p,"into")@;@/ end; @ Subroutine |save_for_after| puts a token on the stack for save-keeping. -@z + z @x @* \[20] Token lists. @@ -1724,17 +1743,21 @@ XeTeX_def_code: begin scan_char_num; if m=math_code_base then begin - cur_val1:=ho(math_code(cur_val)); - scanned_result(cur_val1)(int_val) + scanned_result(ho(math_code(cur_val)))(int_val) end else if m=math_code_base+1 then begin - print_err("Can't use \XeTeXextmathcode as a number"); - help2("\XeTeXextmathcode is for setting a mathcode from separate values;")@/ - ("use \XeTeXmathcode to access them as single values."); error; + print_err("Can't use \XeTeXmathcode as a number"); + help2("\XeTeXmathcode is for setting a mathcode from separate values;")@/ + ("use \XeTeXmathcodenum to access them as single values."); error; scanned_result(0)(int_val) end - else begin - scanned_result(-1)(int_val); { FIXME - XeTeXdelcode } + else if m=del_code_base then begin + scanned_result(ho(del_code(cur_val)))(int_val) + end else begin + print_err("Can't use \XeTeXdelcode as a number"); + help2("\XeTeXdelcode is for setting a delcode from separate values;")@/ + ("use \XeTeXdelcodenum to access them as single values."); error; + scanned_result(0)(int_val); end; end; @z @@ -1749,7 +1772,7 @@ if m=math_code_base then begin cur_val1:=ho(math_code(cur_val)); if is_active_math_char(cur_val1) then cur_val1:=@"8000 - else if (math_class_field(cur_val1)>8) or + else if (math_class_field(cur_val1)>7) or (math_fam_field(cur_val1)>15) or (math_char_field(cur_val1)>255) then begin print_err("Extended mathchar used as mathchar"); @@ -1764,30 +1787,14 @@ if m=math_code_base then begin end else if m=del_code_base then begin cur_val1:=del_code(cur_val); - if (math_class_field(cur_val1) > 8) or - (math_fam_field(cur_val1) > 15) or - (math_char_field(cur_val1) > 255) then begin + if cur_val1>=@"40000000 then begin print_err("Extended delcode used as delcode"); @.Bad delcode@> help2("A delimiter code must be between 0 and ""7FFFFFF.")@/ ("I changed this one to zero."); error; scanned_result(0)(int_val); end else begin - cur_val1:=del_code1(cur_val); - if (math_class_field(cur_val1) > 0) or - (math_fam_field(cur_val1) > 15) or - (math_char_field(cur_val1) > 255) then begin - print_err("Extended delcode used as delcode"); - help2("A delimiter code must be between 0 and ""7FFFFFF.")@/ - ("I changed this one to zero."); error; - scanned_result(0)(int_val); - end else begin - scanned_result(((math_class_field(del_code(cur_val))*@"1000) + - (math_fam_field(del_code(cur_val))*@"100) + - math_char_field(del_code(cur_val)))*@"1000 + - (math_fam_field(cur_val1)*@"100) + - math_char_field(cur_val1))(int_val); - end + scanned_result(cur_val1)(int_val); end end @z @@ -1798,7 +1805,7 @@ end @# @d XeTeX_int=eTeX_int+8 {first of \XeTeX\ codes for integers} @# -@d eTeX_dim=XeTeX_int+27 {first of \eTeX\ codes for dimensions} +@d eTeX_dim=XeTeX_int+29 {first of \eTeX\ codes for dimensions} {changed for \XeTeX\ to make room for \XeTeX\ integers} @z @@ -1886,41 +1893,6 @@ end; procedure scan_four_bit_int; @z - x -procedure scan_fifteen_bit_int; -begin scan_int; -if (cur_val<0)or(cur_val>@'77777) then - begin print_err("Bad mathchar"); -@.Bad mathchar@> - help2("A mathchar number must be between 0 and 32767.")@/ - ("I changed this one to zero."); int_error(cur_val); cur_val:=0; - end; -end; - y -procedure scan_real_fifteen_bit_int; -begin scan_int; -if (cur_val<0)or(cur_val>@'77777) then - begin print_err("Bad mathchar"); -@.Bad mathchar@> - help2("A mathchar number must be between 0 and 32767.")@/ - ("I changed this one to zero."); int_error(cur_val); cur_val:=0; - end; -end; - -procedure scan_fifteen_bit_int; { scans a \mathchar value and expands it to 32-bit form } -begin scan_int; -if (cur_val<0)or(cur_val>@'77777) then - begin print_err("Bad mathchar"); -@.Bad mathchar@> - help2("A mathchar number must be between 0 and 32767.")@/ - ("I changed this one to zero."); int_error(cur_val); cur_val:=0; - end; -cur_val := set_class_field(cur_val div @"1000) + - set_family_field((cur_val mod @"1000) div @"100) + - (cur_val mod @"100); -end; - z - @x procedure scan_twenty_seven_bit_int; begin scan_int; @@ -1940,32 +1912,9 @@ if (cur_val<0)or(cur_val>@'777777777) then help2("A numeric delimiter code must be between 0 and 2^{27}-1.")@/ ("I changed this one to zero."); int_error(cur_val); cur_val:=0; end; -cur_val1 := set_family_field((cur_val mod @"1000) div @"100) + - (cur_val mod @"100); -cur_val := cur_val div @"1000; -cur_val := set_family_field((cur_val mod @"1000) div @"100) + - set_class_field(cur_val div @"1000) + - (cur_val mod @"100); end; @z -procedure scan_twenty_seven_bit_int; -begin scan_int; -if (cur_val<0)or(cur_val>@'777777777) then - begin print_err("Bad delimiter code"); -@.Bad delimiter code@> - help2("A numeric delimiter code must be between 0 and 2^{27}-1.")@/ - ("I changed this one to zero."); int_error(cur_val); cur_val:=0; - end; -cur_val1 := (((cur_val mod @"1000) div @"100) * @"10000) + - (cur_val mod @"100); -cur_val := cur_val div @"1000; -cur_val := ((cur_val div @"1000) * @"1000000) + - (((cur_val mod @"1000) div @"100) * @"10000) + - (cur_val mod @"100); -end; - z - @x if cur_val>255 then @y @@ -2025,8 +1974,9 @@ end; @d XeTeX_variation_name_code=7 { must match codes in xetexmac.c } @d XeTeX_feature_name_code=8 @d XeTeX_selector_name_code=9 +@d XeTeX_glyph_name_code=10 -@d etex_convert_codes=XeTeX_selector_name_code+1 {end of \eTeX's command codes} +@d etex_convert_codes=XeTeX_glyph_name_code+1 {end of \eTeX's command codes} @z @x @@ -4117,11 +4067,11 @@ math_char_num: begin scan_fifteen_bit_int; c:=cur_val; end; @y math_char_num: - if cur_chr = 2 then begin { \XeTeXextmathchar } + if cur_chr = 2 then begin { \XeTeXmathchar } scan_math_class_int; c := set_class_field(cur_val); scan_math_fam_int; c := c + set_family_field(cur_val); scan_usv_num; c := c + cur_val; - end else if cur_chr = 1 then begin { \XeTeXmathchar } + end else if cur_chr = 1 then begin { \XeTeXmathcharnum } scan_xetex_math_char_int; c := cur_val; end else begin scan_fifteen_bit_int; c := set_class_field(cur_val div @"1000) + @@ -4141,8 +4091,17 @@ math_given: begin end; XeTeX_math_given: c:=cur_chr; delim_num: begin - scan_delimiter_int; - c := cur_val; {cur_val is the 'small' delimiter mathchar value} + if cur_chr=1 then begin {\XeTeXdelimiter <cls> <fam> <usv>} + scan_math_class_int; c := set_class_field(cur_val); + scan_math_fam_int; c := c + set_family_field(cur_val); + scan_usv_num; c := c + cur_val; + end else begin {\delimiter <27-bit delcode>} + scan_delimiter_int; + c := cur_val div @'10000; {get the 'small' delimiter field} + c := set_class_field(c div @"1000) + + set_family_field((c mod @"1000) div @"100) + + (c mod @"100); {and convert it to a xetex mathchar code} + end; @z @x @@ -4160,12 +4119,12 @@ plane_and_fam_field(p) := plane_and_fam_field(p) + (math_char_field(c) div @"100 mmode+math_char_num: begin scan_fifteen_bit_int; set_math_char(cur_val); end; @y -mmode+math_char_num: if cur_chr = 2 then begin { \XeTeXextmathchar } +mmode+math_char_num: if cur_chr = 2 then begin { \XeTeXmathchar } scan_math_class_int; t := set_class_field(cur_val); scan_math_fam_int; t := t + set_family_field(cur_val); scan_usv_num; t := t + cur_val; set_math_char(t); - end else if cur_chr = 1 then begin { \XeTeXmathchar } + end else if cur_chr = 1 then begin { \XeTeXmathcharnum } scan_xetex_math_char_int; set_math_char(cur_val); end else begin scan_fifteen_bit_int; set_math_char(set_class_field(cur_val div @"1000) + @@ -4186,8 +4145,18 @@ mmode+math_given: begin end; mmode+XeTeX_math_given: set_math_char(cur_chr); mmode+delim_num: begin - scan_delimiter_int; - set_math_char(cur_val); + if cur_chr=1 then begin {\XeTeXdelimiter} + scan_math_class_int; t := set_class_field(cur_val); + scan_math_fam_int; t := t + set_family_field(cur_val); + scan_usv_num; t := t + cur_val; + set_math_char(t); + end else begin + scan_delimiter_int; + cur_val:=cur_val div @'10000; {discard the large delimiter code} + set_math_char(set_class_field(cur_val div @"1000) + + set_family_field((cur_val mod @"1000) div @"100) + + (cur_val mod @"100)); + end; @z @x @@ -4226,7 +4195,15 @@ procedure scan_delimiter(@!p:pointer;@!r:boolean); begin if r then scan_twenty_seven_bit_int @y procedure scan_delimiter(@!p:pointer;@!r:boolean); -begin if r then scan_delimiter_int +begin + if r then begin + if cur_chr=1 then begin {\XeTeXradical} + cur_val1 := @"40000000; {extended delcode flag} + scan_math_fam_int; cur_val1 := cur_val1 + cur_val * @"200000; + scan_usv_num; cur_val := cur_val1 + cur_val; + end else {\radical} + scan_delimiter_int; + end @z @x @@ -4235,10 +4212,15 @@ begin if r then scan_delimiter_int othercases cur_val:=-1 @y letter,other_char: begin - cur_val:=del_code(cur_chr); cur_val1:=del_code1(cur_chr); + cur_val:=del_code(cur_chr); end; - delim_num: scan_delimiter_int; - othercases begin cur_val:=-1; cur_val1:=-1; end; + delim_num: if cur_chr=1 then begin {\XeTeXdelimiter} + cur_val1 := @"40000000; {extended delcode flag} + scan_math_class_int; {discarded} + scan_math_fam_int; cur_val1 := cur_val1 + cur_val * @"200000; + scan_usv_num; cur_val := cur_val1 + cur_val; + end else scan_delimiter_int; {normal \delimiter} + othercases begin cur_val:=-1; end; @z @x @@ -4251,12 +4233,19 @@ large_char(p):=qi(cur_val mod 256); @y if cur_val<0 then begin @<Report that an invalid delimiter code is being changed to null; set~|cur_val:=0|@>; - cur_val1:=0; end; -small_plane_and_fam_field(p) := (math_char_field(cur_val) div @"10000) * @"100 + math_fam_field(cur_val); -small_char_field(p) := cur_val mod @"10000; -large_plane_and_fam_field(p) := (math_char_field(cur_val1) div @"10000) * @"100 + math_fam_field(cur_val1); -large_char_field(p) := cur_val1 mod @"10000; +if cur_val>=@"40000000 then begin {extended delcode, only one size} + small_plane_and_fam_field(p) := ((cur_val mod @"200000) div @"10000) * @"100 {plane} + + (cur_val div @"200000) mod @"100; {family} + small_char_field(p) := qi(cur_val mod @"10000); + large_plane_and_fam_field(p) := 0; + large_char_field(p) := 0; +end else begin {standard delcode, 4-bit families and 8-bit char codes} + small_plane_and_fam_field(p) := (cur_val div @'4000000) mod 16; + small_char_field(p) := qi((cur_val div @'10000) mod 256); + large_plane_and_fam_field(p) := (cur_val div 256) mod 16; + large_char_field(p) := qi(cur_val mod 256); +end; @z @x @@ -4328,8 +4317,8 @@ any_mode(XeTeX_def_code), @d mu_skip_def_code=5 {|shorthand_def| for \.{\\muskipdef}} @d toks_def_code=6 {|shorthand_def| for \.{\\toksdef}} @d char_sub_def_code=7 {|shorthand_def| for \.{\\charsubdef}} -@d XeTeX_math_char_def_code=8 -@d XeTeX_ext_math_char_def_code=9 +@d XeTeX_math_char_num_def_code=8 +@d XeTeX_math_char_def_code=9 @z @x @@ -4337,8 +4326,8 @@ primitive("mathchardef",shorthand_def,math_char_def_code);@/ @!@:math_char_def_}{\.{\\mathchardef} primitive@> @y primitive("mathchardef",shorthand_def,math_char_def_code);@/ +primitive("XeTeXmathcharnumdef",shorthand_def,XeTeX_math_char_num_def_code);@/ primitive("XeTeXmathchardef",shorthand_def,XeTeX_math_char_def_code);@/ -primitive("XeTeXextmathchardef",shorthand_def,XeTeX_ext_math_char_def_code);@/ @!@:math_char_def_}{\.{\\mathchardef} primitive@> @z @@ -4347,7 +4336,7 @@ primitive("XeTeXextmathchardef",shorthand_def,XeTeX_ext_math_char_def_code);@/ @y math_char_def_code: print_esc("mathchardef"); XeTeX_math_char_def_code: print_esc("XeTeXmathchardef"); - XeTeX_ext_math_char_def_code: print_esc("XeTeXextmathchardef"); + XeTeX_math_char_num_def_code: print_esc("XeTeXmathcharnumdef"); @z @x @@ -4378,10 +4367,10 @@ else begin n:=cur_chr; get_r_token; p:=cur_cs; define(p,relax,too_big_char); @y math_char_def_code: begin scan_fifteen_bit_int; define(p,math_given,cur_val); end; - XeTeX_math_char_def_code: begin scan_xetex_math_char_int; + XeTeX_math_char_num_def_code: begin scan_xetex_math_char_int; define(p, XeTeX_math_given, cur_val); end; - XeTeX_ext_math_char_def_code: begin + XeTeX_math_char_def_code: begin scan_math_class_int; n := set_class_field(cur_val); scan_math_fam_int; n := n + set_family_field(cur_val); scan_usv_num; n := n + cur_val; @@ -4393,15 +4382,24 @@ else begin n:=cur_chr; get_r_token; p:=cur_cs; define(p,relax,too_big_char); primitive("mathcode",def_code,math_code_base); @y primitive("mathcode",def_code,math_code_base); -primitive("XeTeXmathcode",XeTeX_def_code,math_code_base); -primitive("XeTeXextmathcode",XeTeX_def_code,math_code_base+1); +primitive("XeTeXmathcodenum",XeTeX_def_code,math_code_base); +primitive("XeTeXmathcode",XeTeX_def_code,math_code_base+1); +@z + +@x +primitive("delcode",def_code,del_code_base); +@y +primitive("delcode",def_code,del_code_base); +primitive("XeTeXdelcodenum",XeTeX_def_code,del_code_base); +primitive("XeTeXdelcode",XeTeX_def_code,del_code_base+1); @z @x def_family: print_size(chr_code-math_font_base); @y -XeTeX_def_code: if chr_code=math_code_base then print_esc("XeTeXmathcode") - else if chr_code=math_code_base+1 then print_esc("XeTeXextmathcode") +XeTeX_def_code: if chr_code=math_code_base then print_esc("XeTeXmathcodenum") + else if chr_code=math_code_base+1 then print_esc("XeTeXmathcode") + else if chr_code=del_code_base then print_esc("XeTeXdelcodenum") else print_esc("XeTeXdelcode"); def_family: print_size(chr_code-math_font_base); @z @@ -4426,7 +4424,28 @@ XeTeX_def_code: begin scan_usv_num; n := n + cur_val; define(p,data,hi(n)); end - else do_nothing; {FIXME - XeTeXdelcode} + else if cur_chr = del_code_base then begin + p:=cur_chr; scan_char_num; + p:=p+cur_val; + scan_optional_equals; + scan_int; {scan_xetex_del_code_int; !!FIXME!!} + word_define(p,hi(cur_val)); + end else begin +{ +bit usage in delcode values: +original layout: @"00cffCFF small/LARGE family & char +extended: @"40000000 FLAG + + ff << 21 (mult by @"200000) FAMILY + + 1ccccc (21 bits) USV +} + p:=cur_chr-1; scan_char_num; + p:=p+cur_val; + scan_optional_equals; + n := @"40000000; {extended delcode flag} + scan_math_fam_int; n := n + cur_val * @"200000; + scan_usv_num; n := n + cur_val; + word_define(p,hi(n)); + end; end; def_code: begin @<Let |n| be the largest legal code value, based on |cur_chr|@>; @z @@ -4443,27 +4462,16 @@ def_code: begin @<Let |n| be the largest legal code value, based on |cur_chr|@>; if cur_val=@"8000 then cur_val:=active_math_char else cur_val:=set_class_field(cur_val div @"1000) + set_family_field((cur_val mod @"1000) div @"100) + - (cur_val mod @"100); + (cur_val mod @"100); {!!FIXME!! check how this is used} define(p,data,hi(cur_val)); end @z +-- from Omega; not needed with new xetex delimiter coding x else word_define(p,cur_val); y else begin - cur_val1:=cur_val div @"1000; - cur_val1:=(cur_val1 div @"100)*@"10000 + (cur_val1 mod @"100); - cur_val:=cur_val mod @"1000; - cur_val:=(cur_val div @"100)*@"10000 + (cur_val mod @"100); - word_define(p,cur_val); - word_define1(p,cur_val1); - end; - z -@x - else word_define(p,cur_val); -@y - else begin cur_val1 := cur_val mod @"1000; { large delim code } cur_val1 := set_family_field(cur_val1 div @"100) + cur_val1 mod @"100; cur_val := cur_val div @"1000; @@ -4473,7 +4481,7 @@ def_code: begin @<Let |n| be the largest legal code value, based on |cur_chr|@>; word_define(p, cur_val); word_define1(p, cur_val1); end; -@z + z @x else n:=255 @@ -4881,53 +4889,68 @@ begin native_word_node: begin - { merge with any following word fragments, discarding discretionary breaks } + { merge with any following word fragments in same font, discarding discretionary breaks } while (link(q) <> p) do q := link(q); { bring q up in preparation for deletion of nodes starting at p } pp := link(p); restart: - if (pp <> null) and (not is_char_node(pp)) and (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) and (native_font(ppp) = native_font(p)) then begin - pp := link(ppp); + if (pp <> null) and (not is_char_node(pp)) then begin + if (type(pp) = whatsit_node) + and (subtype(pp) = native_word_node) + and (native_font(pp) = native_font(p)) then begin + pp := link(pp); goto restart; 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) + and (native_font(ppp) = native_font(p)) then begin + pp := link(ppp); + goto restart; + end + end end; + { now pp points to the non-native_word node that ended the chain, or null } - + + { we can just check type(p)=whatsit_node below, as we know that the chain + contains only discretionaries and native_word nodes, no other whatsits or char_nodes } + if (pp <> link(p)) then begin { found a chain of at least two pieces starting at p } total_chars := 0; - p := q; + p := link(q); { the first fragment } while (p <> pp) do begin - p := link(p); { point to fragment } - total_chars := total_chars + native_length(p); { accumulate char count } - ppp := p; { remember last fragment seen } - p := link(p); { point to discretionary or other terminator } + if (type(p) = whatsit_node) then + total_chars := total_chars + native_length(p); { accumulate char count } + ppp := p; { remember last node seen } + p := link(p); { point to next fragment or discretionary or terminator } end; - - p := link(q); { the first fragment } + + p := link(q); { the first fragment again } pp := new_native_word_node(native_font(p), total_chars); { make new node for merged word } link(q) := pp; { link to preceding material } link(pp) := link(ppp); { attach remainder of hlist to it } link(ppp) := null; { and detach from the old fragments } - + { copy the chars into new node } total_chars := 0; ppp := p; repeat - for k := 0 to native_length(ppp)-1 do begin - set_native_char(pp, total_chars, get_native_char(ppp, k)); - incr(total_chars); - end; + if (type(ppp) = whatsit_node) then + for k := 0 to native_length(ppp)-1 do begin + set_native_char(pp, total_chars, get_native_char(ppp, k)); + incr(total_chars); + end; ppp := link(ppp); - if (ppp <> null) then ppp := link(ppp); { pass a disc_node } until (ppp = null); - + flush_node_list(p); { delete the fragments } p := link(q); { update p to point to the new node } set_native_metrics(p, XeTeX_use_glyph_metrics); { and measure it (i.e., re-do the OT layout) } end; - + { now incorporate the native_word node measurements into the box we're packing } if height(p) > h then h := height(p); @@ -4935,7 +4958,7 @@ begin d := depth(p); x := x + width(p); end; - + glyph_node, pic_node, pdf_node: begin if height(p) > h then @@ -4944,7 +4967,7 @@ begin d := depth(p); x := x + width(p); end; - + othercases do_nothing @@ -5244,12 +5267,7 @@ begin native_font(tail):=cur_font; native_glyph(tail):=cur_val; set_native_glyph_metrics(tail, XeTeX_use_glyph_metrics); - end else begin - print_err("Invalid use of \XeTeXglyph"); - help2("The \XeTeXglyph command can only be used with AAT or OT fonts,") - ("not TFM-based fonts. So I'm ignoring this."); - error; - end + end else not_native_font_error(extension, glyph_code, cur_font); end end @@ -5327,10 +5345,10 @@ begin { access the picture file and check its size } result := find_pic_file(address_of(pic_path), address_of(bounds), pdf_box_type, page); - setPoint(corners[0], 0.0, 0.0); - setPoint(corners[1], 0.0, htField(bounds) * 72.27 / 72.0); - setPoint(corners[2], wdField(bounds) * 72.27 / 72.0, htField(bounds) * 72.27 / 72.0); - setPoint(corners[3], wdField(bounds) * 72.27 / 72.0, 0.0); + setPoint(corners[0], xField(bounds) * 72.27 / 72.0, yField(bounds) * 72.27 / 72.0); + setPoint(corners[1], xField(corners[0]), (yField(bounds) + htField(bounds)) * 72.27 / 72.0); + setPoint(corners[2], (xField(bounds) + wdField(bounds)) * 72.27 / 72.0, yField(corners[1])); + setPoint(corners[3], xField(corners[2]), yField(corners[0])); x_size_req := 0.0; y_size_req := 0.0; @@ -5424,8 +5442,8 @@ begin pic_transform2(tail) := X2Fix(bField(t)); pic_transform3(tail) := X2Fix(cField(t)); pic_transform4(tail) := X2Fix(dField(t)); - pic_transform5(tail) := X2Fix(xField(t)); - pic_transform6(tail) := X2Fix(yField(t)); + pic_transform5(tail) := X2Fix(txField(t)); + pic_transform6(tail) := X2Fix(tyField(t)); memcpy(address_of(mem[tail + pic_node_size]), pic_path, strlen(pic_path)); libc_free(pic_path); @@ -5529,9 +5547,13 @@ end @d XeTeX_glyph_index_code=XeTeX_int+23 @d XeTeX_font_type_code=XeTeX_int+24 -@d pdf_last_x_pos_code = XeTeX_int+25 -@d pdf_last_y_pos_code = XeTeX_int+26 -{ remember to update eTeX_dim when new items are added here } +@d XeTeX_first_char_code=XeTeX_int+25 +@d XeTeX_last_char_code=XeTeX_int+26 + +@d pdf_last_x_pos_code = XeTeX_int+27 +@d pdf_last_y_pos_code = XeTeX_int+28 + +{ NB: must update eTeX_dim when items are added here! } @z @x @@ -5576,8 +5598,13 @@ primitive("XeTeXOTfeaturetag",last_item,XeTeX_OT_feature_code); primitive("XeTeXcharglyph", last_item, XeTeX_map_char_to_glyph_code); primitive("XeTeXglyphindex", last_item, XeTeX_glyph_index_code); +primitive("XeTeXglyphname",convert,XeTeX_glyph_name_code); + primitive("XeTeXfonttype", last_item, XeTeX_font_type_code); +primitive("XeTeXfirstfontchar", last_item, XeTeX_first_char_code); +primitive("XeTeXlastfontchar", last_item, XeTeX_last_char_code); + primitive("pdflastxpos",last_item,pdf_last_x_pos_code); primitive("pdflastypos",last_item,pdf_last_y_pos_code); @z @@ -5618,6 +5645,9 @@ XeTeX_glyph_index_code: print_esc("XeTeXglyphindex"); XeTeX_font_type_code: print_esc("XeTeXfonttype"); +XeTeX_first_char_code: print_esc("XeTeXfirstfontchar"); +XeTeX_last_char_code: print_esc("XeTeXlastfontchar"); + pdf_last_x_pos_code: print_esc("pdflastxpos"); pdf_last_y_pos_code: print_esc("pdflastypos"); @z @@ -5779,6 +5809,17 @@ XeTeX_font_type_code: end end; +XeTeX_first_char_code,XeTeX_last_char_code: + begin + scan_font_ident; n:=cur_val; + if is_native_font(n) then + cur_val:=get_font_char_range(n, m = XeTeX_first_char_code) + else begin + if m = XeTeX_first_char_code then cur_val:=font_bc[n] + else cur_val:=font_ec[n]; + end + end; + pdf_last_x_pos_code: cur_val := pdf_last_x_pos; pdf_last_y_pos_code: cur_val := pdf_last_y_pos; @@ -5825,6 +5866,7 @@ XeTeX_revision_code: print_esc("XeTeXrevision"); XeTeX_variation_name_code: print_esc("XeTeXvariationname"); XeTeX_feature_name_code: print_esc("XeTeXfeaturename"); XeTeX_selector_name_code: print_esc("XeTeXselectorname"); +XeTeX_glyph_name_code: print_esc("XeTeXglyphname"); @ @<Cases of `Scan the argument for command |c|'@>= eTeX_revision_code: do_nothing; @@ -5837,7 +5879,7 @@ XeTeX_feature_name_code: if is_atsu_font(fnt) then begin scan_int; arg1:=cur_val; arg2:=0; end else - not_atsu_font_error(convert, c, f); + not_atsu_font_error(convert, c, fnt); end; XeTeX_selector_name_code: @@ -5846,7 +5888,16 @@ XeTeX_selector_name_code: if is_atsu_font(fnt) then begin scan_int; arg1:=cur_val; scan_int; arg2:=cur_val; end else - not_atsu_font_error(convert, c, f); + not_atsu_font_error(convert, c, fnt); + end; + +XeTeX_glyph_name_code: + begin + scan_font_ident; fnt:=cur_val; + if is_native_font(fnt) then begin + scan_int; arg1:=cur_val; + end else + not_native_font_error(convert, c, fnt); end; @ @<Cases of `Print the result of command |c|'@>= @@ -5858,6 +5909,9 @@ XeTeX_feature_name_code, XeTeX_selector_name_code: if is_atsu_font(fnt) then atsu_print_font_name(c, font_layout_engine[fnt], arg1, arg2); + +XeTeX_glyph_name_code: + if is_native_font(fnt) then print_glyph_name(fnt, arg1); @z @x |