%!PS %%Version: 3.3.1 %%DocumentFonts: (atend) %%Pages: (atend) %%EndComments % % Version 3.3.1 prologue for troff files. % /#copies 1 store /aspectratio 1 def /formsperpage 1 def /landscape false def /linewidth .3 def /magnification 1 def /margin 0 def /orientation 0 def /resolution 720 def /rotation 1 def /xoffset 0 def /yoffset 0 def /roundpage true def /useclippath true def /pagebbox [0 0 612 792] def /R /Times-Roman def /I /Times-Italic def /B /Times-Bold def /BI /Times-BoldItalic def /H /Helvetica def /HI /Helvetica-Oblique def /HB /Helvetica-Bold def /HX /Helvetica-BoldOblique def /CW /Courier def /CO /Courier def /CI /Courier-Oblique def /CB /Courier-Bold def /CX /Courier-BoldOblique def /PA /Palatino-Roman def /PI /Palatino-Italic def /PB /Palatino-Bold def /PX /Palatino-BoldItalic def /Hr /Helvetica-Narrow def /Hi /Helvetica-Narrow-Oblique def /Hb /Helvetica-Narrow-Bold def /Hx /Helvetica-Narrow-BoldOblique def /KR /Bookman-Light def /KI /Bookman-LightItalic def /KB /Bookman-Demi def /KX /Bookman-DemiItalic def /AR /AvantGarde-Book def /AI /AvantGarde-BookOblique def /AB /AvantGarde-Demi def /AX /AvantGarde-DemiOblique def /NR /NewCenturySchlbk-Roman def /NI /NewCenturySchlbk-Italic def /NB /NewCenturySchlbk-Bold def /NX /NewCenturySchlbk-BoldItalic def /ZD /ZapfDingbats def /ZI /ZapfChancery-MediumItalic def /S /S def /S1 /S1 def /GR /Symbol def /inch {72 mul} bind def /min {2 copy gt {exch} if pop} bind def /setup { counttomark 2 idiv {def} repeat pop landscape {/orientation 90 orientation add def} if /scaling 72 resolution div def linewidth setlinewidth 1 setlinecap pagedimensions xcenter ycenter translate orientation rotation mul rotate width 2 div neg height 2 div translate xoffset inch yoffset inch neg translate margin 2 div dup neg translate magnification dup aspectratio mul scale scaling scaling scale addmetrics 0 0 moveto } def /pagedimensions { useclippath userdict /gotpagebbox known not and { /pagebbox [clippath pathbbox newpath] def roundpage currentdict /roundpagebbox known and {roundpagebbox} if } if pagebbox aload pop 4 -1 roll exch 4 1 roll 4 copy landscape {4 2 roll} if sub /width exch def sub /height exch def add 2 div /xcenter exch def add 2 div /ycenter exch def userdict /gotpagebbox true put } def /addmetrics { /Symbol /S null Sdefs cf /Times-Roman /S1 StandardEncoding dup length array copy S1defs cf } def /pagesetup { /page exch def currentdict /pagedict known currentdict page known and { page load pagedict exch get cvx exec } if } def /decodingdefs [ {counttomark 2 idiv {y moveto show} repeat} {neg /y exch def counttomark 2 idiv {y moveto show} repeat} {neg moveto {2 index stringwidth pop sub exch div 0 32 4 -1 roll widthshow} repeat} {neg moveto {spacewidth sub 0.0 32 4 -1 roll widthshow} repeat} {counttomark 2 idiv {y moveto show} repeat} {neg setfunnytext} ] def /setdecoding {/t decodingdefs 3 -1 roll get bind def} bind def /w {neg moveto show} bind def /m {neg dup /y exch def moveto} bind def /done {/lastpage where {pop lastpage} if} def /f { dup /font exch def findfont exch dup /ptsize exch def scaling div dup /size exch def scalefont setfont linewidth ptsize mul scaling 10 mul div setlinewidth /spacewidth ( ) stringwidth pop def } bind def /changefont { /fontheight exch def /fontslant exch def currentfont [ 1 0 fontheight ptsize div fontslant sin mul fontslant cos div fontheight ptsize div 0 0 ] makefont setfont } bind def /sf {f} bind def /cf { dup length 2 idiv /entries exch def /chtab exch def /newencoding exch def /newfont exch def findfont dup length 1 add dict /newdict exch def {1 index /FID ne {newdict 3 1 roll put}{pop pop} ifelse} forall newencoding type /arraytype eq {newdict /Encoding newencoding put} if newdict /Metrics entries dict put newdict /Metrics get begin chtab aload pop 1 1 entries {pop def} for newfont newdict definefont pop end } bind def % % A few arrays used to adjust reference points and character widths in some % of the printer resident fonts. If square roots are too high try changing % the lines describing /radical and /radicalex to, % % /radical [0 -75 550 0] % /radicalex [-50 -75 500 0] % % Move braceleftbt a bit - default PostScript character is off a bit. % /Sdefs [ /bracketlefttp [201 500] /bracketleftbt [201 500] /bracketrighttp [-81 380] /bracketrightbt [-83 380] /braceleftbt [203 490] /bracketrightex [220 -125 500 0] /radical [0 0 550 0] /radicalex [-50 0 500 0] /parenleftex [-20 -170 0 0] /integral [100 -50 500 0] /infinity [10 -75 730 0] ] def /S1defs [ /underscore [0 80 500 0] /endash [7 90 650 0] ] def % % Tries to round clipping path dimensions, as stored in array pagebbox, so they % match one of the known sizes in the papersizes array. Lower left coordinates % are always set to 0. % /roundpagebbox { 7 dict begin /papersizes [8.5 inch 11 inch 14 inch 17 inch] def /mappapersize { /val exch def /slop .5 inch def /diff slop def /j 0 def 0 1 papersizes length 1 sub { /i exch def papersizes i get val sub abs dup diff le {/diff exch def /j i def} {pop} ifelse } for diff slop lt {papersizes j get} {val} ifelse } def pagebbox 0 0 put pagebbox 1 0 put pagebbox dup 2 get mappapersize 2 exch put pagebbox dup 3 get mappapersize 3 exch put end } bind def %%EndProlog %%BeginSetup mark 10 dict dup begin /FontType 3 def /FontMatrix [1 0 0 1 0 0] def /FontBBox [1 1 0 0] def /Encoding 256 array def 0 1 255 {Encoding exch /.notdef put} for Encoding 33 /h33 put Encoding 34 /h34 put Encoding 35 /h35 put Encoding 36 /h36 put Encoding 37 /h37 put Encoding 38 /h38 put Encoding 39 /h39 put Encoding 40 /h40 put Encoding 41 /h41 put Encoding 42 /h42 put Encoding 43 /h43 put Encoding 44 /h44 put Encoding 45 /h45 put Encoding 46 /h46 put Encoding 47 /h47 put Encoding 48 /h48 put Encoding 49 /h49 put Encoding 50 /h50 put Encoding 51 /h51 put Encoding 52 /h52 put Encoding 53 /h53 put Encoding 54 /h54 put Encoding 55 /h55 put Encoding 56 /h56 put Encoding 57 /h57 put Encoding 58 /h58 put Encoding 59 /h59 put Encoding 60 /h60 put Encoding 61 /h61 put Encoding 62 /h62 put Encoding 63 /h63 put Encoding 64 /h64 put Encoding 65 /h65 put Encoding 66 /h66 put Encoding 67 /h67 put Encoding 68 /h68 put Encoding 69 /h69 put Encoding 70 /h70 put Encoding 71 /h71 put Encoding 72 /h72 put Encoding 73 /h73 put Encoding 74 /h74 put Encoding 75 /h75 put Encoding 76 /h76 put Encoding 77 /h77 put Encoding 78 /h78 put Encoding 79 /h79 put Encoding 80 /h80 put Encoding 81 /h81 put Encoding 82 /h82 put Encoding 83 /h83 put Encoding 84 /h84 put Encoding 85 /h85 put Encoding 86 /h86 put Encoding 87 /h87 put Encoding 88 /h88 put Encoding 89 /h89 put Encoding 90 /h90 put Encoding 91 /h91 put Encoding 92 /h92 put Encoding 93 /h93 put Encoding 94 /h94 put Encoding 95 /h95 put Encoding 96 /h96 put Encoding 97 /h97 put Encoding 98 /h98 put Encoding 99 /h99 put Encoding 100 /h100 put Encoding 101 /h101 put Encoding 102 /h102 put Encoding 103 /h103 put Encoding 104 /h104 put Encoding 105 /h105 put Encoding 106 /h106 put Encoding 107 /h107 put Encoding 108 /h108 put Encoding 109 /h109 put Encoding 110 /h110 put Encoding 111 /h111 put Encoding 112 /h112 put Encoding 113 /h113 put Encoding 114 /h114 put Encoding 115 /h115 put Encoding 116 /h116 put Encoding 117 /h117 put Encoding 118 /h118 put Encoding 119 /h119 put Encoding 161 /k33 put Encoding 162 /k34 put Encoding 163 /k35 put Encoding 164 /k36 put Encoding 165 /k37 put Encoding 166 /k38 put Encoding 167 /k39 put Encoding 168 /k40 put Encoding 169 /k41 put Encoding 170 /k42 put Encoding 171 /k43 put Encoding 172 /k44 put Encoding 173 /k45 put Encoding 174 /k46 put Encoding 175 /k47 put Encoding 176 /k48 put Encoding 177 /k49 put Encoding 178 /k50 put Encoding 179 /k51 put Encoding 180 /k52 put Encoding 181 /k53 put Encoding 182 /k54 put Encoding 183 /k55 put Encoding 184 /k56 put Encoding 185 /k57 put Encoding 186 /k58 put Encoding 187 /k59 put Encoding 188 /k60 put Encoding 189 /k61 put Encoding 190 /k62 put Encoding 191 /k63 put Encoding 192 /k64 put Encoding 193 /k65 put Encoding 194 /k66 put Encoding 195 /k67 put Encoding 196 /k68 put Encoding 197 /k69 put Encoding 198 /k70 put Encoding 199 /k71 put Encoding 200 /k72 put Encoding 201 /k73 put Encoding 202 /k74 put Encoding 203 /k75 put Encoding 204 /k76 put Encoding 205 /k77 put Encoding 206 /k78 put Encoding 207 /k79 put Encoding 208 /k80 put Encoding 209 /k81 put Encoding 210 /k82 put Encoding 211 /k83 put Encoding 212 /k84 put Encoding 213 /k85 put Encoding 214 /k86 put Encoding 215 /k87 put Encoding 216 /k88 put Encoding 217 /k89 put Encoding 218 /k90 put Encoding 219 /k91 put Encoding 220 /k92 put Encoding 221 /k93 put Encoding 222 /k94 put Encoding 223 /k95 put Encoding 224 /k96 put Encoding 225 /k97 put Encoding 226 /k98 put Encoding 227 /k99 put Encoding 228 /k100 put Encoding 229 /k101 put Encoding 230 /k102 put Encoding 231 /k103 put Encoding 232 /k104 put Encoding 233 /k105 put Encoding 234 /k106 put Encoding 235 /k107 put Encoding 236 /k108 put Encoding 237 /k109 put Encoding 238 /k110 put Encoding 239 /k111 put Encoding 240 /k112 put Encoding 241 /k113 put Encoding 242 /k114 put Encoding 243 /k115 put Encoding 244 /k116 put Encoding 245 /k117 put Encoding 246 /k118 put Encoding 247 /k119 put /BuildChar { 0 begin /char exch def /fontdict exch def /charname fontdict /Encoding get char get def /charinfo fontdict /CharData get charname get def 1 0 setcharwidth charinfo 5 get charinfo 6 get true fontdict /imagemaskmatrix get dup 4 charinfo 7 get put dup 5 charinfo 8 get put charinfo 9 1 getinterval cvx imagemask end } def /BuildChar load 0 6 dict put /imagemaskmatrix [24 0 0 -24 0 0] def /CharData 256 dict def CharData begin /h33 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000000000000000000400000300000300000270007fe00004000004400004400007f0001c4c003486006483004503008603008e03009a0600e20c0000700000000> ] def /h34 [1 0 0 1 1 24 24 -.5 23.5 <00c000007000006000006300107f800ffc0000c00000c40000860000860000bf8001cc6002883004981808901810a00c10c00c20c00c20c00c2140182660183c6030300060000380> ] def /h35 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000000000000000000000000000000000000000000800000403000400c00400400400600400200420300440300640300280f0038030038000018000000000000000> ] def /h36 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000002000001000001000c018002018001018001818000818000c18000c18400418400618c0060c801e0d800e0f0006070000070000030000000000000000000000> ] def /h37 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000002000001800000e00000600000000000000010e0000f30000c180000180000180000180000180000300000300000600000c00003000000000> ] def /h38 [1 0 0 1 1 24 24 -.5 23.5 <006000001c00000700000300000000000000000000001e0004710003c0800300c00000c00000c00000c00000c00000c00000c000018000018000030000060000180000e000000000> ] def /h39 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000001000000c00000700000300000000000200008f00007300004600000c0000180000300000600000d000018800038c000307f00003e0000000> ] def /h40 [1 0 0 1 1 24 24 -.5 23.5 <002000001800000e00000600000000000000000200021f0001f300018600000c0000180000300000200000400000c0000180000360000610000e10001c1800180ff80003f8000000> ] def /h41 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000000000000000000000001000000c00000c0000081c000983004f830038040008000008f0000b0c000c0600180600380601680600c80c0058f00008000000000> ] def /h42 [1 0 0 1 1 24 24 -.5 23.5 <00000003000001c00001800001806001801801980c31f80c1fc0300100000100000103c0011c7001601801800c03000c07000c4d000c7900183900381788f00387c0010000000000> ] def /h43 [1 0 0 1 1 24 24 -.5 23.5 <00000001800000c00000e00000c00000800000806001f81847860c79020633020603020702020706023f0606060c06000c0400180c00180c0031180070f800607000006000000000> ] def /h44 [1 0 0 1 1 24 24 -.5 23.5 <00000601800300c03300e01800c0180080000080c001f83047861879020c33020c03020e02020e06023e06060c0c06000c0400180c00180c0031180070f800607000006000000000> ] def /h45 [1 0 0 1 1 24 24 -.5 23.5 <01c00000c000006000006700103e000ff0000718000008e0000fc0081c0007e2000303000001800000c000f8e00307e00400600800000800000c000007000003fe0000fe00000000> ] def /h46 [1 0 0 1 1 24 24 -.5 23.5 <01c00600c003006033006718103e180ff0000718000008e0000fc0081c0007e2000303000001800000c000f8e00307e00400600800000800000c000007000003fe0000fe00000000> ] def /h47 [1 0 0 1 1 24 24 -.5 23.5 <0000800000c00001c0000380000700000e0000380000600001800006000008000008000004000003000001c000006000003000001c00000e000007000003800001800001c00000c0> ] def /h48 [1 0 0 1 1 24 24 -.5 23.5 <000100000180000386000703000e33001c1800301800600001800006000008000008000004000003000001c000006000003000001800000c00000600000700000300000380000180> ] def /h49 [1 0 0 1 1 24 24 -.5 23.5 <0000001803800c00e00c00600c00601800601800661841ff103fe01018603000603000603200603200603200603400403400c01c00c01800c0180080180180080100000200000400> ] def /h50 [1 0 0 1 1 24 24 -.5 23.5 <000006300003180e3318039818019830018030018030018c2107fe20ff80606180600180640180640180640180680100680300380300300300300200300600100400000800001000> ] def /h51 [1 0 0 1 1 24 24 -.5 23.5 <00000000000002000001f000007fc00007c0001c000060000000000000000000000000000000000000000800001000001000001000001000000c000007fff001fff0000000000000> ] def /h52 [1 0 0 1 1 24 24 -.5 23.5 <00000600000302003301f018007f98000780001c000060000000000000000000000000000000000000000800001000001000001000001000000c000007fff001fff0000000000000> ] def /h53 [1 0 0 1 1 24 24 -.5 23.5 <00e00001c00000c1800060e00031c0101f000ffc000386000003000001800000c00000e0003e6001c3f006007004002008000008000004000007000003f00000ff80000f80000000> ] def /h54 [1 0 0 1 1 24 24 -.5 23.5 <01c00603800301863300c398006718103c000ff800038c000006000003000001800001c0003cc001c7e00600e004004008000008000004000007000003f00000ff80000f80000000> ] def /h55 [1 0 0 1 1 24 24 -.5 23.5 <0600000300000380000380000380000300000300000300000300000300000300000300000300000300000200000200000200040200080200100200600103c001ff00007800000000> ] def /h56 [1 0 0 1 1 24 24 -.5 23.5 <0600000300000380000381800380c0030cc00306000306000300000300000300000300000300000300000200000200000200040200080200100200600103c001ff00007800000000> ] def /h57 [1 0 0 1 1 24 24 -.5 23.5 <001800000e00000700000600000600001ffe83fc1f7f0400300400007c00008c0001060001060001060001060000860000fe00006400000c0000080000180000100000200000c000> ] def /h58 [1 0 0 1 1 24 24 -.5 23.5 <001806000e0300073300061800061800060083fffe7f041f300400007c00008c0001060001060001060001060000860000fe00006400000c0000080000180000100000200000c000> ] def /h59 [1 0 0 1 1 24 24 -.5 23.5 <0003000001800001c006018003018003018003018003018e031fff0ff180fb0180630180030100030300031300030e0003060001000001000001800000e000007ff0001ff0000000> ] def /h60 [1 0 0 1 1 24 24 -.5 23.5 <00000600060300033306039803031803030003030003031c031ffe0ff300fb0300630300030200030600032600031c00030c0001000001000001800000e000007ff0001ff0000000> ] def /h61 [1 0 0 1 1 24 24 -.5 23.5 <00000000070001398001e380008600000c000018000030000040000081f8011ffc0666000f88003c1000302000002000004000004000004000002000003000001e00000f80000380> ] def /h62 [1 0 0 1 1 24 24 -.5 23.5 <00000000070001398601e383008633000c180018180030000040000081f8011ffc0666000f88003c1000302000002000004000004000004000002000003000001e00000f80000380> ] def /h63 [1 0 0 1 1 24 24 -.5 23.5 <00000001800000c00000c000008c0001bc0041f0007f81c033007803001c02001c0600600400000c00000c0000180000181000302000302000701000601c00000ffc0001fc000000> ] def /h64 [1 0 0 1 1 24 24 -.5 23.5 <00000601800300c03300c018008c1801bc0041f0007f81c033007803001c02001c0600600400000c00000c0000180000181000302000302000701000601c00000ffc0001fc000000> ] def /h65 [1 0 0 1 1 24 24 -.5 23.5 <01800000c00000c00000800001860021bf003fe0001980000100000100000300000303c0021c3002701802c00c07000c07000c0600180000380000700000e0000380001c00000000> ] def /h66 [1 0 0 1 1 24 24 -.5 23.5 <01800000c00000c00600800301863321bf183fe0181980000100000100000300000303c0021c3002701802c00c07000c07000c0600180000380000700000e0000380001c00000000> ] def /h67 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000000000000000000000000000000f000078c013c0600f00300400300000300000300000600000600000c0000300000c00000000000000000000> ] def /h68 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000000fc000f03003c0088f000c7c000438000600000600000600000e00000c00001c0000380000700001c0000700003800000000000000000000> ] def /h69 [1 0 0 1 1 24 24 -.5 23.5 <000006000003000033000018000018000f8000f0e003c0308f00187c001838000c00000c00000c00000c0000180000380000700000e0000380000e00007000000000000000000000> ] def /h70 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000f0001ff841f3807f06003c0c0010100000200000200000400000400000800000800000800000800000c000004000006000003800001f000007c00001c0000000> ] def /h71 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000e0001ff041f3807f06063c0c0310103300201800201800400000400000800000800000800000800000c000004000006000003800001f000007c00001c0000000> ] def /h72 [1 0 0 1 1 24 24 -.5 23.5 <00000003000001800001c0000180000180000180000080000081c00087c0009f0000780000e0000180000300000600000400000800000800000800000400e003ffe000ff80000000> ] def /h73 [1 0 0 1 1 24 24 -.5 23.5 <00000003000c01800601c0660180300180300180000080000081c00087c0009f0000780000e0000180000300000600000400000800000800000800000400e003ffe000ff80000000> ] def /h74 [1 0 0 1 1 24 24 -.5 23.5 <00600000300000600000600040cc007ffe0038800001007003000c02003e0600c60c010018010038020070020060020000020000020000fa000107800202e002067001fc30007800> ] def /h75 [1 0 0 1 1 24 24 -.5 23.5 <0000000800000c00000c00000c01e00c0ff818303c1800601800801800001000003000003000003100003100003210003220003220001430001c1ffe1c07fc0c0000080000000000> ] def /h76 [1 0 0 1 1 24 24 -.5 23.5 <000000006000001000001800101000101000103f8010f06013201816200c18600c18400638c0062c800647800647000e83000c8787cccd883858083c300ce6000386000000000000> ] def /h77 [1 0 0 1 1 24 24 -.5 23.5 <0600000300000180000180000180000300000300000783c05f1c3032601802800807000c06000c0e000c0a000c1a000c12001c320798730c786b083c4f0c660607c6060000000000> ] def /h78 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000001f0000f8c0038c30060c180c0c0c18180c10180620300620200640600640400640c00661800663000c36000c3c00181800300000c0000300000000000000> ] def /h79 [1 0 0 1 1 24 24 -.5 23.5 <0000003001801800601c006018006018004018004030204e301ffc300c403000402000406000406400406400606400606c0060680fe028307038407c3840ee183fc6100f00000000> ] def /h80 [1 0 0 1 1 24 24 -.5 23.5 <0000063000031806331c0198180198180180180100308138307ff03031003001002001006001006401006401806401806c0180681f802861c03881f03883b8187f18101c00000000> ] def /h81 [1 0 0 1 1 24 24 -.5 23.5 <00000030000018060e1c019118019118019118010e308130307ff03031003001002001006001006401006401806401806c0180681f802861c03881f03883b8187f18101c00000000> ] def /h82 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000806003c0604fc0603980600300600200700600500400580c00980c008c08008e180187180102180100180300180200180600080c000e380007f00001c000000000> ] def /h83 [1 0 0 1 1 24 24 -.5 23.5 <0000060000030100330781989f81987301800601800401c00c014008016018016018013010013830011c300208300200300200300400300c001018001c70000fe000038000000000> ] def /h84 [1 0 0 1 1 24 24 -.5 23.5 <00000000000001000e0781919f819173019106018e0401c00c014008016018016018013010013830011c300208300200300200300400300c001018001c70000fe000038000000000> ] def /h85 [1 0 0 1 1 24 24 -.5 23.5 <000000004000002000003000001800000c00000c00001000002000002000004000004000002000003000001fe000783c018806860c079c0c1f780c0670fc00203800000000000000> ] def /h86 [1 0 0 1 1 24 24 -.5 23.5 <00000000400000200000300000180c000c06000c66001030002030002000004000004000002000003000001fe000783c018806860c079c0c1f780c0670fc00203800000000000000> ] def /h87 [1 0 0 1 1 24 24 -.5 23.5 <000000004000002000003000001800000c00000c38001044002044002044004038004000002000003000001fe000783c018806860c079c0c1f780c0670fc00203800000000000000> ] def /h88 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000000000000380000640000420000c20000c1000081800180c00180600b00300f001806000e000007000003800001e00000f000003000000000000000000000000> ] def /h89 [1 0 0 1 1 24 24 -.5 23.5 <0000000000600000300003300381800641800420000c20000c1000081800180c00180600b00300f001806000e000007000003800001e00000f000003000000000000000000000000> ] def /h90 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000000000700380880640880420880c20700c1000081800180c00180600b00300f001806000e000007000003800001e00000f000003000000000000000000000000> ] def /h91 [1 0 0 1 1 24 24 -.5 23.5 <0000003000001801f81c3ffc1800c018006018006030006030007c3001f8303f602000606000606400606400606400606c00606807e028187038207c3820ee181fc6100700000000> ] def /h92 [1 0 0 1 1 24 24 -.5 23.5 <0000003000001803c61cffe318030318019818018c30018c3001803001f030ffe02001806001806401806401806401806c0180681f802861c03881f03883b8187f18101c00000000> ] def /h93 [1 0 0 1 1 24 24 -.5 23.5 <00000e3000111803911cffd118030e1801801801803001803001f0300fe030f9802001806001806401806401806401806c0180681f802861c03881f03883b8187f18101c00000000> ] def /h94 [1 0 0 1 1 24 24 -.5 23.5 <001800000c00000e00000c00000c001009e00fffc00708000009000008c0080bc007ff00038800000800000800000c00000c0003fc000c0f80100de0183c700ff83003e000000000> ] def /h95 [1 0 0 1 1 24 24 -.5 23.5 <000000000000083c0007ce00030e00001c0000180000304000202000603000403000c03003fe600d87e03100702300fc4600ce4c0186580180700300200200000400000000000000> ] def /h96 [1 0 0 1 1 24 24 -.5 23.5 <00000006000003000003000003380003f8007fe03033004802004c0200460e004613005e2300442300402300401200200e00200600200400300400700601f003ffe000ff00000000> ] def /h97 [1 0 0 1 1 24 24 -.5 23.5 <000000001800000c00200c00300c00100800101f8018f8e00b90380e301c1c200c34600e64400646c006c3800683800e83800c86c01c4c40187000302000c0000300000000000000> ] def /h98 [1 0 0 1 1 24 24 -.5 23.5 <00c00000600000700000600000600008400007400001c00000c00001800006800008800009008007e04001f8600118200300300300300300300100600180e000ffc0003f00000000> ] def /h99 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000000000000000000200000180001f8000218000207c0033c6001c0302380301ec4600c6380003000001000001800000800000c00000c00000600000600000000> ] def /h100 [1 0 0 1 1 24 24 -.5 23.5 <001000000800038c00047e00080c000801f00c0e0c06700603c0030700039d8007f8c61e7063fc0060f0003000001800001800000c00000c00000e00000600000700000300000000> ] def /h101 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000000000001800002400024700025ac0046260048220048230054230054230064230062620063460021cc0000700000c00000800001000000000> ] def /h102 [1 0 0 1 1 24 24 -.5 23.5 <000000003800404400208600308fc031323031421831830c21030c63030665030665030668830668830c68460c304618302670301fe0100f80000800001800001000002000004000> ] def /h103 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000000000001000000c00000c00000c000008c0000fc000080000080000080000080000080000080000f800030f00020bc00118c000f000000000> ] def /h104 [1 0 0 1 1 24 24 -.5 23.5 <006000003800001c000018000018000018000018e0001ff000180000180000180000180000180000180000180000180000180007fe000c1f801019e01018701870300fc000000000> ] def /h105 [1 0 0 1 1 24 24 -.5 23.5 <004000002000003000001800003c0000cc000100000100000200000200000200000200000207800618600660300780180f00180e00180400380000300000e0000380001c00000000> ] def /h106 [1 0 0 1 1 24 24 -.5 23.5 <020000030000010f000111800120c00120c00340600340600380600380600300600300600300600300600100600000c00000c00000c0000180000180000300000600000c00003000> ] def /h107 [1 0 0 1 1 24 24 -.5 23.5 <000000000c00027e0003c700018e00000c0000180000300000600000c000008000019f0003e0c00380600700300e00301c0030187030019830010c600106c0018700007c00000000> ] def /h108 [1 0 0 1 1 24 24 -.5 23.5 <0600000300000380000300000300000207000218808720c07f40c03280c00700c00700c00e00800c01801c01801c0180340180340180660180f601c3ce00fe0e0038040000000000> ] def /h109 [1 0 0 1 1 24 24 -.5 23.5 <000000020c0003fe0001c600000c0000180000100000200000600000c000018f800370600780300e00181c00183800183000180000380000300000600001c0000700007800000000> ] def /h110 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000000000000000000800000600000600000400000400000e00007c7000298c000a06001c0600180300380300280300480600e80600980c000c70000c000000000> ] def /h111 [1 0 0 1 1 24 24 -.5 23.5 <01800000c00000e00000c00000c00000800000800001e00027e1e01cc63800980c01a00e02c0060280060580060c800608800e18800c34c01872c03061c0c001c300008000000000> ] def /h112 [1 0 0 1 1 24 24 -.5 23.5 <00000004180003fc00018c00001800001800001000003000002000006f8000f06003c0100c801819800811000c23000c22000c260f1c3410d81c10700818e0000f80000000000000> ] def /h113 [1 0 0 1 1 24 24 -.5 23.5 <000600023f0003e600018400000c000018000037800078c000c06001806007006006786000ccc0008d80007e000060000080000100e00603380d860c387c0e70383e601004000000> ] def /h114 [1 0 0 1 1 24 24 -.5 23.5 <0060000030000030001026000fff0006600000c00000800001007003603807b0f80e1bc01c1e0018380000780000980001180002080004000004000007800003ffc000ffc0000000> ] def /h115 [1 0 0 1 1 24 24 -.5 23.5 <000000001800000c00001c0000180000380000300000600000600000c0000080000180000300000270000798000e18000c1802181806180c0c300c18700c70600fe0600780000000> ] def /h116 [1 0 0 1 1 24 24 -.5 23.5 <202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020> ] def /h117 [1 0 0 1 1 24 24 -.5 23.5 <202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020> ] def /h118 [1 0 0 1 1 24 24 -.5 23.5 <202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020> ] def /h119 [1 0 0 1 1 24 24 -.5 23.5 <202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020> ] def /k33 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000000000000000000040083fe007e0600700f0002300001c00001800001800001000003000003000002000006000004000008000010000000000> ] def /k34 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000f021fffc3fc01e1c003e003078001cc0000f00000c00000c0000180000180000100000300000200000600000400000c000008000010000020000040000000000> ] def /k35 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000000000000100000180000180000300000600000c00001800003c0000640000c400030400000400000400000c00000c00000c00000400000000> ] def /k36 [1 0 0 1 1 24 24 -.5 23.5 <0001000001800003c0000380000700000600000e00001c0000380000780000cc00018c00030c000c0c00300c00000c00000c00000c00000c00000c00000c00000c00000800000000> ] def /k37 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000000000002000001800001800021fe001f0700100600300600300c00100c0000180000180000300000200000400000800001000002000000000> ] def /k38 [1 0 0 1 1 24 24 -.5 23.5 <0000000070000038000018000018003018f01ffff80f803c0c00380c00300c00700c00600c00600c00c00800c0000180000180000300000600000400000800001000002000000000> ] def /k39 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000000000000000000000000000000000000000000000002038001ffc001a0000018000018000018000018000010000010001010c00ffff0070030000000000000> ] def /k40 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000000000001000e00ffff007303000180000180000180000180000180000180000180000380000300000300080fff87ffffe3c000e000000000000000000000000> ] def /k41 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000000000001000000c00000c00000c60087ff007cc00021c0000140000340000640000c4000184000304000c0400003c00001c00000c00000000> ] def /k42 [1 0 0 1 1 24 24 -.5 23.5 <000000000c000007000003000003000003000003fc21fffe1fc7000c0f00001f00003b0000330000630000c300018300030300060300180300600300001300000f00000700000200> ] def /k43 [1 0 0 1 1 24 24 -.5 23.5 <000000001800000c00000e00000c00001c00001820107ff00ffe3807303800603000603000c06000c0600180600180c00300c00600c00c0180182180301380400f00000700000200> ] def /k44 [1 0 0 1 1 24 24 -.5 23.5 <000006001803000c33000e18000c18001c00001820107ff00ffe3807303800603000603000c06000c0600180600180c00300c00600c00c0180182180301380400f00000700000200> ] def /k45 [1 0 0 1 1 24 24 -.5 23.5 <00000001800000e0000060000061c0002fe0007e0021e0001f30000c3000001038001bfc001f0040f8003f8c001c0c00000400000600000600000600000300000300000300000100> ] def /k46 [1 0 0 1 1 24 24 -.5 23.5 <00000601800300e033006018006198002fc0007c0021e0001f30000c3000001038001bfc001f0040f8003f8c001c0c00000400000600000600000600000300000300000300000100> ] def /k47 [1 0 0 1 1 24 24 -.5 23.5 <000000002000003800003040007fe0007c7000e07001c0e00300c00601c0080180100380000700000e00000c0000180000300000600000c000018000030000060000180000000000> ] def /k48 [1 0 0 1 1 24 24 -.5 23.5 <00000600000300403300701800609800ffc000f8e001c0e00381c00601800c0380100700200e00001c0000180000300000600000c0000180000300000600000c0000300000000000> ] def /k49 [1 0 0 1 1 24 24 -.5 23.5 <00000000c00000600000600000e00000c00001807c03fffe067e000c0300100300200300000600000600000c00000c0000180000300000600000c0000180000300000c0000000000> ] def /k50 [1 0 0 1 1 24 24 -.5 23.5 <00000600c00300603300601800e01800c00001800003007c06fffe0c3e00100300200300000600000600000c00000c0000180000300000600000c0000180000300000c0000000000> ] def /k51 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000000000000000e0107ff00ff0380700300000300000700000600000600000600000600000e00000c00000c01000c00fffe007c060000000000000000000000000> ] def /k52 [1 0 0 1 1 24 24 -.5 23.5 <0000060000030000330000180000180001c0107fe00ff0700700600000600000e00000c00000c00000c00001c00001800001801001800fffc007c0c0000000000000000000000000> ] def /k53 [1 0 0 1 1 24 24 -.5 23.5 <0000000006000003800301c001818001818001819e819fff7ff180398180018180018180018380018300018300010300000600000600000400000c00001800001000002000004000> ] def /k54 [1 0 0 1 1 24 24 -.5 23.5 <000006000c0300073303039801831801830001830001831c819ffe7ff300398300018300018700018600018600010600000c00000c00000800001800003000002000004000008000> ] def /k55 [1 0 0 1 1 24 24 -.5 23.5 <00000000000006000003800001c00000c0000000000000000000021800040f00080380100180600000c0000180000300000e00003c0010f0001fe0000f8000060000000000000000> ] def /k56 [1 0 0 1 1 24 24 -.5 23.5 <00000600000306003303801801c01800c0000000000000000000021800040f00080380100180600000c0000180000300000e00003c0010f0001fe0000f8000060000000000000000> ] def /k57 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000180041fc003f8e001c1c0000180000380000300000600000600000c00001c0000320000618000c0e001807006003818001c60000c000000000000000000> ] def /k58 [1 0 0 1 1 24 24 -.5 23.5 <000006000003000033000318083f9807f1c0038180000380000300000700000600000e00000c0000180000360000618000c0e001807006003818001c60000c000000000000000000> ] def /k59 [1 0 0 1 1 24 24 -.5 23.5 <00000000000001800000c00000e00000c00000c00000c07000cff800fc3c07c0707ec0c030c10000c20000c00000c00000c000004000007000003ff8000ff8000000000000000000> ] def /k60 [1 0 0 1 1 24 24 -.5 23.5 <00000600000301803300c01800e01800c00000c00000c07000cff800fc3c07c0707ec0c030c10000c20000c00000c00000c000004000007000003ff8000ff8000000000000000000> ] def /k61 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000600000301000380c00300600700700600300e00380c00181c0000180000300000300000600000c00000c00001800003000002000004000008000010000000000> ] def /k62 [1 0 0 1 1 24 24 -.5 23.5 <0000060000030000330003184001983001c01801801c01800c03000e0300060600000600000c00000c00001800001000003000006000004000008000010000020000040000000000> ] def /k63 [1 0 0 1 1 24 24 -.5 23.5 <000000003000001800001860003ff000773800603000c0700180600360c00631c0181980001b00000700000600000c0000180000300000600000c000018000060000180000000000> ] def /k64 [1 0 0 1 1 24 24 -.5 23.5 <000006006003003033003018006198007fc000d8e00180c003018006c1800c6300303300003600000c00000c0000180000300000600000c0000180000300000c0000300000000000> ] def /k65 [1 0 0 1 1 24 24 -.5 23.5 <000000000200000300000f80003e0000f800070c00000c00000c00000c7841fffe3f8c061c0c00000c00000c00001800001800001800003000003000006000004000008000010000> ] def /k66 [1 0 0 1 1 24 24 -.5 23.5 <000006000203000333000f98003e1800f800070c00000c00000c00000c7841fffe3f8c061c0c00000c00000c00001800001800001800003000003000006000004000008000010000> ] def /k67 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000000000000000000000000000000000000000000020400410700218600318600308c00100c0000180000100000300000600000400000800001000002000000000> ] def /k68 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000000403000601820201c1030181830381c30300c00300c00600000600000c00000c0000180000180000300000600000c00001800003000006000018000000000> ] def /k69 [1 0 0 1 1 24 24 -.5 23.5 <0000060000030000330103180181984081c020c18030c18038c380180300180300000600000600000c00000c0000180000180000300000600000c0000180000300000c0000000000> ] def /k70 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000403c003ffe001e00000000000000000000000007840fffe3fc80e1c0c00000c00000c00001800001800001800003000003000002000006000004000008000010000> ] def /k71 [1 0 0 1 1 24 24 -.5 23.5 <00000600000304073303ff9801c0180000000000000000000000f040fffc3fc81c1c0c00000c00000c00001800001800001800003000003000002000006000004000008000010000> ] def /k72 [1 0 0 1 1 24 24 -.5 23.5 <00000003000001c00000e00000e00000c00000c00000c00000c00000f00000ce0000c38000c0e000c07000c03000c00000c00000c00000c00000c00000c00000c000008000000000> ] def /k73 [1 0 0 1 1 24 24 -.5 23.5 <00000003000001c03000e01800e19800c0c000c0c000c00000c00000f00000ce0000c38000c0e000c07000c03000c00000c00000c00000c00000c00000c00000c000008000000000> ] def /k74 [1 0 0 1 1 24 24 -.5 23.5 <000000003000001800000c00000c00000c00000c00000c7841fffe3f8c0e1c0c00000c00001c00001800001800001800003000003000002000006000004000008000010000000000> ] def /k75 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000000000008078007ffe00380e0000000000000000000000000000000000000000000000000000000400ff03ffffe1f001e000000000000000000000000000000> ] def /k76 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000000200e001fff000e0e00000c00001c000018003030000c300003600001c00000e00001b000033800031800061c000c0c00180000300000c0000300000000000> ] def /k77 [1 0 0 1 1 24 24 -.5 23.5 <003000001c00000e00000600000000000180087fc007e380030700000e00001c00003c80006c6000cc38018c1c030c0e0c0c06300c00000c00000c00000c00000c00000800000000> ] def /k78 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000600000300000380000700000600000e00000c00001c0000180000300000700000600000c0000180000300000600000c000018000060000180000000000000000> ] def /k79 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000000000000300000182000181000180800380c00300600300300600380600180c001c0c000c18000e100006200006c00006000000000000000000000000000000> ] def /k80 [1 0 0 1 1 24 24 -.5 23.5 <0000060000030000330000180300180182000181000180800380c00300600300300600380600180c001c0c000c18000e100006200006c00006000000000000000000000000000000> ] def /k81 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000e00001103001101821101810e0180800380c00300600300300600380600180c001c0c000c18000e100006200006c00006000000000000000000000000000000> ] def /k82 [1 0 0 1 1 24 24 -.5 23.5 <0000001800000e000007000006000006000006000006078007ffc006e00006000006000006000006000006000006000006000007000003c07001fff0007fc0000000000000000000> ] def /k83 [1 0 0 1 1 24 24 -.5 23.5 <0000061800030e003307001806001806000006000006078007ffc006e00006000006000006000006000006000006000006000007000003c07001fff0007fc0000000000000000000> ] def /k84 [1 0 0 1 1 24 24 -.5 23.5 <0000001800000e001c07002206002206002206001c06078007ffc006e00006000006000006000006000006000006000006000007000003c07001fff0007fc0000000000000000000> ] def /k85 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000000000001003e00ffff003c0380000700000600000600000c00000c0000180000180000300000600000c00001800003000006000018000060000000000000000> ] def /k86 [1 0 0 1 1 24 24 -.5 23.5 <0000060000030000330000182007981fffc00780e00000c00001c0000180000180000300000300000600000600000c0000180000300000600000c0000300000c0000000000000000> ] def /k87 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000e000011400f113fff910f01ce000180000380000300000300000600000600000c00000c0000180000300000600000c000018000060000180000000000000000> ] def /k88 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000000000001000003800002c0000660000c30000c1800180c00380600f003006001800000e000007000003c00001e000007000003000000000000000000000000> ] def /k89 [1 0 0 1 1 24 24 -.5 23.5 <00000000006000003000033001018003818002c0000660000c30000c1800180c00380600f003006001800000e000007000003c00001e000007000003000000000000000000000000> ] def /k90 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000000000e001011003811002c1100660e00c30000c1800180c00380600f003006001800000e000007000003c00001e000007000003000000000000000000000000> ] def /k91 [1 0 0 1 1 24 24 -.5 23.5 <000000003000001800001c00001800001800001870403ffc3ff80c1e18000018000018000018400418200418300c181808181c18180c38180c309800007800003800001000000000> ] def /k92 [1 0 0 1 1 24 24 -.5 23.5 <000006003003001833001c180018180018000018e0203ff81ff8180e18000018000018000018400418200418300c181808181c18180c38180c309800007800003800001000000000> ] def /k93 [1 0 0 1 1 24 24 -.5 23.5 <00000000600000300e0038110030110030110031ce407fe03ff0601c300000300000300000308008304008306018303010303830301870301861300000f000007000002000000000> ] def /k94 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000038401ffc3ff80e1f001c0800380000300000600000c0000180008200006400003800001c00000e00000700000700000300000000000000000000> ] def /k95 [1 0 0 1 1 24 24 -.5 23.5 <00000001000000c000007c00001f800003c00000c000000001000001800000f000003f000007c00000c000000000000004000003000001e000007f00000fc00001e0000060000000> ] def /k96 [1 0 0 1 1 24 24 -.5 23.5 <000000000000003000001800001c00001c0000380000300000300000600000600000410000c0800080400180600100300300184201f87ffe0c3f800c18000c000000000000000000> ] def /k97 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000c00000600000700000e00000c003018000c180003300001f00000e00000f00001b800031c00060c000c0e0018060030000060000180000600000000000000000> ] def /k98 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000001007800fffc007c0000060000060000060000060000063f841fffc3fe0001c6000006000006000006000006000006000007800003ff8000ff8000000000000> ] def /k99 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000000000000000000000000000001c00000c00000c0600043f0007c3821e0401f20800c3100001000001000001800001800000800000c00000c00000c00000000> ] def /k100 [1 0 0 1 1 24 24 -.5 23.5 <00000001800003c00000c00000c00000400c0061fe007f0701f00e8fa01c7c30303030c0001000001000001800001800000800000800000c00000c00000600000600000600000000> ] def /k101 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000000000000000000000000000000000000000000000001030000ff8000c300000300000300000200000600000400000400107ff80fc0380c0000000000000000> ] def /k102 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000080f0007ff8003838000030000030000030000030000060000060000060000040000040081fffe7fc03f380000000000000000000000000000> ] def /k103 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000000000000000000000000000000000000000002018001ffc000c18000018000018002018001ff8000c10000010000010000010002010001ff8000c000000000> ] def /k104 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000001003e00ffff0070070000060000060000060000060080fe007fcc00380c00000c00000c00000c0000080000080101f800fffc0070000000000000000000000> ] def /k105 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000403c003ffe001c000000000000000000030101ff80ffc380700300000700000600000e00000c00001c0000380000300000600000c00001800006000038000000000> ] def /k106 [1 0 0 1 1 24 24 -.5 23.5 <0000000001800400c00200e00300c00300c00300c00300c00300c00300c00300c00300c00300c00300c00201c0000180000180000300000300000600000c0000300001c000000000> ] def /k107 [1 0 0 1 1 24 24 -.5 23.5 <000000000000003000001800001c000c18000718000618000618000618000618010c18020c18040c18080c18101818601818c0101b80301f00203e00401c00800800000000000000> ] def /k108 [1 0 0 1 1 24 24 -.5 23.5 <0000000000001800000e00000700000600000600000600000600000600040600080600100600200600c0060180060700060e0006380007f0000fc0000f0000040000000000000000> ] def /k109 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000301ff01ffff818001c18001c1800180800180c00180c00300c00300c00300c00200c00600c00600ffff0040030040000000000000000000000> ] def /k110 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000000000000000000000000040041fe003f0700100600100c00100c0030180030180010300000200000600000c00000800001000006000000000> ] def /k111 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000003000f01ffff80fc01c0c00180c00380c00300c00300c00600c00600400c0000180000180000300000600000c00001800003000006000018000000000000000> ] def /k112 [1 0 0 1 1 24 24 -.5 23.5 <000c00000600000700000600000600000600101fe00ffff007c60003060003060003060003060003061c87fffe7f860e380600000600000600000600000600000600000600000400> ] def /k113 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000000000000001c010fff00fc0e00601c0003300001c000018000018000018000010000010000010000010f080fffe7fe01f3c0003000000000000000000000000> ] def /k114 [1 0 0 1 1 24 24 -.5 23.5 <0000000000000000600407f003fe1801e038000030000030000060081fe007f8c00381c0000180000300000700000600000c0000180000300000600000c000018000020000000000> ] def /k115 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000008000004000007000003800201c00400c0080000100000200000c0000180000300000600000c0000380000700011e0000f80000f0000040000000000000000> ] def /k116 [1 0 0 1 1 24 24 -.5 23.5 <00000600e0030070330030180030183031c01fffe00f80f00c00e00c00c00c01c00c01800c01800c0300080300000600000600000c00000800001000002000004000008000000000> ] def /k117 [1 0 0 1 1 24 24 -.5 23.5 <000000000000000000000000000000000000001000000c00000c00000c0002086001fff00190600030600020400060c000c0c0008080010180021100040f00000600000400000000> ] def /k118 [1 0 0 1 1 24 24 -.5 23.5 <00000000000000000000000000000000000000000000400000600000c00000c0e0018ff0037c00060600080600000400000c00000800001800001000002000004000018000000000> ] def /k119 [1 0 0 1 1 24 24 -.5 23.5 <202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020> ] def /.notdef [0 0 0 0 0 1 1 0 0 <>] def end /UniqueID 2 def end /Kana exch definefont pop /Jp /Kana def /resolution 720 def % % Encoding vector and redefinition of findfont for the ISO Latin1 standard. % The 18 characters missing from ROM based fonts on older printers are noted % below. % /ISOLatin1Encoding [ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /minus /period /slash /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron /space /exclamdown /cent /sterling /currency /yen /brokenbar % missing /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree % missing /plusminus % missing /twosuperior % missing /threesuperior % missing /acute /mu % missing /paragraph /periodcentered /cedilla /onesuperior % missing /ordmasculine /guillemotright /onequarter % missing /onehalf % missing /threequarters % missing /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth % missing /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply % missing /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute % missing /Thorn % missing /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth % missing /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide % missing /oslash /ugrave /uacute /ucircumflex /udieresis /yacute % missing /thorn % missing /ydieresis ] def /NewFontDirectory FontDirectory maxlength dict def % % Apparently no guarantee findfont is defined in systemdict so the obvious % % systemdict /findfont get exec % % can generate an error. So far the only exception is a VT600 (version 48.0). % userdict /@RealFindfont known not { userdict begin /@RealFindfont systemdict begin /findfont load end def end } if /findfont { dup NewFontDirectory exch known not { dup %dup systemdict /findfont get exec % not always in systemdict dup userdict /@RealFindfont get exec dup /Encoding get StandardEncoding eq { dup length dict begin {1 index /FID ne {def}{pop pop} ifelse} forall /Encoding ISOLatin1Encoding def currentdict end /DummyFontName exch definefont } if NewFontDirectory 3 1 roll put } if NewFontDirectory exch get } bind def setup 2 setdecoding %%EndSetup %%Page: 1 1 /saveobj save def mark 1 pagesetup 12 B f (Hello World)1 639 1 2560 1230 t (or)2823 1380 w 12 R f (K)2419 1530 w 12 S f (alhme)2505 1530 w 12 B f (\264)2796 1530 w 12 S f (ra ko)1 304 1 2842 1530 t 12 B f (\264)3093 1530 w 12 S f (sme)3146 1530 w 12 B f (or)2823 1680 w save /Kana findfont 9 ptsize mul scalefont setfont 2442 1830 m (\063) show restore save /Kana findfont 9 ptsize mul scalefont setfont 2563 1830 m (\163) show restore save /Kana findfont 9 ptsize mul scalefont setfont 2684 1830 m (\113) show restore save /Kana findfont 9 ptsize mul scalefont setfont 2805 1830 m (\101) show restore save /Kana findfont 9 ptsize mul scalefont setfont 2926 1830 m (\117) show restore save 3077 1830 m currentpoint translate 9 9 scale ptsize dup scale 24 24 true [24 0 0 -24 0 24] {<071c70061860061860061860061860061860061860061866ffffff061860061860061860061860061860061860061fe006186006186006000006000006000006000c07fffe060000>} imagemask restore save 3198 1830 m currentpoint translate 9 9 scale ptsize dup scale 24 24 true [24 0 0 -24 0 24] {<0800300ffff80c18300c18300c18300ffff00c18300c18300c18300ffff00c743000e20001c1800300e00ee1ff38c19ec0c18600c18000c18000c1800181800181800301800c0180>} imagemask restore 10 I f (Rob Pike)1 363 1 2698 2070 t (Ken Thompson)1 603 1 2578 2190 t 10 R f (AT&T Bell Laboratories)2 993 1 2383 2370 t (Murray Hill, New Jersey 07974)4 1267 1 2246 2490 t 10 I f (ABSTRACT)2643 2870 w 10 R f (Plan 9 from Bell Labs has recently been converted from ASCII to an ASCII\255)13 3350 1 1330 3130 t ( this paper we explain the rea\255)6 1262( In)1 143(compatible variant of Unicode, a 16\255bit character set.)7 2195 3 1080 3250 t ( describe the character set and representation we chose, and present)10 2778(sons for the change,)3 822 2 1080 3370 t ( text format.)2 559(the programming models and software changes that support the new)9 3041 2 1080 3490 t (Although we stopped short of full internationalization)6 2214 1 1080 3610 t 10 S1 f (\320)3294 3610 w 10 R f ( error mes\255)2 459(for example, system)2 827 2 3394 3610 t (sages are in Unixese, not Japanese)5 1394 1 1080 3730 t 10 S1 f (\320)2474 3730 w 10 R f ( Plan 9 is the first system to treat the rep\255)10 1673(we believe)1 433 2 2574 3730 t (resentation of all major languages on a uniform, equal footing throughout all its software.)13 3576 1 1080 3850 t 10 B f (Introduction)720 4210 w 10 R f ( release)1 308( The)1 212( ASCII.)1 318(The world is multilingual but most computer systems are based on English and)12 3232 4 970 4366 t ( system from Bell Laboratories, seemed a good occasion to)9 2408(of Plan 9 [Pike90], a new distributed operating)7 1912 2 720 4486 t ( make such deep changes when building new systems than by refit\255)11 2764( is easier to)3 470( It)1 117(correct this chauvinism.)2 969 4 720 4606 t (ting old ones.)2 542 1 720 4726 t (The ANSI C standard [ANSIC] contains some guidance on the matter of `wide' and `multi\255byte')14 4070 1 970 4882 t ( literature on how)3 707( could find no)3 561( We)1 189(characters but falls far short of solving the myriad associated problems.)10 2863 4 720 5002 t (to convert a)2 483 1 720 5122 t 10 I f (system)1234 5122 w 10 R f ( character sets, although some individual)5 1666(to larger)1 341 2 1531 5122 t 10 I f (programs)3570 5122 w 10 R f ( This)1 235(had been converted.)2 814 2 3991 5122 t ( problem of representing multilingual text at all levels)8 2178(paper reports what we discovered as we explored the)8 2142 2 720 5242 t ( the file system and kernel through the applications and up to the window sys\255)14 3161(of an operating system, from)4 1159 2 720 5362 t (tem and display.)2 658 1 720 5482 t ( its manuals are in English, its error messages are in English,)11 2483(Plan 9 has not been `internationalized':)5 1587 2 970 5638 t ( we can address these other problems, we)7 1651( before)1 280( But)1 196(and it can display text that goes from left to right only.)11 2193 4 720 5758 t ( uniformly and comfortably, the textual representation of all the major written languages.)12 3693(need to handle,)2 627 2 720 5878 t (That subproblem is richer than we had anticipated.)7 2024 1 720 5998 t 10 B f (Standards)720 6238 w 10 R f ( there were only two viable)5 1184( the time \(January 1992\),)4 1073( At)1 168(Our first step was to select a standard.)7 1645 4 970 6394 t ( documents describing both proposals were)5 1773( The)1 215(options: ISO 10646 [ISO10646] and Unicode [Unicode].)6 2332 3 720 6514 t (still in the draft stage.)4 869 1 720 6634 t ( a sparse set of 32\255bit characters, which)7 1580( standard defines)2 676( The)1 205(ISO 10646 was not very attractive to us.)7 1609 4 970 6790 t ( to mollify)2 423( the standard attempts)3 877( Also,)1 265(would be hard to implement and have punitive storage requirements.)9 2755 4 720 6910 t ( sug\255)1 203( The)1 211( partition individually.)2 910(national interests by allocating 16\255bit subspaces to national committees to)9 2996 4 720 7030 t ( use is to ``flip'' between separate national standards to implement the international stan\255)13 3688(gested mode of)2 632 2 720 7150 t ( well, transmitting 32\255bit values in a)6 1507( As)1 171( character set.)2 570( did not strike us as a sound basis for a)10 1633(dard. This)1 439 5 720 7270 t cleartomark showpage saveobj restore %%EndPage: 1 1 %%Page: 2 2 /saveobj save def mark 2 pagesetup 10 R f (\255 2 \255)2 166 1 2797 480 t ( the standard does not)4 927( Since)1 286( such as in pipes, would be expensive and hard to implement.)11 2604(byte stream,)1 503 4 720 840 t ( values)1 281(define a byte order for such transmission, the byte stream would also have to carry state to enable the)18 4039 2 720 960 t (to be recovered.)2 639 1 720 1080 t ( to protest)2 422(Unicode is a proposal by a consortium of mostly American computer companies formed)12 3648 2 970 1236 t ( a uniform 16\255bit code based on the principle of unifi\255)10 2172( defines)1 316( Unicode)1 391(the technical failings of ISO 10646.)5 1441 4 720 1356 t ( they look the same even though they are from different languages.)11 2782(cation: two characters are the same if)6 1538 2 720 1476 t ( allows the large Japanese, Chinese, and Korean character sets to be)11 2772(This principle, called Han unification,)4 1548 2 720 1596 t (packed comfortably into a 16\255bit representation.)5 1924 1 720 1716 t ( Moreover,)1 472( Unicode for its technical merits and because its code space was better defined.)13 3205(We chose)1 393 3 970 1872 t ( 10646 is now in its second draft and)8 1511( ISO)1 216( was derailing the ISO 10646 standard.)6 1586(the existence of Unicode)3 1007 4 720 1992 t ( two standards)2 583( people expect the)3 729( Most)1 258(has only one 16\255bit group defined, which is almost exactly Unicode.)10 2750 4 720 2112 t (bodies to reach a d\351tente so that ISO 10646 and Unicode will represent the same character set.)16 3766 1 720 2232 t ( Unicode standard)2 732( The)1 208(Unicode defines an adequate character set but an unreasonable representation.)9 3130 3 970 2388 t ( also reserves a)3 606( It)1 111(states that all characters are 16 bits wide and are communicated and stored in 16\255bit units.)15 3603 3 720 2508 t ( characters \(hexadecimal FFFE and FEFF\) to detect byte order in transmitted text, requiring state in)15 4053(pair of)1 267 2 720 2628 t ( Unicode, we would)3 822( adopt)1 254( To)1 168( Unicode committee was thinking of files, not pipes.\))8 2182( \(The)1 245(the byte stream.)2 649 6 720 2748 t ( ASCII and Unicode, which cannot be)6 1594(have had to convert all text going into and out of Plan 9 between)13 2726 2 720 2868 t ( is possible to define characters as)6 1364( a single program, in command of all its input and output, it)12 2407(done. Within)1 549 3 720 2988 t ( applications on diverse machines)4 1376(16\255bit quantities; in the context of a networked system with hundreds of)11 2944 2 720 3108 t (by different manufacturers, it is impossible.)5 1745 1 720 3228 t ( by the)2 282(We needed a way to adapt Unicode to the tools\255and\255pipes model of text processing embodied)14 3788 2 970 3384 t ( of Unicode for transmis\255)4 1029( do that, we needed an ASCII\255compatible textual representation)8 2590( To)1 167(Unix system.)1 534 4 720 3504 t ( informative \(non\255required\) Annex called UTF that pro\255)7 2301( the ISO standard there is an)6 1185( In)1 142(sion and storage.)2 692 4 720 3624 t ( encoding uses multibyte sequences composed)5 1906( The)1 215( ISO code.)2 444(vides a byte stream encoding of the 32\255bit)7 1755 4 720 3744 t (from the 190 printable characters of Latin\2551 to represent character values larger than 159.)13 3567 1 720 3864 t ( ASCII)1 288( far the most important is that a byte in the)10 1709( By)1 168(The UTF encoding has several good properties.)6 1905 4 970 4020 t ( UTF is backward compatible with ASCII.)6 1701( Thus)1 250(range 0\255127 represents itself in UTF.)5 1475 3 720 4140 t ( con\255)1 203( ASCII)1 312( byte\255order independent.)2 980( is a byte encoding and is therefore)7 1394( It)1 111(UTF has other advantages.)3 1070 6 970 4296 t ( element of a sequence encoding)5 1339(trol characters appear in the byte stream only as themselves, never as an)12 2981 2 720 4416 t ( ANSI C's)2 466( Finally,)1 381( bytes separate lines of UTF text.)6 1455(another character, so newline)3 1231 4 720 4536 t 10 CW f (strcmp)4300 4536 w 10 R f (function)4707 4536 w (applied to UTF strings preserves the ordering of Unicode characters.)9 2738 1 720 4656 t ( UTF is expensive \(involving multiplication, division, and modulo operations\))9 3167(To encode and decode)3 903 2 970 4812 t ( is in general)3 549( It)1 123( not self\255synchronizing.)2 970( major disadvantage is that the encoding is)7 1792( UTF's)1 324(but workable.)1 562 6 720 4932 t ( of the)2 289(impossible to find the character boundaries in a UTF string without reading from the beginning)14 4031 2 720 5052 t ( control characters such as newlines, tabs, and blanks provide synchronization)10 3216(string, although in practice)3 1104 2 720 5172 t (points.)720 5292 w ( Their)1 267( proposal for another UTF\255like byte encoding of Unicode.)8 2323(In August 1992, X\255Open circulated a)5 1480 3 970 5448 t ( a file name \(in particular a slash\) could be part of an)12 2255(major concern was that an embedded character in)7 2065 2 720 5568 t ( proposal would allow all 7\255)5 1149( Their)1 271( in UTF and therefore confuse a traditional file system.)9 2241(escape sequence)1 659 4 720 5688 t (bit ASCII characters to represent themselves)5 1802 1 720 5808 t 10 I f (and only themselves)2 812 1 2551 5808 t 10 R f ( con\255)1 205( sequences would)2 712( Multibyte)1 449(in text.)1 282 4 3392 5808 t ( a modification to the new UTF that would address)9 2079( proposed)1 395( We)1 192(tain only characters with the high bit set.)7 1654 4 720 5928 t ( new proposal is now informally called UTF\2552 and is being)10 2494( modified)1 400( The)1 219(our synchronization problem.)2 1207 4 720 6048 t (proposed as another informative Annex to ISO 10646.)7 2169 1 720 6168 t ( Unicode character set encoded)4 1249(The model for text in Plan 9 is chosen from these three standards*: the)13 2821 2 970 6324 t ( this)1 171( Although)1 429( by UTF\2552, from an X\255Open proposed modification of Annex F of ISO 10646.)13 3145(as byte stream)2 575 4 720 6444 t ( as expected, ISO adopts)4 988( If,)1 142( not as bad as it sounds.)6 953(may seem like a precarious position for us to adopt, it is)11 2237 4 720 6564 t ( as an Annex, then Plan 9 will be ISO/UTF\2552 com\255)10 2054(Unicode as Group 0 of 10646 and ISO publishes UTF\2552)9 2266 2 720 6684 t (patible.)720 6804 w ( the issue of right\255to\255left text such)6 1360( is)1 92( One)1 216(There are a couple of aspects of Unicode we have not faced.)11 2402 4 970 6960 t 8 S1 f (__________________)720 7060 w 8 R f (* ``That's the nice thing about standards)6 1285 1 720 7160 t 8 S1 f (\320)2005 7160 w 8 R f (there's so many to choose from.'')5 1072 1 2085 7160 t 8 S1 f (\261)3177 7160 w 8 R f (Andy Tannenbaum \(no, the other one\))5 1221 1 3249 7160 t cleartomark showpage saveobj restore %%EndPage: 2 2 %%Page: 3 3 /saveobj save def mark 3 pagesetup 10 R f (\255 3 \255)2 166 1 2797 480 t ( of display, not representation, we believe we can defer that)10 2497( that is an issue)4 655( Since)1 283(as Hebrew or Arabic.)3 885 4 720 840 t ( issue is diacriticals, which)4 1098( Another)1 383( without affecting our ability to solve it later.)8 1844(problem for the moment)3 995 4 720 960 t ( since the Unicode)3 764( these are display issues and,)5 1183( Again,)1 326(cause overstriking of multiple Unicode characters.)5 2047 4 720 1080 t ( Ma\361ana.)1 396(committee is still deciding their finer points, we felt comfortable deferring.)10 2996 2 720 1200 t ( in the altruistic interests of serving foreign languages, we have found)11 2839(Although we converted Plan 9)4 1231 2 970 1356 t ( includes many characters)3 1045( Unicode)1 392( character set attractive for other reasons.)6 1665(the large)1 351 4 720 1476 t 10 S1 f (\320)4173 1476 w 10 R f (mathematical sym\255)1 767 1 4273 1476 t ( more)1 236(bols, scientific notation, more general punctuation, and)6 2230 2 720 1596 t 10 S1 f (\320)3186 1596 w 10 R f ( no)1 131( We)1 194(that we now use daily in our work.)7 1429 3 3286 1596 t ( symbols in our text; why type)6 1259(longer test our imaginations to find ways to include non\255ASCII)9 2601 2 720 1716 t 10 CW f (:\255\))4612 1716 w 10 R f (when)4824 1716 w (you can use the character)4 1055 1 720 1836 t 10 S1 f ()1813 1836 w cleartomark saveobj restore %%BeginGlobal /build_smiley { pop gsave currentpoint translate 7.44 7.68 scale ptsize dup scale 31 32 true [31 0 0 -32 2 31] {< 0007c000 007ff800 01c00600 03000180 060000c0 08000060 18000030 30000018 20000008 4000000c 40183004 c0183006 80183002 80000002 80000002 80000002 860000c2 8e0000e2 8e0000e2 9a0001e2 c3000186 41800304 41c0060c 60f01c08 303ff818 101fe030 08000060 040000c0 03000180 01c00700 007cfc00 000fe000 >} imagemask grestore } def %%EndGlobal /saveobj save def mark 10 S1 f 1813 1836 m 70 build_smiley 1883 1836 m 10 R f ( compelling is the ability to absorb documents and data that contain)11 2844(? Most)1 313 2 1883 1836 t ( the Oxford English Dictionary lets us see the dictionary as it really)12 2751(non\255ASCII characters; our browser for)4 1569 2 720 1956 t (is, with pronunciation in the IPA font, foreign phrases properly rendered, and so on,)13 3353 1 720 2076 t 10 I f (in plain text.)2 503 1 4098 2076 t 10 R f ( the term `UTF' refers to the UTF\2552 encoding)8 1864(In the rest of this paper, except when stated otherwise,)9 2206 2 970 2232 t (of Unicode characters as adopted by Plan 9.)7 1751 1 720 2352 t 10 B f (C Compiler)1 502 1 720 2592 t 10 R f ( levels of conversion.)3 875( are two)2 333( There)1 288(The first program to be converted to UTF was the C Compiler.)11 2574 4 970 2748 t ( to)1 116(On the syntactic level, input to the C compiler is UTF; on the semantic level, the C language needs)18 4204 2 720 2868 t (define how compiled programs manipulate the UTF set.)7 2236 1 720 2988 t ( defines the source character set to be)7 1562( ANSI C language standard)4 1134( The)1 214(The syntactic part is simple.)4 1160 4 970 3144 t ( places)1 277( only)1 207( The)1 209( UTF is backward compatible with ASCII, the compiler needs little change.)11 3065(ASCII. Since)1 562 5 720 3264 t ( 7\255bit ASCII)2 502( Since)1 273( character set is allowed are in character constants, strings, and comments.)11 2976(where a larger)2 569 4 720 3384 t ( compiler does not have to be careful while looking for)10 2196(characters can represent only themselves in UTF, the)7 2124 2 720 3504 t (the termination of a string or comment.)6 1568 1 720 3624 t ( extends ANSI C to treat any Unicode character with a value outside of the)14 3212(The Plan 9 compiler)3 858 2 970 3780 t ( a Greek programmer or an English mathematician,)7 2114( To)1 170(ASCII range as an alphabetic.)4 1230 3 720 3900 t 10 S f (a)4268 3900 w 10 R f (is a sensible and)3 676 1 4364 3900 t (now valid variable name.)3 1009 1 720 4020 t ( notion of a)3 494(On the semantic level, ANSI C allows, but does not tie down, the)12 2744 2 970 4176 t 10 I f (wide character)1 614 1 4245 4176 t 10 R f (and)4896 4176 w ( chose the wide character type to be)7 1524( We)1 202( character constants of this type.)5 1356(admits string and)2 719 4 720 4296 t 10 CW f (unsigned)4560 4296 w (short)720 4416 w 10 R f ( the libraries, the word)4 909(. In)1 160 2 1020 4416 t 10 CW f (Rune)2116 4416 w 10 R f (is defined by a)3 594 1 2384 4416 t 10 CW f (typedef)3006 4416 w 10 R f (to be equivalent to)3 750 1 3454 4416 t 10 CW f (unsigned short)1 808 1 4232 4416 t 10 R f (and is used to signify a Unicode character.)7 1696 1 720 4536 t (There are surprises; for example:)4 1318 1 970 4692 t 9 CW f (L'x')1008 4862 w 9 R f (is 120)1 218 1 1440 4862 t 9 CW f ('x')1008 4972 w 9 R f (is 120)1 218 1 1440 4972 t 9 CW f (L'\377')1008 5082 w 9 R f (is 255)1 218 1 1440 5082 t 9 CW f ('\377')1008 5192 w 9 R f (is)1440 5192 w 9 S1 f (\261)1523 5192 w 9 R f (1, stdio)1 266 1 1582 5192 t 9 CW f (EOF)1871 5192 w 9 R f (\(if)2056 5192 w 9 CW f (char)2164 5192 w 9 R f (is signed\))1 348 1 2403 5192 t 9 CW f (L')1008 5302 w 9 S f (a)1116 5302 w 9 CW f (')1173 5302 w 9 R f (is 945)1 218 1 1440 5302 t 9 CW f (')1008 5412 w 9 S f (a)1062 5412 w 9 CW f (')1119 5412 w 9 R f (is illegal)1 308 1 1440 5412 t 10 R f (In the string constants,)3 905 1 720 5592 t 9 CW f (")1008 5762 w save /Kana findfont 9 ptsize mul scalefont setfont 1062 5762 m (\063) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1153 5762 m (\163) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1244 5762 m (\113) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1335 5762 m (\101) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1426 5762 m (\117) show restore save 1571 5762 m currentpoint translate 9 9 scale ptsize dup scale 24 24 true [24 0 0 -24 0 24] {<071c70061860061860061860061860061860061860061866ffffff061860061860061860061860061860061860061fe006186006186006000006000006000006000c07fffe060000>} imagemask restore save 1662 5762 m currentpoint translate 9 9 scale ptsize dup scale 24 24 true [24 0 0 -24 0 24] {<0800300ffff80c18300c18300c18300ffff00c18300c18300c18300ffff00c743000e20001c1800300e00ee1ff38c19ec0c18600c18000c18000c1800181800181800301800c0180>} imagemask restore (")1753 5762 w (L")1008 5872 w save /Kana findfont 9 ptsize mul scalefont setfont 1116 5872 m (\063) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1207 5872 m (\163) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1298 5872 m (\113) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1389 5872 m (\101) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1480 5872 m (\117) show restore save 1625 5872 m currentpoint translate 9 9 scale ptsize dup scale 24 24 true [24 0 0 -24 0 24] {<071c70061860061860061860061860061860061860061866ffffff061860061860061860061860061860061860061fe006186006186006000006000006000006000c07fffe060000>} imagemask restore save 1716 5872 m currentpoint translate 9 9 scale ptsize dup scale 24 24 true [24 0 0 -24 0 24] {<0800300ffff80c18300c18300c18300ffff00c18300c18300c18300ffff00c743000e20001c1800300e00ee1ff38c19ec0c18600c18000c18000c1800181800181800301800c0180>} imagemask restore (",)1807 5872 w 10 R f (the former is an array of)5 966 1 720 6052 t 10 CW f (chars)1711 6052 w 10 R f ( array of)2 339(with 22 elements and a null byte, while the latter is an)11 2159 2 2036 6052 t 10 CW f (unsigned)4560 6052 w (shorts)720 6172 w 10 R f (\()1105 6172 w 10 CW f (Runes)1138 6172 w 10 R f (\) with 8 elements and a null)6 1110 1 1438 6172 t 10 CW f (Rune)2573 6172 w 10 R f (.)2813 6172 w (The Plan 9 library provides an output conversion function,)8 2347 1 970 6328 t 10 CW f (print)3344 6328 w 10 R f (\(analogous to)1 543 1 3671 6328 t 10 CW f (printf)4241 6328 w 10 R f (\), with for\255)2 439 1 4601 6328 t (mats)720 6448 w 10 CW f (%c)935 6448 w 10 R f (,)1055 6448 w 10 CW f (%C)1106 6448 w 10 R f (,)1226 6448 w 10 CW f (%s)1277 6448 w 10 R f (, and)1 195 1 1397 6448 t 10 CW f (%S)1618 6448 w 10 R f (. Since)1 298 1 1738 6448 t 10 CW f (print)2062 6448 w 10 R f ( character conversion)2 852( The)1 205( its output is always UTF.)5 1034(produces text,)1 561 4 2388 6448 t 10 CW f (%c)720 6568 w 10 R f ( Thus)1 251(\(lower case\) masks its argument to 8 bits before converting to UTF.)11 2718 2 866 6568 t 10 CW f (L'\377')3861 6568 w 10 R f (and)4127 6568 w 10 CW f ('\377')4297 6568 w 10 R f (printed under)1 537 1 4503 6568 t 10 CW f (%c)720 6688 w 10 R f ( identical, but)2 559(will be)1 282 2 872 6688 t 10 CW f (L')1744 6688 w 10 S f (a)1864 6688 w 10 CW f (')1927 6688 w 10 R f ( character)1 395( The)1 211(will print as the Unicode character with decimal value 177.)9 2416 3 2018 6688 t (conversion)720 6808 w 10 CW f (%C)1183 6808 w 10 R f ( Thus)1 250(\(upper case\) masks its argument to 16 bits before converting to UTF.)11 2757 2 1328 6808 t 10 CW f (L'\377')4361 6808 w 10 R f (and)4627 6808 w 10 CW f (L')4797 6808 w 10 S f (a)4917 6808 w 10 CW f (')4980 6808 w 10 R f (will print correctly under)3 1007 1 720 6928 t 10 CW f (%C)1754 6928 w 10 R f (, but)1 180 1 1874 6928 t 10 CW f ('\377')2081 6928 w 10 R f ( conversion)1 465( The)1 207(will not.)1 336 3 2288 6928 t 10 CW f (%s)3323 6928 w 10 R f (\(lower case\) expects a pointer to)5 1303 1 3470 6928 t 10 CW f (char)4800 6928 w 10 R f ( conversion)1 472( The)1 214( a null byte.)3 499(and copies UTF sequences up to)5 1335 4 720 7048 t 10 CW f (%S)3274 7048 w 10 R f (\(upper case\) expects a pointer to)5 1338 1 3428 7048 t 10 CW f (Rune)4800 7048 w 10 R f (and performs sequential)2 959 1 720 7168 t 10 CW f (%C)1704 7168 w 10 R f (conversions until a null)3 936 1 1849 7168 t 10 CW f (Rune)2810 7168 w 10 R f (is encountered.)1 604 1 3075 7168 t cleartomark showpage saveobj restore %%EndPage: 3 3 %%Page: 4 4 /saveobj save def mark 4 pagesetup 10 R f (\255 4 \255)2 166 1 2797 480 t (Another problem in format conversion is the definition of)8 2367 1 970 840 t 10 CW f (%10s)3370 840 w 10 R f ( bytes or)2 362(: does the number refer to)5 1068 2 3610 840 t ( made the)2 400( decided that such formats were most often used to align output columns and so)14 3278(characters? We)1 642 3 720 960 t ( strings in fixed\255)3 682( programs, however, use the count to place blank\255padded)8 2334( Some)1 285(number count characters.)2 1019 4 720 1080 t ( programs must be found and corrected.)6 1588( These)1 288(sized arrays.)1 498 3 720 1200 t (Here is a complete example:)4 1136 1 970 1356 t 9 CW f (#include )1 756 1 1008 1526 t (char c[] = ")3 648 1 1008 1746 t save /Kana findfont 9 ptsize mul scalefont setfont 1656 1746 m (\063) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1747 1746 m (\163) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1838 1746 m (\113) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1929 1746 m (\101) show restore save /Kana findfont 9 ptsize mul scalefont setfont 2020 1746 m (\117) show restore save 2165 1746 m currentpoint translate 9 9 scale ptsize dup scale 24 24 true [24 0 0 -24 0 24] {<071c70061860061860061860061860061860061860061866ffffff061860061860061860061860061860061860061fe006186006186006000006000006000006000c07fffe060000>} imagemask restore save 2256 1746 m currentpoint translate 9 9 scale ptsize dup scale 24 24 true [24 0 0 -24 0 24] {<0800300ffff80c18300c18300c18300ffff00c18300c18300c18300ffff00c743000e20001c1800300e00ee1ff38c19ec0c18600c18000c18000c1800181800181800301800c0180>} imagemask restore (";)2347 1746 w (Rune s[] = L")3 702 1 1008 1856 t save /Kana findfont 9 ptsize mul scalefont setfont 1710 1856 m (\063) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1801 1856 m (\163) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1892 1856 m (\113) show restore save /Kana findfont 9 ptsize mul scalefont setfont 1983 1856 m (\101) show restore save /Kana findfont 9 ptsize mul scalefont setfont 2074 1856 m (\117) show restore save 2219 1856 m currentpoint translate 9 9 scale ptsize dup scale 24 24 true [24 0 0 -24 0 24] {<071c70061860061860061860061860061860061860061866ffffff061860061860061860061860061860061860061fe006186006186006000006000006000006000c07fffe060000>} imagemask restore save 2310 1856 m currentpoint translate 9 9 scale ptsize dup scale 24 24 true [24 0 0 -24 0 24] {<0800300ffff80c18300c18300c18300ffff00c18300c18300c18300ffff00c743000e20001c1800300e00ee1ff38c19ec0c18600c18000c18000c1800181800181800301800c0180>} imagemask restore (";)2401 1856 w (main\(void\))1008 2076 w ({)1008 2186 w (print\("%d, %d\\n", sizeof\(c\), sizeof\(s\)\);)3 2160 1 1440 2296 t (print\("%s\\n", c\);)1 918 1 1440 2406 t (print\("%S\\n", s\);)1 918 1 1440 2516 t (})1008 2626 w 10 R f (This program prints)2 802 1 970 2842 t 10 CW f (23, 18)1 330 1 1802 2842 t 10 R f ( practice,)1 370( In)1 138(and then two identical lines of UTF text.)7 1656 3 2162 2842 t 10 CW f (%S)4356 2842 w 10 R f (and)4506 2842 w 10 CW f (L"...")4680 2842 w 10 R f (are rare in programs; one reason is that most formatted I/O is done in unconverted UTF.)15 3516 1 720 2962 t 10 B f (Ramifications)720 3202 w 10 R f ( change breaks two deep\255)4 1045( This)1 236( now read and write text as UTF, not ASCII.)9 1850(All programs in Plan 9)4 939 4 970 3358 t (rooted symmetries implicit in most C programs:)6 1923 1 720 3478 t ( character is no longer a)5 955(1. A)1 322 2 720 3634 t 10 CW f (char)2022 3634 w 10 R f (.)2262 3634 w ( its external representation)3 1119( internal representation \(Unicode\) of a character now differs from)9 2796(2. The)1 405 3 720 3790 t (\(UTF\).)970 3910 w ( system software)2 695(In the sections that follow, we show how these issues were faced in the layers of)15 3375 2 970 4066 t ( effects are wide\255reaching and often surprising.)6 1880( The)1 205(from the operating system up to the applications.)7 1954 3 720 4186 t 10 B f (Operating system)1 752 1 720 4426 t 10 R f ( 9, the interface to the operating system had to be con\255)11 2234(Since UTF is the only format for text in Plan)9 1836 2 970 4582 t ( several places: command arguments, file names, user)7 2239( strings cross the interface in)5 1215( Text)1 247(verted to UTF.)2 619 4 720 4702 t ( in using their native name\), error messages, and miscellaneous minor places such as)13 3419(names \(people can log)3 901 2 720 4822 t ( required: null\255terminated UTF strings are equivalent to)7 2306( change was)2 513( Little)1 280(commands to the I/O system.)4 1221 4 720 4942 t ( library routines described in)4 1164( The)1 209(null\255terminated ASCII strings for most purposes of the operating system.)9 2947 3 720 5062 t (the next section made that change straightforward.)6 2015 1 720 5182 t (The window system, once called)4 1306 1 970 5338 t 10 CW f (8.5)2301 5338 w 10 R f (, is now rightfully called)4 980 1 2481 5338 t 10 CW f (8\275)3486 5338 w 10 R f (.)3606 5338 w 10 B f (Libraries)720 5578 w 10 R f ( the)1 149(A header file included by all programs \(see [Pike92]\) declares)9 2488 2 970 5734 t 10 CW f (Rune)3634 5734 w 10 R f (type to hold 16\255bit character)4 1139 1 3901 5734 t (values:)720 5854 w 9 CW f (typedef unsigned short Rune;)3 1512 1 1008 6024 t 10 R f (Also defined are several constants relevant to UTF:)7 2054 1 720 6204 t 9 CW f (enum)1008 6374 w ({)1008 6484 w ( maximum bytes per rune */)5 1404( /*)1 324( 3,)1 162(UTFmax =)1 594 4 1224 6594 t ( 0x80, /* cannot represent part of a UTF sequence \(<\) */)11 3024(Runesync =)1 594 2 1224 6704 t ( 0x80, /* rune and UTF sequences are the same \(<\) */)11 2808(Runeself =)1 594 2 1224 6814 t (Runeerror = 0x80, /* decoding error in UTF */)8 2430 1 1224 6924 t (};)1008 7034 w 10 R f (\(With the original UTF,)3 991 1 720 7214 t 10 CW f (Runesync)1748 7214 w 10 R f ( and)1 182(was hexadecimal 21)2 833 2 2265 7214 t 10 CW f (Runeself)3318 7214 w 10 R f (was A0.\))1 373 1 3836 7214 t 10 CW f (UTFmax)4272 7214 w 10 R f (bytes are)1 370 1 4670 7214 t cleartomark showpage saveobj restore %%EndPage: 4 4 %%Page: 5 5 /saveobj save def mark 5 pagesetup 10 R f (\255 5 \255)2 166 1 2797 480 t ( of value less than)4 753( Characters)1 484(sufficient to hold the UTF encoding of any Unicode character.)9 2570 3 720 840 t 10 CW f (Runesync)4560 840 w 10 R f ( Charac\255)1 366( in a UTF string as themselves, never as part of a sequence encoding another character.)15 3486(only appear)1 468 3 720 960 t ( than)1 207(ters of value less)3 701 2 720 1080 t 10 CW f (Runeself)1663 1080 w 10 R f ( when the library)3 709( Finally,)1 369(encode into single bytes of the same value.)7 1784 3 2178 1080 t (detects errors in UTF input)4 1090 1 720 1200 t 10 S1 f (\320)1810 1200 w 10 R f ( sequences)1 432(byte sequences that are not valid UTF)6 1526 2 1910 1200 t 10 S1 f (\320)3868 1200 w 10 R f (it converts the first byte of)5 1072 1 3968 1200 t (the error sequence to the character)5 1374 1 720 1320 t 10 CW f (Runeerror)2120 1320 w 10 R f ( little a rune\255oriented program can do when given)8 1979( is)1 93(. There)1 308 3 2660 1320 t ( routines, described)2 813( the conversion)2 642( Originally)1 477(bad data except exit, which is unreasonable, or carry on.)9 2388 4 720 1440 t ( errors when given invalid UTF, but we found ourselves repeatedly checking for errors and)14 3689(below, returned)1 631 2 720 1560 t ( convert a bad sequence to a valid rune and continue processing.)11 2676( therefore decided to)3 849( We)1 197(ignoring them.)1 598 4 720 1680 t (\(The ANSI C routines, on the other hand, return errors.\))9 2234 1 720 1800 t ( byte strings in and out)5 919(This technique does have the unfortunate property that converting invalid UTF)10 3151 2 970 1956 t ( only occurs when non\255textual input is given to a)9 1969(of runes does not preserve the input, but this circumstance)9 2351 2 720 2076 t ( to represent characters from other sets)6 1605( defines an error character, value FFFD,)6 1649( Unicode)1 397(textual program.)1 669 4 720 2196 t ( The)1 221(that are not represented in Unicode.)5 1504 2 720 2316 t 10 CW f (Runeerror)2486 2316 w 10 R f ( different concept, related to UTF)5 1416(character is a)2 557 2 3067 2316 t (rather than Unicode, so we chose a different character for it.)10 2397 1 720 2436 t ( first set converts)3 721( The)1 217(The Plan 9 C library contains a number of routines for manipulating runes.)12 3132 3 970 2592 t (between runes and UTF strings:)4 1276 1 720 2712 t 9 CW f ( Rune*\);)1 432( runetochar\(char*,)1 1188(extern int)1 594 3 1008 2882 t ( char*\);)1 432( chartorune\(Rune*,)1 1188(extern int)1 594 3 1008 2992 t ( runelen\(long\);)1 1026(extern int)1 594 2 1008 3102 t ( int\);)1 324( fullrune\(char*,)1 1080(extern int)1 594 3 1008 3212 t 10 CW f (Runetochar)720 3392 w 10 R f (translates a single)2 740 1 1360 3392 t 10 CW f (Rune)2140 3392 w 10 R f ( returns the number of bytes produced.)6 1640(to a UTF sequence and)4 980 2 2420 3392 t 10 CW f (Chartorune)720 3512 w 10 R f ( many bytes were consumed.)4 1160(goes the other way, reporting how)5 1374 2 1347 3512 t 10 CW f (Runelen)3932 3512 w 10 R f (returns the num\255)2 662 1 4378 3512 t (ber of bytes in the UTF encoding of a rune.)9 1730 1 720 3632 t 10 CW f (Fullrune)2500 3632 w 10 R f ( number of)2 440(examines a UTF string up to a specified)7 1595 2 3005 3632 t ( routines use the)3 697( these)1 246( All)1 194(bytes and reports whether the string begins with a complete UTF encoding.)11 3183 4 720 3752 t 10 CW f (Runeerror)720 3872 w 10 R f (character to work around encoding problems.)5 1812 1 1285 3872 t ( the)1 153(There is also a set of routines for examining null\255terminated UTF strings, based on the model of)16 3917 2 970 4028 t (ANSI standard)1 596 1 720 4148 t 10 CW f (str)1341 4148 w 10 R f (routines, but with)2 703 1 1546 4148 t 10 CW f (utf)2274 4148 w 10 R f (substituted for)1 575 1 2479 4148 t 10 CW f (str)3079 4148 w 10 R f (and)3284 4148 w 10 CW f (rune)3453 4148 w 10 R f (for)3718 4148 w 10 CW f (chr)3859 4148 w 10 R f (:)4039 4148 w 9 CW f ( utflen\(char*\);)1 1026(extern int)1 594 2 1008 4318 t ( long\);)1 378( utfrune\(char*,)1 918(extern char*)1 702 3 1008 4428 t ( long\);)1 378( utfrrune\(char*,)1 972(extern char*)1 702 3 1008 4538 t ( char*\);)1 432( utfutf\(char*,)1 864(extern char*)1 702 3 1008 4648 t 10 CW f (Utflen)720 4828 w 10 R f (returns the number of runes in a UTF string;)8 1786 1 1107 4828 t 10 CW f (utfrune)2920 4828 w 10 R f (returns a pointer to the first occurrence of)7 1673 1 3367 4828 t (a rune in a UTF string; and)6 1094 1 720 4948 t 10 CW f (utfrrune)1841 4948 w 10 R f (a pointer to the last.)4 799 1 2348 4948 t 10 CW f (Utfutf)3199 4948 w 10 R f (searches for the first occurrence of a)6 1455 1 3585 4948 t ( the synchronizing property of UTF\2552,)5 1586( Given)1 305( string.)1 289(UTF string in another UTF)4 1123 4 720 5068 t 10 CW f (utfutf)4059 5068 w 10 R f (is the same as)3 585 1 4455 5068 t 10 CW f (strstr)720 5188 w 10 R f (if the arguments point to valid UTF strings.)7 1739 1 1105 5188 t (It is a mistake to use)5 859 1 970 5344 t 10 CW f (strchr)1862 5344 w 10 R f (or)2255 5344 w 10 CW f (strrchr)2371 5344 w 10 R f ( is, a)2 204(unless searching for a 7\255bit ASCII character, that)7 2012 2 2824 5344 t (character less than)2 736 1 720 5464 t 10 CW f (Runeself)1481 5464 w 10 R f (.)1961 5464 w (We have no routines for manipulating null\255terminated arrays of)8 2550 1 970 5620 t 10 CW f (Runes)3547 5620 w 10 R f ( should prob\255)2 539( they)1 199(. Although)1 455 3 3847 5620 t ( we have found no need for them, for the same reason that)12 2343(ably exist for completeness,)3 1124 2 720 5740 t 10 CW f (%S)4214 5740 w 10 R f (and)4361 5740 w 10 CW f (L"...")4532 5740 w 10 R f (are)4919 5740 w (rarely used.)1 465 1 720 5860 t ( contains)1 365( BIO)1 229(Most Plan 9 programs use a new buffered I/O library, BIO, in place of Standard I/O.)15 3476 3 970 6016 t (routines to read and write UTF streams, converting to and from runes.)11 2952 1 720 6136 t 10 CW f (Bgetrune)3736 6136 w 10 R f (returns, as a)2 507 1 4255 6136 t 10 CW f (Rune)4800 6136 w 10 R f (within a)1 335 1 720 6256 t 10 CW f (long)1090 6256 w 10 R f (, the next character in the UTF input stream;)8 1852 1 1330 6256 t 10 CW f (Bputrune)3217 6256 w 10 R f (takes a rune and writes its UTF)6 1308 1 3732 6256 t (representation.)720 6376 w 10 CW f (Bungetrune)1360 6376 w 10 R f (puts a rune back into the input stream for rereading.)9 2068 1 1985 6376 t ( these)1 239( Converting)1 509(Plan 9 programs use a simple set of macros to process command line arguments.)13 3322 3 970 6532 t ( general, argument)2 771( In)1 146( automatically updated the argument processing of most programs.)8 2770(macros to UTF)2 633 4 720 6652 t (flag names can no longer be held in bytes and arrays of 256 bytes cannot be used to hold a set of flags.)22 4095 1 720 6772 t ( do not feel qualified to)5 1005(We have done nothing analogous to ANSI C's locales, partly because we)11 3065 2 970 6928 t ( That)1 233( and partly because we remain unconvinced of that model for dealing with the problems.)14 3535(define locales)1 552 3 720 7048 t ( conversion to a larger character set; on the other hand,)10 2271(is really more an issue of internationalization than)7 2049 2 720 7168 t (because we have chosen a single character set that encompasses most languages, some of the need for)16 4320 1 720 7288 t cleartomark showpage saveobj restore %%EndPage: 5 5 %%Page: 6 6 /saveobj save def mark 6 pagesetup 10 R f (\255 6 \255)2 166 1 2797 480 t ( have a utility,)3 572( \(We)1 221(locales is eliminated.)2 841 3 720 840 t 10 CW f (tcs)2379 840 w 10 R f (, that translates between UTF and other character sets.\))8 2194 1 2559 840 t ( does not follow the ANSI design for wide and multi\255byte)10 2379(There are several reasons why our library)6 1691 2 970 996 t ( ANSI model was designed by a committee, untried, almost as an afterthought, whereas we)14 3683(characters. The)1 637 2 720 1116 t ( interface as we became familiar with)6 1513( made several major changes to the)6 1414( \(We)1 223(wanted to design as we built.)5 1170 4 720 1236 t ( the)1 154( Also,)1 271( handling of invalid multi\255byte sequences.)5 1717( disagree with ANSI C's)4 1014( We)1 196(the problems involved.\))2 968 6 720 1356 t ( multi\255byte)1 448(ANSI C library is incomplete: although it contains some crucial routines for handling wide and)14 3872 2 720 1476 t ( pre\255)1 188( example, our software can exploit the fact that UTF)9 2126( For)1 193(characters, there are some serious omissions.)5 1813 4 720 1596 t ( could remove that assumption by replacing all calls to)9 2310( We)1 202( in the byte stream.)4 819(serves ASCII characters)2 989 4 720 1716 t 10 CW f (strchr)720 1836 w 10 R f (with)1109 1836 w 10 CW f (utfrune)1316 1836 w 10 R f ( we have actu\255)3 587( of the weaker properties of the original UTF,)8 1853( \(Because)1 419(and so on.)2 416 4 1765 1836 t ( portable code should)3 872( C cannot: the standard says nothing about the representation, so)10 2612( ANSI)1 287(ally done so.\))2 549 4 720 1956 t 10 I f (never)720 2076 w 10 R f (call)980 2076 w 10 CW f (strchr)1163 2076 w 10 R f (, yet there is no ANSI equivalent to)7 1513 1 1523 2076 t 10 CW f (utfrune)3075 2076 w 10 R f ( C simultaneously invalidates)3 1223(. ANSI)1 322 2 3495 2076 t 10 CW f (strchr)720 2196 w 10 R f (and offers no replacement.)3 1063 1 1105 2196 t ( characters into the I/O system: it gives no method for)10 2263(Finally, ANSI did nothing to integrate wide)6 1807 2 970 2352 t ( In)1 138( therefore needed to invent some things and decided to invent everything.)11 2989( We)1 193( characters.)1 458(printing wide)1 542 5 720 2472 t ( ANSI routines)2 609(the end, some of our entry points do correspond closely to)10 2332 2 720 2592 t 10 S1 f (\320)3661 2592 w 10 R f (for example)1 481 1 3761 2592 t 10 CW f (chartorune)4269 2592 w 10 R f (and)4896 2592 w 10 CW f (runetochar)720 2712 w 10 R f (are similar to)2 571 1 1367 2712 t 10 CW f (mbtowc)1985 2712 w 10 R f (and)2391 2712 w 10 CW f (wctomb)2581 2712 w 10 S1 f (\320)2941 2712 w 10 R f (but Plan 9's library defines more functionality,)6 1999 1 3041 2712 t (enough to write real applications comfortably.)5 1847 1 720 2832 t 10 B f (Converting the tools)2 866 1 720 3072 t 10 R f ( already been converted to work with Latin\2551, so it was)10 2244(The source for our tools and applications had)7 1826 2 970 3228 t ( programs needed no change at)5 1238( Some)1 278( Unicode and UTF is more involved.)6 1468(`8\255bit safe', but the conversion to)5 1336 4 720 3348 t (all:)720 3468 w 10 CW f (cat)875 3468 w 10 R f ( UTF, as file names that it passes uninter\255)8 1686(, for instance, interprets its argument strings, delivered in)8 2299 2 1055 3468 t (preted to the)2 507 1 720 3588 t 10 CW f (open)1256 3588 w 10 R f ( its output; it never makes deci\255)6 1278(system call, and then just copies bytes from its input to)10 2237 2 1525 3588 t ( 9)1 88( \(Plan)1 274( on the values of the bytes.)6 1146(sions based)1 470 4 720 3708 t 10 CW f (cat)2736 3708 w 10 R f (has no options such as)4 946 1 2954 3708 t 10 CW f (\255v)3938 3708 w 10 R f (to complicate matters.\))2 944 1 4096 3708 t (Most programs, however, needed modest change.)5 1979 1 720 3828 t ( places that need attention, but)5 1230(It is difficult to find automatically the)6 1517 2 970 3984 t 10 CW f (grep)3745 3984 w 10 R f ( that uses)2 378(helps. Software)1 649 2 4013 3984 t ( examine bytes as characters:)4 1191(the libraries conscientiously can be searched for calls to library routines that)11 3129 2 720 4104 t 10 CW f (strchr)720 4224 w 10 R f (,)1080 4224 w 10 CW f (strrchr)1139 4224 w 10 R f (,)1559 4224 w 10 CW f (strstr)1618 4224 w 10 R f ( these by calls to)4 702( Replacing)1 464(, etc.)1 200 3 1978 4224 t 10 CW f (utfrune)3379 4224 w 10 R f (,)3799 4224 w 10 CW f (utfrrune)3859 4224 w 10 R f (, and)1 204 1 4339 4224 t 10 CW f (utfutf)4578 4224 w 10 R f (is)4973 4224 w ( internally; more typically they)4 1258( tools actually need to operate on runes)7 1603( Few)1 228(enough to fix many programs.)4 1231 4 720 4344 t ( the 170 C source programs)5 1126( Of)1 159(need only to look for the final slash in a file name and similar trivial tasks.)15 3035 3 720 4464 t (in the top levels of)4 744 1 720 4584 t 10 CW f (/sys/src/cmd)1489 4584 w 10 R f (, only 23 now contain the word)6 1246 1 2209 4584 t 10 CW f (Rune)3480 4584 w 10 R f (.)3720 4584 w (The programs that)2 732 1 970 4740 t 10 I f (do)1727 4740 w 10 R f (store runes internally are mostly those whose)6 1803 1 1852 4740 t 10 I f (raison d'\352tre)1 519 1 3680 4740 t 10 R f (is character manipu\255)2 816 1 4224 4740 t (lation:)720 4860 w 10 CW f (sam)1004 4860 w 10 R f (\(the text editor\),)2 652 1 1212 4860 t 10 CW f (sed)1892 4860 w 10 R f (,)2072 4860 w 10 CW f (sort)2125 4860 w 10 R f (,)2365 4860 w 10 CW f (tr)2418 4860 w 10 R f (,)2538 4860 w 10 CW f (troff)2590 4860 w 10 R f (,)2890 4860 w 10 CW f (8\275)2942 4860 w 10 R f (\(the window system and terminal emulator\), and)6 1951 1 3089 4860 t ( the cost)2 343( decide whether to compute using runes or UTF\255encoded byte strings requires balancing)12 3569( To)1 165(so on.)1 243 4 720 4980 t ( For)1 196( relevant text on demand.)4 1040(of converting the data when read and written against the cost of converting)12 3084 3 720 5100 t ( a long time with a relatively constant dataset, runes are the better choice.)13 2982(programs such as editors that run)5 1338 2 720 5220 t ( they are more complicated: plain ASCII text grows when converted)10 2748(There are space considerations too, but)5 1572 2 720 5340 t (to runes; UTF\255encoded Japanese shrinks.)4 1644 1 720 5460 t (Again, it is hard to automate the conversion of a program from)11 2573 1 970 5616 t 10 CW f (chars)3574 5616 w 10 R f (to)3905 5616 w 10 CW f (Runes)4014 5616 w 10 R f ( not enough)2 486( is)1 98(. It)1 142 3 4314 5616 t ( are equivalent can be insidi\255)5 1180(just to change the type of variables; the assumption that bytes and characters)12 3140 2 720 5736 t ( instance, to clear a character array by)7 1510(ous. For)1 353 2 720 5856 t 9 CW f (memset\(buf, 0, BUFSIZE\))2 1242 1 1008 6026 t 10 R f (becomes wrong if)2 745 1 720 6206 t 10 CW f (buf)1505 6206 w 10 R f ( an array of)3 504(is changed from)2 673 2 1725 6206 t 10 CW f (chars)2943 6206 w 10 R f (to an array of)3 582 1 3284 6206 t 10 CW f (Runes)3907 6206 w 10 R f ( program that)2 570(. Any)1 263 2 4207 6206 t ( Consider)1 424(indexes tables based on character values needs rethinking.)7 2413 2 720 6326 t 10 CW f (tr)3595 6326 w 10 R f ( used multiple)2 591(, which originally)2 734 2 3715 6326 t ( Instead)1 348( na\357ve conversion would yield multiple 65536\255rune arrays.)7 2411( The)1 214(256\255byte arrays for the mapping.)4 1347 4 720 6446 t (Plan 9)1 253 1 720 6566 t 10 CW f (tr)998 6566 w 10 R f (saves space by building in effect a run\255encoded version of the map.)11 2688 1 1143 6566 t 10 CW f (Sort)970 6722 w 10 R f ( cooperation of UTF and)4 1027( The)1 215(has related problems.)2 871 3 1245 6722 t 10 CW f (strcmp)3393 6722 w 10 R f ( simple sort)2 489(means that a)2 519 2 3788 6722 t 10 S1 f (\320)4796 6722 w 10 R f (one)4896 6722 w (with no options)2 641 1 720 6842 t 10 S1 f (\320)1361 6842 w 10 R f (can be done on the original UTF strings using)8 1896 1 1461 6842 t 10 CW f (strcmp)3390 6842 w 10 R f ( sorting options enabled,)3 1007(. With)1 283 2 3750 6842 t (however,)720 6962 w 10 CW f (sort)1126 6962 w 10 R f ( for example, option)3 852(may need to convert its input to runes:)7 1626 2 1404 6962 t 10 CW f (\255t)3921 6962 w 10 S f (a)4041 6962 w 10 R f (requires searching for)2 897 1 4143 6962 t ( field specifier)2 582( The)1 208(alphas in the input text to crack the input into fields.)10 2115 3 720 7082 t 10 CW f (+3.2)3652 7082 w 10 R f (refers to 2 runes beyond the)5 1121 1 3919 7082 t ( the other options are hopelessly provincial: consider the case\255folding and dictionary)11 3485( of)1 117( Some)1 287(third field.)1 431 4 720 7202 t cleartomark showpage saveobj restore %%EndPage: 6 6 %%Page: 7 7 /saveobj save def mark 7 pagesetup 10 R f (\255 7 \255)2 166 1 2797 480 t (order options \(Japanese doesn't even have an official dictionary order\) or)10 3075 1 720 840 t 10 CW f (\255M)3834 840 w 10 R f (which compares by case\255)3 1047 1 3993 840 t ( larger issues of internationalization)4 1467( these options involves the)4 1093( Handling)1 430(insensitive English month name.)3 1330 4 720 960 t ( 9)1 87( Plan)1 240( beyond the scope of this paper and our expertise.)9 2087(and is)1 249 4 720 1080 t 10 CW f (sort)3420 1080 w 10 R f (works sensibly with options that)4 1343 1 3697 1080 t ( simple and most important options are, however, usually meaningful.)9 2816( The)1 207(make sense relative to the input.)5 1297 3 720 1200 t (In particular,)1 515 1 720 1320 t 10 CW f (sort)1260 1320 w 10 R f (sorts UTF into the same order that)6 1371 1 1525 1320 t 10 CW f (look)2921 1320 w 10 R f (expects.)3186 1320 w ( Deterministic)1 607(Regular expression\255matching algorithms need rethinking to be applied to UTF text.)10 3463 2 970 1476 t ( awk\255)1 227(automata are usually applied to bytes; converting them to operate on variable\255sized byte sequences is)14 4093 2 720 1596 t ( measurable expense and the state tables)6 1619( the other hand, converting the input stream to runes adds)10 2304(ward. On)1 397 3 720 1716 t ( simple string searching, the)4 1136( For)1 192(expand from size 256 to 65536; it can be expensive just to generate them.)13 2992 3 720 1836 t ( strings;)1 333(Boyer\255Moore algorithm works with UTF provided the input is guaranteed to be only valid UTF)14 3987 2 720 1956 t ( level, even character classes are)5 1294( a more mundane)3 693( At)1 151(however, it does not work with the old UTF encoding.)9 2182 4 720 2076 t ( with 65536)2 506(harder: the usual bit\255vector representation within a non\255deterministic automaton is unwieldy)10 3814 2 720 2196 t (characters in the alphabet.)3 1041 1 720 2316 t ( and executing regular expressions was adapted)6 1931( existing library for compiling)4 1225( An)1 177(We compromised.)1 737 4 970 2472 t ( on runes, with two entry points for searching in arrays of runes and arrays of chars \(the pattern is)19 4005(to work)1 315 2 720 2592 t ( internally as runs of runes; the reserved Unicode value)9 2221( classes are represented)3 935( Character)1 438(always UTF text\).)2 726 4 720 2712 t 10 CW f (FFFF)720 2832 w 10 R f ( Then)1 271(marks the end of the class.)5 1139 2 1001 2832 t 10 I f (all)2452 2832 w 10 R f ( regular expressions)2 828(utilities that use)2 666 2 2599 2832 t 10 S1 f (\320)4093 2832 w 10 R f (editors,)4193 2832 w 10 CW f (grep)4530 2832 w 10 R f (,)4770 2832 w 10 CW f (awk)4835 2832 w 10 R f (,)5015 2832 w (etc.)720 2952 w 10 S1 f (\320)861 2952 w 10 R f ( some pro\255)2 433( For)1 192( was grandfathered, were converted to use the library.)8 2167(except the shell, whose notation)4 1287 4 961 2952 t ( our knowl\255)2 470( To)1 164(grams, there was a concomitant loss of performance, but there was also a strong advantage.)14 3686 3 720 3072 t ( single definition and implementation of regular expres\255)7 2254(edge, Plan 9 is the only Unix\255like system that has a)10 2066 2 720 3192 t (sions; patterns are written and interpreted identically by all the programs in the system.)13 3479 1 720 3312 t ( the issue)2 376(A handful of programs have the notion of character built into them so strongly as to confuse)16 3694 2 970 3468 t ( exam\255)1 274( For)1 189( programs were treated as individual special cases.)7 2017( Such)1 250( they should do with UTF input.)6 1287(of what)1 303 6 720 3588 t (ple,)720 3708 w 10 CW f (wc)895 3708 w 10 R f ( option,)1 310(is, by default, unchanged in behavior and output; a new)9 2243 2 1043 3708 t 10 CW f (\255r)3625 3708 w 10 R f (, counts the number of correctly)5 1295 1 3745 3708 t (encoded runes)1 573 1 720 3828 t 10 S1 f (\320)1293 3828 w 10 R f (valid UTF sequences)2 843 1 1393 3828 t 10 S1 f (\320)2236 3828 w 10 R f (in its input;)2 457 1 2336 3828 t 10 CW f (\255b)2818 3828 w 10 R f (the number of invalid sequences.)4 1317 1 2963 3828 t ( UTF.)1 255(It took us several months to convert all the software in the system to Unicode and the old)17 3815 2 970 3984 t ( we)1 153( First,)1 271( the new UTF, only three things needed to be done.)10 2167(When we decided to convert from that to)7 1729 4 720 4104 t ( we converted)2 563( Next,)1 271( took an evening.)3 694( This)1 230(rewrote the library routines to encode and decode the new UTF.)10 2562 5 720 4224 t ( non\255ASCII bytes)2 711( wrote a trivial program to look for)7 1423( We)1 192(all the files containing UTF to the new encoding.)8 1994 4 720 4344 t (in text files and used a Plan 9 program called)9 1872 1 720 4464 t 10 CW f (tcs)2625 4464 w 10 R f ( Finally,)1 368(\(translate character set\) to change encodings.)5 1834 2 2838 4464 t ( so recompilation was sufficient)4 1276(we recompiled all the system software; the library interface was unchanged,)10 3044 2 720 4584 t ( con\255)1 204( We)1 190( an afternoon.)2 555( second two steps were done concurrently and took)8 2048( The)1 206(to effect the transformation.)3 1117 6 720 4704 t ( to the software; the adoption of large characters)8 2000(cluded that the actual encoding is relatively unimportant)7 2320 2 720 4824 t (and a byte\255stream encoding)3 1100 1 720 4944 t 10 I f (per se)1 241 1 1845 4944 t 10 R f (are much deeper issues.)3 947 1 2111 4944 t 10 B f (Graphics and fonts)2 818 1 720 5184 t 10 R f ( instead designed to be used with)6 1351( is)1 96( It)1 115(Plan 9 provides only minimal support for plain text terminals.)9 2508 4 970 5340 t ( window system such as)4 990(all character input and output mediated by a)7 1804 2 720 5460 t 10 CW f (8\275)3545 5460 w 10 R f ( window system and related)4 1139(. The)1 236 2 3665 5460 t ( plain text, the win\255)4 804( For)1 195(software are responsible for the display of UTF text as Unicode character images.)12 3321 3 720 5580 t (dow system must provide a user\255settable)5 1688 1 720 5700 t 10 I f (font)2446 5700 w 10 R f ( empty\) picture for each Unicode)5 1381(that provides a \(possibly)3 1019 2 2640 5700 t ( multiple pic\255)2 551( applications that use bold and Italic characters need multiple fonts storing)11 3026(character. Fancier)1 743 3 720 5820 t ( of displaying a single)4 887( the issues are apparent, though, in just the problem)9 2074( All)1 180(tures for each Unicode value.)4 1179 4 720 5940 t ( 128 or even 256)4 715( With)1 261( of a plain text terminal.)5 1015(image for each character, that is, the Unicode equivalent)8 2329 4 720 6060 t ( 65536 characters, a more sophisticated design is)7 2015( With)1 259( of bitmaps.)2 493(characters, a font can be just an array)7 1553 4 720 6180 t ( ideographs for just Japanese as 16)6 1422( store the)2 376(necessary. To)1 578 3 720 6300 t 10 S f (\264)3096 6300 w 10 R f (16)3151 6300 w 10 S f (\264)3251 6300 w 10 R f (1 bit images, the smallest they can reason\255)7 1734 1 3306 6300 t ( and)1 173( the images a little larger, store more bits per pixel,)10 2086( Make)1 282(ably be, takes over a quarter of a megabyte.)8 1779 4 720 6420 t (hold a copy in every running application, and the memory cost becomes unreasonable.)12 3455 1 720 6540 t ( summary,)1 425( In)1 136( [Pike91].)1 397(The structure of the bitmap graphics services is described at length elsewhere)11 3112 4 970 6696 t ( same machine that has the display, mouse, and keyboard:)9 2361(the memory holding the bitmaps is stored in the)8 1959 2 720 6816 t ( memory and associated ser\255)4 1164( to that)2 290( Access)1 338(the terminal in Plan 9 terminology, the workstation in others'.)9 2528 4 720 6936 t ( of those files,)3 662( One)1 248( by system software on the terminal.)6 1643(vices is provided by device files served)6 1767 4 720 7056 t 10 CW f (/dev/bitblt)720 7176 w 10 R f ( actions corresponding to entry points in)6 1616(, interprets messages written upon it as requests for)8 2044 2 1380 7176 t ( window)1 362( The)1 220( draw a text string, etc.)5 987(the graphics library: allocate a bitmap, execute a raster operation,)9 2751 4 720 7296 t cleartomark showpage saveobj restore %%EndPage: 7 7 %%Page: 8 8 /saveobj save def mark 8 pagesetup 10 R f (\255 8 \255)2 166 1 2797 480 t ( that mediates access to the services and resources of the terminal by simulating)13 3199(system acts as a multiplexer)4 1121 2 720 840 t ( is, each window has a dis\255)6 1073( That)1 233( client window a set of files mirroring those provided by the system.)12 2728(in each)1 286 4 720 960 t (tinct)720 1080 w 10 CW f (/dev/mouse)926 1080 w 10 R f (,)1526 1080 w 10 CW f (/dev/bitblt)1579 1080 w 10 R f ( so on through which applications drive graphical input and out\255)10 2604(, and)1 197 2 2239 1080 t (put.)720 1200 w (One of the resources managed by)5 1392 1 970 1356 t 10 CW f (8\275)2399 1356 w 10 R f (and the terminal is the set of active)7 1486 1 2557 1356 t 10 I f (subfonts.)4081 1356 w 10 R f (Each subfont)1 537 1 4503 1356 t ( are)1 156( Subfonts)1 416( data structures for a sequential set of Unicode characters.)9 2394(holds the bitmaps and associated)4 1354 4 720 1476 t ( and loaded into the terminal by)6 1307(stored in files)2 554 2 720 1596 t 10 CW f (8\275)2612 1596 w 10 R f ( example, one subfont might hold)5 1374( For)1 195(or an application.)2 708 3 2763 1596 t ( set;)1 178(the images of the first 256 characters of the Unicode space, corresponding to the Latin\2551 character)15 4142 2 720 1716 t ( These)1 289( characters with value 0250 to 02A8.)6 1478(another might hold the standard phonetic character set, Unicode)8 2553 3 720 1836 t (files are collected in directories corresponding to typefaces:)7 2422 1 720 1956 t 10 CW f (/lib/font/bit/pelm)3173 1956 w 10 R f (contains the Pellu\255)2 756 1 4284 1956 t ( Latin\2551, Greek, Cyrillic and other components of)7 2032(cida Monospace character set, with subfonts holding the)7 2288 2 720 2076 t ( \(in a subfont\255specific way\) the size of the images:)9 2249( suffix on subfont files encodes)5 1386( A)1 149(the typeface.)1 536 4 720 2196 t 10 CW f (/lib/font/bit/pelm/latin1.9)720 2316 w 10 R f (contains the Latin\2551 Pellucida Monospace characters with lower)7 2662 1 2378 2316 t (case letters 9 pixels high;)4 1110 1 720 2436 t 10 CW f (/lib/font/bit/jis/jis5400.16)1880 2436 w 10 R f ( high ideographs)2 714(contains 16\255pixel)1 716 2 3610 2436 t (starting at Unicode value 5400.)4 1251 1 720 2556 t ( a font file, in)4 569( Instead,)1 370( do not identify which portion of the Unicode space they cover.)11 2606(The subfonts)1 525 4 970 2712 t ( font file is presented as an)6 1070( The)1 205( to assemble subfonts into a complete character set.)8 2049(plain text, describes how)3 996 4 720 2832 t ( in text windows and applications.)5 1386(argument to the window system to determine how plain text is displayed)11 2934 2 720 2952 t (Here is the beginning of the font file)7 1505 1 720 3072 t 10 CW f (/lib/font/bit/pelm/jis.9.font)2257 3072 w 10 R f ( the lay\255)2 339(, which describes)2 704 2 3997 3072 t ( Unicode for which we have characters of typical display size, using)11 2809(out of a font covering that portion of)7 1511 2 720 3192 t (Japanese characters to cover the Han space:)6 1743 1 720 3312 t 9 CW f (18 14)1 540 1 1008 3482 t (0x0000 0x00FF latin1.9)2 1296 1 1008 3592 t (0x0100 0x017E latineur.9)2 1404 1 1008 3702 t (0x0250 0x02E9 ipa.9)2 1134 1 1008 3812 t (0x0386 0x03F5 greek.9)2 1242 1 1008 3922 t (0x0400 0x0475 cyrillic.9)2 1404 1 1008 4032 t (0x2000 0x2044 ../misc/genpunc.9)2 1782 1 1008 4142 t (0x2070 0x208E supsub.9)2 1296 1 1008 4252 t (0x20A0 0x20AA currency.9)2 1404 1 1008 4362 t (0x2100 0x2138 ../misc/letterlike.9)2 1944 1 1008 4472 t (0x2190 0x21EA ../misc/arrows)2 1620 1 1008 4582 t (0x2200 0x227F ../misc/math1)2 1566 1 1008 4692 t (0x2280 0x22F1 ../misc/math2)2 1566 1 1008 4802 t (0x2300 0x232C ../misc/tech)2 1512 1 1008 4912 t (0x2500 0x257F ../misc/chart)2 1566 1 1008 5022 t (0x2600 0x266F ../misc/ding)2 1512 1 1008 5132 t (0x3000 0x303f ../jis/jis3000.16)2 1782 1 1008 5242 t (0x30a1 0x30fe ../jis/katakana.16)2 1836 1 1008 5352 t (0x3041 0x309e ../jis/hiragana.16)2 1836 1 1008 5462 t (0x4e00 0x4fff ../jis/jis4e00.16)2 1782 1 1008 5572 t (0x5000 0x51ff ../jis/jis5000.16)2 1782 1 1008 5682 t (...)1008 5792 w 10 R f ( the baseline to)3 617(The first two numbers set the interline spacing of the font \(18 pixels\) and the distance from)16 3703 2 720 5972 t ( they are placed so as best to fit within those)10 1800( characters are displayed,)3 1019( When)1 292(the top of the line \(14 pixels\).)6 1209 4 720 6092 t ( rest of the file associates subfont files with)8 1819( The)1 216( truncated.)1 432(constraints; characters too large to fit will be)7 1853 4 720 6212 t ( in the Pellucida Monospace typeface and directory;)7 2090( first four such files are)5 943( The)1 208(portions of Unicode space.)3 1079 4 720 6332 t ( file names are relative to the font file's own location.)10 2143( The)1 205(others reside in other directories.)4 1311 3 720 6452 t ( it simultaneously breaks the huge Uni\255)6 1577( First,)1 260( several advantages to this two\255level structure.)6 1855(There are)1 378 4 970 6608 t ( into manageable components and provides a unifying architecture for assembling fonts from)12 3872(code space)1 448 2 720 6728 t ( example, we have only one set of Japanese)8 1825( For)1 200( the structure promotes sharing.)4 1306( Second,)1 379(disjoint pieces.)1 610 5 720 6848 t ( to store only one)4 702(characters but dozens of typefaces for the Latin\2551 characters, and this structure permits us)13 3618 2 720 6968 t ( English\255)1 410( customization is easy.)3 968( Also,)1 285( set but use it with any Roman typeface.)8 1769(copy of the Japanese)3 888 5 720 7088 t ( Oxford English)2 688(speaking users who don't need Japanese characters but may want to read an on\255line)13 3632 2 720 7208 t cleartomark showpage saveobj restore %%EndPage: 8 8 %%Page: 9 9 /saveobj save def mark 9 pagesetup 10 R f (\255 9 \255)2 166 1 2797 480 t ( a custom font with the Latin\2551 \(or even just ASCII\) characters and the Interna\255)14 3319(Dictionary can assemble)2 1001 2 720 840 t ( to do so requires just editing a plain text file, not using a special)14 2579( Moreover,)1 468( \(IPA\).)1 277(tional Phonetic Alphabet)2 996 4 720 960 t ( design of caching protocols to improve performance and)8 2316( the structure guides the)4 966( Finally,)1 362(font editing tool.)2 676 4 720 1080 t (memory usage.)1 610 1 720 1200 t ( consume too much memory)4 1182(To load a complete Unicode character set into each application would)10 2888 2 970 1356 t ( Plan 9 assembles a multi\255)5 1067( Instead,)1 367(and, particularly on slow terminal lines, would take unreasonably long.)9 2886 3 720 1476 t ( application opens a font file, reads and parses it, and allocates a data)13 2765( An)1 173( structure for each font.)4 937(level cache)1 445 4 720 1596 t ( message written to)3 804(structure. A)1 506 2 720 1716 t 10 CW f (/dev/bitblt)2064 1716 w 10 R f (allocates an associated structure held in the terminal, in)8 2282 1 2758 1716 t ( messages copy these images)4 1163( Other)1 278( bitmap to act as a cache for recently used character images.)11 2403(particular, a)1 476 4 720 1836 t ( screen by loading characters from subfonts into the cache on demand and from there)14 3425(to bitmaps such as the)4 895 2 720 1956 t ( charac\255)1 319( protocol to draw characters is in terms of cache indices, not Unicode)12 2775( The)1 206(to the destination bitmap.)3 1020 4 720 2076 t ( details are hidden from the application, which instead sees only a)11 2761( These)1 300(ter number or UTF sequences.)4 1259 3 720 2196 t ( functions to discover character size information,)6 1984(subroutine to draw a string in a bitmap from a given font,)11 2336 2 720 2316 t (and routines to allocate and to free fonts.)7 1630 1 720 2436 t ( read, and then downloaded to the ter\255)7 1548(As needed, whole subfonts are opened by the graphics library,)9 2522 2 970 2592 t ( when the program closes a sub\255)6 1286( Even)1 255( library in an LRU\255replacement list.)5 1431( are held open by the)5 839(minal. They)1 509 5 720 2712 t ( terminal)1 361( the application opens the subfont, it asks the)8 1812( When)1 290(font, it is retained in the terminal for later use.)9 1857 4 720 2832 t ( level of cache has the prop\255)6 1136( This)1 230( reading it from the file server if possible.)8 1677(if it already has a copy to avoid)7 1277 4 720 2952 t ( bitmaps for, say, all the Japanese characters are stored only once, in the terminal; the applica\255)16 3835(erty that the)2 485 2 720 3072 t (tions read only size and width information from the terminal and share the images.)13 3301 1 720 3192 t ( simple algo\255)2 542( A)1 132( by the application are adaptive.)5 1325(The sizes of the character and subfont caches held)8 2071 4 970 3348 t ( size of the character)4 848( The)1 211( required.)1 388(rithm monitors the cache miss rate to enlarge and shrink the caches as)12 2873 4 720 3468 t ( For)1 201( Japanese text.)2 603(cache is limited to 2048 images maximum, which in practice seems enough even for)13 3516 3 720 3588 t (plain ASCII\255like text it naturally stays around 128 images.)8 2340 1 720 3708 t ( implemented by only about 500 lines in the library and)10 2311(This mechanism sounds complicated but is)5 1759 2 970 3864 t ( driver and)2 434(considerably less in each of the terminal's graphics)7 2057 2 720 3984 t 10 CW f (8\275)3237 3984 w 10 R f ( has the advantage that only characters)6 1546(. It)1 137 2 3357 3984 t ( the characters being drawn are in the)7 1576( is also efficient: if)4 793( It)1 122(that are being used are loaded into memory.)7 1829 4 720 4104 t ( works particularly well for alphabetic character sets, but also)9 2590( It)1 126(cache the extra overhead is negligible.)5 1604 3 720 4224 t ( a user first looks at Japanese text, it takes a few seconds to)13 2440( When)1 294( for ideographic sets.)3 855(adapts on demand)2 731 4 720 4344 t ( are larger, so)3 545(read all the font data, but thereafter the text is drawn almost as fast as regular text \(the images)18 3775 2 720 4464 t ( by the terminal, if a second application)7 1651( because the bitmaps are remembered)5 1543( Also,)1 273(draw a little slower\).)3 853 4 720 4584 t (then looks at Japanese text it starts faster than the first.)10 2183 1 720 4704 t ( the applica\255)2 501(We considered building a `font server' to cache character images and associated data for)13 3569 2 970 4860 t ( because, although isolating many of)5 1505( rejected this design)3 823( We)1 197(tions, the window system, and the terminal.)6 1795 4 720 4980 t ( in)1 105( Moreover,)1 470( font management into a separate program, it didn't simplify the applications.)11 3116(the problems of)2 629 4 720 5100 t ( the man\255)2 389( Making)1 367( easy to have too many special purpose servers.)8 1941(a distributed system such as Plan 9 it is)8 1623 4 720 5220 t ( the concern of only the essential components simplifies the system and makes boot\255)13 3481(agement of the fonts)3 839 2 720 5340 t (strapping less intricate.)2 924 1 720 5460 t 10 B f (Input)720 5700 w 10 R f ( We)1 210( the system.)2 519(A completely different problem is how to type Unicode characters as input to)12 3341 3 970 5856 t ( gen\255)1 202(selected an unused key on our ASCII keyboards to serve as a prefix for multi\255keystroke sequences that)16 4118 2 720 5976 t ( example, the character \374 is generated by the prefix key \(typically)11 2747( For)1 201(erate Unicode characters.)2 1033 3 720 6096 t 10 CW f (ALT)4739 6096 w 10 R f (or)4957 6096 w 10 CW f (Compose)720 6216 w 10 R f ( the application,)2 645( that character is read by)5 992( When)1 291(\) followed by a double quote and a lower\255case u.)9 1972 4 1140 6216 t (from the file)2 503 1 720 6336 t 10 CW f (/dev/cons)1250 6336 w 10 R f ( sequences generate charac\255)3 1117( Such)1 253( course presented as its UTF encoding.)6 1568(, it is of)3 312 4 1790 6336 t ( technical charac\255)2 708(ters from an arbitrary set that includes all of Latin\2551 plus a selection of mathematical and)15 3612 2 720 6456 t ( and four hex\255)3 571( arbitrary Unicode character may be generated by typing the prefix, an upper case X,)14 3406(ters. An)1 343 3 720 6576 t (adecimal digits that identify the Unicode value.)6 1895 1 720 6696 t ( day\255to\255day needs: it's easy to remember to)7 1797(These simple mechanisms are adequate for most of our)8 2273 2 970 6852 t ( the occasional unusual charac\255)4 1262( For)1 193( Latin letters.)2 538( `ALT accent letter' for accented)5 1333( or)1 121(type `ALT 1 2' for \275)5 873 6 720 6972 t (ter, the cut and paste features of)6 1301 1 720 7092 t 10 CW f (8\275)2051 7092 w 10 R f ( program called \(perhaps misleadingly\))4 1589( A)1 127(serve well.)1 437 3 2201 7092 t 10 CW f (unicode)4384 7092 w 10 R f (takes)4835 7092 w ( UTF representation of that character, which may then be)9 2346(as argument a hexadecimal value, and prints the)7 1974 2 720 7212 t cleartomark showpage saveobj restore %%EndPage: 9 9 %%Page: 10 10 /saveobj save def mark 10 pagesetup 10 R f (\255 10 \255)2 216 1 2772 480 t (picked up with the mouse and used as input.)8 1768 1 720 840 t ( the native)2 448( In)1 148(These methods are clearly unsatisfactory when working in a non\255English language.)10 3474 3 970 996 t ( it's also reasonable)3 829( But)1 208( to be at hand.)4 615(country of such a language the appropriate keyboard is likely)9 2568 4 720 1116 t 10 S1 f (\320)4940 1116 w 10 R f (especially now the system handles Unicode)5 1739 1 720 1236 t 10 S1 f (\320)2459 1236 w 10 R f (to work in a language foreign to the keyboard.)8 1849 1 2559 1236 t ( Russian, it is straightforward to construct a program that)9 2344(For alphabetic languages such as Greek or)6 1726 2 970 1392 t ( yields the Greek `)4 781(does phonetic substitution, so that, for example, typing a Latin `a')10 2754 2 720 1512 t 10 S f (a)4255 1512 w 10 R f ( Plan 9,)2 325('. Within)1 397 2 4318 1512 t (such a program can be inserted transparently between the real keyboard and a program such as the window)17 4320 1 720 1632 t (system, providing a manageable input device for such languages.)8 2601 1 720 1752 t ( users of such)3 567( Native)1 323( the problem is harder.)4 929(For ideographic languages such as Chinese or Japanese)7 2251 4 970 1908 t ( involve a hybrid technique based on)6 1476(languages have adopted methods for dealing with Latin keyboards that)9 2844 2 720 2028 t ( choose the desired one.)4 1020(phonetics to generate a list of possible symbols followed by menu selection to)12 3300 2 720 2148 t ( be effective, but their design must be rooted in information about the language unknown)14 3587(Such methods can)2 733 2 720 2268 t ( \()1 98(to non\255native speakers.)2 953 2 720 2388 t 10 CW f (Cxterm)1771 2388 w 10 R f ( emulator built by and for Chinese programmers,)7 2065(, a Chinese terminal)3 844 2 2131 2388 t ( the technical problem of implementing such a)7 1954( Although)1 443(employs such a technique [Pong and Zhang].\))6 1923 3 720 2508 t (device is easy in Plan 9)5 985 1 720 2628 t 10 S1 f (\320)1705 2628 w 10 R f ( alphabetic languages)2 881(it is just an elaboration of the technique for)8 1800 2 1805 2628 t 10 S1 f (\320)4486 2628 w 10 R f (our lack of)2 454 1 4586 2628 t (familiarity with such languages has restrained our enthusiasm for building one.)10 3160 1 720 2748 t ( emotionally the most important of)5 1427(The input problem is technically the least interesting but perhaps)9 2643 2 970 2904 t ( that remain the deeper prob\255)5 1170( Beyond)1 364( a system to an international character set.)7 1695(the problems of converting)3 1091 4 720 3024 t ( and command names, problems we are not)7 1737(lems of internationalization such as multi\255lingual error messages)7 2583 2 720 3144 t ( the ability to treat text of most languages on an equal footing, though, we can)15 3311( With)1 263( solve.)1 274(qualified to)1 472 4 720 3264 t ( will consider adopting Plan 9,)5 1292( people in non\255English speaking countries)5 1744( Perhaps)1 379(begin down that path.)3 905 4 720 3384 t (solving the input problem locally)4 1372 1 720 3504 t 10 S1 f (\320)2092 3504 w 10 R f ( their local terminals)3 854(perhaps just by plugging in)4 1133 2 2192 3504 t 10 S1 f (\320)4179 3504 w 10 R f (and begin to use a)4 761 1 4279 3504 t (system with at least the capacity to be international.)8 2067 1 720 3624 t 10 B f (Acknowledgements)720 3864 w 10 R f ( Flandrena converted most of the)5 1417( Bob)1 237( and encouragement.)2 868(Dennis Ritchie provided consultation)3 1548 4 970 4020 t ( implementations and)2 875( Kernighan suffered cheerfully with several inadequate)6 2241( Brian)1 280(standard tools to UTF.)3 924 4 720 4140 t (converted)720 4260 w 10 CW f (troff)1146 4260 w 10 R f ( Hobby built the)3 680( John)1 248( Drechsler converted his Postscript driver to UTF.)7 2060( Rich)1 248(to UTF.)1 325 5 1479 4260 t (Postscript)720 4380 w 10 S1 f ()1140 4380 w 1140 4380 m 70 build_smiley 1210 4380 m 10 R f ( thank them all.)3 622(. We)1 213 2 1210 4380 t 10 B f (References)720 4620 w 10 R f ([ANSIC])720 4776 w 10 I f ( for Information Systems)3 1028(American National Standard)2 1182 2 1124 4776 t 10 S1 f (\261)3373 4776 w 10 I f (Programming Language C)2 1106 1 3477 4776 t 10 R f (, American)1 457 1 4583 4776 t (National Standards Institute, Inc., New York, 1990)6 2036 1 720 4896 t ( 10646\2551:1993)1 592([ISO10646] ISO/IEC DIS)2 1048 2 720 5052 t 10 I f (Information technology)1 947 1 2391 5052 t 10 S1 f (\261)3369 5052 w 10 I f (Universal Multiple\255Octet Coded Char\255)3 1575 1 3465 5052 t (acter Set \(UCS\))2 632 1 720 5172 t 10 S1 f (\320)1377 5172 w 10 I f (Part 1: Architecture and Basic Multilingual Plane)6 2016 1 1502 5172 t 10 R f ( ``Plan 9 from Bell Labs'', UKUUG Proc. of the)9 2001([Pike90] R. Pike, D. Presotto, K. Thompson, H. Trickey,)8 2319 2 720 5328 t (Summer 1990 Conf., London, England, 1990)5 1808 1 720 5448 t ([Pike91] Pike, R., ``8.5, The Plan 9 Window System'', USENIX Summer Conf. Proc., Nashville, 1991)14 4114 1 720 5604 t ([Pike92] Pike, R., ``How to Use the Plan 9 C Compiler'', in)11 2517 1 720 5760 t 10 I f ( Manual)1 348(The Plan 9 Programmer's)3 1085 2 3273 5760 t 10 R f (, AT&T)1 334 1 4706 5760 t (Bell Laboratories, Murray Hill, NJ, 1992)5 1637 1 720 5880 t ( Emulator for the X)4 786([Pong and Zhang] Man\255Chi Pong and Yongguang Zhang, ``cxterm: A Chinese Terminal)11 3534 2 720 6036 t (Window System'',)1 755 1 720 6156 t 10 I f (Software)1500 6156 w 10 S1 f (\261)1856 6156 w 10 I f (Practice and Experience,)2 1011 1 1921 6156 t 10 R f (Vol 22\(1\), 809\255926, October 1992.)4 1395 1 2957 6156 t ([Unicode])720 6312 w 10 I f (The Unicode Standard, Worldwide Character Encoding, Version 1.0, Volume 1)9 3287 1 1161 6312 t 10 R f (, The Unicode)2 592 1 4448 6312 t (Consortium, Addison Wesley, New York, 1991)5 1904 1 720 6432 t cleartomark showpage saveobj restore %%EndPage: 10 10 %%Trailer done %%Pages: 10 %%DocumentFonts: Times-Bold Times-Italic Times-Roman Symbol Courier Times-Roman