Browse Source

Plan 9 from Bell Labs 2006-01-15

David du Colombier 18 years ago
parent
commit
5ec998cc2d
77 changed files with 9084 additions and 4686 deletions
  1. 73 83
      dist/replica/_plan9.db
  2. 73 83
      dist/replica/plan9.db
  3. 303 0
      dist/replica/plan9.log
  4. 0 342
      sys/src/cmd/aux/antiword/COPYING
  5. 0 180
      sys/src/cmd/aux/antiword/ChangeLog
  6. 0 134
      sys/src/cmd/aux/antiword/Emacs
  7. 0 14
      sys/src/cmd/aux/antiword/Exmh
  8. 0 97
      sys/src/cmd/aux/antiword/FAQ
  9. 0 44
      sys/src/cmd/aux/antiword/History
  10. 0 88
      sys/src/cmd/aux/antiword/Mozilla
  11. 0 24
      sys/src/cmd/aux/antiword/Mutt
  12. 0 129
      sys/src/cmd/aux/antiword/Netscape
  13. 0 56
      sys/src/cmd/aux/antiword/QandA
  14. 0 113
      sys/src/cmd/aux/antiword/ReadMe
  15. 0 143
      sys/src/cmd/aux/antiword/antiword.1.txt
  16. 158 61
      sys/src/cmd/aux/antiword/antiword.h
  17. 0 146
      sys/src/cmd/aux/antiword/antiword.man
  18. 0 34
      sys/src/cmd/aux/antiword/antiword.php
  19. 233 92
      sys/src/cmd/aux/antiword/blocklist.c
  20. 184 70
      sys/src/cmd/aux/antiword/chartrans.c
  21. 16 1
      sys/src/cmd/aux/antiword/debug.h
  22. 43 40
      sys/src/cmd/aux/antiword/dib2sprt.c
  23. 75 0
      sys/src/cmd/aux/antiword/doclist.c
  24. 433 435
      sys/src/cmd/aux/antiword/draw.c
  25. 422 0
      sys/src/cmd/aux/antiword/drawfile.c
  26. 433 0
      sys/src/cmd/aux/antiword/drawfile.h
  27. 8 18
      sys/src/cmd/aux/antiword/findtext.c
  28. 167 0
      sys/src/cmd/aux/antiword/fmt_text.c
  29. 0 207
      sys/src/cmd/aux/antiword/fontinfo.pl
  30. 18 9
      sys/src/cmd/aux/antiword/fontlist.c
  31. 243 74
      sys/src/cmd/aux/antiword/fonts.c
  32. 21 19
      sys/src/cmd/aux/antiword/fonts_r.c
  33. 54 36
      sys/src/cmd/aux/antiword/fonts_u.c
  34. 371 0
      sys/src/cmd/aux/antiword/hdrftrlist.c
  35. 30 28
      sys/src/cmd/aux/antiword/icons.c
  36. 57 27
      sys/src/cmd/aux/antiword/imgexam.c
  37. 0 386
      sys/src/cmd/aux/antiword/main_r.c
  38. 520 0
      sys/src/cmd/aux/antiword/main_ros.c
  39. 60 17
      sys/src/cmd/aux/antiword/main_u.c
  40. 280 33
      sys/src/cmd/aux/antiword/misc.c
  41. 8 6
      sys/src/cmd/aux/antiword/mkfile
  42. 548 69
      sys/src/cmd/aux/antiword/notes.c
  43. 317 153
      sys/src/cmd/aux/antiword/options.c
  44. 150 52
      sys/src/cmd/aux/antiword/out2window.c
  45. 82 10
      sys/src/cmd/aux/antiword/output.c
  46. 1148 0
      sys/src/cmd/aux/antiword/pdf.c
  47. 16 7
      sys/src/cmd/aux/antiword/pictlist.c
  48. 268 26
      sys/src/cmd/aux/antiword/postscript.c
  49. 136 15
      sys/src/cmd/aux/antiword/prop0.c
  50. 122 29
      sys/src/cmd/aux/antiword/prop2.c
  51. 203 72
      sys/src/cmd/aux/antiword/prop6.c
  52. 322 182
      sys/src/cmd/aux/antiword/prop8.c
  53. 59 6
      sys/src/cmd/aux/antiword/properties.c
  54. 64 103
      sys/src/cmd/aux/antiword/riscos.c
  55. 1 2
      sys/src/cmd/aux/antiword/rowlist.c
  56. 201 144
      sys/src/cmd/aux/antiword/saveas.c
  57. 51 11
      sys/src/cmd/aux/antiword/sectlist.c
  58. 32 46
      sys/src/cmd/aux/antiword/startup.c
  59. 33 8
      sys/src/cmd/aux/antiword/stylelist.c
  60. 85 64
      sys/src/cmd/aux/antiword/stylesheet.c
  61. 85 44
      sys/src/cmd/aux/antiword/summary.c
  62. 10 18
      sys/src/cmd/aux/antiword/tabstop.c
  63. BIN
      sys/src/cmd/aux/antiword/testdoc.doc
  64. 7 7
      sys/src/cmd/aux/antiword/text.c
  65. 4 4
      sys/src/cmd/aux/antiword/unix.c
  66. 58 96
      sys/src/cmd/aux/antiword/utf8.c
  67. 12 4
      sys/src/cmd/aux/antiword/version.h
  68. 394 61
      sys/src/cmd/aux/antiword/word2text.c
  69. 18 7
      sys/src/cmd/aux/antiword/wordconst.h
  70. 5 2
      sys/src/cmd/aux/antiword/worddos.c
  71. 3 1
      sys/src/cmd/aux/antiword/wordlib.c
  72. 17 3
      sys/src/cmd/aux/antiword/wordmac.c
  73. 16 4
      sys/src/cmd/aux/antiword/wordole.c
  74. 65 35
      sys/src/cmd/aux/antiword/wordtypes.h
  75. 6 2
      sys/src/cmd/aux/antiword/wordwin.c
  76. 26 13
      sys/src/cmd/aux/antiword/xmalloc.c
  77. 237 117
      sys/src/cmd/aux/antiword/xml.c

+ 73 - 83
dist/replica/_plan9.db

@@ -9522,89 +9522,79 @@ sys/src/cmd/aux/9pcon.c - 664 sys sys 1127394247 6284
 sys/src/cmd/aux/accupoint.c - 664 sys sys 985124882 2166
 sys/src/cmd/aux/acidleak.c - 664 sys sys 1126879783 5952
 sys/src/cmd/aux/antiword - 20000000775 sys sys 1069793877 0
-sys/src/cmd/aux/antiword/COPYING - 664 sys sys 1069793863 17985
-sys/src/cmd/aux/antiword/ChangeLog - 664 sys sys 1069793863 7543
-sys/src/cmd/aux/antiword/Emacs - 664 sys sys 1069793863 4368
-sys/src/cmd/aux/antiword/Exmh - 664 sys sys 1069793863 463
-sys/src/cmd/aux/antiword/FAQ - 664 sys sys 1069793864 4682
-sys/src/cmd/aux/antiword/History - 664 sys sys 1069793864 1528
-sys/src/cmd/aux/antiword/Mozilla - 664 sys sys 1069793864 1983
-sys/src/cmd/aux/antiword/Mutt - 664 sys sys 1069793864 717
-sys/src/cmd/aux/antiword/Netscape - 664 sys sys 1069793864 4313
-sys/src/cmd/aux/antiword/QandA - 664 sys sys 1069793864 2709
-sys/src/cmd/aux/antiword/ReadMe - 664 sys sys 1069793864 3539
-sys/src/cmd/aux/antiword/antiword.1.txt - 664 sys sys 1069793865 4443
-sys/src/cmd/aux/antiword/antiword.h - 664 sys sys 1069793865 23228
-sys/src/cmd/aux/antiword/antiword.man - 664 sys sys 1069793865 5447
-sys/src/cmd/aux/antiword/antiword.php - 664 sys sys 1069793865 926
-sys/src/cmd/aux/antiword/asc85enc.c - 664 sys sys 1069793865 3910
-sys/src/cmd/aux/antiword/blocklist.c - 664 sys sys 1069793865 18691
-sys/src/cmd/aux/antiword/chartrans.c - 664 sys sys 1069793866 18395
-sys/src/cmd/aux/antiword/datalist.c - 664 sys sys 1069793866 8933
-sys/src/cmd/aux/antiword/debug.h - 664 sys sys 1069793866 2915
-sys/src/cmd/aux/antiword/depot.c - 664 sys sys 1069793866 2724
-sys/src/cmd/aux/antiword/dib2eps.c - 664 sys sys 1069793866 12146
-sys/src/cmd/aux/antiword/dib2sprt.c - 664 sys sys 1069793866 14217
-sys/src/cmd/aux/antiword/draw.c - 664 sys sys 1069793867 27039
-sys/src/cmd/aux/antiword/draw.h - 664 sys sys 1069793867 1012
-sys/src/cmd/aux/antiword/fail.c - 664 sys sys 1069793867 613
-sys/src/cmd/aux/antiword/fail.h - 664 sys sys 1069793867 401
-sys/src/cmd/aux/antiword/finddata.c - 664 sys sys 1069793867 3797
-sys/src/cmd/aux/antiword/findtext.c - 664 sys sys 1069793867 7654
-sys/src/cmd/aux/antiword/fontinfo.h - 664 sys sys 1069793868 126349
-sys/src/cmd/aux/antiword/fontinfo.pl - 664 sys sys 1069793868 7360
-sys/src/cmd/aux/antiword/fontlist.c - 664 sys sys 1069793868 4135
-sys/src/cmd/aux/antiword/fonts.c - 664 sys sys 1069793868 22217
-sys/src/cmd/aux/antiword/fonts_r.c - 664 sys sys 1069793869 5701
-sys/src/cmd/aux/antiword/fonts_u.c - 664 sys sys 1069793869 6964
-sys/src/cmd/aux/antiword/icons.c - 664 sys sys 1069793869 2328
-sys/src/cmd/aux/antiword/imgexam.c - 664 sys sys 1069793869 25704
-sys/src/cmd/aux/antiword/imgtrans.c - 664 sys sys 1069793869 1703
-sys/src/cmd/aux/antiword/jpeg2eps.c - 664 sys sys 1069793869 1482
-sys/src/cmd/aux/antiword/jpeg2sprt.c - 664 sys sys 1069793870 2159
-sys/src/cmd/aux/antiword/listlist.c - 664 sys sys 1069793870 7855
-sys/src/cmd/aux/antiword/main_r.c - 664 sys sys 1069793870 8346
-sys/src/cmd/aux/antiword/main_u.c - 664 sys sys 1069793870 7015
-sys/src/cmd/aux/antiword/misc.c - 664 sys sys 1069793870 15240
-sys/src/cmd/aux/antiword/mkfile - 664 sys sys 1069793871 943
-sys/src/cmd/aux/antiword/notes.c - 664 sys sys 1069793871 11146
-sys/src/cmd/aux/antiword/options.c - 664 sys sys 1069793871 20371
-sys/src/cmd/aux/antiword/out2window.c - 664 sys sys 1069793871 16844
-sys/src/cmd/aux/antiword/output.c - 664 sys sys 1069793871 9013
-sys/src/cmd/aux/antiword/pictlist.c - 664 sys sys 1069793872 2294
-sys/src/cmd/aux/antiword/png2eps.c - 664 sys sys 1069793872 4032
-sys/src/cmd/aux/antiword/png2sprt.c - 664 sys sys 1069793872 572
-sys/src/cmd/aux/antiword/postscript.c - 664 sys sys 1069793872 26420
-sys/src/cmd/aux/antiword/prop0.c - 664 sys sys 1069793872 9513
-sys/src/cmd/aux/antiword/prop2.c - 664 sys sys 1069793872 25584
-sys/src/cmd/aux/antiword/prop6.c - 664 sys sys 1069793873 26935
-sys/src/cmd/aux/antiword/prop8.c - 664 sys sys 1069793873 36372
-sys/src/cmd/aux/antiword/properties.c - 664 sys sys 1069793873 3874
-sys/src/cmd/aux/antiword/propmod.c - 664 sys sys 1069793873 2427
-sys/src/cmd/aux/antiword/riscos.c - 664 sys sys 1069793873 6885
-sys/src/cmd/aux/antiword/rowlist.c - 664 sys sys 1069793874 2842
-sys/src/cmd/aux/antiword/saveas.c - 664 sys sys 1069793874 8173
-sys/src/cmd/aux/antiword/sectlist.c - 664 sys sys 1069793874 2957
-sys/src/cmd/aux/antiword/startup.c - 664 sys sys 1069793874 3563
-sys/src/cmd/aux/antiword/stylelist.c - 664 sys sys 1069793874 11414
-sys/src/cmd/aux/antiword/stylesheet.c - 664 sys sys 1069793874 21419
-sys/src/cmd/aux/antiword/summary.c - 664 sys sys 1069793875 22128
-sys/src/cmd/aux/antiword/tabstop.c - 664 sys sys 1069793875 5442
-sys/src/cmd/aux/antiword/testdoc.doc - 664 sys sys 1069793875 23552
-sys/src/cmd/aux/antiword/text.c - 664 sys sys 1069793875 3892
-sys/src/cmd/aux/antiword/unix.c - 664 sys sys 1069793875 820
-sys/src/cmd/aux/antiword/utf8.c - 664 sys sys 1069793875 8491
-sys/src/cmd/aux/antiword/version.h - 664 sys sys 1069793876 614
-sys/src/cmd/aux/antiword/word2text.c - 664 sys sys 1069793876 30234
-sys/src/cmd/aux/antiword/wordconst.h - 664 sys sys 1069793876 11243
-sys/src/cmd/aux/antiword/worddos.c - 664 sys sys 1069793876 2700
-sys/src/cmd/aux/antiword/wordlib.c - 664 sys sys 1069793876 7850
-sys/src/cmd/aux/antiword/wordmac.c - 664 sys sys 1069793876 2256
-sys/src/cmd/aux/antiword/wordole.c - 664 sys sys 1069793877 21957
-sys/src/cmd/aux/antiword/wordtypes.h - 664 sys sys 1069793877 7489
-sys/src/cmd/aux/antiword/wordwin.c - 664 sys sys 1069793877 5447
-sys/src/cmd/aux/antiword/xmalloc.c - 664 sys sys 1069793877 2185
-sys/src/cmd/aux/antiword/xml.c - 664 sys sys 1069793877 30883
+sys/src/cmd/aux/antiword/antiword.h - 664 sys sys 1137261472 27773
+sys/src/cmd/aux/antiword/asc85enc.c - 664 sys sys 1137261472 3910
+sys/src/cmd/aux/antiword/blocklist.c - 664 sys sys 1137261472 22483
+sys/src/cmd/aux/antiword/chartrans.c - 664 sys sys 1137261472 22456
+sys/src/cmd/aux/antiword/datalist.c - 664 sys sys 1137261472 8933
+sys/src/cmd/aux/antiword/debug.h - 664 sys sys 1137261472 3153
+sys/src/cmd/aux/antiword/depot.c - 664 sys sys 1137261472 2724
+sys/src/cmd/aux/antiword/dib2eps.c - 664 sys sys 1137261472 12146
+sys/src/cmd/aux/antiword/dib2sprt.c - 664 sys sys 1137261472 14486
+sys/src/cmd/aux/antiword/doclist.c - 664 sys sys 1137261472 1610
+sys/src/cmd/aux/antiword/draw.c - 664 sys sys 1137261472 26682
+sys/src/cmd/aux/antiword/draw.h - 664 sys sys 1137261472 1012
+sys/src/cmd/aux/antiword/drawfile.c - 664 sys sys 1137261473 10881
+sys/src/cmd/aux/antiword/drawfile.h - 664 sys sys 1137261473 12215
+sys/src/cmd/aux/antiword/fail.c - 664 sys sys 1137261473 613
+sys/src/cmd/aux/antiword/fail.h - 664 sys sys 1137261473 401
+sys/src/cmd/aux/antiword/finddata.c - 664 sys sys 1137261473 3797
+sys/src/cmd/aux/antiword/findtext.c - 664 sys sys 1137261473 7321
+sys/src/cmd/aux/antiword/fmt_text.c - 664 sys sys 1137261473 3691
+sys/src/cmd/aux/antiword/fontinfo.h - 664 sys sys 1137261473 126349
+sys/src/cmd/aux/antiword/fontlist.c - 664 sys sys 1137261473 4339
+sys/src/cmd/aux/antiword/fonts.c - 664 sys sys 1137261473 27501
+sys/src/cmd/aux/antiword/fonts_r.c - 664 sys sys 1137261473 5843
+sys/src/cmd/aux/antiword/fonts_u.c - 664 sys sys 1137261473 7542
+sys/src/cmd/aux/antiword/hdrftrlist.c - 664 sys sys 1137261473 9314
+sys/src/cmd/aux/antiword/icons.c - 664 sys sys 1137261473 2504
+sys/src/cmd/aux/antiword/imgexam.c - 664 sys sys 1137261473 26488
+sys/src/cmd/aux/antiword/imgtrans.c - 664 sys sys 1137261473 1703
+sys/src/cmd/aux/antiword/jpeg2eps.c - 664 sys sys 1137261473 1482
+sys/src/cmd/aux/antiword/jpeg2sprt.c - 664 sys sys 1137261473 2159
+sys/src/cmd/aux/antiword/listlist.c - 664 sys sys 1137261473 7855
+sys/src/cmd/aux/antiword/main_ros.c - 664 sys sys 1137261473 13140
+sys/src/cmd/aux/antiword/main_u.c - 664 sys sys 1137261473 8171
+sys/src/cmd/aux/antiword/misc.c - 664 sys sys 1137261473 21663
+sys/src/cmd/aux/antiword/mkfile - 664 sys sys 1137261473 1007
+sys/src/cmd/aux/antiword/notes.c - 664 sys sys 1137261473 24813
+sys/src/cmd/aux/antiword/options.c - 664 sys sys 1137261473 24707
+sys/src/cmd/aux/antiword/out2window.c - 664 sys sys 1137261474 19601
+sys/src/cmd/aux/antiword/output.c - 664 sys sys 1137261474 10773
+sys/src/cmd/aux/antiword/pdf.c - 664 sys sys 1137261474 31661
+sys/src/cmd/aux/antiword/pictlist.c - 664 sys sys 1137261474 2512
+sys/src/cmd/aux/antiword/png2eps.c - 664 sys sys 1137261474 4032
+sys/src/cmd/aux/antiword/png2sprt.c - 664 sys sys 1137261474 572
+sys/src/cmd/aux/antiword/postscript.c - 664 sys sys 1137261474 33883
+sys/src/cmd/aux/antiword/prop0.c - 664 sys sys 1137261474 12600
+sys/src/cmd/aux/antiword/prop2.c - 664 sys sys 1137261474 28409
+sys/src/cmd/aux/antiword/prop6.c - 664 sys sys 1137261474 30660
+sys/src/cmd/aux/antiword/prop8.c - 664 sys sys 1137261474 40247
+sys/src/cmd/aux/antiword/properties.c - 664 sys sys 1137261474 5989
+sys/src/cmd/aux/antiword/propmod.c - 664 sys sys 1137261474 2427
+sys/src/cmd/aux/antiword/riscos.c - 664 sys sys 1137261474 5517
+sys/src/cmd/aux/antiword/rowlist.c - 664 sys sys 1137261474 2801
+sys/src/cmd/aux/antiword/saveas.c - 664 sys sys 1137261474 9851
+sys/src/cmd/aux/antiword/sectlist.c - 664 sys sys 1137261474 3785
+sys/src/cmd/aux/antiword/startup.c - 664 sys sys 1137261474 3416
+sys/src/cmd/aux/antiword/stylelist.c - 664 sys sys 1137261474 12060
+sys/src/cmd/aux/antiword/stylesheet.c - 664 sys sys 1137261474 22114
+sys/src/cmd/aux/antiword/summary.c - 664 sys sys 1137261474 23077
+sys/src/cmd/aux/antiword/tabstop.c - 664 sys sys 1137261474 5122
+sys/src/cmd/aux/antiword/text.c - 664 sys sys 1137261474 3878
+sys/src/cmd/aux/antiword/unix.c - 664 sys sys 1137261474 818
+sys/src/cmd/aux/antiword/utf8.c - 664 sys sys 1137261474 7564
+sys/src/cmd/aux/antiword/version.h - 664 sys sys 1137261474 800
+sys/src/cmd/aux/antiword/word2text.c - 664 sys sys 1137261474 39070
+sys/src/cmd/aux/antiword/wordconst.h - 664 sys sys 1137261474 11743
+sys/src/cmd/aux/antiword/worddos.c - 664 sys sys 1137261474 2790
+sys/src/cmd/aux/antiword/wordlib.c - 664 sys sys 1137261474 7910
+sys/src/cmd/aux/antiword/wordmac.c - 664 sys sys 1137261474 2658
+sys/src/cmd/aux/antiword/wordole.c - 664 sys sys 1137261474 22402
+sys/src/cmd/aux/antiword/wordtypes.h - 664 sys sys 1137261474 8285
+sys/src/cmd/aux/antiword/wordwin.c - 664 sys sys 1137261474 5584
+sys/src/cmd/aux/antiword/xmalloc.c - 664 sys sys 1137261474 2501
+sys/src/cmd/aux/antiword/xml.c - 664 sys sys 1137261474 34115
 sys/src/cmd/aux/apm.c - 664 sys sys 1130423972 20275
 sys/src/cmd/aux/astarld.c - 664 sys sys 1015008684 4638
 sys/src/cmd/aux/cddb.c - 664 sys sys 1126795279 4610

+ 73 - 83
dist/replica/plan9.db

@@ -9522,89 +9522,79 @@ sys/src/cmd/aux/9pcon.c - 664 sys sys 1127394247 6284
 sys/src/cmd/aux/accupoint.c - 664 sys sys 985124882 2166
 sys/src/cmd/aux/acidleak.c - 664 sys sys 1126879783 5952
 sys/src/cmd/aux/antiword - 20000000775 sys sys 1069793877 0
-sys/src/cmd/aux/antiword/COPYING - 664 sys sys 1069793863 17985
-sys/src/cmd/aux/antiword/ChangeLog - 664 sys sys 1069793863 7543
-sys/src/cmd/aux/antiword/Emacs - 664 sys sys 1069793863 4368
-sys/src/cmd/aux/antiword/Exmh - 664 sys sys 1069793863 463
-sys/src/cmd/aux/antiword/FAQ - 664 sys sys 1069793864 4682
-sys/src/cmd/aux/antiword/History - 664 sys sys 1069793864 1528
-sys/src/cmd/aux/antiword/Mozilla - 664 sys sys 1069793864 1983
-sys/src/cmd/aux/antiword/Mutt - 664 sys sys 1069793864 717
-sys/src/cmd/aux/antiword/Netscape - 664 sys sys 1069793864 4313
-sys/src/cmd/aux/antiword/QandA - 664 sys sys 1069793864 2709
-sys/src/cmd/aux/antiword/ReadMe - 664 sys sys 1069793864 3539
-sys/src/cmd/aux/antiword/antiword.1.txt - 664 sys sys 1069793865 4443
-sys/src/cmd/aux/antiword/antiword.h - 664 sys sys 1069793865 23228
-sys/src/cmd/aux/antiword/antiword.man - 664 sys sys 1069793865 5447
-sys/src/cmd/aux/antiword/antiword.php - 664 sys sys 1069793865 926
-sys/src/cmd/aux/antiword/asc85enc.c - 664 sys sys 1069793865 3910
-sys/src/cmd/aux/antiword/blocklist.c - 664 sys sys 1069793865 18691
-sys/src/cmd/aux/antiword/chartrans.c - 664 sys sys 1069793866 18395
-sys/src/cmd/aux/antiword/datalist.c - 664 sys sys 1069793866 8933
-sys/src/cmd/aux/antiword/debug.h - 664 sys sys 1069793866 2915
-sys/src/cmd/aux/antiword/depot.c - 664 sys sys 1069793866 2724
-sys/src/cmd/aux/antiword/dib2eps.c - 664 sys sys 1069793866 12146
-sys/src/cmd/aux/antiword/dib2sprt.c - 664 sys sys 1069793866 14217
-sys/src/cmd/aux/antiword/draw.c - 664 sys sys 1069793867 27039
-sys/src/cmd/aux/antiword/draw.h - 664 sys sys 1069793867 1012
-sys/src/cmd/aux/antiword/fail.c - 664 sys sys 1069793867 613
-sys/src/cmd/aux/antiword/fail.h - 664 sys sys 1069793867 401
-sys/src/cmd/aux/antiword/finddata.c - 664 sys sys 1069793867 3797
-sys/src/cmd/aux/antiword/findtext.c - 664 sys sys 1069793867 7654
-sys/src/cmd/aux/antiword/fontinfo.h - 664 sys sys 1069793868 126349
-sys/src/cmd/aux/antiword/fontinfo.pl - 664 sys sys 1069793868 7360
-sys/src/cmd/aux/antiword/fontlist.c - 664 sys sys 1069793868 4135
-sys/src/cmd/aux/antiword/fonts.c - 664 sys sys 1069793868 22217
-sys/src/cmd/aux/antiword/fonts_r.c - 664 sys sys 1069793869 5701
-sys/src/cmd/aux/antiword/fonts_u.c - 664 sys sys 1069793869 6964
-sys/src/cmd/aux/antiword/icons.c - 664 sys sys 1069793869 2328
-sys/src/cmd/aux/antiword/imgexam.c - 664 sys sys 1069793869 25704
-sys/src/cmd/aux/antiword/imgtrans.c - 664 sys sys 1069793869 1703
-sys/src/cmd/aux/antiword/jpeg2eps.c - 664 sys sys 1069793869 1482
-sys/src/cmd/aux/antiword/jpeg2sprt.c - 664 sys sys 1069793870 2159
-sys/src/cmd/aux/antiword/listlist.c - 664 sys sys 1069793870 7855
-sys/src/cmd/aux/antiword/main_r.c - 664 sys sys 1069793870 8346
-sys/src/cmd/aux/antiword/main_u.c - 664 sys sys 1069793870 7015
-sys/src/cmd/aux/antiword/misc.c - 664 sys sys 1069793870 15240
-sys/src/cmd/aux/antiword/mkfile - 664 sys sys 1069793871 943
-sys/src/cmd/aux/antiword/notes.c - 664 sys sys 1069793871 11146
-sys/src/cmd/aux/antiword/options.c - 664 sys sys 1069793871 20371
-sys/src/cmd/aux/antiword/out2window.c - 664 sys sys 1069793871 16844
-sys/src/cmd/aux/antiword/output.c - 664 sys sys 1069793871 9013
-sys/src/cmd/aux/antiword/pictlist.c - 664 sys sys 1069793872 2294
-sys/src/cmd/aux/antiword/png2eps.c - 664 sys sys 1069793872 4032
-sys/src/cmd/aux/antiword/png2sprt.c - 664 sys sys 1069793872 572
-sys/src/cmd/aux/antiword/postscript.c - 664 sys sys 1069793872 26420
-sys/src/cmd/aux/antiword/prop0.c - 664 sys sys 1069793872 9513
-sys/src/cmd/aux/antiword/prop2.c - 664 sys sys 1069793872 25584
-sys/src/cmd/aux/antiword/prop6.c - 664 sys sys 1069793873 26935
-sys/src/cmd/aux/antiword/prop8.c - 664 sys sys 1069793873 36372
-sys/src/cmd/aux/antiword/properties.c - 664 sys sys 1069793873 3874
-sys/src/cmd/aux/antiword/propmod.c - 664 sys sys 1069793873 2427
-sys/src/cmd/aux/antiword/riscos.c - 664 sys sys 1069793873 6885
-sys/src/cmd/aux/antiword/rowlist.c - 664 sys sys 1069793874 2842
-sys/src/cmd/aux/antiword/saveas.c - 664 sys sys 1069793874 8173
-sys/src/cmd/aux/antiword/sectlist.c - 664 sys sys 1069793874 2957
-sys/src/cmd/aux/antiword/startup.c - 664 sys sys 1069793874 3563
-sys/src/cmd/aux/antiword/stylelist.c - 664 sys sys 1069793874 11414
-sys/src/cmd/aux/antiword/stylesheet.c - 664 sys sys 1069793874 21419
-sys/src/cmd/aux/antiword/summary.c - 664 sys sys 1069793875 22128
-sys/src/cmd/aux/antiword/tabstop.c - 664 sys sys 1069793875 5442
-sys/src/cmd/aux/antiword/testdoc.doc - 664 sys sys 1069793875 23552
-sys/src/cmd/aux/antiword/text.c - 664 sys sys 1069793875 3892
-sys/src/cmd/aux/antiword/unix.c - 664 sys sys 1069793875 820
-sys/src/cmd/aux/antiword/utf8.c - 664 sys sys 1069793875 8491
-sys/src/cmd/aux/antiword/version.h - 664 sys sys 1069793876 614
-sys/src/cmd/aux/antiword/word2text.c - 664 sys sys 1069793876 30234
-sys/src/cmd/aux/antiword/wordconst.h - 664 sys sys 1069793876 11243
-sys/src/cmd/aux/antiword/worddos.c - 664 sys sys 1069793876 2700
-sys/src/cmd/aux/antiword/wordlib.c - 664 sys sys 1069793876 7850
-sys/src/cmd/aux/antiword/wordmac.c - 664 sys sys 1069793876 2256
-sys/src/cmd/aux/antiword/wordole.c - 664 sys sys 1069793877 21957
-sys/src/cmd/aux/antiword/wordtypes.h - 664 sys sys 1069793877 7489
-sys/src/cmd/aux/antiword/wordwin.c - 664 sys sys 1069793877 5447
-sys/src/cmd/aux/antiword/xmalloc.c - 664 sys sys 1069793877 2185
-sys/src/cmd/aux/antiword/xml.c - 664 sys sys 1069793877 30883
+sys/src/cmd/aux/antiword/antiword.h - 664 sys sys 1137261472 27773
+sys/src/cmd/aux/antiword/asc85enc.c - 664 sys sys 1137261472 3910
+sys/src/cmd/aux/antiword/blocklist.c - 664 sys sys 1137261472 22483
+sys/src/cmd/aux/antiword/chartrans.c - 664 sys sys 1137261472 22456
+sys/src/cmd/aux/antiword/datalist.c - 664 sys sys 1137261472 8933
+sys/src/cmd/aux/antiword/debug.h - 664 sys sys 1137261472 3153
+sys/src/cmd/aux/antiword/depot.c - 664 sys sys 1137261472 2724
+sys/src/cmd/aux/antiword/dib2eps.c - 664 sys sys 1137261472 12146
+sys/src/cmd/aux/antiword/dib2sprt.c - 664 sys sys 1137261472 14486
+sys/src/cmd/aux/antiword/doclist.c - 664 sys sys 1137261472 1610
+sys/src/cmd/aux/antiword/draw.c - 664 sys sys 1137261472 26682
+sys/src/cmd/aux/antiword/draw.h - 664 sys sys 1137261472 1012
+sys/src/cmd/aux/antiword/drawfile.c - 664 sys sys 1137261473 10881
+sys/src/cmd/aux/antiword/drawfile.h - 664 sys sys 1137261473 12215
+sys/src/cmd/aux/antiword/fail.c - 664 sys sys 1137261473 613
+sys/src/cmd/aux/antiword/fail.h - 664 sys sys 1137261473 401
+sys/src/cmd/aux/antiword/finddata.c - 664 sys sys 1137261473 3797
+sys/src/cmd/aux/antiword/findtext.c - 664 sys sys 1137261473 7321
+sys/src/cmd/aux/antiword/fmt_text.c - 664 sys sys 1137261473 3691
+sys/src/cmd/aux/antiword/fontinfo.h - 664 sys sys 1137261473 126349
+sys/src/cmd/aux/antiword/fontlist.c - 664 sys sys 1137261473 4339
+sys/src/cmd/aux/antiword/fonts.c - 664 sys sys 1137261473 27501
+sys/src/cmd/aux/antiword/fonts_r.c - 664 sys sys 1137261473 5843
+sys/src/cmd/aux/antiword/fonts_u.c - 664 sys sys 1137261473 7542
+sys/src/cmd/aux/antiword/hdrftrlist.c - 664 sys sys 1137261473 9314
+sys/src/cmd/aux/antiword/icons.c - 664 sys sys 1137261473 2504
+sys/src/cmd/aux/antiword/imgexam.c - 664 sys sys 1137261473 26488
+sys/src/cmd/aux/antiword/imgtrans.c - 664 sys sys 1137261473 1703
+sys/src/cmd/aux/antiword/jpeg2eps.c - 664 sys sys 1137261473 1482
+sys/src/cmd/aux/antiword/jpeg2sprt.c - 664 sys sys 1137261473 2159
+sys/src/cmd/aux/antiword/listlist.c - 664 sys sys 1137261473 7855
+sys/src/cmd/aux/antiword/main_ros.c - 664 sys sys 1137261473 13140
+sys/src/cmd/aux/antiword/main_u.c - 664 sys sys 1137261473 8171
+sys/src/cmd/aux/antiword/misc.c - 664 sys sys 1137261473 21663
+sys/src/cmd/aux/antiword/mkfile - 664 sys sys 1137261473 1007
+sys/src/cmd/aux/antiword/notes.c - 664 sys sys 1137261473 24813
+sys/src/cmd/aux/antiword/options.c - 664 sys sys 1137261473 24707
+sys/src/cmd/aux/antiword/out2window.c - 664 sys sys 1137261474 19601
+sys/src/cmd/aux/antiword/output.c - 664 sys sys 1137261474 10773
+sys/src/cmd/aux/antiword/pdf.c - 664 sys sys 1137261474 31661
+sys/src/cmd/aux/antiword/pictlist.c - 664 sys sys 1137261474 2512
+sys/src/cmd/aux/antiword/png2eps.c - 664 sys sys 1137261474 4032
+sys/src/cmd/aux/antiword/png2sprt.c - 664 sys sys 1137261474 572
+sys/src/cmd/aux/antiword/postscript.c - 664 sys sys 1137261474 33883
+sys/src/cmd/aux/antiword/prop0.c - 664 sys sys 1137261474 12600
+sys/src/cmd/aux/antiword/prop2.c - 664 sys sys 1137261474 28409
+sys/src/cmd/aux/antiword/prop6.c - 664 sys sys 1137261474 30660
+sys/src/cmd/aux/antiword/prop8.c - 664 sys sys 1137261474 40247
+sys/src/cmd/aux/antiword/properties.c - 664 sys sys 1137261474 5989
+sys/src/cmd/aux/antiword/propmod.c - 664 sys sys 1137261474 2427
+sys/src/cmd/aux/antiword/riscos.c - 664 sys sys 1137261474 5517
+sys/src/cmd/aux/antiword/rowlist.c - 664 sys sys 1137261474 2801
+sys/src/cmd/aux/antiword/saveas.c - 664 sys sys 1137261474 9851
+sys/src/cmd/aux/antiword/sectlist.c - 664 sys sys 1137261474 3785
+sys/src/cmd/aux/antiword/startup.c - 664 sys sys 1137261474 3416
+sys/src/cmd/aux/antiword/stylelist.c - 664 sys sys 1137261474 12060
+sys/src/cmd/aux/antiword/stylesheet.c - 664 sys sys 1137261474 22114
+sys/src/cmd/aux/antiword/summary.c - 664 sys sys 1137261474 23077
+sys/src/cmd/aux/antiword/tabstop.c - 664 sys sys 1137261474 5122
+sys/src/cmd/aux/antiword/text.c - 664 sys sys 1137261474 3878
+sys/src/cmd/aux/antiword/unix.c - 664 sys sys 1137261474 818
+sys/src/cmd/aux/antiword/utf8.c - 664 sys sys 1137261474 7564
+sys/src/cmd/aux/antiword/version.h - 664 sys sys 1137261474 800
+sys/src/cmd/aux/antiword/word2text.c - 664 sys sys 1137261474 39070
+sys/src/cmd/aux/antiword/wordconst.h - 664 sys sys 1137261474 11743
+sys/src/cmd/aux/antiword/worddos.c - 664 sys sys 1137261474 2790
+sys/src/cmd/aux/antiword/wordlib.c - 664 sys sys 1137261474 7910
+sys/src/cmd/aux/antiword/wordmac.c - 664 sys sys 1137261474 2658
+sys/src/cmd/aux/antiword/wordole.c - 664 sys sys 1137261474 22402
+sys/src/cmd/aux/antiword/wordtypes.h - 664 sys sys 1137261474 8285
+sys/src/cmd/aux/antiword/wordwin.c - 664 sys sys 1137261474 5584
+sys/src/cmd/aux/antiword/xmalloc.c - 664 sys sys 1137261474 2501
+sys/src/cmd/aux/antiword/xml.c - 664 sys sys 1137261474 34115
 sys/src/cmd/aux/apm.c - 664 sys sys 1130423972 20275
 sys/src/cmd/aux/astarld.c - 664 sys sys 1015008684 4638
 sys/src/cmd/aux/cddb.c - 664 sys sys 1126795279 4610

+ 303 - 0
dist/replica/plan9.log

@@ -24809,3 +24809,306 @@
 1137180625 3 c sys/src/9/alphapc/mem.h - 664 sys sys 1137179967 2312
 1137180625 4 a sys/src/9/alphapc/osf1pal.h - 664 sys sys 1137179966 1471
 1137180625 5 c sys/src/9/alphapc/sd53c8xx.c - 664 sys sys 1137179967 55257
+1137261647 110 c sys/src/cmd/aux/antiword/antiword.h - 640 sys sys 1137261472 27773
+1137261647 111 m sys/src/cmd/aux/antiword/antiword.h - 640 sys sys 1137261472 27773
+1137261647 112 c sys/src/cmd/aux/antiword/asc85enc.c - 640 sys sys 1137261472 3910
+1137261647 113 m sys/src/cmd/aux/antiword/asc85enc.c - 640 sys sys 1137261472 3910
+1137261647 114 c sys/src/cmd/aux/antiword/blocklist.c - 640 sys sys 1137261472 22483
+1137261647 115 m sys/src/cmd/aux/antiword/blocklist.c - 640 sys sys 1137261472 22483
+1137261647 116 c sys/src/cmd/aux/antiword/chartrans.c - 640 sys sys 1137261472 22456
+1137261647 117 m sys/src/cmd/aux/antiword/chartrans.c - 640 sys sys 1137261472 22456
+1137261647 118 c sys/src/cmd/aux/antiword/datalist.c - 640 sys sys 1137261472 8933
+1137261647 119 m sys/src/cmd/aux/antiword/datalist.c - 640 sys sys 1137261472 8933
+1137261647 120 c sys/src/cmd/aux/antiword/debug.h - 640 sys sys 1137261472 3153
+1137261647 121 m sys/src/cmd/aux/antiword/debug.h - 640 sys sys 1137261472 3153
+1137261647 122 c sys/src/cmd/aux/antiword/depot.c - 640 sys sys 1137261472 2724
+1137261647 123 m sys/src/cmd/aux/antiword/depot.c - 640 sys sys 1137261472 2724
+1137261647 124 c sys/src/cmd/aux/antiword/dib2eps.c - 640 sys sys 1137261472 12146
+1137261647 125 m sys/src/cmd/aux/antiword/dib2eps.c - 640 sys sys 1137261472 12146
+1137261647 126 c sys/src/cmd/aux/antiword/dib2sprt.c - 640 sys sys 1137261472 14486
+1137261647 127 m sys/src/cmd/aux/antiword/dib2sprt.c - 640 sys sys 1137261472 14486
+1137261647 128 a sys/src/cmd/aux/antiword/doclist.c - 640 sys sys 1137261472 1610
+1137261647 129 c sys/src/cmd/aux/antiword/draw.c - 640 sys sys 1137261472 26682
+1137261647 130 m sys/src/cmd/aux/antiword/draw.c - 640 sys sys 1137261472 26682
+1137261647 131 c sys/src/cmd/aux/antiword/draw.h - 640 sys sys 1137261472 1012
+1137261647 132 m sys/src/cmd/aux/antiword/draw.h - 640 sys sys 1137261472 1012
+1137261647 133 a sys/src/cmd/aux/antiword/drawfile.c - 640 sys sys 1137261473 10881
+1137261647 134 a sys/src/cmd/aux/antiword/drawfile.h - 640 sys sys 1137261473 12215
+1137261647 135 c sys/src/cmd/aux/antiword/fail.c - 640 sys sys 1137261473 613
+1137261647 136 m sys/src/cmd/aux/antiword/fail.c - 640 sys sys 1137261473 613
+1137261647 137 c sys/src/cmd/aux/antiword/fail.h - 640 sys sys 1137261473 401
+1137261647 138 m sys/src/cmd/aux/antiword/fail.h - 640 sys sys 1137261473 401
+1137261647 139 c sys/src/cmd/aux/antiword/finddata.c - 640 sys sys 1137261473 3797
+1137261647 140 m sys/src/cmd/aux/antiword/finddata.c - 640 sys sys 1137261473 3797
+1137261647 141 c sys/src/cmd/aux/antiword/findtext.c - 640 sys sys 1137261473 7321
+1137261647 142 m sys/src/cmd/aux/antiword/findtext.c - 640 sys sys 1137261473 7321
+1137261647 143 a sys/src/cmd/aux/antiword/fmt_text.c - 640 sys sys 1137261473 3691
+1137261647 144 c sys/src/cmd/aux/antiword/fontinfo.h - 640 sys sys 1137261473 126349
+1137261647 145 m sys/src/cmd/aux/antiword/fontinfo.h - 640 sys sys 1137261473 126349
+1137261647 146 c sys/src/cmd/aux/antiword/fontlist.c - 640 sys sys 1137261473 4339
+1137261647 147 m sys/src/cmd/aux/antiword/fontlist.c - 640 sys sys 1137261473 4339
+1137261647 148 c sys/src/cmd/aux/antiword/fonts.c - 640 sys sys 1137261473 27501
+1137261647 149 m sys/src/cmd/aux/antiword/fonts.c - 640 sys sys 1137261473 27501
+1137261647 150 c sys/src/cmd/aux/antiword/fonts_r.c - 640 sys sys 1137261473 5843
+1137261647 151 m sys/src/cmd/aux/antiword/fonts_r.c - 640 sys sys 1137261473 5843
+1137261647 152 c sys/src/cmd/aux/antiword/fonts_u.c - 640 sys sys 1137261473 7542
+1137261647 153 m sys/src/cmd/aux/antiword/fonts_u.c - 640 sys sys 1137261473 7542
+1137261647 154 a sys/src/cmd/aux/antiword/hdrftrlist.c - 640 sys sys 1137261473 9314
+1137261647 155 c sys/src/cmd/aux/antiword/icons.c - 640 sys sys 1137261473 2504
+1137261647 156 m sys/src/cmd/aux/antiword/icons.c - 640 sys sys 1137261473 2504
+1137261647 157 c sys/src/cmd/aux/antiword/imgexam.c - 640 sys sys 1137261473 26488
+1137261647 158 m sys/src/cmd/aux/antiword/imgexam.c - 640 sys sys 1137261473 26488
+1137261647 159 c sys/src/cmd/aux/antiword/imgtrans.c - 640 sys sys 1137261473 1703
+1137261647 160 m sys/src/cmd/aux/antiword/imgtrans.c - 640 sys sys 1137261473 1703
+1137261647 161 c sys/src/cmd/aux/antiword/jpeg2eps.c - 640 sys sys 1137261473 1482
+1137261647 162 m sys/src/cmd/aux/antiword/jpeg2eps.c - 640 sys sys 1137261473 1482
+1137261647 163 c sys/src/cmd/aux/antiword/jpeg2sprt.c - 640 sys sys 1137261473 2159
+1137261647 164 m sys/src/cmd/aux/antiword/jpeg2sprt.c - 640 sys sys 1137261473 2159
+1137261647 166 c sys/src/cmd/aux/antiword/listlist.c - 640 sys sys 1137261473 7855
+1137261647 167 m sys/src/cmd/aux/antiword/listlist.c - 640 sys sys 1137261473 7855
+1137261647 168 a sys/src/cmd/aux/antiword/main_ros.c - 640 sys sys 1137261473 13140
+1137261647 169 c sys/src/cmd/aux/antiword/main_u.c - 640 sys sys 1137261473 8171
+1137261647 170 m sys/src/cmd/aux/antiword/main_u.c - 640 sys sys 1137261473 8171
+1137261647 171 c sys/src/cmd/aux/antiword/misc.c - 640 sys sys 1137261473 21663
+1137261647 172 m sys/src/cmd/aux/antiword/misc.c - 640 sys sys 1137261473 21663
+1137261647 173 c sys/src/cmd/aux/antiword/mkfile - 640 sys sys 1137261473 1007
+1137261647 174 m sys/src/cmd/aux/antiword/mkfile - 640 sys sys 1137261473 1007
+1137261647 175 c sys/src/cmd/aux/antiword/notes.c - 640 sys sys 1137261473 24813
+1137261647 176 m sys/src/cmd/aux/antiword/notes.c - 640 sys sys 1137261473 24813
+1137261647 177 c sys/src/cmd/aux/antiword/options.c - 640 sys sys 1137261473 24707
+1137261647 178 m sys/src/cmd/aux/antiword/options.c - 640 sys sys 1137261473 24707
+1137261647 179 c sys/src/cmd/aux/antiword/out2window.c - 640 sys sys 1137261474 19601
+1137261647 180 m sys/src/cmd/aux/antiword/out2window.c - 640 sys sys 1137261474 19601
+1137261647 181 c sys/src/cmd/aux/antiword/output.c - 640 sys sys 1137261474 10773
+1137261647 182 m sys/src/cmd/aux/antiword/output.c - 640 sys sys 1137261474 10773
+1137261647 183 a sys/src/cmd/aux/antiword/pdf.c - 640 sys sys 1137261474 31661
+1137261647 184 c sys/src/cmd/aux/antiword/pictlist.c - 640 sys sys 1137261474 2512
+1137261647 185 m sys/src/cmd/aux/antiword/pictlist.c - 640 sys sys 1137261474 2512
+1137261647 186 c sys/src/cmd/aux/antiword/png2eps.c - 640 sys sys 1137261474 4032
+1137261647 187 m sys/src/cmd/aux/antiword/png2eps.c - 640 sys sys 1137261474 4032
+1137261647 188 c sys/src/cmd/aux/antiword/png2sprt.c - 640 sys sys 1137261474 572
+1137261647 189 m sys/src/cmd/aux/antiword/png2sprt.c - 640 sys sys 1137261474 572
+1137261647 190 c sys/src/cmd/aux/antiword/postscript.c - 640 sys sys 1137261474 33883
+1137261647 191 m sys/src/cmd/aux/antiword/postscript.c - 640 sys sys 1137261474 33883
+1137261647 192 c sys/src/cmd/aux/antiword/prop0.c - 640 sys sys 1137261474 12600
+1137261647 193 m sys/src/cmd/aux/antiword/prop0.c - 640 sys sys 1137261474 12600
+1137261647 194 c sys/src/cmd/aux/antiword/prop2.c - 640 sys sys 1137261474 28409
+1137261647 195 m sys/src/cmd/aux/antiword/prop2.c - 640 sys sys 1137261474 28409
+1137261647 196 c sys/src/cmd/aux/antiword/prop6.c - 640 sys sys 1137261474 30660
+1137261647 197 m sys/src/cmd/aux/antiword/prop6.c - 640 sys sys 1137261474 30660
+1137261647 198 c sys/src/cmd/aux/antiword/prop8.c - 640 sys sys 1137261474 40247
+1137261647 199 m sys/src/cmd/aux/antiword/prop8.c - 640 sys sys 1137261474 40247
+1137261647 200 c sys/src/cmd/aux/antiword/properties.c - 640 sys sys 1137261474 5989
+1137261647 201 m sys/src/cmd/aux/antiword/properties.c - 640 sys sys 1137261474 5989
+1137261647 202 c sys/src/cmd/aux/antiword/propmod.c - 640 sys sys 1137261474 2427
+1137261647 203 m sys/src/cmd/aux/antiword/propmod.c - 640 sys sys 1137261474 2427
+1137261647 204 c sys/src/cmd/aux/antiword/riscos.c - 640 sys sys 1137261474 5517
+1137261647 205 m sys/src/cmd/aux/antiword/riscos.c - 640 sys sys 1137261474 5517
+1137261647 206 c sys/src/cmd/aux/antiword/rowlist.c - 640 sys sys 1137261474 2801
+1137261647 207 m sys/src/cmd/aux/antiword/rowlist.c - 640 sys sys 1137261474 2801
+1137261647 208 c sys/src/cmd/aux/antiword/saveas.c - 640 sys sys 1137261474 9851
+1137261647 209 m sys/src/cmd/aux/antiword/saveas.c - 640 sys sys 1137261474 9851
+1137261647 210 c sys/src/cmd/aux/antiword/sectlist.c - 640 sys sys 1137261474 3785
+1137261647 211 m sys/src/cmd/aux/antiword/sectlist.c - 640 sys sys 1137261474 3785
+1137261647 212 c sys/src/cmd/aux/antiword/startup.c - 640 sys sys 1137261474 3416
+1137261647 213 m sys/src/cmd/aux/antiword/startup.c - 640 sys sys 1137261474 3416
+1137261647 214 c sys/src/cmd/aux/antiword/stylelist.c - 640 sys sys 1137261474 12060
+1137261647 215 m sys/src/cmd/aux/antiword/stylelist.c - 640 sys sys 1137261474 12060
+1137261647 216 c sys/src/cmd/aux/antiword/stylesheet.c - 640 sys sys 1137261474 22114
+1137261647 217 m sys/src/cmd/aux/antiword/stylesheet.c - 640 sys sys 1137261474 22114
+1137261647 218 c sys/src/cmd/aux/antiword/summary.c - 640 sys sys 1137261474 23077
+1137261647 219 m sys/src/cmd/aux/antiword/summary.c - 640 sys sys 1137261474 23077
+1137261647 220 c sys/src/cmd/aux/antiword/tabstop.c - 640 sys sys 1137261474 5122
+1137261647 221 m sys/src/cmd/aux/antiword/tabstop.c - 640 sys sys 1137261474 5122
+1137261647 222 c sys/src/cmd/aux/antiword/text.c - 640 sys sys 1137261474 3878
+1137261647 223 m sys/src/cmd/aux/antiword/text.c - 640 sys sys 1137261474 3878
+1137261647 224 c sys/src/cmd/aux/antiword/unix.c - 640 sys sys 1137261474 818
+1137261647 225 m sys/src/cmd/aux/antiword/unix.c - 640 sys sys 1137261474 818
+1137261647 226 c sys/src/cmd/aux/antiword/utf8.c - 640 sys sys 1137261474 7564
+1137261647 227 m sys/src/cmd/aux/antiword/utf8.c - 640 sys sys 1137261474 7564
+1137261647 228 c sys/src/cmd/aux/antiword/version.h - 640 sys sys 1137261474 800
+1137261647 229 m sys/src/cmd/aux/antiword/version.h - 640 sys sys 1137261474 800
+1137261647 230 c sys/src/cmd/aux/antiword/word2text.c - 640 sys sys 1137261474 39070
+1137261647 231 m sys/src/cmd/aux/antiword/word2text.c - 640 sys sys 1137261474 39070
+1137261647 232 c sys/src/cmd/aux/antiword/wordconst.h - 640 sys sys 1137261474 11743
+1137261647 233 m sys/src/cmd/aux/antiword/wordconst.h - 640 sys sys 1137261474 11743
+1137261647 234 c sys/src/cmd/aux/antiword/worddos.c - 640 sys sys 1137261474 2790
+1137261647 235 m sys/src/cmd/aux/antiword/worddos.c - 640 sys sys 1137261474 2790
+1137261647 236 c sys/src/cmd/aux/antiword/wordlib.c - 640 sys sys 1137261474 7910
+1137261647 237 m sys/src/cmd/aux/antiword/wordlib.c - 640 sys sys 1137261474 7910
+1137261647 238 c sys/src/cmd/aux/antiword/wordmac.c - 640 sys sys 1137261474 2658
+1137261647 239 m sys/src/cmd/aux/antiword/wordmac.c - 640 sys sys 1137261474 2658
+1137261647 240 c sys/src/cmd/aux/antiword/wordole.c - 640 sys sys 1137261474 22402
+1137261647 241 m sys/src/cmd/aux/antiword/wordole.c - 640 sys sys 1137261474 22402
+1137261647 242 c sys/src/cmd/aux/antiword/wordtypes.h - 600 sys sys 1137261474 8285
+1137261647 243 m sys/src/cmd/aux/antiword/wordtypes.h - 600 sys sys 1137261474 8285
+1137261647 244 c sys/src/cmd/aux/antiword/wordwin.c - 640 sys sys 1137261474 5584
+1137261647 245 m sys/src/cmd/aux/antiword/wordwin.c - 640 sys sys 1137261474 5584
+1137261647 246 c sys/src/cmd/aux/antiword/xmalloc.c - 640 sys sys 1137261474 2501
+1137261647 247 m sys/src/cmd/aux/antiword/xmalloc.c - 640 sys sys 1137261474 2501
+1137261647 248 c sys/src/cmd/aux/antiword/xml.c - 640 sys sys 1137261474 34115
+1137261647 249 m sys/src/cmd/aux/antiword/xml.c - 640 sys sys 1137261474 34115
+1137261647 250 d sys/src/cmd/aux/antiword/testdoc.doc - 664 sys sys 1069793875 0
+1137261647 251 d sys/src/cmd/aux/antiword/main_r.c - 664 sys sys 1069793870 0
+1137261647 252 d sys/src/cmd/aux/antiword/fontinfo.pl - 664 sys sys 1069793868 0
+1137261647 253 d sys/src/cmd/aux/antiword/antiword.php - 664 sys sys 1069793865 0
+1137261647 254 d sys/src/cmd/aux/antiword/antiword.man - 664 sys sys 1069793865 0
+1137261647 255 d sys/src/cmd/aux/antiword/antiword.1.txt - 664 sys sys 1069793865 0
+1137261647 256 d sys/src/cmd/aux/antiword/ReadMe - 664 sys sys 1069793864 0
+1137261647 257 d sys/src/cmd/aux/antiword/QandA - 664 sys sys 1069793864 0
+1137261647 258 d sys/src/cmd/aux/antiword/Netscape - 664 sys sys 1069793864 0
+1137261647 259 d sys/src/cmd/aux/antiword/Mutt - 664 sys sys 1069793864 0
+1137261647 260 d sys/src/cmd/aux/antiword/Mozilla - 664 sys sys 1069793864 0
+1137261647 261 d sys/src/cmd/aux/antiword/History - 664 sys sys 1069793864 0
+1137261647 262 d sys/src/cmd/aux/antiword/FAQ - 664 sys sys 1069793864 0
+1137261647 263 d sys/src/cmd/aux/antiword/Exmh - 664 sys sys 1069793863 0
+1137261647 264 d sys/src/cmd/aux/antiword/Emacs - 664 sys sys 1069793863 0
+1137261647 265 d sys/src/cmd/aux/antiword/ChangeLog - 664 sys sys 1069793863 0
+1137261647 266 d sys/src/cmd/aux/antiword/COPYING - 664 sys sys 1069793863 0
+1137267049 0 m sys/src/cmd/aux/antiword/antiword.h - 660 sys sys 1137261472 27773
+1137267049 1 m sys/src/cmd/aux/antiword/asc85enc.c - 660 sys sys 1137261472 3910
+1137267049 2 m sys/src/cmd/aux/antiword/blocklist.c - 660 sys sys 1137261472 22483
+1137267049 3 m sys/src/cmd/aux/antiword/chartrans.c - 660 sys sys 1137261472 22456
+1137267049 4 m sys/src/cmd/aux/antiword/datalist.c - 660 sys sys 1137261472 8933
+1137267049 5 m sys/src/cmd/aux/antiword/debug.h - 660 sys sys 1137261472 3153
+1137267049 6 m sys/src/cmd/aux/antiword/depot.c - 660 sys sys 1137261472 2724
+1137267049 7 m sys/src/cmd/aux/antiword/dib2eps.c - 660 sys sys 1137261472 12146
+1137267049 8 m sys/src/cmd/aux/antiword/dib2sprt.c - 660 sys sys 1137261472 14486
+1137267049 9 m sys/src/cmd/aux/antiword/doclist.c - 660 sys sys 1137261472 1610
+1137267049 10 m sys/src/cmd/aux/antiword/draw.c - 660 sys sys 1137261472 26682
+1137267049 11 m sys/src/cmd/aux/antiword/draw.h - 660 sys sys 1137261472 1012
+1137267049 12 m sys/src/cmd/aux/antiword/drawfile.c - 660 sys sys 1137261473 10881
+1137267049 13 m sys/src/cmd/aux/antiword/drawfile.h - 660 sys sys 1137261473 12215
+1137267049 14 m sys/src/cmd/aux/antiword/fail.c - 660 sys sys 1137261473 613
+1137267049 15 m sys/src/cmd/aux/antiword/fail.h - 660 sys sys 1137261473 401
+1137267049 16 m sys/src/cmd/aux/antiword/finddata.c - 660 sys sys 1137261473 3797
+1137267049 17 m sys/src/cmd/aux/antiword/findtext.c - 660 sys sys 1137261473 7321
+1137267049 18 m sys/src/cmd/aux/antiword/fmt_text.c - 660 sys sys 1137261473 3691
+1137267049 19 m sys/src/cmd/aux/antiword/fontinfo.h - 660 sys sys 1137261473 126349
+1137267049 20 m sys/src/cmd/aux/antiword/fontlist.c - 660 sys sys 1137261473 4339
+1137267049 21 m sys/src/cmd/aux/antiword/fonts.c - 660 sys sys 1137261473 27501
+1137267049 22 m sys/src/cmd/aux/antiword/fonts_r.c - 660 sys sys 1137261473 5843
+1137267049 23 m sys/src/cmd/aux/antiword/fonts_u.c - 660 sys sys 1137261473 7542
+1137267049 24 m sys/src/cmd/aux/antiword/hdrftrlist.c - 660 sys sys 1137261473 9314
+1137267049 25 m sys/src/cmd/aux/antiword/icons.c - 660 sys sys 1137261473 2504
+1137267049 26 m sys/src/cmd/aux/antiword/imgexam.c - 660 sys sys 1137261473 26488
+1137267049 27 m sys/src/cmd/aux/antiword/imgtrans.c - 660 sys sys 1137261473 1703
+1137267049 28 m sys/src/cmd/aux/antiword/jpeg2eps.c - 660 sys sys 1137261473 1482
+1137267049 29 m sys/src/cmd/aux/antiword/jpeg2sprt.c - 660 sys sys 1137261473 2159
+1137267049 30 m sys/src/cmd/aux/antiword/listlist.c - 660 sys sys 1137261473 7855
+1137267049 31 m sys/src/cmd/aux/antiword/main_ros.c - 660 sys sys 1137261473 13140
+1137267049 32 m sys/src/cmd/aux/antiword/main_u.c - 660 sys sys 1137261473 8171
+1137267049 33 m sys/src/cmd/aux/antiword/misc.c - 660 sys sys 1137261473 21663
+1137267049 34 m sys/src/cmd/aux/antiword/mkfile - 660 sys sys 1137261473 1007
+1137267049 35 m sys/src/cmd/aux/antiword/notes.c - 660 sys sys 1137261473 24813
+1137267049 36 m sys/src/cmd/aux/antiword/options.c - 660 sys sys 1137261473 24707
+1137267049 37 m sys/src/cmd/aux/antiword/out2window.c - 660 sys sys 1137261474 19601
+1137267049 38 m sys/src/cmd/aux/antiword/output.c - 660 sys sys 1137261474 10773
+1137267049 39 m sys/src/cmd/aux/antiword/pdf.c - 660 sys sys 1137261474 31661
+1137267049 40 m sys/src/cmd/aux/antiword/pictlist.c - 660 sys sys 1137261474 2512
+1137267049 41 m sys/src/cmd/aux/antiword/png2eps.c - 660 sys sys 1137261474 4032
+1137267049 42 m sys/src/cmd/aux/antiword/png2sprt.c - 660 sys sys 1137261474 572
+1137267049 43 m sys/src/cmd/aux/antiword/postscript.c - 660 sys sys 1137261474 33883
+1137267049 44 m sys/src/cmd/aux/antiword/prop0.c - 660 sys sys 1137261474 12600
+1137267049 45 m sys/src/cmd/aux/antiword/prop2.c - 660 sys sys 1137261474 28409
+1137267049 46 m sys/src/cmd/aux/antiword/prop6.c - 660 sys sys 1137261474 30660
+1137267049 47 m sys/src/cmd/aux/antiword/prop8.c - 660 sys sys 1137261474 40247
+1137267049 48 m sys/src/cmd/aux/antiword/properties.c - 660 sys sys 1137261474 5989
+1137267049 49 m sys/src/cmd/aux/antiword/propmod.c - 660 sys sys 1137261474 2427
+1137267049 50 m sys/src/cmd/aux/antiword/riscos.c - 660 sys sys 1137261474 5517
+1137267049 51 m sys/src/cmd/aux/antiword/rowlist.c - 660 sys sys 1137261474 2801
+1137267049 52 m sys/src/cmd/aux/antiword/saveas.c - 660 sys sys 1137261474 9851
+1137267049 53 m sys/src/cmd/aux/antiword/sectlist.c - 660 sys sys 1137261474 3785
+1137267049 54 m sys/src/cmd/aux/antiword/startup.c - 660 sys sys 1137261474 3416
+1137267049 55 m sys/src/cmd/aux/antiword/stylelist.c - 660 sys sys 1137261474 12060
+1137267049 56 m sys/src/cmd/aux/antiword/stylesheet.c - 660 sys sys 1137261474 22114
+1137267049 57 m sys/src/cmd/aux/antiword/summary.c - 660 sys sys 1137261474 23077
+1137267049 58 m sys/src/cmd/aux/antiword/tabstop.c - 660 sys sys 1137261474 5122
+1137267049 59 m sys/src/cmd/aux/antiword/text.c - 660 sys sys 1137261474 3878
+1137267049 60 m sys/src/cmd/aux/antiword/unix.c - 660 sys sys 1137261474 818
+1137267049 61 m sys/src/cmd/aux/antiword/utf8.c - 660 sys sys 1137261474 7564
+1137267049 62 m sys/src/cmd/aux/antiword/version.h - 660 sys sys 1137261474 800
+1137267049 63 m sys/src/cmd/aux/antiword/word2text.c - 660 sys sys 1137261474 39070
+1137267049 64 m sys/src/cmd/aux/antiword/wordconst.h - 660 sys sys 1137261474 11743
+1137267049 65 m sys/src/cmd/aux/antiword/worddos.c - 660 sys sys 1137261474 2790
+1137267049 66 m sys/src/cmd/aux/antiword/wordlib.c - 660 sys sys 1137261474 7910
+1137267049 67 m sys/src/cmd/aux/antiword/wordmac.c - 660 sys sys 1137261474 2658
+1137267049 68 m sys/src/cmd/aux/antiword/wordole.c - 660 sys sys 1137261474 22402
+1137267049 69 m sys/src/cmd/aux/antiword/wordtypes.h - 660 sys sys 1137261474 8285
+1137267049 70 m sys/src/cmd/aux/antiword/wordwin.c - 660 sys sys 1137261474 5584
+1137267049 71 m sys/src/cmd/aux/antiword/xmalloc.c - 660 sys sys 1137261474 2501
+1137267049 72 m sys/src/cmd/aux/antiword/xml.c - 660 sys sys 1137261474 34115
+1137267049 73 d sys/src/cmd/aux/antiword/kantiword - 750 sys sys 1137261473 0
+1137268850 0 m sys/src/cmd/aux/antiword/antiword.h - 664 sys sys 1137261472 27773
+1137268850 1 m sys/src/cmd/aux/antiword/asc85enc.c - 664 sys sys 1137261472 3910
+1137268850 2 m sys/src/cmd/aux/antiword/blocklist.c - 664 sys sys 1137261472 22483
+1137268850 3 m sys/src/cmd/aux/antiword/chartrans.c - 664 sys sys 1137261472 22456
+1137268850 4 m sys/src/cmd/aux/antiword/datalist.c - 664 sys sys 1137261472 8933
+1137268850 5 m sys/src/cmd/aux/antiword/debug.h - 664 sys sys 1137261472 3153
+1137268850 6 m sys/src/cmd/aux/antiword/depot.c - 664 sys sys 1137261472 2724
+1137268850 7 m sys/src/cmd/aux/antiword/dib2eps.c - 664 sys sys 1137261472 12146
+1137268850 8 m sys/src/cmd/aux/antiword/dib2sprt.c - 664 sys sys 1137261472 14486
+1137268850 9 m sys/src/cmd/aux/antiword/doclist.c - 664 sys sys 1137261472 1610
+1137268850 10 m sys/src/cmd/aux/antiword/draw.c - 664 sys sys 1137261472 26682
+1137268850 11 m sys/src/cmd/aux/antiword/draw.h - 664 sys sys 1137261472 1012
+1137268850 12 m sys/src/cmd/aux/antiword/drawfile.c - 664 sys sys 1137261473 10881
+1137268850 13 m sys/src/cmd/aux/antiword/drawfile.h - 664 sys sys 1137261473 12215
+1137268850 14 m sys/src/cmd/aux/antiword/fail.c - 664 sys sys 1137261473 613
+1137268850 15 m sys/src/cmd/aux/antiword/fail.h - 664 sys sys 1137261473 401
+1137268850 16 m sys/src/cmd/aux/antiword/finddata.c - 664 sys sys 1137261473 3797
+1137268850 17 m sys/src/cmd/aux/antiword/findtext.c - 664 sys sys 1137261473 7321
+1137268850 18 m sys/src/cmd/aux/antiword/fmt_text.c - 664 sys sys 1137261473 3691
+1137268850 19 m sys/src/cmd/aux/antiword/fontinfo.h - 664 sys sys 1137261473 126349
+1137268850 20 m sys/src/cmd/aux/antiword/fontlist.c - 664 sys sys 1137261473 4339
+1137268850 21 m sys/src/cmd/aux/antiword/fonts.c - 664 sys sys 1137261473 27501
+1137268850 22 m sys/src/cmd/aux/antiword/fonts_r.c - 664 sys sys 1137261473 5843
+1137268850 23 m sys/src/cmd/aux/antiword/fonts_u.c - 664 sys sys 1137261473 7542
+1137268850 24 m sys/src/cmd/aux/antiword/hdrftrlist.c - 664 sys sys 1137261473 9314
+1137268850 25 m sys/src/cmd/aux/antiword/icons.c - 664 sys sys 1137261473 2504
+1137268850 26 m sys/src/cmd/aux/antiword/imgexam.c - 664 sys sys 1137261473 26488
+1137268850 27 m sys/src/cmd/aux/antiword/imgtrans.c - 664 sys sys 1137261473 1703
+1137268850 28 m sys/src/cmd/aux/antiword/jpeg2eps.c - 664 sys sys 1137261473 1482
+1137268850 29 m sys/src/cmd/aux/antiword/jpeg2sprt.c - 664 sys sys 1137261473 2159
+1137268850 30 m sys/src/cmd/aux/antiword/listlist.c - 664 sys sys 1137261473 7855
+1137268850 31 m sys/src/cmd/aux/antiword/main_ros.c - 664 sys sys 1137261473 13140
+1137268850 32 m sys/src/cmd/aux/antiword/main_u.c - 664 sys sys 1137261473 8171
+1137268850 33 m sys/src/cmd/aux/antiword/misc.c - 664 sys sys 1137261473 21663
+1137268850 34 m sys/src/cmd/aux/antiword/mkfile - 664 sys sys 1137261473 1007
+1137268850 35 m sys/src/cmd/aux/antiword/notes.c - 664 sys sys 1137261473 24813
+1137268850 36 m sys/src/cmd/aux/antiword/options.c - 664 sys sys 1137261473 24707
+1137268850 37 m sys/src/cmd/aux/antiword/out2window.c - 664 sys sys 1137261474 19601
+1137268850 38 m sys/src/cmd/aux/antiword/output.c - 664 sys sys 1137261474 10773
+1137268850 39 m sys/src/cmd/aux/antiword/pdf.c - 664 sys sys 1137261474 31661
+1137268850 40 m sys/src/cmd/aux/antiword/pictlist.c - 664 sys sys 1137261474 2512
+1137268850 41 m sys/src/cmd/aux/antiword/png2eps.c - 664 sys sys 1137261474 4032
+1137268850 42 m sys/src/cmd/aux/antiword/png2sprt.c - 664 sys sys 1137261474 572
+1137268850 43 m sys/src/cmd/aux/antiword/postscript.c - 664 sys sys 1137261474 33883
+1137268850 44 m sys/src/cmd/aux/antiword/prop0.c - 664 sys sys 1137261474 12600
+1137268850 45 m sys/src/cmd/aux/antiword/prop2.c - 664 sys sys 1137261474 28409
+1137268850 46 m sys/src/cmd/aux/antiword/prop6.c - 664 sys sys 1137261474 30660
+1137268850 47 m sys/src/cmd/aux/antiword/prop8.c - 664 sys sys 1137261474 40247
+1137268850 48 m sys/src/cmd/aux/antiword/properties.c - 664 sys sys 1137261474 5989
+1137268850 49 m sys/src/cmd/aux/antiword/propmod.c - 664 sys sys 1137261474 2427
+1137268850 50 m sys/src/cmd/aux/antiword/riscos.c - 664 sys sys 1137261474 5517
+1137268850 51 m sys/src/cmd/aux/antiword/rowlist.c - 664 sys sys 1137261474 2801
+1137268850 52 m sys/src/cmd/aux/antiword/saveas.c - 664 sys sys 1137261474 9851
+1137268850 53 m sys/src/cmd/aux/antiword/sectlist.c - 664 sys sys 1137261474 3785
+1137268850 54 m sys/src/cmd/aux/antiword/startup.c - 664 sys sys 1137261474 3416
+1137268850 55 m sys/src/cmd/aux/antiword/stylelist.c - 664 sys sys 1137261474 12060
+1137268850 56 m sys/src/cmd/aux/antiword/stylesheet.c - 664 sys sys 1137261474 22114
+1137268850 57 m sys/src/cmd/aux/antiword/summary.c - 664 sys sys 1137261474 23077
+1137268850 58 m sys/src/cmd/aux/antiword/tabstop.c - 664 sys sys 1137261474 5122
+1137268850 59 m sys/src/cmd/aux/antiword/text.c - 664 sys sys 1137261474 3878
+1137268850 60 m sys/src/cmd/aux/antiword/unix.c - 664 sys sys 1137261474 818
+1137268850 61 m sys/src/cmd/aux/antiword/utf8.c - 664 sys sys 1137261474 7564
+1137268850 62 m sys/src/cmd/aux/antiword/version.h - 664 sys sys 1137261474 800
+1137268850 63 m sys/src/cmd/aux/antiword/word2text.c - 664 sys sys 1137261474 39070
+1137268850 64 m sys/src/cmd/aux/antiword/wordconst.h - 664 sys sys 1137261474 11743
+1137268850 65 m sys/src/cmd/aux/antiword/worddos.c - 664 sys sys 1137261474 2790
+1137268850 66 m sys/src/cmd/aux/antiword/wordlib.c - 664 sys sys 1137261474 7910
+1137268850 67 m sys/src/cmd/aux/antiword/wordmac.c - 664 sys sys 1137261474 2658
+1137268850 68 m sys/src/cmd/aux/antiword/wordole.c - 664 sys sys 1137261474 22402
+1137268850 69 m sys/src/cmd/aux/antiword/wordtypes.h - 664 sys sys 1137261474 8285
+1137268850 70 m sys/src/cmd/aux/antiword/wordwin.c - 664 sys sys 1137261474 5584
+1137268850 71 m sys/src/cmd/aux/antiword/xmalloc.c - 664 sys sys 1137261474 2501
+1137268850 72 m sys/src/cmd/aux/antiword/xml.c - 664 sys sys 1137261474 34115

+ 0 - 342
sys/src/cmd/aux/antiword/COPYING

@@ -1,342 +0,0 @@
-
-
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                          675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	Appendix: How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) 19yy  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) 19yy name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
-

+ 0 - 180
sys/src/cmd/aux/antiword/ChangeLog

@@ -1,180 +0,0 @@
-****************************************************************************
-* Changes in Antiword from versions 0.22 to 0.34                           *
-****************************************************************************
-
-Changes 0.33 to 0.34
---------------------
-Bug fixes:
-- Bug in UTF-8 tables fixed
-- Bug reported by Stewart Goldwater <sg@janus.freeserve.co.uk> fixed
-- Bug reported by Karl-Otto Linn <linn@informatik.fh-wiesbaden.de> fixed
-- Fixed a bug that made DOS hang when Antiword processed a document > 8 MB.
-New features:
-- Better approximations for fancy characters in the output
-- A Word document can now be saved as XML/DocBook.
-- Linux Makefile is now closer to conventions.
-- Support for Text Boxes
-- An environment variable ANTIWORDHOME was added to create a more flexable
-  place for the mapping files.
-- Antiword is now Latin9 enabled. Thanks to Stefan Bellon
-  <sbellon@sbellon.de> (RISC OS only)
-- Some support for MacWord 4 and 5 documents
-- More support for Word-for-DOS documents
-- Support for superscripts and subscripts
-- Displays slightly more images.
-- Improved lists, especially in documents from Word 97 or later.
-
-Changes 0.32 to 0.33
---------------------
-Bug fixes:
-- Bug reported by Yannick PERRET <yperret@bat710.univ-lyon1.fr> fixed
-Old features:
-- The -X option is no longer supported. Replace "-X 2" by "-m 8859-2.txt"
-New features:
-- Slightly more accurate font translation
-- Full support for WinWord 2.0 documents
-- Some support for Word-for-DOS and WinWord 1.x documents
-- Selective header numbering
-- Implementation of stylesheets
-- The system-wide directory for the mapping files was changed from
-  "/opt/antiword/share" to "/usr/share/antiword", in accordance with FHS,
-  the file-system hierarchy standard, as suggested by Anand Buddhdev
-  <arb@anand.org>.
-- Antiword now turns white text into light gray text.
-- Antiword is now closer to "64-bit clean". Based on information supplied by
-  Duncan Haldane <f.duncan.m.haldane@worldnet.att.net>.
-
-Changes 0.31 to 0.32
---------------------
-Bug fixes:
-- Bug reported by Forrest J. Cavalier III <mibsoft@mibsoftware.com> fixed
-- Bug reported by Jan ONDREJ (SAL) <ondrejj@salstar.sk> fixed
-- Bug in dealing with RLE compressed bitmap images fixed
-- Bug in image scaling fixed (RISC OS only)
-New features:
-- Improved leading (Unix only; PostScript version only)
-- Antiword can now read from the standard input. This is based on an idea by
-  Matthew Miller <mattdm@mattdm.org>. (Unix only)
-- A white background looks much better. (RISC OS only)
-- A system-wide directory for the mapping files, as suggested by Sven Geggus
-  <sven@geggus.net> and many others. (Unix only)
-- Antiword can now deal with documents larger than 7 MB.
-
-Changes 0.30 to 0.31
---------------------
-Bug fixes:
-- Bug in the "Show hidden (by Word) text" feature fixed
-- Bug reported by David Aspinwall <aspinwall@timesten.com> fixed
-- Bug reported by Robert Steinmetz <rob@steinmetznet.com> fixed
-Old features:
-- The -g and -c options are no longer supported. The -c option was the default
-  and is now used automatically. (Unix only)
-New features:
-- Ability to display some of the images
-- Ability to use landscape mode (Unix only; PostScript version only)
-- Support for all ISO-8859 character sets plus KOI8 and some code pages
-  (Unix only; text version only)
-- Antiword will now give a warning if the specified PostScript paper size is
-  unsupported. Thanks to Greg Robinson <Greg.Robinson@dsto.defence.gov.au>
-- Changed from PostScript version 1 to version 2
-- Antiword now returns 1 if no Word document is found among the files listed
-  on the command line, as suggested by Jens Schleusener
-  <Jens.Schleusener@dlr.de>.
-- Takes the right margin into account
-- The PostScript part now supports the AvantGarde, Bookman, Helvetica-Narrow,
-  NewCenturySchlbk and Palatino fonts (Unix only)
-- More accurate fontnames translation table
-- Initial scale factor is now configurable (RISC OS only)
-
-Changes 0.29 to 0.30
---------------------
-Bug fixes:
-- Bug in the generated PostScript (nocurrentpoint) fixed
-- Bug reported by Keith Bamford <kbamford@eurobell.co.uk> fixed
-- Bug in the chapter numbering font fixed
-New features:
-- Improved handling of changes in the font size on a single line.
-- Some support for long file names (RISC OS only)
-- Thanks to David Kanareck <david@davidkanareck.demon.co.uk>, Antiword can
-  now deal with documents made by "Word for Asian languages", but only
-  when these documents are written in a European language.
-- Character properties "Caps" and "SmallCaps" for accented characters
-- More accurate fontnames translation table. (RISC OS only)
-- PostScript part now supports the Times and Helvetica fonts. (Unix only)
-
-Changes 0.28 to 0.29
---------------------
-Bug fixes:
-- Bug reported by Paul McCann <P.J.McCann@cfm1220.x400.icl.co.uk> fixed
-- Character property "SmallCaps" works better now
-- Bug reported by Richard Lambley <richard@wireless.demon.co.uk> fixed
-- Fixed a bug in the linewidth computation (Unix only)
-New features:
-- A Word document can now be saved as PostScript (Unix only, Courier font only)
-- Left, Center, Right and Justify alignment added for Word 97
-- Supports the Macintosh character set
-
-Changes 0.27 to 0.28
---------------------
-Licence:
-- Distributed under the GNU General Public License
-Bug fixes:
-- Bug reported by Richard Lambley <richard@wireless.demon.co.uk> has not
-  been fixed yet.
-- Deals correctly with fancy quotes in files from a Macintosh
-New features:
-- Supports character properties "SmallCaps", "Caps" and "Hidden Text"
-- The use of fonts and font sizes for "fast saved" documents is now supported.
-- Separators between the text, the footnotes and the endnotes
-- Footnotes are now numbered in Arabic numericals (1, 2, 3), endnotes are now
-  numbered in Roman numericals (i, ii, iii).
-
-Changes 0.26 to 0.27
---------------------
-Bug fixes:
-- The main title now shows the first 12 characters of the file name.
-New features:
-- "Fast saved" documents are now supported for Word 97.
-- All tables are now supported for Word 97.
-- It is now possible to scale the text.
-
-Changes 0.25 to 0.26
---------------------
-Bug fixes:
-- Fixed several problems with the Choices file
-- Closed a small memory leak
-New features:
-- The use of fonts and font sizes for "full saved" documents is now supported.
-- Most tables are now supported for Word 97.
-- Header numbers are now supported for Word 97.
-
-Changes 0.24 to 0.25
---------------------
-Bug fixes:
-- Improved handling of memory shortages
-- Some special tables were messed up.
-New features:
-- "Fast saved" documents are now supported for Word 6 and 7.
-- A new option to permit Antiword to change the filetype of Word documents to
-  MSWord (&ae6).
-- A Wordfile can now be saved as a Drawfile.
-- The look and feel has been changed from editor-like to browser-like
-
-Changes 0.23 to 0.24
---------------------
-Bug fixes:
-- Empty paragraphs in numbered list were not always numbered correctly.
-- In very complex tables some text could get lost.
-New features:
-- F3 is now a shortcut to the "Save as" dialogue box.
-- Left, Center, Right and Justify alignment added for Word 6 and 7
-- [pic] marks the place where an image should have been.
-- It is now possible to have a writeable Choices file, even when Antiword
-  itself is on a read-only medium.
-
-Changes 0.22 to 0.23
---------------------
-New features:
-- Paragraph breaks are now an option.
-- Bulleted single level lists for files from Word 6 and 7
-- Numbered single level lists (some styles) for files from Word 6 and 7

+ 0 - 134
sys/src/cmd/aux/antiword/Emacs

@@ -1,134 +0,0 @@
-From: Alex Schroeder <alex@emacswiki.org>
-Subject: Re: MS Word mode?
-Date: Fri, 08 Nov 2002 00:40:15 +0100
-
-Roger Mason <rmason@sparky2.esd.mun.ca> writes:
-
-> There was a question about this recently on this forum.  Look for
-> undoc.el, I got it from the wiki (I think).  It has worked very well for
-> me to date, although I have not attempted ro read complex documents.
-
-Well, it makes things readable, but it is far from perfect -- it seems
-to just delete any non-ascii characters, such that sometimes you will
-see words such as "Alex8" where "8" is some garbage that just looked
-like being part of a real word...  In other words, interfacing to
-something like catdoc, antiword, or wvText (included with AbiWord)
-might be cool.  Actually all you need is this:
-
-(add-to-list 'auto-mode-alist '("\\.doc\\'" . no-word))
-
-(defun no-word ()
-  "Run antiword on the entire buffer."
-  (shell-command-on-region (point-min) (point-max) "antiword - " t t))
-
-Alex.
-
-===============================================================================
-
-From: Arnaldo Mandel <am@ime.usp.br>
-Subject: Re: MS Word mode?
-Date: Fri, 8 Nov 2002 11:52:33 -0200
-
-Alex Schroeder wrote (on Nov 8, 2002):
-
- >                 Actually all you need is this:
- > 
- > (add-to-list 'auto-mode-alist '("\\.doc\\'" . no-word))
- > 
- > (defun no-word ()
- >   "Run antiword on the entire buffer."
- >   (shell-command-on-region (point-min) (point-max) "antiword - " t t))
-
-On my system there are lots of filenames ending in .doc whose files
-are not Word files.  So I modified your function thusly
-
-(defun no-word ()
-  "Run antiword on the entire buffer."
-  (if (string-match "Microsoft "
-		    (shell-command-to-string (concat "file " buffer-file-name)))
-      (shell-command-on-region (point-min) (point-max) "antiword - " t t)))
-
-Works in Solaris and Linux, and should work on other unixes as well.
-
-am
-
-===============================================================================
-
-From: Alex Schroeder <alex@emacswiki.org>
-Subject: Re: MS Word mode?
-Date: Fri, 08 Nov 2002 18:24:07 +0100
-
-Arnaldo Mandel <am@ime.usp.br> writes:
-
-> (defun no-word ()
->   "Run antiword on the entire buffer."
->   (if (string-match "Microsoft "
-> 		    (shell-command-to-string (concat "file " buffer-file-name)))
->       (shell-command-on-region (point-min) (point-max) "antiword - " t t)))
-
-Cool.  I did not know about "file"...  :)
-
-My stuff is on the wiki, btw:
-
-* http://www.emacswiki.org/cgi-bin/wiki.pl?AntiWord
-
-Alex.
-
-===============================================================================
-
-From: Benjamin Riefenstahl <Benjamin.Riefenstahl@epost.de>
-Subject: Re: emacs rmail. How to convert .doc to plain text
-Date: 24 Nov 2002 18:08:22 +0100
-
-Hi,
-
-Puff Addison <puff@theaddisons.demon.co.uk> writes:
-> Yes, please post your Emacs integration code.
-
-Ok, see below.  I should note that it is probably also possible to
-(ab-)use jka-compr for this, which would make my two functions
-obsolete.
-
-so long, benny
-
->>>>>>>
-
-(defun benny-antiword-file-handler (operation &rest args)
-  ;; First check for the specific operations
-  ;; that we have special handling for.
-  (cond ((eq operation 'insert-file-contents)
-	 (apply 'benny-antiword-insert-file args))
-	((eq operation 'file-writable-p)
-	 nil)
-	((eq operation 'write-region)
-	 (error "Word documents can't be written"))
-	;; Handle any operation we don't know about.
-	(t (let ((inhibit-file-name-handlers
-		  (cons 'benny-antiword-file-handler
-			(and (eq inhibit-file-name-operation operation)
-			     inhibit-file-name-handlers)))
-		 (inhibit-file-name-operation operation))
-	     (apply operation args)))))
-
-(defun benny-antiword-insert-file (filename &optional visit beg end replace)
-  (set-buffer-modified-p nil)
-  (setq buffer-file-name (file-truename filename))
-  (setq buffer-read-only t)
-  (let ((start (point))
-	(inhibit-read-only t))
-    (if replace (delete-region (point-min) (point-max)))
-    (save-excursion
-      (let ((coding-system-for-read 'utf-8)
-	    (filename (encode-coding-string
-		       buffer-file-name
-		       (or file-name-coding-system
-			   default-file-name-coding-system))))
-	(call-process "antiword" nil t nil "-m" "UTF-8.txt"
-		      filename))
-      (list buffer-file-name (- (point) start)))))
-
-(setq file-name-handler-alist
-      (cons '("\\.doc\\'" . benny-antiword-file-handler)
-	    file-name-handler-alist))
-
-<<<<<<<

+ 0 - 14
sys/src/cmd/aux/antiword/Exmh

@@ -1,14 +0,0 @@
-From: Glenn Burkhardt <glenn@vtecus.com>
-Subject: It's great!
-Date: Wed, 22 Aug 2001 12:02:54 -0400
-
-Thank you for this program.  Thank you very much!  Thank you immensely!!
-
-
-P.S.  I find entry helpful as a /etc/mailcap rule:
-
-application/msword;/usr/local/bin/antiword -t %s | less; needsterminal; \
-copiousoutput; print=antiword -p letter %s|lpr
-
-I completely integrates the text mode with my mailer, exmh.  You might
-want to include it in your documentation.

+ 0 - 97
sys/src/cmd/aux/antiword/FAQ

@@ -1,97 +0,0 @@
-Frequently Asked Questions
-==========================
-
-These questions and answers are mainly Linux/Unix oriented. For other
-Operating Systems you may want to read the documentation provided by the
-people who ported Antiword.
-
-Q1: How do I install Antiword?
-A1: (a) Make a suitable directory such as '$HOME/src/antiword' and copy the
-        'antiword.tar.gz' file to this directory.
-    (b) decompress: 'gunzip antiword.tar.gz'
-    (c) unpack: 'tar xvf antiword.tar'
-    (d) compile: 'make all'
-    (e) install: 'make install'. This will install Antiword in the $HOME/bin
-        directory.
-    (f) copy the file 'fontnames' and one or more mapping files from the
-        Resources directory to the $HOME/.antiword directory (note the dot
-        before antiword!).
-    NOTE: you can skip point (f) if your system administrator already copied
-          these files to /usr/share/antiword.
-
-Q2: I get the message "I can't open your mapping file (xxxx-x.txt)"
-A2: This means that the mapping file has not been installed. The installation
-    may have to be done manually. See above answer A1, point (f).
-    NOTE: Antiword assumes that a file that can't be opened for reading is a
-          file that doesn't exist.
-
-Q3: How do I use Antiword?
-A3: Type antiword -h and see.
-
-Q4: I tried "antiword -m /some/directory/8859-1.txt word.doc", but this
-    doesn't work.
-A4: The -m option is followed by the name of a mapping file, a full pathname
-    won't work.
-
-Q5: How does Antiword deal with Word macro viruses?
-A5: Antiword does not run any Word macros because it can't do so.
-    Therefore such a virus will not harm your computer system.
-
-Q6: What is the purpose of the file 'fontnames' in the '/usr/share/antiword/'
-    or '$HOME/.antiword' directory?
-A6: This file provides a translation table from the font names used in a Word
-    document to the font names used by a PostScript printer.
-    The file 'fontnames' can be edited to match the font collection used by
-    your PostScript printer.
-
-Q7: What is 'Hidden Text'?
-A7: Hidden Text is Microsoft speak for text that may or may not be shown
-    on the screen, subject to the user's preferences, but such text is never
-    printed.
-
-Q8: Antiword claims to support all ISO-8859 character sets, but I can't see
-    any of this.
-A8: There is support for all ISO-8859 character sets, but only in the text
-    output, not in the PostScript output.
-    The result can only be seen if your xterm, vtterm, kvt or similar
-    terminal emulation program uses a font compatible with that ISO-8859
-    character set.
-
-Q9: Which mapping file (-m option) is correct in my situation?
-A9: The correct mapping file depends on the character set you need for output
-    in a specific language.
-    For Western European languages (like English, French, German) this is
-    8859-1.txt. (OS/2: cp1252.txt) (DOS: cp850.txt)
-    For Eastern European languages (like Polish, Czech, Slovak, Croatian) this
-    is 8859-2.txt. (OS/2: cp1250.txt) (DOS: cp852.txt)
-    For Esperanto use 8859-3.txt.
-    For Russian use 8859-5.txt or koi8-r.txt. (OS/2: cp1251.txt)
-     (DOS: cp866.txt)
-    For Ukrainian use koi8-u.txt.
-    For Hebrew use 8859-8.txt. (DOS: cp862.txt)
-    If your system supports it, you might also try UTF-8.txt.
-
-    NOTE: UTF-8 also enables Antiword to show text in languages like Chinese,
-          Japanese and Korean.
-
-Q10: I tried UTF-8, but some documents show more garbage than text. Why?
-A10: UTF-8 will only work if the document was saved by a Unicode enabled
-    version of Word (or if Word used ISO-8859-1 as its internal encoding).
-    The following versions of Word are known to be Unicode enabled:
-    Word 6 and Word 7 for Asian languages, all versions of Word 97,
-    Word 98 (Mac), Word 2000, Word 2001 (Mac) and Word 2002 (aka Word XP).
-
-Q11: Why can't Antiword read from stdin directly? Why use a temporary file?
-A11: The information in a Word document is not stored sequentially. Therefore
-    the use of the "fseek" function can't be avoided. So Antiword must copy
-    stdin to a temporary file first and then process that file.
-
-Q12: Why does the XML output of Antiword sometimes contain such a strange
-     structure or practically no structure at all?
-A12: Remember that Word is basically 'text plus appearance' and XML is
-     basically 'text plus structure'. If a Word document is written by a
-     competent person there will be a balance between appearance and structure,
-     but if a Word document is written by an inexperienced or incompetent
-     person the Word document can end up without a structure, or worse, with a
-     terrible structure.
-     Antiword can't create a structure when there is none.

+ 0 - 44
sys/src/cmd/aux/antiword/History

@@ -1,44 +0,0 @@
-History of Antiword by (C) Adri van Os
-------------------------------------
-
-
-The Name
---------
-The name comes from: "The antidote against people who send Microsoft(R) Word
-files to everybody, because they believe that everybody runs Windows(R) and
-therefore runs Word".
-
-
-Version 0.34 (25 Aug 2003)
---------------------------
-Beta release, for evaluation by the public.
-
-
-Known Limitations
------------------
-
-1) The layout of Word documents is kept secret by Microsoft(R). Therefore
-   Antiword is based on information gathered from the Internet and on
-   guesswork.
-2) Antiword doesn't show all the images included in a Word document.
-3) Antiword doesn't do any hyphenation, because hyphenation is language
-   dependent.
-4) Antiword places footnotes at the end of the text.
-5) Antiword places box text after normal text and not in a box.
-6) Antiword doesn't try to emulate any of Word's DTP abilities.
-7) PostScript ouput will not work in combination with UTF-8. It only worask in
-   combination with character sets ISO 8859-1 and ISO 8859-2.
-8) Antiword's error messages are not very helpful.
-
-
-Known Bugs
-----------
-
-1) Antiword cannot handle encrypted documents.
-2) Antiword assumes default tab stops.
-3) Antiword doesn't handle frames.
-4) Antiword ignores page headers and footers.
-5) Antiword only handles lists in some of the styles.
-6) Antiword cannot handle some types of multilevel lists.
-7) Antiword assumes that all Word documents made on a Macintosh with Word
-   version 6 or older use the MacRoman character set.

+ 0 - 88
sys/src/cmd/aux/antiword/Mozilla

@@ -1,88 +0,0 @@
-Date: Mon, 11 Nov 2002 11:36:21 +0000
-From: Cam <camilo@mesias.co.uk>
-Subject: Re: antiword
-
-Hi
-
-I have updated the script for the latest Mozilla with plugger, as found 
-in RedHat 8. This makes the default action a very quick text view of a 
-document, much better IMHO than starting ooffice or abiword. If users 
-want to edit the file they can still save as.
-
-Here is a slightly improved script for gnome users:
-
-#!/bin/bash
-
-tmpfile=/tmp/aw$$.txt
-
-lastditch=`which vi`
-
-editor=${EDITOR:-$lastditch}
-
-if [ ! -x $editor ] ; then
-   editor=$lastditch
-fi
-
-
-tmpfile=/tmp/aw$$.txt
-
-gtopts="-t antiword-helper --hide-menubar"
-
-antiword "$1" > $tmpfile
-chmod -w $tmpfile
-gnome-terminal $gtopts -x $editor $tmpfile ; chmod +w $tmpfile ; rm $tmpfile
-
-
-
-Here is the script for non-gnome users:
-
-#!/bin/bash
-
-tmpfile=/tmp/aw$$.txt
-
-lastditch=`which vi`
-
-editor=${EDITOR:-$lastditch}
-
-if [ ! -x $editor ] ; then
-   editor=$lastditch
-fi
-
-
-antiword "$1" > $tmpfile
-chmod -w $tmpfile
-xterm -T "antiword-helper" -e $editor $tmpfile
-chmod +w $tmpfile
-rm $tmpfile
-
-
-
-To use the scripts add an entry into your plugger config file 
-(pluggerrc, for locations check man plugger). Mine is in 
-/home/cxm/.netscape/pluggerrc:
-
-The line to add is (it has a leading tab):
-
-   ignore_errors exits: antiword-helper "$file"
-
-
-Here is my config file after I added the line
-
-application/rtf: rtf: Rich Text Format
-application/x-msword: doc, dot: Microsoft Word Document
-application/msword: doc, dot: Microsoft Word Document
-         ignore_errors exits: antiword-helper "$file"
-         nokill exits: oowriter "$file"
-         repeat swallow(AbiWord) fill: AbiWord -nosplash -geometry 
-+9000+9000 "$file" >/dev/null 2>/dev/null
-         repeat swallow(PCFileViewer) fill: sdtpcv "$file"
-         repeat swallow(PCFileViewer) fill: /opt/SUNWdtpcv/bin/sdtpcv 
-"$file"
-
-
-Then start Mozilla / Netscape and you should be able to quickly view 
-word docs from the browser and as email attachments.
-
-Hope that helps,
-
--Cam

+ 0 - 24
sys/src/cmd/aux/antiword/Mutt

@@ -1,24 +0,0 @@
-From: Sven Geggus (sven@geggus.net)
-Subject: Re: Word attachments in Mutt
-Newsgroups: comp.mail.mutt
-Date: 2001-05-16 01:21:11 PST
-
-Bob Zimmerman <bobzim@no.spam.org> wrote:
-
-> I receive MS Word attachments in Mutt reguarly. Is there a way to
-> read these via Mutt in a Linux/Solaris environment? (e.g. Lynx or
-> some type of viewer)?
-
-The best M$-word to ASCII converter has to be antiword!
-
-Just put the following line into .mailcap:
-
-application/msword; antiword %s; copiousoutput
-
-Sven
-
---
-"We just typed make"
-(Stephen Lambrigh, Director of Server Product Marketing at Informix
-                                      about porting their Database to Linux)
-/me is giggls@ircnet, http://geggus.net/sven/ on the Web

+ 0 - 129
sys/src/cmd/aux/antiword/Netscape

@@ -1,129 +0,0 @@
-From: "Craig D. Miller" <Craig.D.Miller@jpl.nasa.gov>
-
-Hi,
-
-Steps to integrate antiword into NetScape 4.73 (should also work with earlier
-versions).
-
-Programs that launch from netscape must startup an X window to display their
-output (otherwise output ends up it the bit bucket on your system).  I wrote the
-following script to do this for antiword (and saved it as
-"/usr/local/bin/xantiword":
-
-#!/bin/csh -f
-setenv FILE $1
-setenv NEWFILE ${FILE}.xantiword
-/usr/local/bin/antiword $FILE >&$NEWFILE
-/usr/bin/X11/xterm -title "$FILE (MS Word)" -e /usr/bsd/more $NEWFILE
-rm -f $NEWFILE
-
-The above script works, but may not be the best way to do it.  If you come up
-with a more elegant solution, then please let me know.
-
-Next you'll have to tell netscape to execute the "/usr/local/bin/xantiword"
-script when word documents are clicked on.  The easiest way to do this is to
-change the /usr/local/lib/netscape/mailcap netscape configuration file.  For
-SGI version of netscape the following two lines are changed.  For other versions
-of netscape, one should find similar lines or will need to add the new lines.
-
-Old lines (try to run SoftWindows, which is not installed on my system):
-
-    application/x-dos_ms_word; /usr/local/lib/netscape/swinexec %s winword; \
-        description="Microsoft Word-for-Windows Document";
-    application/msword; /usr/local/lib/netscape/swinexec %s winword; \
-        description="Microsoft Word-for-Windows Document";
-
-New lines (for antiword execution), which replace old lines on my system:
-
-    application/x-dos_ms_word; /usr/local/bin/xantiword %s; \
-        description="Microsoft Word-for-Windows Document";
-    application/msword; /usr/local/bin/xantiword %s; \
-        description="Microsoft Word-for-Windows Document";
-
-These changes can also be made via the netscape preferences, under
-Navigator/Applications, but then the changes would only be for the user that
-changed them.  The above change to the mailcap file affects all users, which is
-what you'll usually want.
-
- Note that the above file paths may be different for your system.  On our linux
-box, a quick search DID NOT show where the mailcap for netscape was stored, but
-I did find one in /etc/mailcap.  I don't have time to experiment to see if this
-is the same one that netscape uses.
-
-If you have questions then please E-mail me.
-
-- Craig
-
-===============================================================================
-
-From: "Craig D. Miller" <Craig.D.Miller@jpl.nasa.gov>
-
-Hi,
-
-I just discovered a program called "xless".  It would actually be easier to use
-than my previous xterm/more solution.  To use it change the
-"/usr/local/bin/xantiword" script to: 
-
-#!/bin/csh -f
-setenv FILE $1
-/usr/local/bin/antiword $FILE | /usr/freeware/bin/xless \
-            -title "$FILE (MS Word)" -geometry 100x60
-
-Note that one also needs to have xless installed.  It can be found on the
-SGI Freeware Feb 1999 (or later) CD-ROM.
-
-- Craig
-
-===============================================================================
-
-From: Bruno Crochet <bruno.crochet@pse.unige.ch>
-
-Hi!
-
-Another way to integrate antiword into netscape is to copy the following
-line in your .mailcap file :
-
-application/msword; ns="%s"\; nf="${ns}".ps\; antiword -pa4 "${ns}" >
-"${nf}"\; gv "${nf}"\; sleep 2 \; rm "${nf}"
-
-Bruno.
-
-===============================================================================
-
-From: Andoni Zarate <azarate@saincotrafico.com>
-
-In order to view the file into netscape you can write the xantiword file
-like this:
- 
-#!/bin/csh -f
-setenv FILE $1
-setenv NEWFILE ${FILE}.xantiword
-/usr/local/bin/antiword $FILE >&$NEWFILE
-netscape -remote 'openFile('$NEWFILE')'
- 
-Andoni Zárate.
-
-===============================================================================
-
-From: Evelyne Pinter <epinter@ptcs.ch>
-
-I include a script for netscape to see the document with ghostview.
- 
-#!/bin/csh -f
-setenv FILE $1
-setenv NEWFILE ${FILE}.xantiword
-/usr/local/bin/antiword -pa4 $FILE >&$NEWFILE
-/usr/X11R6/bin/gv $NEWFILE
-rm -f $NEWFILE
- 
-In netscape the application must be called like that
-"/usr/local/bin/xantiword %s"
- 
-This is just a small change(done by Roger Luechinger) to the xantiword
-you included in the distribution 0.31
- 
-Thanks
- 
-SG E.M.S.P.
-
-===============================================================================

+ 0 - 56
sys/src/cmd/aux/antiword/QandA

@@ -1,56 +0,0 @@
-Questions and Answers (RISC OS version)
-=======================================
-
-Q1: How do I install Antiword?
-A1: Copy the application-directory and all the files within it to a
-    suitable directory.
-
-Q2: How do I use Antiword?
-A2: Double click on a Word document, filetype MSWord (&ae6). Or drag and drop
-    a file onto the Antiword icon on the iconbar.
-
-Q3: How does Antiword deal with Word macro viruses?
-A3: Antiword does not run any Word macros because it cannot do so.
-    Therefore your Archimedes will not be harmed by such a virus.
-
-Q4: What does the 'Paragraph breaks' option do?
-A4: This option controls the maximum number of characters per line in
-    paragraphs. If your screen is 640 pixels wide (like modes 20 and 27)
-    than 76 is probably best. If your screen is 800 or more pixels wide
-    (like mode 31) then numbers near 94 work best. You can switch this
-    option off if the (text only) output of Antiword will be the input to a
-    wordprocessor or a DTP program.
-
-Q5: What does the 'Auto filetype' option do?
-A5: When auto filetype is allowed, Antiword will change the filetype of
-    Word documents to MSWord (&ae6)
-
-Q6: When Antiword uses outline fonts it becomes terribly slow. What can I
-    do about this?
-A6: When Antiword uses outline fonts it needs a large font cache. A small
-    font cache will make Antiword (very) slow. The larger the font cache the
-    better, but usually 160K or 256K will do.
-
-Q7: What is the purpose of the file 'FontNames' in the Choices directory?
-A7: This file provides a translation table from the font names found in a
-    Word document to the font names used by the RISC OS font-manager.
-    The file 'FontNames' is can be edited to match your font collection.
-    Some examples are provided in the Resources directory.
-
-Q8: What is 'Hidden Text'?
-A8: Hidden Text is Microsoft speak for text that may or may not be shown
-    on the screen, subject to the user's preferences, but such text is never
-    printed.
-
-Q9: After upgrading to a new version of Antiword, I found that Antiword does
-    not put a new _updated_ version of FontNames in !Choices. Why not?
-A9: The user can change the file Fontnames to reflect the fonts available
-    on a specific computer. Antiword cannot be permitted to overwrite changes
-    made by a user. So after upgrading you should remove or rename the old
-    FontNames file.
-
-Q10: Why does Antiword freeze my computer while converting the Word document?
-A10: This can happen when the Word document contains a very large image and
-     the image must be scaled to a much smaller size before displaying. The
-     delay occurs while RISC OS does the scaling, so there is not much
-     Antiword can do about it.

+ 0 - 113
sys/src/cmd/aux/antiword/ReadMe

@@ -1,113 +0,0 @@
-                    ___        _   _                       _
-                   / _ \      | | (_)                     | |
-                  | |_| |_ __ | |_ ___      _____  _ __ __| |
-                  |  _  | '_ \| __| \ \ /\ / / _ \| '__/ _` |
-                  | | | | | | | |_| |\ V  V / (_) | | | (_| |
-                  |_| |_|_| |_|\__|_| \_/\_/ \___/|_|  \__,_|
-
-Antiword
-========
-
-Version 0.34 (25 Aug 2003)
---------------------------     
-
-Introduction
-------------
-
-Antiword is an application for displaying Microsoft(R) Word documents.
-
-
-License
--------
-
-This program is distributed under the GNU General Public License - see the
-accompanying COPYING file for more details.
-
-
-Problems
---------
-
-Any bugs found should be reported to the author with full details of how to
-get the problem to occur, but don't *expect* support for a product that you
-have not paid for!
-
-Please include Antiword's version number and version date, otherwise you
-make it impossible for the author to help.
-
-
-Thanks To
----------
-
-Victor B. Wagner <vitus@agropc.msk.su> creator of "catdoc"
-Duncan Simpson <word2x@duncan.telstar.net> creator of "word2x"
-Martin Schwartz <schwartz@cs.tu-berlin.de> creator of "laola" and "elser"
-Caolan McNamara <Caolan.McNamara@ul.ie> creator of "mswordview"
-Andrew Scriven <andy.scriven@research.natpower.co.uk> creator of "OLEdecode"
-Craig Southeren <geoffw@extro.ucc.oz.au> creator of "nenscript"
-Thomas Merz <tm@muc.de> creator of "jpeg2ps"
-Ulrich von Zadow <uzadow@cs.tu-berlin.de> creator of "paintlib"
-
-
-Contributors
-------------
-
-ISO-8859-2 support by: Pawel Turnau <uzturnau@cyf-kr.edu.pl>
-Character set mapping by: Dmitry Chernyak
-                          <Dmitry.Chernyak@p998.f983.n5030.z2.fidonet.org>
-UTF-8 support by: Karl Koehler <koehler@or.uni-bonn.de> and
-                  Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk>
-
-
-Ports
------
-
-Antiword was ported to BeOS by Pete Goodeve <pete@jwgibbs.cchem.berkeley.edu>
-Antiword was ported to OS/2 by Dave Yeo <dave_yeo@mindlink.bc.ca>
-Antiword was ported to Mac OS X by Ronaldo Nascimento <ronaldo@ronaldo.com>
-Antiword was ported to Amiga by Raffaele Pisapia <rafpis@libero.it>
-Antiword was ported to VMS by Joseph Huber <huber@mppmu.mpg.de>
-Antiword was ported to NetWare by Guenter Knauf <info@gknw.de>
-Antiword was ported to EPOC by Max Tomin <tomin@samaramail.ru>
-Antiword was ported to Zaurus PDA by Piotr Jachimczyk
-                                     <P.Jachimczyk@prioris.mini.pw.edu.pl>
-Antiword was ported to DOS by myself ;-)
-Yen-Ming Lee <leeym@freebsd.org> is the maintainer of the FreeBSD version of
-Antiword.
-
-
-Acknowledgements
-----------------
-
-Microsoft is a registered trademark and Windows is a trademark of Microsoft
-Corporation.
-UNIX is a registered trademark of the X/Open Company, Ltd.
-Linux is a registered trademark of Linus Torvalds.
-Postscript is a trademark of Adobe Systems Incorporated.
-All other trademarks are acknowledged.
-
-
-Future Versions
----------------
-
-If you have any comments, bug reports or suggestions for future versions
-don't hesitate to write to me.
-New versions of the program will only be available if sufficient people
-are using this program. So let me know!
-
-
-Most recent version
--------------------
-
-Most recent version of Antiword can be found on the author's website:
-==>>  http://www.winfield.demon.nl/index.html  <<==
-==>>  http://antiword.cjb.net/  <<==
-
-
-Author
-------
-
-The author can be reached by e-mail:
-antiword@winfield.demon.nl
-comments@antiword.cjb.net
-
-But PLEASE read the FAQ before you write!!

+ 0 - 143
sys/src/cmd/aux/antiword/antiword.1.txt

@@ -1,143 +0,0 @@
-.TH ANTIWORD 1 "Jun 24, 2003" "Antiword 0.34" "Linux User\'s Manual"
-.SH NAME
-antiword - show the text and images of MS Word documents
-.SH SYNOPSIS
-.B antiword
-[
-.I options
-]
-.I wordfiles
-.SH DESCRIPTION
-.I Antiword
-is an application that displays the text and the images of Microsoft Word
-documents.
-.br
-A wordfile named - stands for a Word document read from the standard input.
-.br
-Only documents made by MS Word version 2 and version 6 or later are supported.
-.SH OPTIONS
-.TP
-.B \-h
-Give a help message.
-.TP
-.BI "\-i " "image level"
-The image level determines how images will be shown.
-.RS
-.TP 3
-0:
-Use non-standard extensions from Ghostscript. This output may not print on
-any PostScript printer, but is useful in case no hard copy is needed. It is
-also useful when Ghostscript is used as a filter to print a PostScript file to
-a non-PostScript printer.
-.TP 3
-1:
-Show no images.
-.TP 3
-2:
-PostScript level 2 compatible. (default)
-.TP 3
-3:
-PostScript level 3 compatible. (EXPERIMENTAL, Portable Network Graphics (PNG)
-images are not printed correctly)
-.RE
-.TP
-.BI "\-m " "mapping file"
-This file is used to map Unicode characters to your local character set.
-The default is UTF-8.txt in locales that support UTF-8 and 8859-1.txt in other
-locales.
-.TP
-.BI "\-p " papersize
-Output in PostScript form. Printable on paper of the specified size: 10x14,
-a3, a4, a5, b4, b5, executive, folio, legal, letter, note, quarto, statement
-or tabloid.
-.TP
-.B \-s
-Include text with the so-called "hidden text" attribute.
-.TP
-.B \-t
-Output in text form. (default)
-.TP
-.BI "\-w " width
-In text mode this is the line width in characters. A value of zero puts an
-entire paragraph on a line, useful when the text is to used as input for
-another wordprocessor. This value is ignored in PostScript mode.
-.TP
-.BI "\-x " "document type definition"
-Output in XML form. Currently the only document type definition is db
-(for DocBook).
-.TP
-.B \-L
-In PostScript mode: use landscape mode.
-.RE
-.SH FILES
-.TP
-Mapping files like 8859-1.txt
-.br
-Antiword looks for its mapping files in three directories, in the order given:
-.br
-(1) The directory specified by $ANTIWORDHOME
-.br
-(2) The directory specified by $HOME/.antiword
-.br
-(3) Directory /usr/share/antiword
-.TP
-The fontnames file
-.br
-Antiword will look for its fontname file in the same directories as used for the
-mapping files.
-.br
-The fontnames file contains the translation table from font names used by MS
-Word to font names used by PostScript.
-.TP
-NOTE:
-.br
-Antiword cannot tell the difference between a file that does not exist and a
-file that cannot be opened for reading.
-.SH ENVIRONMENT
-Antiword uses the environment variable ``ANTIWORDHOME'' as the first directory
-to look for its files. Antiword uses the environment variable ``HOME'' to find
-the user's home directory. When in text mode it uses the variable ``COLUMNS''
-to set the width of the output (unless overridden by the -w option).
-.SH BUGS
-Antiword is far from complete. Many features are still missing. Many images are
-not shown yet. Some of the images that are shown, are shown in the wrong place.
-PostScript output is only available in ISO 8859-1 and ISO 8859-2.
-.SH WEB SITES
-The most recent released version of Antiword is always available from:
-.br
-http://www.winfield.demon.nl/index.html
-.br
-or try
-.br
-http://antiword.cjb.net/
-.SH AUTHOR
-Adri van Os <antiword@winfield.demon.nl>
-.br
-or try <comments@antiword.cjb.net>
-.sp
-R.F. Smith <rsmith@xs4all.nl> and
-.br
-Sindi Keesan <keesan@cyberspace.org>
-.br
-contributed to this manual page.
-.SH LICENSE
-Antiword is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your option)
-any later version.
-
-This program is distributed in the hope that it will be useful but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-.SH ACKNOWLEDGEMENTS
-Linux is a registered trademark of Linus Torvalds.
-.br
-PostScript is a trademark of Adobe Systems Incorporated.
-.br
-Microsoft is a registered trademark and Windows is a trademark of Microsoft
-Corporation.

+ 158 - 61
sys/src/cmd/aux/antiword/antiword.h

@@ -1,6 +1,6 @@
 /*
  * antiword.h
- * Copyright (C) 1998-2003 A.J. van Os; Released under GNU GPL
+ * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Generic include file for project 'Antiword'
@@ -16,11 +16,12 @@
 #include <stdio.h>
 #include <limits.h>
 #if defined(__riscos)
-#include "wimp.h"
-#include "drawfobj.h"
-#include "font.h"
-#include "werr.h"
-#include "draw.h"
+#include "DeskLib:Font.h"
+#include "DeskLib:Wimp.h"
+#include "Desklib:Window.h"
+#include "drawfile.h"
+#define window_ANY	event_ANY
+#define icon_ANY	event_ANY
 #else
 #include <sys/types.h>
 #endif /* __riscos */
@@ -66,7 +67,7 @@
 
 #if defined(__riscos)
 #define FILE_SEPARATOR		"."
-#elif defined(__dos)
+#elif defined(__dos) || defined(__CYGMING__)
 #define FILE_SEPARATOR		"\\"
 #else	/* All others */
 #define FILE_SEPARATOR		"/"
@@ -125,8 +126,10 @@
 #define SCALE_100_PCT			 7
 #define SCALE_150_PCT			 8
 
-/* New draw objects */
-#define draw_OBJJPEG		16
+/* Save menu fields */
+#define SAVEMENU_SCALEVIEW		0
+#define SAVEMENU_SAVEDRAW		1
+#define SAVEMENU_SAVETEXT		2
 #else
 /* Margins for the PostScript version */
 #define PS_LEFT_MARGIN			(72 * 640L)
@@ -138,11 +141,11 @@
 /* Macros */
 #define STREQ(x,y)	(*(x) == *(y) && strcmp(x,y) == 0)
 #define STRNEQ(x,y,n)	(*(x) == *(y) && strncmp(x,y,n) == 0)
-#if defined(__dos)
+#if defined(__dos) || defined(__EMX__)
 #define STRCEQ(x,y)	(stricmp(x,y) == 0)
 #else
 #define STRCEQ(x,y)	(strcasecmp(x,y) == 0)
-#endif /* __dos */
+#endif /* __dos or __EMX__ */
 #define elementsof(a)	(sizeof(a) / sizeof(a[0]))
 #define odd(x)		(((x)&0x01)!=0)
 #define ROUND4(x)	(((x)+3)&~0x03)
@@ -196,6 +199,10 @@
 #define GLOBAL_ANTIWORD_DIR	"SYS:.antiword"
 #define ANTIWORD_DIR		".antiword"
 #define FONTNAMES_FILE		"fontnames"
+#elif defined(N_PLAT_NLM)
+#define GLOBAL_ANTIWORD_DIR	"SYS:/antiword"
+#define ANTIWORD_DIR		"antiword"
+#define FONTNAMES_FILE		"fontname.txt"
 #elif defined(__vms)
 #define GLOBAL_ANTIWORD_DIR	"/usr/share/antiword"
 #define ANTIWORD_DIR		"antiword"
@@ -204,19 +211,42 @@
 #define GLOBAL_ANTIWORD_DIR	"/boot/home/config/apps/antiword"
 #define ANTIWORD_DIR		"antiword"
 #define FONTNAMES_FILE		"fontnames"
+#elif defined(__CYGMING__)
+#define GLOBAL_ANTIWORD_DIR	"C:\\antiword"
+#define ANTIWORD_DIR		"antiword"
+#define FONTNAMES_FILE		"fontnames"
 #elif defined(__Plan9__)
 #define GLOBAL_ANTIWORD_DIR	"/sys/lib/antiword"
 #define ANTIWORD_DIR		"lib/antiword"
 #define FONTNAMES_FILE		"fontnames"
+#elif defined(__sun__)
+#define GLOBAL_ANTIWORD_DIR	"/usr/local/share/antiword"
+#define ANTIWORD_DIR		".antiword"
+#define FONTNAMES_FILE		"fontnames"
 #else	/* All others */
 #define GLOBAL_ANTIWORD_DIR	"/usr/share/antiword"
 #define ANTIWORD_DIR		".antiword"
 #define FONTNAMES_FILE		"fontnames"
 #endif /* __dos */
-/* The name of the default mapping file */
-#define MAPPING_FILE_DEFAULT_1	"8859-1.txt"
-#define MAPPING_FILE_DEFAULT_2	"8859-2.txt"
-#define MAPPING_FILE_DEFAULT_8	"UTF-8.txt"
+/* The names of grouped mapping files */
+	/* ASCII */
+#define MAPPING_FILE_CP437	"cp437.txt"
+	/* Latin1 */
+#define MAPPING_FILE_8859_1	"8859-1.txt"
+	/* Latin2 */
+#define MAPPING_FILE_8859_2	"8859-2.txt"
+#define MAPPING_FILE_CP852	"cp852.txt"
+#define MAPPING_FILE_CP1250	"cp1250.txt"
+	/* Cyrillic */
+#define MAPPING_FILE_8859_5	"8859-5.txt"
+#define MAPPING_FILE_KOI8_R	"koi8-r.txt"
+#define MAPPING_FILE_KOI8_U	"koi8-u.txt"
+#define MAPPING_FILE_CP866	"cp866.txt"
+#define MAPPING_FILE_CP1251	"cp1251.txt"
+	/* Latin9 */
+#define MAPPING_FILE_8859_15	"8859-15.txt"
+	/* UTF-8 */
+#define MAPPING_FILE_UTF_8	"UTF-8.txt"
 #endif /* __riscos */
 
 /* Prototypes */
@@ -230,17 +260,23 @@ extern void	vDestroyTextBlockList(void);
 extern BOOL	bAdd2TextBlockList(const text_block_type *);
 extern void	vSplitBlockList(FILE *, ULONG, ULONG, ULONG, ULONG, ULONG,
 			ULONG, ULONG, ULONG, BOOL);
+extern BOOL	bExistsHdrFtr(void);
 extern BOOL	bExistsTextBox(void);
 extern BOOL	bExistsHdrTextBox(void);
 extern USHORT	usNextChar(FILE *, list_id_enum, ULONG *, ULONG *, USHORT *);
+extern USHORT	usToHdrFtrPosition(FILE *, ULONG);
+extern USHORT	usToFootnotePosition(FILE *, ULONG);
+extern ULONG	ulCharPos2FileOffsetX(ULONG, list_id_enum *);
 extern ULONG	ulCharPos2FileOffset(ULONG);
+extern ULONG	ulHdrFtrOffset2CharPos(ULONG);
 extern ULONG	ulGetSeqNumber(ULONG);
 #if defined(__riscos)
 extern ULONG	ulGetDocumentLength(void);
 #endif /* __riscos */
 /* chartrans.c */
-extern UCHAR	ucGetNbspValue(void);
-extern BOOL	bReadCharacterMappingTable(const char *);
+extern UCHAR	ucGetBulletCharacter(conversion_type, encoding_type);
+extern UCHAR	ucGetNbspCharacter(void);
+extern BOOL	bReadCharacterMappingTable(FILE *);
 extern ULONG	ulTranslateCharacters(USHORT, ULONG, int, conversion_type,
 			encoding_type, BOOL);
 extern ULONG	ulToUpper(ULONG);
@@ -263,18 +299,26 @@ extern ULONG	ulDepotOffset(ULONG, size_t);
 /* dib2eps & dib2sprt.c */
 extern BOOL	bTranslateDIB(diagram_type *,
 			FILE *, ULONG, const imagedata_type *);
+#if defined(__dos)
+/* dos.c */
+extern int	iGetCodepage(void);
+#endif /* __dos */
+/* doclist.c */
+extern void	vDestroyDocumentInfoList(void);
+extern void	vCreateDocumentInfoList(const document_block_type *);
+extern UCHAR	ucGetDopHdrFtrSpecification(void);
 /* draw.c & output.c */
 extern BOOL	bAddDummyImage(diagram_type *, const imagedata_type *);
 extern diagram_type *pCreateDiagram(const char *, const char *);
 extern void	vPrologue2(diagram_type *, int);
-extern void	vMove2NextLine(diagram_type *, draw_fontref, USHORT);
+extern void	vMove2NextLine(diagram_type *, drawfile_fontref, USHORT);
 extern void	vSubstring2Diagram(diagram_type *,
 			char *, size_t, long, UCHAR, USHORT,
-			draw_fontref, USHORT, USHORT);
+			drawfile_fontref, USHORT, USHORT);
 extern void	vStartOfParagraph1(diagram_type *, long);
 extern void	vStartOfParagraph2(diagram_type *);
-extern void	vEndOfParagraph(diagram_type *, draw_fontref, USHORT, long);
-extern void	vEndOfPage(diagram_type *, long);
+extern void	vEndOfParagraph(diagram_type *, drawfile_fontref, USHORT, long);
+extern void	vEndOfPage(diagram_type *, long, BOOL);
 extern void	vSetHeaders(diagram_type *, USHORT);
 extern void	vStartOfList(diagram_type *, UCHAR, BOOL);
 extern void	vEndOfList(diagram_type *);
@@ -283,14 +327,20 @@ extern void	vEndOfTable(diagram_type *);
 extern BOOL	bAddTableRow(diagram_type *, char **, int,
 			const short *, UCHAR);
 #if defined(__riscos)
+extern BOOL	bDestroyDiagram(event_pollblock *, void *);
 extern void	vImage2Diagram(diagram_type *, const imagedata_type *,
 			UCHAR *, size_t);
 extern BOOL	bVerifyDiagram(diagram_type *);
 extern void	vShowDiagram(diagram_type *);
-extern void	vMainEventHandler(wimp_eventstr *, void *);
-extern void	vScaleOpenAction(diagram_type *);
+extern void	vMainButtonClick(mouse_block *);
+extern BOOL	bMainKeyPressed(event_pollblock *, void *);
+extern BOOL	bMainEventHandler(event_pollblock *, void *);
+extern BOOL	bRedrawMainWindow(event_pollblock *, void *);
+extern BOOL	bScaleOpenAction(event_pollblock *, void *);
 extern void	vSetTitle(diagram_type *);
-extern void	vScaleEventHandler(wimp_eventstr *, void *);
+extern void	vScaleButtonClick(mouse_block *, diagram_type *);
+extern BOOL	bScaleKeyPressed(event_pollblock *, void *);
+extern BOOL	bScaleEventHandler(event_pollblock *, void *);
 #else
 extern void	vImagePrologue(diagram_type *, const imagedata_type *);
 extern void	vImageEpilogue(diagram_type *);
@@ -308,6 +358,10 @@ extern BOOL	bGet6DocumentText(FILE *, BOOL, ULONG,
 extern BOOL	bGet8DocumentText(FILE *, const pps_info_type *,
 				const ULONG *, size_t, const ULONG *, size_t,
 				const UCHAR *);
+/* fmt_text.c */
+extern void	vPrologueFMT(diagram_type *, const options_type *);
+extern void	vSubstringFMT(diagram_type *, const char *, size_t, long,
+				USHORT);
 /* fontlist.c */
 extern void	vDestroyFontInfoList(void);
 extern void	vCorrectFontValues(font_block_type *);
@@ -319,7 +373,7 @@ extern int	iGetFontByNumber(UCHAR, USHORT);
 extern const char	*szGetOurFontname(int);
 extern int	iFontname2Fontnumber(const char *, USHORT);
 extern void	vCreate0FontTable(void);
-extern void	vCreate2FontTable(FILE *, const UCHAR *);
+extern void	vCreate2FontTable(FILE *, int, const UCHAR *);
 extern void	vCreate6FontTable(FILE *, ULONG,
 			const ULONG *, size_t, const UCHAR *);
 extern void	vCreate8FontTable(FILE *, const pps_info_type *,
@@ -329,24 +383,33 @@ extern void	vDestroyFontTable(void);
 extern const font_table_type	*pGetNextFontTableRecord(
 						const font_table_type *);
 extern size_t	tGetFontTableLength(void);
+extern void	vCorrectFontTable(conversion_type, encoding_type);
+extern long	lComputeSpaceWidth(drawfile_fontref, USHORT);
 /* fonts_r.c & fonts_u.c */
 extern FILE	*pOpenFontTableFile(void);
 extern void	vCloseFont(void);
-extern draw_fontref	tOpenFont(UCHAR, USHORT, USHORT);
-extern draw_fontref	tOpenTableFont(USHORT);
-extern long	lComputeStringWidth(const char *, size_t, draw_fontref, USHORT);
+extern drawfile_fontref	tOpenFont(UCHAR, USHORT, USHORT);
+extern drawfile_fontref	tOpenTableFont(USHORT);
+extern long	lComputeStringWidth(const char *, size_t, drawfile_fontref, USHORT);
 extern size_t	tCountColumns(const char *, size_t);
 extern size_t	tGetCharacterLength(const char *);
 /* fonts_u.c */
 #if !defined(__riscos)
-extern const char	*szGetFontname(draw_fontref);
+extern const char	*szGetFontname(drawfile_fontref);
 #endif /* !__riscos */
+/* hdrftrlist.c */
+extern void	vDestroyHdrFtrInfoList(void);
+extern void	vCreat8HdrFtrInfoList(const ULONG *, size_t);
+extern void	vCreat6HdrFtrInfoList(const ULONG *, size_t);
+extern void	vCreat2HdrFtrInfoList(const ULONG *, size_t);
+extern const hdrftr_block_type *pGetHdrFtrInfo(int, BOOL, BOOL, BOOL);
+extern void	vPrepareHdrFtrText(FILE *);
 #if defined(__riscos)
 /* icons.c */
-extern void	vUpdateIcon(wimp_w, wimp_icon *);
-extern void	vUpdateRadioButton(wimp_w, wimp_i, BOOL);
-extern void	vUpdateWriteable(wimp_w, wimp_i, char *);
-extern void	vUpdateWriteableNumber(wimp_w, wimp_i, int);
+extern void	vUpdateIcon(window_handle, icon_block *);
+extern void	vUpdateRadioButton(window_handle, icon_handle, BOOL);
+extern void	vUpdateWriteable(window_handle, icon_handle, const char *);
+extern void	vUpdateWriteableNumber(window_handle, icon_handle, int);
 #endif /* __riscos */
 /* imgexam.c */
 extern image_info_enum	eExamineImage(FILE *, ULONG, imagedata_type *);
@@ -388,19 +451,24 @@ extern long	lComputeLeading(USHORT);
 extern size_t	tUcs2Utf8(ULONG, char *, size_t);
 extern void	vGetBulletValue(conversion_type, encoding_type, char *, size_t);
 extern BOOL	bAllZero(const UCHAR *, size_t);
+extern BOOL	bGetNormalizedCodeset(char *, size_t, BOOL *);
+extern const char	*szGetDefaultMappingFile(void);
+extern time_t	tConvertDTTM(ULONG);
 /* notes.c */
 extern void	vDestroyNotesInfoLists(void);
 extern void	vGetNotesInfo(FILE *, const pps_info_type *,
 			const ULONG *, size_t, const ULONG *, size_t,
 			const UCHAR *, int);
+extern void	vPrepareFootnoteText(FILE *);
+extern const char	*szGetFootnootText(UINT);
 extern notetype_enum eGetNotetype(ULONG);
 /* options.c */
 extern int	iReadOptions(int, char **);
 extern void	vGetOptions(options_type *);
 #if defined(__riscos)
-extern void	vChoicesOpenAction(wimp_w);
-extern void	vChoicesMouseClick(wimp_mousestr *);
-extern void	vChoicesKeyPressed(wimp_caretstr *);
+extern void	vChoicesOpenAction(window_handle);
+extern BOOL	bChoicesMouseClick(event_pollblock *, void *);
+extern BOOL	bChoicesKeyPressed(event_pollblock *, void *);
 #endif /* __riscos */
 /* out2window.c */
 extern void	vSetLeftIndentation(diagram_type *, long);
@@ -409,10 +477,26 @@ extern void	vAlign2Window(diagram_type *, output_type *,
 extern void	vJustify2Window(diagram_type *, output_type *,
 			long, long, UCHAR);
 extern void	vResetStyles(void);
-extern size_t	tStyle2Window(char *, const style_block_type *,
+extern size_t	tStyle2Window(char *, size_t, const style_block_type *,
 			const section_block_type *);
-extern void	vTableRow2Window(diagram_type *,
-			output_type *, const row_block_type *);
+extern void	vTableRow2Window(diagram_type *, output_type *,
+			const row_block_type *, conversion_type, int);
+/* pdf.c */
+extern void	vCreateInfoDictionary(diagram_type *, int);
+extern void	vProloguePDF(diagram_type *,
+			const char *, const options_type *);
+extern void	vEpiloguePDF(diagram_type *);
+extern void	vImageProloguePDF(diagram_type *, const imagedata_type *);
+extern void	vImageEpiloguePDF(diagram_type *);
+extern BOOL	bAddDummyImagePDF(diagram_type *, const imagedata_type *);
+extern void	vAddFontsPDF(diagram_type *);
+extern void	vMove2NextLinePDF(diagram_type *, USHORT);
+extern void	vSubstringPDF(diagram_type *,
+				char *, size_t, long, UCHAR, USHORT,
+				drawfile_fontref, USHORT, USHORT);
+extern void	vStartOfParagraphPDF(diagram_type *, long);
+extern void	vEndOfParagraphPDF(diagram_type *, USHORT, long);
+extern void	vEndOfPagePDF(diagram_type *, BOOL);
 /* pictlist.c */
 extern void	vDestroyPictInfoList(void);
 extern void	vAdd2PictInfoList(const picture_block_type *);
@@ -431,16 +515,19 @@ extern void	vAddFontsPS(diagram_type *);
 extern void	vMove2NextLinePS(diagram_type *, USHORT);
 extern void	vSubstringPS(diagram_type *,
 				char *, size_t, long, UCHAR, USHORT,
-				draw_fontref, USHORT, USHORT);
+				drawfile_fontref, USHORT, USHORT);
 extern void	vStartOfParagraphPS(diagram_type *, long);
-extern void	vEndOfParagraphPS(diagram_type *, draw_fontref, USHORT, long);
-extern void	vEndOfPagePS(diagram_type *);
+extern void	vEndOfParagraphPS(diagram_type *, USHORT, long);
+extern void	vEndOfPagePS(diagram_type *, BOOL);
 /* prop0.c */
+extern void	vGet0DopInfo(FILE *, const UCHAR *);
 extern void	vGet0SepInfo(FILE *, const UCHAR *);
 extern void	vGet0PapInfo(FILE *, const UCHAR *);
 extern void	vGet0ChrInfo(FILE *, const UCHAR *);
 /* prop2.c */
+extern void	vGet2DopInfo(FILE *, const UCHAR *);
 extern void	vGet2SepInfo(FILE *, const UCHAR *);
+extern void	vGet2HdrFtrInfo(FILE *, const UCHAR *);
 extern row_info_enum	eGet2RowInfo(int,
 			const UCHAR *, int, row_block_type *);
 extern void	vGet2StyleInfo(int,
@@ -452,8 +539,12 @@ extern void	vGet2FontInfo(int,
 			const UCHAR *, size_t, font_block_type *);
 extern void	vGet2ChrInfo(FILE *, int, const UCHAR *);
 /* prop6.c */
+extern void	vGet6DopInfo(FILE *, ULONG, const ULONG *, size_t,
+			const UCHAR *);
 extern void	vGet6SepInfo(FILE *, ULONG, const ULONG *, size_t,
 			const UCHAR *);
+extern void	vGet6HdrFtrInfo(FILE *, ULONG, const ULONG *, size_t,
+			const UCHAR *);
 extern row_info_enum	eGet6RowInfo(int,
 			const UCHAR *, int, row_block_type *);
 extern void	vGet6StyleInfo(int,
@@ -465,9 +556,15 @@ extern void	vGet6FontInfo(int, USHORT,
 extern void	vGet6ChrInfo(FILE *, ULONG, const ULONG *, size_t,
 			const UCHAR *);
 /* prop8.c */
+extern void	vGet8DopInfo(FILE *, const pps_type *,
+			const ULONG *, size_t, const ULONG *, size_t,
+			const UCHAR *);
 extern void	vGet8SepInfo(FILE *, const pps_info_type *,
 			const ULONG *, size_t, const ULONG *, size_t,
 			const UCHAR *);
+extern void	vGet8HdrFtrInfo(FILE *, const pps_type *,
+			const ULONG *, size_t, const ULONG *, size_t,
+			const UCHAR *);
 extern row_info_enum	eGet8RowInfo(int,
 			const UCHAR *, int, row_block_type *);
 extern void	vGet8StyleInfo(int,
@@ -503,16 +600,16 @@ extern void	vSetFiletype(const char *, int);
 extern BOOL	bMakeDirectory(const char *);
 extern int	iReadCurrentAlphabetNumber(void);
 extern int	iGetRiscOsVersion(void);
-extern BOOL	bDrawRenderDiag360(draw_diag *,
-			draw_redrawstr *, double, draw_error *);
+extern BOOL	bDrawRenderDiag360(void *, size_t,
+			window_redrawblock *, double, os_error *);
 #if defined(DEBUG)
 extern BOOL	bGetJpegInfo(UCHAR *, size_t);
 #endif /* DEBUG */
 #endif /* __riscos */
 /* saveas.c */
 #if defined(__riscos)
-extern void	vSaveTextfile(diagram_type *);
-extern void	vSaveDrawfile(diagram_type *);
+extern BOOL	bSaveTextfile(event_pollblock *, void *);
+extern BOOL	bSaveDrawfile(event_pollblock *, void *);
 #endif /* __riscos */
 /* sectlist.c */
 extern void	vDestroySectionInfoList(void);
@@ -521,6 +618,8 @@ extern void	vGetDefaultSection(section_block_type *);
 extern void	vDefault2SectionInfoList(ULONG);
 extern const section_block_type *
 		pGetSectionInfo(const section_block_type *, ULONG);
+extern size_t	tGetNumberOfSections(void);
+extern UCHAR	ucGetSepHdrFtrSpecification(size_t);
 /* stylelist.c */
 extern void	vDestroyStyleInfoList(void);
 extern level_type_enum	eGetNumType(UCHAR);
@@ -528,6 +627,7 @@ extern void	vCorrectStyleValues(style_block_type *);
 extern void	vAdd2StyleInfoList(const style_block_type *);
 extern const style_block_type	*pGetNextStyleInfoListItem(
 					const style_block_type *);
+extern const style_block_type	*pGetNextTextStyle(const style_block_type *);
 extern USHORT	usGetIstd(ULONG);
 extern BOOL	bStyleImpliesList(const style_block_type *, int);
 /* stylesheet.c */
@@ -555,6 +655,8 @@ extern const char	*szGetTitle(void);
 extern const char	*szGetSubject(void);
 extern const char	*szGetAuthor(void);
 extern const char	*szGetLastSaveDtm(void);
+extern const char	*szGetModDate(void);
+extern const char	*szGetCreationDate(void);
 extern const char	*szGetCompany(void);
 extern const char	*szGetLanguage(void);
 /* tabstop.c */
@@ -571,10 +673,10 @@ extern void	vStartOfParagraphTXT(diagram_type *, long);
 extern void	vEndOfParagraphTXT(diagram_type *, long);
 extern void	vEndOfPageTXT(diagram_type *, long);
 /* unix.c */
-#if !defined(__riscos)
 extern void	werr(int, const char *, ...);
-extern void	visdelay_begin(void);
-extern void	visdelay_end(void);
+#if !defined(__riscos)
+extern void	Hourglass_On(void);
+extern void	Hourglass_Off(void);
 #endif /* !__riscos */
 /* utf8.c */
 #if !defined(__riscos)
@@ -583,7 +685,10 @@ extern int	utf8_chrlength(const char *);
 extern BOOL	is_locale_utf8(void);
 #endif /* !__riscos */
 /* word2text.c */
+extern BOOL	bOutputContainsText(const output_type *);
 extern BOOL	bWordDecryptor(FILE *, long, diagram_type *);
+extern output_type	*pHdrFtrDecryptor(FILE *, ULONG, ULONG);
+extern char		*szFootnoteDecryptor(FILE *, ULONG, ULONG);
 /* worddos.c */
 extern int	iInitDocumentDOS(FILE *, long);
 /* wordlib.c */
@@ -610,14 +715,14 @@ extern void 	*xrealloc(void *, size_t);
 extern char	*xstrdup(const char *);
 extern void 	*xfree(void *);
 /* xml.c */
-extern void	vCreateBookIntro(diagram_type *, int, encoding_type);
-extern void	vPrologueXML(diagram_type *);
+extern void	vCreateBookIntro(diagram_type *, int);
+extern void	vPrologueXML(diagram_type *, const options_type *);
 extern void	vEpilogueXML(diagram_type *);
 extern void	vMove2NextLineXML(diagram_type *);
 extern void	vSubstringXML(diagram_type *,
 				const char *, size_t, long, USHORT);
-extern void	vStartOfParagraphXML(diagram_type *, int);
-extern void	vEndOfParagraphXML(diagram_type *, int);
+extern void	vStartOfParagraphXML(diagram_type *, UINT);
+extern void	vEndOfParagraphXML(diagram_type *, UINT);
 extern void	vEndOfPageXML(diagram_type *);
 extern void	vSetHeadersXML(diagram_type *, USHORT);
 extern void	vStartOfListXML(diagram_type *, UCHAR, BOOL);
@@ -627,12 +732,4 @@ extern void	vEndOfTableXML(diagram_type *);
 extern void	vAddTableRowXML(diagram_type *, char **, int,
 			const short *, UCHAR);
 
-
-/* For use with Gray Watson dmalloc library */
-#if defined(DMALLOC)
-#include "dmalloc.h"
-/* The xfree in Antiword is incompatible with the one in dmalloc */
-#undef xfree
-#endif /* DMALLOC */
-
 #endif /* __antiword_h */

+ 0 - 146
sys/src/cmd/aux/antiword/antiword.man

@@ -1,146 +0,0 @@
-ANTIWORD(1)            Linux User's Manual            ANTIWORD(1)
-
-
-
-NAME
-       antiword - show the text and images of MS Word documents
-
-SYNOPSIS
-       antiword [ options ] wordfiles
-
-DESCRIPTION
-       Antiword  is an application that displays the text and the
-       images of Microsoft Word documents.
-       A wordfile named - stands for a Word  document  read  from
-       the standard input.
-       Only  documents made by MS Word version 2 and version 6 or
-       later are supported.
-
-OPTIONS
-       -h     Give a help message.
-
-       -i image level
-              The image  level  determines  how  images  will  be
-              shown.
-
-              0: Use  non-standard  extensions  from Ghostscript.
-                 This output may  not  print  on  any  PostScript
-                 printer,  but  is useful in case no hard copy is
-                 needed. It is also useful  when  Ghostscript  is
-                 used as a filter to print a PostScript file to a
-                 non-PostScript printer.
-
-              1: Show no images.
-
-              2: PostScript level 2 compatible. (default)
-
-              3: PostScript level  3  compatible.  (EXPERIMENTAL,
-                 Portable  Network  Graphics (PNG) images are not
-                 printed correctly)
-
-       -m mapping file
-              This file is used to map Unicode characters to your
-              local  character  set.  The default is UTF-8.txt in
-              locales that support UTF-8 and 8859-1.txt in  other
-              locales.
-
-       -p papersize
-              Output  in  PostScript  form. Printable on paper of
-              the specified size: 10x14,  a3,  a4,  a5,  b4,  b5,
-              executive,  folio,  legal,  letter,  note,  quarto,
-              statement or tabloid.
-
-       -s     Include  text  with  the  so-called  "hidden  text"
-              attribute.
-
-       -t     Output in text form. (default)
-
-       -w width
-              In  text mode this is the line width in characters.
-              A value of zero puts an entire paragraph on a line,
-              useful  when  the  text  is  to  used  as input for
-              another wordprocessor. This  value  is  ignored  in
-              PostScript mode.
-
-       -x document type definition
-              Output  in  XML  form.  Currently the only document
-              type definition is db (for DocBook).
-
-       -L     In PostScript mode: use landscape mode.
-
-FILES
-       Mapping files like 8859-1.txt
-              Antiword looks  for  its  mapping  files  in  three
-              directories, in the order given:
-              (1) The directory specified by $ANTIWORDHOME
-              (2) The directory specified by $HOME/.antiword
-              (3) Directory /usr/share/antiword
-
-       The fontnames file
-              Antiword  will  look  for  its fontname file in the
-              same directories as used for the mapping files.
-              The fontnames file contains the  translation  table
-              from  font names used by MS Word to font names used
-              by PostScript.
-
-       NOTE:
-              Antiword cannot tell the difference between a  file
-              that  does  not  exist  and  a  file that cannot be
-              opened for reading.
-
-ENVIRONMENT
-       Antiword uses the environment variable ``ANTIWORDHOME'' as
-       the  first  directory to look for its files. Antiword uses
-       the environment variable ``HOME'' to find the user's  home
-       directory.   When  in  text  mode  it  uses  the  variable
-       ``COLUMNS'' to set the width of the output  (unless  over-
-       ridden by the -w option).
-
-BUGS
-       Antiword  is  far  from  complete. Many features are still
-       missing. Many images are not shown yet. Some of the images
-       that  are shown, are shown in the wrong place.  PostScript
-       output is only available in ISO 8859-1 and ISO 8859-2.
-
-WEB SITES
-       The most recent released version  of  Antiword  is  always
-       available from:
-       http://www.winfield.demon.nl/index.html
-       or try
-       http://antiword.cjb.net/
-
-AUTHOR
-       Adri van Os <antiword@winfield.demon.nl>
-       or try <comments@antiword.cjb.net>
-
-       R.F. Smith <rsmith@xs4all.nl> and
-       Sindi Keesan <keesan@cyberspace.org>
-       contributed to this manual page.
-
-LICENSE
-       Antiword  is free software; you can redistribute it and/or
-       modify it under  the  terms  of  the  GNU  General  Public
-       License  as  published  by  the  Free Software Foundation;
-       either version 2 of the License, or (at your  option)  any
-       later version.
-
-       This  program  is  distributed in the hope that it will be
-       useful but WITHOUT ANY WARRANTY; without even the  implied
-       warranty  of  MERCHANTABILITY  or FITNESS FOR A PARTICULAR
-       PURPOSE. See the  GNU  General  Public  License  for  more
-       details.
-
-       You  should have received a copy of the GNU General Public
-       License along with this program; if not, write to the Free
-       Software  Foundation,  Inc.,  59  Temple Place, Suite 330,
-       Boston, MA 02111-1307 USA
-
-ACKNOWLEDGEMENTS
-       Linux is a registered trademark of Linus Torvalds.
-       PostScript is a trademark of Adobe Systems Incorporated.
-       Microsoft is a  registered  trademark  and  Windows  is  a
-       trademark of Microsoft Corporation.
-
-
-
-Antiword 0.34              Jun 24, 2003               ANTIWORD(1)

+ 0 - 34
sys/src/cmd/aux/antiword/antiword.php

@@ -1,34 +0,0 @@
-From: Paul Southworth <pauls@etext.org>
-Subject: antiword PHP script
-Date: Thu, 24 Oct 2002 14:01:05 -0700 (PDT)
-
-Please find attached a trivial example of using a web form to process an
-uploaded Word doc to text using antiword.  Perhaps other antiword users
-would find it useful.
-
---Paul
-
-<?
-/* antiword.php
-   A PHP script to convert uploaded MS Word docs to text using antiword.
-   This script is public domain, no copyright.
-   September 11, 2002
-   Paul Southworth
-*/
-function print_form() {
-?>
-<html><head><title>antiword</title></head><body>
-<form method=post action=antiword.php enctype="multipart/form-data">
-<input name=upload type=file>
-<input type=submit name=submit value=convert>
-</form>
-</body></html>
-<?
-}
-if ($_FILES['upload']) {
-    header ("Content-type: text/plain");
-    system("/usr/local/bin/antiword " . $_FILES['upload']['tmp_name']);
-} else {
-    print_form();
-}
-?>

+ 233 - 92
sys/src/cmd/aux/antiword/blocklist.c

@@ -1,6 +1,6 @@
 /*
  * blocklist.c
- * Copyright (C) 1998-2003 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Build, read and destroy the lists of Word "text" blocks
@@ -19,21 +19,28 @@ typedef struct list_mem_tag {
 	struct list_mem_tag	*pNext;
 } list_mem_type;
 
+typedef struct readinfo_tag {
+	list_mem_type		*pBlockCurrent;
+	ULONG			ulBlockOffset;
+	size_t			tByteNext;
+	UCHAR			aucBlock[BIG_BLOCK_SIZE];
+} readinfo_type;
+
 /* Variables to describe the start of the block lists */
 static list_mem_type	*pTextAnchor = NULL;
-static list_mem_type	*pFootAnchor = NULL;
+static list_mem_type	*pFootnoteAnchor = NULL;
 static list_mem_type	*pHdrFtrAnchor = NULL;
 static list_mem_type	*pMacroAnchor = NULL;
 static list_mem_type	*pAnnotationAnchor = NULL;
-static list_mem_type	*pEndAnchor = NULL;
+static list_mem_type	*pEndnoteAnchor = NULL;
 static list_mem_type	*pTextBoxAnchor = NULL;
 static list_mem_type	*pHdrTextBoxAnchor = NULL;
 /* Variable needed to build the block list */
 static list_mem_type	*pBlockLast = NULL;
-/* Variable needed to read a block list */
-static list_mem_type	*pBlockCurrent = NULL;
-/* Last block read */
-static UCHAR		aucBlock[BIG_BLOCK_SIZE];
+/* Variable needed to read the block lists */
+static readinfo_type	tOthers = { NULL, 0, 0, };
+static readinfo_type	tHdrFtr = { NULL, 0, 0, };
+static readinfo_type	tFootnote = { NULL, 0, 0, };
 
 
 /*
@@ -65,16 +72,18 @@ vDestroyTextBlockList(void)
 
 	/* Free the lists one by one */
 	pTextAnchor = pFreeOneList(pTextAnchor);
-	pFootAnchor = pFreeOneList(pFootAnchor);
+	pFootnoteAnchor = pFreeOneList(pFootnoteAnchor);
 	pHdrFtrAnchor = pFreeOneList(pHdrFtrAnchor);
 	pMacroAnchor = pFreeOneList(pMacroAnchor);
 	pAnnotationAnchor = pFreeOneList(pAnnotationAnchor);
-	pEndAnchor = pFreeOneList(pEndAnchor);
+	pEndnoteAnchor = pFreeOneList(pEndnoteAnchor);
 	pTextBoxAnchor = pFreeOneList(pTextBoxAnchor);
 	pHdrTextBoxAnchor = pFreeOneList(pHdrTextBoxAnchor);
 	/* Reset all the controle variables */
 	pBlockLast = NULL;
-	pBlockCurrent = NULL;
+	tOthers.pBlockCurrent = NULL;
+	tHdrFtr.pBlockCurrent = NULL;
+	tFootnote.pBlockCurrent = NULL;
 } /* end of vDestroyTextBlockList */
 
 /*
@@ -283,11 +292,12 @@ bIsEmptyBox(FILE *pFile, const list_mem_type *pAnchor)
 	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
 		fail(pCurr->tInfo.ulLength == 0);
 		tSize = (size_t)pCurr->tInfo.ulLength;
-#if defined(__dos)
+#if defined(__dos) && !defined(__DJGPP__)
 		if (pCurr->tInfo.ulLength > 0xffffUL) {
 			tSize = 0xffff;
 		}
-#endif /* __dos */
+#endif /* __dos && !__DJGPP__ */
+		fail(aucBuffer != NULL);
 		aucBuffer = xmalloc(tSize);
 		if (!bReadBytes(aucBuffer, tSize,
 				pCurr->tInfo.ulFileOffset, pFile)) {
@@ -306,8 +316,9 @@ bIsEmptyBox(FILE *pFile, const list_mem_type *pAnchor)
 				return FALSE;
 			}
 		}
+		aucBuffer = xfree(aucBuffer);
 	}
-	aucBuffer = xfree(aucBuffer);
+	fail(aucBuffer != NULL);
 	return TRUE;
 } /* end of bIsEmptyBox */
 
@@ -337,17 +348,17 @@ vSplitBlockList(FILE *pFile, ULONG ulTextLen, ULONG ulFootnoteLen,
 	pGarbageAnchor = NULL;
 
 	DBG_MSG_C(ulTextLen != 0, "Text block list");
-	vSpitList(&pTextAnchor, &pFootAnchor, ulTextLen);
+	vSpitList(&pTextAnchor, &pFootnoteAnchor, ulTextLen);
 	DBG_MSG_C(ulFootnoteLen != 0, "Footnote block list");
-	vSpitList(&pFootAnchor, &pHdrFtrAnchor, ulFootnoteLen);
+	vSpitList(&pFootnoteAnchor, &pHdrFtrAnchor, ulFootnoteLen);
 	DBG_MSG_C(ulHdrFtrLen != 0, "Header/Footer block list");
 	vSpitList(&pHdrFtrAnchor, &pMacroAnchor, ulHdrFtrLen);
 	DBG_MSG_C(ulMacroLen != 0, "Macro block list");
 	vSpitList(&pMacroAnchor, &pAnnotationAnchor, ulMacroLen);
 	DBG_MSG_C(ulAnnotationLen != 0, "Annotation block list");
-	vSpitList(&pAnnotationAnchor, &pEndAnchor, ulAnnotationLen);
+	vSpitList(&pAnnotationAnchor, &pEndnoteAnchor, ulAnnotationLen);
 	DBG_MSG_C(ulEndnoteLen != 0, "Endnote block list");
-	vSpitList(&pEndAnchor, &pTextBoxAnchor, ulEndnoteLen);
+	vSpitList(&pEndnoteAnchor, &pTextBoxAnchor, ulEndnoteLen);
 	DBG_MSG_C(ulTextBoxLen != 0, "Textbox block list");
 	vSpitList(&pTextBoxAnchor, &pHdrTextBoxAnchor, ulTextBoxLen);
 	DBG_MSG_C(ulHdrTextBoxLen != 0, "HeaderTextbox block list");
@@ -359,12 +370,12 @@ vSplitBlockList(FILE *pFile, ULONG ulTextLen, ULONG ulFootnoteLen,
 
 #if defined(DEBUG)
 	vCheckList(pTextAnchor, ulTextLen, "Software error (Text)");
-	vCheckList(pFootAnchor, ulFootnoteLen, "Software error (Footnote)");
+	vCheckList(pFootnoteAnchor, ulFootnoteLen, "Software error (Footnote)");
 	vCheckList(pHdrFtrAnchor, ulHdrFtrLen, "Software error (Hdr/Ftr)");
 	vCheckList(pMacroAnchor, ulMacroLen, "Software error (Macro)");
 	vCheckList(pAnnotationAnchor, ulAnnotationLen,
 						"Software error (Annotation)");
-	vCheckList(pEndAnchor, ulEndnoteLen, "Software error (Endnote)");
+	vCheckList(pEndnoteAnchor, ulEndnoteLen, "Software error (Endnote)");
 	vCheckList(pTextBoxAnchor, ulTextBoxLen, "Software error (TextBox)");
 	vCheckList(pHdrTextBoxAnchor, ulHdrTextBoxLen,
 						"Software error (HdrTextBox)");
@@ -387,11 +398,11 @@ vSplitBlockList(FILE *pFile, ULONG ulTextLen, ULONG ulFootnoteLen,
 	 */
 
 	apAnchors[0] = pTextAnchor;
-	apAnchors[1] = pFootAnchor;
+	apAnchors[1] = pFootnoteAnchor;
 	apAnchors[2] = pHdrFtrAnchor;
 	apAnchors[3] = pMacroAnchor;
 	apAnchors[4] = pAnnotationAnchor;
-	apAnchors[5] = pEndAnchor;
+	apAnchors[5] = pEndnoteAnchor;
 	apAnchors[6] = pTextBoxAnchor;
 	apAnchors[7] = pHdrTextBoxAnchor;
 
@@ -428,8 +439,8 @@ ulGetDocumentLength(void)
 	DBG_MSG("ulGetDocumentLength");
 
 	ulTotal = ulComputeListLength(pTextAnchor);
-	ulTotal += ulComputeListLength(pFootAnchor);
-	ulTotal += ulComputeListLength(pEndAnchor);
+	ulTotal += ulComputeListLength(pFootnoteAnchor);
+	ulTotal += ulComputeListLength(pEndnoteAnchor);
 	ulTotal += ulComputeListLength(pTextBoxAnchor);
 	ulTotal += ulComputeListLength(pHdrTextBoxAnchor);
 	DBG_DEC(ulTotal);
@@ -437,6 +448,18 @@ ulGetDocumentLength(void)
 } /* end of ulGetDocumentLength */
 #endif /* __riscos */
 
+#if 0
+/*
+ * bExistsHdrFtr - are there headers and/or footers?
+ */
+BOOL
+bExistsHdrFtr(void)
+{
+	return pHdrFtrAnchor != NULL &&
+		pHdrFtrAnchor->tInfo.ulLength != 0;
+} /* end of bExistsHdrFtr */
+#endif
+
 /*
  * bExistsTextBox - is there a text box?
  */
@@ -456,83 +479,129 @@ bExistsHdrTextBox(void)
 	return pHdrTextBoxAnchor != NULL &&
 		pHdrTextBoxAnchor->tInfo.ulLength != 0;
 } /* end of bExistsHdrTextBox */
+
 /*
  * usGetNextByte - get the next byte from the specified block list
  */
 static USHORT
-usGetNextByte(FILE *pFile, list_mem_type *pAnchor,
+usGetNextByte(FILE *pFile, readinfo_type *pInfoCurrent, list_mem_type *pAnchor,
 	ULONG *pulFileOffset, ULONG *pulCharPos, USHORT *pusPropMod)
 {
-	static ULONG	ulBlockOffset = 0;
-	static size_t	tByteNext = 0;
 	ULONG	ulReadOff;
 	size_t	tReadLen;
 
-	if (pBlockCurrent == NULL ||
-	    tByteNext >= sizeof(aucBlock) ||
-	    ulBlockOffset + tByteNext >= pBlockCurrent->tInfo.ulLength) {
-		if (pBlockCurrent == NULL) {
+	fail(pInfoCurrent == NULL);
+
+	if (pInfoCurrent->pBlockCurrent == NULL ||
+	    pInfoCurrent->tByteNext >= sizeof(pInfoCurrent->aucBlock) ||
+	    pInfoCurrent->ulBlockOffset + pInfoCurrent->tByteNext >=
+				pInfoCurrent->pBlockCurrent->tInfo.ulLength) {
+		if (pInfoCurrent->pBlockCurrent == NULL) {
 			/* First block, first part */
-			pBlockCurrent = pAnchor;
-			ulBlockOffset = 0;
-		} else if (ulBlockOffset + sizeof(aucBlock) <
-				pBlockCurrent->tInfo.ulLength) {
+			pInfoCurrent->pBlockCurrent = pAnchor;
+			pInfoCurrent->ulBlockOffset = 0;
+		} else if (pInfoCurrent->ulBlockOffset +
+				sizeof(pInfoCurrent->aucBlock) <
+				pInfoCurrent->pBlockCurrent->tInfo.ulLength) {
 			/* Same block, next part */
-			ulBlockOffset += sizeof(aucBlock);
+			pInfoCurrent->ulBlockOffset +=
+					sizeof(pInfoCurrent->aucBlock);
 		} else {
 			/* Next block, first part */
-			pBlockCurrent = pBlockCurrent->pNext;
-			ulBlockOffset = 0;
+			pInfoCurrent->pBlockCurrent =
+					pInfoCurrent->pBlockCurrent->pNext;
+			pInfoCurrent->ulBlockOffset = 0;
 		}
-		if (pBlockCurrent == NULL) {
+		if (pInfoCurrent->pBlockCurrent == NULL) {
 			/* Past the last part of the last block */
 			return (USHORT)EOF;
 		}
 		tReadLen = (size_t)
-			(pBlockCurrent->tInfo.ulLength - ulBlockOffset);
-		if (tReadLen > sizeof(aucBlock)) {
-			tReadLen = sizeof(aucBlock);
+			(pInfoCurrent->pBlockCurrent->tInfo.ulLength -
+			 pInfoCurrent->ulBlockOffset);
+		if (tReadLen > sizeof(pInfoCurrent->aucBlock)) {
+			tReadLen = sizeof(pInfoCurrent->aucBlock);
 		}
-		ulReadOff = pBlockCurrent->tInfo.ulFileOffset +
-				ulBlockOffset;
-		if (!bReadBytes(aucBlock, tReadLen, ulReadOff, pFile)) {
+		ulReadOff = pInfoCurrent->pBlockCurrent->tInfo.ulFileOffset +
+				pInfoCurrent->ulBlockOffset;
+		if (!bReadBytes(pInfoCurrent->aucBlock,
+						tReadLen, ulReadOff, pFile)) {
 			/* Don't read from this list any longer */
-			pBlockCurrent = NULL;
+			pInfoCurrent->pBlockCurrent = NULL;
 			return (USHORT)EOF;
 		}
-		tByteNext = 0;
+		pInfoCurrent->tByteNext = 0;
 	}
 	if (pulFileOffset != NULL) {
-		*pulFileOffset = pBlockCurrent->tInfo.ulFileOffset +
-			ulBlockOffset + tByteNext;
+		*pulFileOffset =
+			pInfoCurrent->pBlockCurrent->tInfo.ulFileOffset +
+			pInfoCurrent->ulBlockOffset +
+			pInfoCurrent->tByteNext;
 	}
 	if (pulCharPos != NULL) {
-		*pulCharPos = pBlockCurrent->tInfo.ulCharPos +
-			ulBlockOffset + tByteNext;
+		*pulCharPos =
+			pInfoCurrent->pBlockCurrent->tInfo.ulCharPos +
+			pInfoCurrent->ulBlockOffset +
+			pInfoCurrent->tByteNext;
 	}
 	if (pusPropMod != NULL) {
-		*pusPropMod = pBlockCurrent->tInfo.usPropMod;
+		*pusPropMod = pInfoCurrent->pBlockCurrent->tInfo.usPropMod;
 	}
-	return (USHORT)aucBlock[tByteNext++];
+	return (USHORT)pInfoCurrent->aucBlock[pInfoCurrent->tByteNext++];
 } /* end of usGetNextByte */
 
+
 /*
  * usGetNextChar - get the next character from the specified block list
  */
 static USHORT
-usGetNextChar(FILE *pFile, list_mem_type *pAnchor,
+usGetNextChar(FILE *pFile, list_id_enum eListID,
 	ULONG *pulFileOffset, ULONG *pulCharPos, USHORT *pusPropMod)
 {
+	readinfo_type	*pReadinfo;
+	list_mem_type	*pAnchor;
 	USHORT	usLSB, usMSB;
 
-	usLSB = usGetNextByte(pFile, pAnchor,
-			pulFileOffset, pulCharPos, pusPropMod);
+	switch (eListID) {
+	case text_list:
+		pReadinfo = &tOthers;
+		pAnchor = pTextAnchor;
+		break;
+	case footnote_list:
+		pReadinfo = &tFootnote;
+		pAnchor = pFootnoteAnchor;
+		break;
+	case hdrftr_list:
+		pReadinfo = &tHdrFtr;
+		pAnchor = pHdrFtrAnchor;
+		break;
+	case endnote_list:
+		pReadinfo = &tOthers;
+		pAnchor = pEndnoteAnchor;
+		break;
+	case textbox_list:
+		pReadinfo = &tOthers;
+		pAnchor = pTextBoxAnchor;
+		break;
+	case hdrtextbox_list:
+		pReadinfo = &tOthers;
+		pAnchor = pHdrTextBoxAnchor;
+		break;
+	default:
+		DBG_DEC(eListID);
+		return (USHORT)EOF;
+	}
+
+	usLSB = usGetNextByte(pFile, pReadinfo, pAnchor,
+				pulFileOffset, pulCharPos, pusPropMod);
 	if (usLSB == (USHORT)EOF) {
 		return (USHORT)EOF;
 	}
-	if (pBlockCurrent->tInfo.bUsesUnicode) {
-		usMSB = usGetNextByte(pFile, pAnchor,
-				NULL, NULL, NULL);
+	fail(pReadinfo->pBlockCurrent == NULL);
+
+	if (pReadinfo->pBlockCurrent->tInfo.bUsesUnicode) {
+		usMSB = usGetNextByte(pFile,
+				pReadinfo, pAnchor, NULL, NULL, NULL);
 	} else {
 		usMSB = 0x00;
 	}
@@ -556,33 +625,8 @@ usNextChar(FILE *pFile, list_id_enum eListID,
 
 	fail(pFile == NULL);
 
-	switch (eListID) {
-	case text_list:
-		usRetVal = usGetNextChar(pFile, pTextAnchor,
-				pulFileOffset, pulCharPos, pusPropMod);
-		break;
-	case footnote_list:
-		usRetVal = usGetNextChar(pFile, pFootAnchor,
-				pulFileOffset, pulCharPos, pusPropMod);
-		break;
-	case endnote_list:
-		usRetVal = usGetNextChar(pFile, pEndAnchor,
+	usRetVal = usGetNextChar(pFile, eListID,
 				pulFileOffset, pulCharPos, pusPropMod);
-		break;
-	case textbox_list:
-		usRetVal = usGetNextChar(pFile, pTextBoxAnchor,
-				pulFileOffset, pulCharPos, pusPropMod);
-		break;
-	case hdrtextbox_list:
-		usRetVal = usGetNextChar(pFile, pHdrTextBoxAnchor,
-				pulFileOffset, pulCharPos, pusPropMod);
-		break;
-	default:
-		DBG_DEC(eListID);
-		usRetVal = (USHORT)EOF;
-		break;
-	}
-
 	if (usRetVal == (USHORT)EOF) {
 		if (pulFileOffset != NULL) {
 			*pulFileOffset = FC_INVALID;
@@ -598,27 +642,82 @@ usNextChar(FILE *pFile, list_id_enum eListID,
 } /* end of usNextChar */
 
 /*
- * Translate a character position to an offset in the file.
+ * usToHdrFtrPosition - Go to a character position in header/foorter list
+ *
+ * Returns the character found on the specified character position
+ */
+USHORT
+usToHdrFtrPosition(FILE *pFile, ULONG ulCharPos)
+{
+	ULONG	ulCharPosCurr;
+	USHORT	usChar;
+
+	tHdrFtr.pBlockCurrent = NULL;	/* To reset the header/footer list */
+	do {
+		usChar = usNextChar(pFile,
+				hdrftr_list, NULL, &ulCharPosCurr, NULL);
+	} while (usChar != (USHORT)EOF && ulCharPosCurr != ulCharPos);
+	return usChar;
+} /* end of usToHdrFtrPosition */
+
+/*
+ * usToFootnotePosition - Go to a character position in footnote list
+ *
+ * Returns the character found on the specified character position
+ */
+USHORT
+usToFootnotePosition(FILE *pFile, ULONG ulCharPos)
+{
+	ULONG	ulCharPosCurr;
+	USHORT	usChar;
+
+	tFootnote.pBlockCurrent = NULL;	/* To reset the footnote list */
+	do {
+		usChar = usNextChar(pFile,
+				footnote_list, NULL, &ulCharPosCurr, NULL);
+	} while (usChar != (USHORT)EOF && ulCharPosCurr != ulCharPos);
+	return usChar;
+} /* end of usToFootnotePosition */
+
+/*
+ * Convert a character position to an offset in the file.
  * Logical to physical offset.
  *
  * Returns:	FC_INVALID: in case of error
  *		otherwise: the computed file offset
  */
 ULONG
-ulCharPos2FileOffset(ULONG ulCharPos)
+ulCharPos2FileOffsetX(ULONG ulCharPos, list_id_enum *peListID)
 {
-	list_mem_type	*apAnchors[5];
+	static list_id_enum	eListIDs[8] = {
+		text_list,	footnote_list,		hdrftr_list,
+		macro_list,	annotation_list,	endnote_list,
+		textbox_list,	hdrtextbox_list,
+	};
+	list_mem_type	*apAnchors[8];
 	list_mem_type	*pCurr;
+	list_id_enum	eListGuess;
 	ULONG		ulBestGuess;
 	size_t		tIndex;
 
+	fail(peListID == NULL);
+
+	if (ulCharPos == CP_INVALID) {
+		*peListID = no_list;
+		return FC_INVALID;
+	}
+
 	apAnchors[0] = pTextAnchor;
-	apAnchors[1] = pFootAnchor;
-	apAnchors[2] = pEndAnchor;
-	apAnchors[3] = pTextBoxAnchor;
-	apAnchors[4] = pHdrTextBoxAnchor;
+	apAnchors[1] = pFootnoteAnchor;
+	apAnchors[2] = pHdrFtrAnchor;
+	apAnchors[3] = pMacroAnchor;
+	apAnchors[4] = pAnnotationAnchor;
+	apAnchors[5] = pEndnoteAnchor;
+	apAnchors[6] = pTextBoxAnchor;
+	apAnchors[7] = pHdrTextBoxAnchor;
 
-	ulBestGuess = FC_INVALID; /* Best guess is "fileoffset not found" */
+	eListGuess = no_list;	  /* Best guess is no list */
+	ulBestGuess = FC_INVALID; /* Best guess is "file offset not found" */
 
 	for (tIndex = 0; tIndex < elementsof(apAnchors); tIndex++) {
 		for (pCurr = apAnchors[tIndex];
@@ -632,6 +731,7 @@ ulCharPos2FileOffset(ULONG ulCharPos)
 				 * block, so we guess it's the first byte of
 				 * the next block (if there is a next block)
 				 */
+				eListGuess= eListIDs[tIndex];
 				ulBestGuess = pCurr->pNext->tInfo.ulFileOffset;
 			}
 
@@ -643,6 +743,7 @@ ulCharPos2FileOffset(ULONG ulCharPos)
 			}
 
 			/* The character position is in the current block */
+			*peListID = eListIDs[tIndex];
 			return pCurr->tInfo.ulFileOffset +
 				ulCharPos - pCurr->tInfo.ulCharPos;
 		}
@@ -650,9 +751,49 @@ ulCharPos2FileOffset(ULONG ulCharPos)
 	/* Passed beyond the end of the last list */
 	NO_DBG_HEX(ulCharPos);
 	NO_DBG_HEX(ulBestGuess);
+	*peListID = eListGuess;
 	return ulBestGuess;
+} /* end of ulCharPos2FileOffsetX */
+
+/*
+ * Convert a character position to an offset in the file.
+ * Logical to physical offset.
+ *
+ * Returns:	FC_INVALID: in case of error
+ *		otherwise: the computed file offset
+ */
+ULONG
+ulCharPos2FileOffset(ULONG ulCharPos)
+{
+	list_id_enum	eListID;
+
+	return ulCharPos2FileOffsetX(ulCharPos, &eListID);
 } /* end of ulCharPos2FileOffset */
 
+/*
+ * Convert an offset in the header/footer list to a character position.
+ *
+ * Returns:	CP_INVALID: in case of error
+ *		otherwise: the computed character position
+ */
+ULONG
+ulHdrFtrOffset2CharPos(ULONG ulHdrFtrOffset)
+{
+	list_mem_type	*pCurr;
+	ULONG		ulOffset;
+
+	ulOffset = ulHdrFtrOffset;
+	for (pCurr = pHdrFtrAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
+		if (ulOffset >= pCurr->tInfo.ulLength) {
+			/* The offset is not in this block */
+			ulOffset -= pCurr->tInfo.ulLength;
+			continue;
+		}
+		return pCurr->tInfo.ulCharPos + ulOffset;
+	}
+	return CP_INVALID;
+} /* end of ulHdrFtrOffset2CharPos */
+
 /*
  * Get the sequence number beloning to the given file offset
  *

+ 184 - 70
sys/src/cmd/aux/antiword/chartrans.c

@@ -1,6 +1,6 @@
 /*
  * chartrans.c
- * Copyright (C) 1999-2003 A.J. van Os; Released under GNU GPL
+ * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Translate Word characters to local representation
@@ -14,7 +14,7 @@
 #endif /* __STDC_ISO_10646__ */
 #include "antiword.h"
 
-static const USHORT usCp850[] = {
+static const USHORT usCp850[] = {	/* DOS implementation of Latin1 */
 	0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
 	0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
 	0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
@@ -33,7 +33,7 @@ static const USHORT usCp850[] = {
 	0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0,
 };
 
-static const USHORT usCp1250[] = {
+static const USHORT usCp1250[] = {	/* Windows implementation of Latin2 */
 	0x20ac, 0x003f, 0x201a, 0x003f, 0x201e, 0x2026, 0x2020, 0x2021,
 	0x003f, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179,
 	0x003f, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
@@ -52,14 +52,45 @@ static const USHORT usCp1250[] = {
 	0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9,
 };
 
-static const USHORT usCp1252[] = {
+static const USHORT usCp1251[] = {	/* Windows implementation of Cyrillic */
+	0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021,
+	0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f,
+	0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
+	0x00f3, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f,
+	0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7,
+	0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407,
+	0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7,
+	0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457,
+	0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+	0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
+	0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+	0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
+	0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+	0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
+	0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+	0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
+};
+
+static const USHORT usCp1252[] = {	/* Windows implementation of Latin1 */
 	0x20ac, 0x003f, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021,
 	0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x003f, 0x017d, 0x003f,
 	0x003f, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
 	0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x003f, 0x017e, 0x0178,
+	0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+	0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+	0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
+	0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+	0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+	0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+	0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+	0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+	0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+	0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+	0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+	0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff,
 };
 
-static const USHORT usMacRoman[] = {
+static const USHORT usMacRoman[] = {	/* Apple implementation of Latin1 */
 	0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1,
 	0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8,
 	0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3,
@@ -110,11 +141,12 @@ static const USHORT usPrivateArea[] = {
 };
 
 typedef struct char_table_tag {
-	USHORT	usLocal;
+	UCHAR	ucLocal;
 	USHORT	usUnicode;
 } char_table_type;
 
-static char_table_type atCharTable[128];
+static char_table_type	atCharTable[256];
+static size_t		tNextPosFree = 0;
 
 
 /*
@@ -151,31 +183,71 @@ pGetCharTableRecord(USHORT usUnicode)
 {
 	char_table_type	tKey;
 
+	if (tNextPosFree == 0) {
+		return NULL;
+	}
 	tKey.usUnicode = usUnicode;
-	tKey.usLocal = 0;
+	tKey.ucLocal = 0;
 	return (char_table_type *)bsearch(&tKey,
 			atCharTable,
-			elementsof(atCharTable), sizeof(atCharTable[0]),
+			tNextPosFree, sizeof(atCharTable[0]),
 			iCompare);
 } /* end of pGetCharTableRecord */
 
 /*
- * ucGetNbspValue - get the local representation of the non-breaking space
+ * ucGetBulletCharacter - get the local representation of the bullet
  */
 UCHAR
-ucGetNbspValue(void)
+ucGetBulletCharacter(conversion_type eConversionType, encoding_type eEncoding)
+{
+#if defined(__riscos)
+	return 0x8f;
+#else
+	const char_table_type	*pRec;
+
+	fail(eEncoding == encoding_utf_8);
+
+	if (eEncoding == encoding_latin_1 &&
+	    (eConversionType == conversion_ps ||
+	     eConversionType == conversion_pdf)) {
+		/* Ugly, but it makes the PostScript and PDF look better */
+		return (UCHAR)143;
+	}
+	if (eConversionType != conversion_text &&
+	    eConversionType != conversion_fmt_text) {
+		pRec = pGetCharTableRecord(UNICODE_BULLET);
+		if (pRec != NULL) {
+			return pRec->ucLocal;
+		}
+		pRec = pGetCharTableRecord(UNICODE_BULLET_OPERATOR);
+		if (pRec != NULL) {
+			return pRec->ucLocal;
+		}
+		pRec = pGetCharTableRecord(UNICODE_MIDDLE_DOT);
+		if (pRec != NULL) {
+			return pRec->ucLocal;
+		}
+	}
+	return (UCHAR)'.';
+#endif /* __riscos */
+} /* end of ucGetBulletCharacter */
+
+/*
+ * ucGetNbspCharacter - get the local representation of the non-breaking space
+ */
+UCHAR
+ucGetNbspCharacter(void)
 {
 	const char_table_type	*pRec;
 
 	pRec = pGetCharTableRecord(0x00a0);	/* Unicode non-breaking space */
-	if (pRec == NULL || pRec->usLocal > 0xff) {
-		DBG_MSG_C(pRec == NULL, "Non-breaking space record not found");
-		DBG_HEX_C(pRec != NULL, pRec->usLocal);
+	if (pRec == NULL) {
+		DBG_MSG("Non-breaking space record not found");
 		/* No value found, use the best guess */
 		return (UCHAR)0xa0;
 	}
-	return (UCHAR)pRec->usLocal;
-} /* end of ucGetNbspValue */
+	return pRec->ucLocal;
+} /* end of ucGetNbspCharacter */
 
 /*
  * bReadCharacterMappingTable - read the mapping table
@@ -185,29 +257,22 @@ ucGetNbspValue(void)
  * returns TRUE if successful, otherwise FALSE
  */
 BOOL
-bReadCharacterMappingTable(const char *szFilename)
+bReadCharacterMappingTable(FILE *pFile)
 {
-	FILE	*pFile;
 	char	*pcTmp;
 	ULONG	ulUnicode;
 	UINT	uiLocal;
 	int	iFields;
 	char	szLine[81];
 
-	DBG_MSG(szFilename);
-
-	fail(szFilename == NULL);
-
-	if (szFilename == NULL || szFilename[0] == '\0') {
-		return FALSE;
-	}
-	pFile = fopen(szFilename, "r");
 	if (pFile == NULL) {
-		DBG_MSG(szFilename);
 		return FALSE;
 	}
+
+	/* Clean the table first */
 	(void)memset(atCharTable, 0, sizeof(atCharTable));
 
+	/* Fill the table */
 	while (fgets(szLine, (int)sizeof(szLine), pFile)) {
 		if (szLine[0] == '#' ||
 		    szLine[0] == '\r' ||
@@ -233,24 +298,30 @@ bReadCharacterMappingTable(const char *szFilename)
 					uiLocal, ulUnicode);
 			continue;
 		}
-		if (uiLocal >= 0x80) {
-			atCharTable[uiLocal - 0x80].usLocal =
-						(USHORT)uiLocal;
-			atCharTable[uiLocal - 0x80].usUnicode =
-						(USHORT)ulUnicode;
+		/* Store only the relevant entries */
+		if (uiLocal != ulUnicode || uiLocal >= 0x80) {
+			atCharTable[tNextPosFree].ucLocal = (UCHAR)uiLocal;
+			atCharTable[tNextPosFree].usUnicode = (USHORT)ulUnicode;
+			tNextPosFree++;
+		}
+		if (tNextPosFree >= elementsof(atCharTable)) {
+			werr(0, "Too many entries in the character mapping "
+				"file. Ignoring the rest.");
+			break;
 		}
 	}
-	(void)fclose(pFile);
 
-	DBG_HEX(atCharTable[0].usUnicode);
-	DBG_HEX(atCharTable[elementsof(atCharTable)-1].usUnicode);
+	if (tNextPosFree != 0) {
+		DBG_HEX(atCharTable[0].usUnicode);
+		DBG_HEX(atCharTable[tNextPosFree - 1].usUnicode);
 
-	qsort(atCharTable,
-		elementsof(atCharTable), sizeof(atCharTable[0]),
-		iCompare);
+		qsort(atCharTable,
+			tNextPosFree, sizeof(atCharTable[0]),
+			iCompare);
 
-	DBG_HEX(atCharTable[0].usUnicode);
-	DBG_HEX(atCharTable[elementsof(atCharTable)-1].usUnicode);
+		DBG_HEX(atCharTable[0].usUnicode);
+		DBG_HEX(atCharTable[tNextPosFree - 1].usUnicode);
+	}
 
 	return TRUE;
 } /* end of bReadCharacterMappingTable */
@@ -268,35 +339,38 @@ ulTranslateCharacters(USHORT usChar, ULONG ulFileOffset, int iWordVersion,
 	BOOL bUseMacCharSet)
 {
 	const char_table_type	*pTmp;
+	const USHORT	*usCharSet;
 
+	usCharSet = NULL;
 	if (bUseMacCharSet) {
-		/* Translate special Macintosh characters */
-		if (usChar >= 0x80 && usChar <= 0xff) {
-			usChar = usMacRoman[usChar - 0x80];
-		}
+		/* Macintosh character set */
+		usCharSet = usMacRoman;
 	} else if (iWordVersion == 0) {
-		/* From Code Page 850 to Unicode */
-		if (usChar >= 0x80 && usChar <= 0xff) {
-			usChar = usCp850[usChar - 0x80];
-		}
+		/* DOS character set */
+		usCharSet = usCp850;
 	} else {
-		if (eEncoding == encoding_iso_8859_2) {
-			/* Translate implementation defined characters */
-			if (usChar >= 0x80 && usChar <= 0x9f) {
-				usChar = usCp1250[usChar - 0x80];
-			}
-			/* From Code Page 1250 to Unicode */
-			if (iWordVersion < 8 &&
-			    usChar >= 0xa0 && usChar <= 0xff) {
-				usChar = usCp1250[usChar - 0x80];
-			}
-		} else {
-			/* Translate implementation defined characters */
-			if (usChar >= 0x80 && usChar <= 0x9f) {
-				usChar = usCp1252[usChar - 0x80];
-			}
+		/* Windows character set */
+		switch (eEncoding) {
+		case encoding_latin_2:
+			usCharSet = usCp1250;
+			break;
+		case encoding_cyrillic:
+			usCharSet = usCp1251;
+			break;
+		case encoding_latin_1:
+		default:
+			usCharSet = usCp1252;
+			break;
 		}
 	}
+	fail(usCharSet == NULL);
+	if (usChar >= 0x80 && usChar <= 0x9f) {
+		/* Translate implementation defined characters */
+		usChar = usCharSet[usChar - 0x80];
+	} else if (iWordVersion < 8 && usChar >= 0xa0 && usChar <= 0xff) {
+		/* Translate old character set to Unixcode */
+		usChar = usCharSet[usChar - 0x80];
+	}
 
 	/* Microsoft Unicode to real Unicode */
 	if (usChar >= 0xf020 && usChar <= 0xf0ff) {
@@ -339,15 +413,17 @@ ulTranslateCharacters(USHORT usChar, ULONG ulFileOffset, int iWordVersion,
 		break;
 	}
 
-	if (eEncoding != encoding_utf8) {
+	if (eEncoding != encoding_utf_8) {
 		/* Latin characters in an oriental text */
 		if (usChar >= 0xff01 && usChar <= 0xff5e) {
 			usChar -= 0xfee0;
 		}
 	}
 
-	if (eConversionType == conversion_ps &&
-	    eEncoding == encoding_iso_8859_1) {
+	if (eEncoding == encoding_latin_1 &&
+	    (eConversionType == conversion_ps ||
+	     eConversionType == conversion_pdf)) {
+		/* Ugly, but it makes the PostScript and PDF look better */
 		switch (usChar) {
 		case UNICODE_ELLIPSIS:
 			return 140;
@@ -356,8 +432,9 @@ ulTranslateCharacters(USHORT usChar, ULONG ulFileOffset, int iWordVersion,
 		case UNICODE_PER_MILLE_SIGN:
 			return 142;
 		case UNICODE_BULLET:
+		case UNICODE_BULLET_OPERATOR:
 		case UNICODE_BLACK_CLUB_SUIT:
-			return (ULONG)(UCHAR)OUR_BULLET_PS;
+			return 143;
 		case UNICODE_LEFT_SINGLE_QMARK:
 			return 144;
 		case UNICODE_RIGHT_SINGLE_QMARK:
@@ -395,6 +472,25 @@ ulTranslateCharacters(USHORT usChar, ULONG ulFileOffset, int iWordVersion,
 		}
 	}
 
+	if (eConversionType == conversion_pdf) {
+		if (eEncoding == encoding_latin_1) {
+			switch (usChar) {
+			case UNICODE_EURO_SIGN:
+				return 128;
+			default:
+				break;
+			}
+		} else if (eEncoding == encoding_latin_2) {
+			switch (usChar) {
+			case UNICODE_CAPITAL_D_WITH_STROKE:
+			case UNICODE_SMALL_D_WITH_STROKE:
+				return 0x3f;
+			default:
+				break;
+			}
+		}
+	}
+
 	if (usChar < 0x80) {
 		/* US ASCII */
 		if (usChar < 0x20 || usChar == 0x7f) {
@@ -406,7 +502,7 @@ ulTranslateCharacters(USHORT usChar, ULONG ulFileOffset, int iWordVersion,
 		return (ULONG)usChar;
 	}
 
-	if (eEncoding == encoding_utf8) {
+	if (eEncoding == encoding_utf_8) {
 		/* No need to convert Unicode characters */
 		return (ULONG)usChar;
 	}
@@ -415,7 +511,7 @@ ulTranslateCharacters(USHORT usChar, ULONG ulFileOffset, int iWordVersion,
 	pTmp = pGetCharTableRecord(usChar);
 	if (pTmp != NULL) {
 		DBG_HEX_C(usChar >= 0x7f && usChar <= 0x9f, usChar);
-		return (ULONG)pTmp->usLocal;
+		return (ULONG)pTmp->ucLocal;
 	}
 
 	/* Fancy characters to simple US ASCII */
@@ -442,6 +538,7 @@ ulTranslateCharacters(USHORT usChar, ULONG ulFileOffset, int iWordVersion,
 	case UNICODE_FIGURE_SPACE:
 	case UNICODE_PUNCTUATION_SPACE:
 	case UNICODE_THIN_SPACE:
+	case UNICODE_NARROW_NO_BREAK_SPACE:
 	case UNICODE_LIGHT_SHADE:
 	case UNICODE_MEDIUM_SHADE:
 	case UNICODE_DARK_SHADE:
@@ -479,16 +576,27 @@ ulTranslateCharacters(USHORT usChar, ULONG ulFileOffset, int iWordVersion,
 	case UNICODE_DOUBLE_DAGGER:
 		return (ULONG)'#';
 	case UNICODE_BULLET:
+	case UNICODE_BULLET_OPERATOR:
 	case UNICODE_BLACK_CLUB_SUIT:
-		return (ULONG)OUR_BULLET_TEXT;
+		return (ULONG)ucGetBulletCharacter(eConversionType, eEncoding);
 	case UNICODE_ONE_DOT_LEADER:
+	case UNICODE_TWO_DOT_LEADER:
 		return (ULONG)'.';
 	case UNICODE_ELLIPSIS:
+#if defined(__riscos)
 		return (ULONG)OUR_ELLIPSIS;
+#else
+		if (ulFileOffset == 0) {
+			return (ULONG)OUR_ELLIPSIS;
+		}
+		return UNICODE_ELLIPSIS;
+#endif /* __riscos */
+	case UNICODE_DOUBLE_LEFT_ANGLE_QMARK:
 	case UNICODE_TRIANGULAR_BULLET:
 	case UNICODE_SINGLE_LEFT_ANGLE_QMARK:
 	case UNICODE_LEFTWARDS_ARROW:
 		return (ULONG)'<';
+	case UNICODE_DOUBLE_RIGHT_ANGLE_QMARK:
 	case UNICODE_SINGLE_RIGHT_ANGLE_QMARK:
 	case UNICODE_RIGHTWARDS_ARROW:
 		return (ULONG)'>';
@@ -503,6 +611,8 @@ ulTranslateCharacters(USHORT usChar, ULONG ulFileOffset, int iWordVersion,
 		return (ULONG)'O';
 	case UNICODE_DIAMOND:
 		return (ULONG)OUR_DIAMOND;
+	case UNICODE_NUMERO_SIGN:
+		return (ULONG)'N';
 	case UNICODE_KELVIN_SIGN:
 		return (ULONG)'K';
 	case UNICODE_DOWNWARDS_ARROW:
@@ -542,6 +652,10 @@ ulTranslateCharacters(USHORT usChar, ULONG ulFileOffset, int iWordVersion,
 	case UNICODE_RIGHT_TO_LEFT_MARK:
 	case UNICODE_LEFT_TO_RIGHT_EMBEDDING:
 	case UNICODE_RIGHT_TO_LEFT_EMBEDDING:
+	case UNICODE_POP_DIRECTIONAL_FORMATTING:
+	case UNICODE_LEFT_TO_RIGHT_OVERRIDE:
+	case UNICODE_RIGHT_TO_LEFT_OVERRIDE:
+	case UNICODE_ZERO_WIDTH_NO_BREAK_SPACE:
 		return IGNORE_CHARACTER;
 	default:
 		break;

+ 16 - 1
sys/src/cmd/aux/antiword/debug.h

@@ -1,6 +1,6 @@
 /*
  * debug.h
- * Copyright (C) 1998-2001 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2005 A.J. van Os; Released under GPL
  *
  * Description:
  * Macro's for debuging.
@@ -99,4 +99,19 @@
 #define NO_DBG_HEX_C(c,m)	/* EMPTY */
 #define NO_DBG_FLT_C(c,m)	/* EMPTY */
 
+#if defined(TRACE)
+
+#define TRACE_MSG(t)	do {\
+			(void)fprintf(stderr,\
+				"%s[%3d]: TRACE:%.40s\n",\
+				__FILE__, __LINE__, (t));\
+			(void)fflush(stderr);\
+			} while(0)
+
+#else
+
+#define TRACE_MSG(t)		/* EMPTY */
+
+#endif /* TRACE */
+
 #endif /* !__debug_h */

+ 43 - 40
sys/src/cmd/aux/antiword/dib2sprt.c

@@ -8,7 +8,8 @@
 
 #include <stdio.h>
 #include <string.h>
-#include "wimpt.h"
+#include "DeskLib:Error.h"
+#include "DeskLib:Sprite.h"
 #include "antiword.h"
 
 #if 0 /* defined(DEBUG) */
@@ -37,36 +38,38 @@ iGetByteWidth(const imagedata_type *pImg)
 } /* end of iGetByteWidth */
 
 /*
- * bCreateBlankSprite - Create a blank sprite.
+ * pCreateBlankSprite - Create a blank sprite.
  *
  * Create a blank sprite and add a palette if needed
  *
  * returns a pointer to the sprite when successful, otherwise NULL
  */
-static UCHAR *
-pucCreateBlankSprite(const imagedata_type *pImg, size_t *ptSize)
+static sprite_areainfo *
+pCreateBlankSprite(const imagedata_type *pImg, size_t *pSize)
 {
-	sprite_area	*pArea;
+	sprite_areainfo	*pArea;
 	UCHAR	*pucTmp;
 	size_t	tSize;
-	int	iIndex, iMode, iPaletteEntries, iByteWidth;
+	screen_modeval	uMode;
+	int	iIndex, iPaletteEntries;
 
-	DBG_MSG("pCreateBlankSprite");
+	TRACE_MSG("pCreateBlankSprite");
 
 	fail(pImg == NULL);
+	fail(pSize == NULL);
 
 	switch (pImg->uiBitsPerComponent) {
 	case  1:
-		iMode = 18;
+		uMode.screen_mode = 18;
 		iPaletteEntries = 2;
 		break;
 	case  4:
-		iMode = 20;
+		uMode.screen_mode = 20;
 		iPaletteEntries = 16;
 		break;
 	case  8:
 	case 24:
-		iMode = 21;
+		uMode.screen_mode = 21;
 		iPaletteEntries = 0;
 		break;
 	default:
@@ -75,26 +78,26 @@ pucCreateBlankSprite(const imagedata_type *pImg, size_t *ptSize)
 	}
 	fail(iPaletteEntries < 0 || iPaletteEntries > 16);
 
-	/* Create the sprite */
-
-	iByteWidth = iGetByteWidth(pImg);
-
-	tSize = sizeof(sprite_area) +
-		sizeof(sprite_header) +
-		iPaletteEntries * 8 +
-		iByteWidth * pImg->iHeight;
+	/* Get memory for the sprite */
+	tSize = sizeof(sprite_areainfo) +
+		Sprite_MemorySize(pImg->iWidth, pImg->iHeight, uMode,
+		iPaletteEntries > 0 ? sprite_HASPAL : sprite_HASNOMASKPAL);
 	DBG_DEC(tSize);
 	pArea = xmalloc(tSize);
-	sprite_area_initialise(pArea, tSize);
 
-	wimpt_noerr(sprite_create(pArea, "wordimage",
-		iPaletteEntries > 0 ? sprite_haspalette : sprite_nopalette,
-		pImg->iWidth, pImg->iHeight, iMode));
+	/* Initialise sprite area */
+	pArea->areasize = tSize;
+	pArea->numsprites = 0;
+	pArea->firstoffset = sizeof(sprite_areainfo);
+	pArea->freeoffset = sizeof(sprite_areainfo);
 
-	/* Add the palette */
+	/* Create a blank sprite */
+	Error_CheckFatal(Sprite_Create(pArea, "wordimage",
+		iPaletteEntries > 0 ? 1 : 0,
+		pImg->iWidth, pImg->iHeight, uMode));
 
-	pucTmp = (UCHAR *)pArea +
-		sizeof(sprite_area) + sizeof(sprite_header);
+	/* Add the palette */
+	pucTmp = (UCHAR *)pArea + pArea->firstoffset + sizeof(sprite_header);
 	for (iIndex = 0; iIndex < iPaletteEntries; iIndex++) {
 		/* First color */
 		*pucTmp++ = 0;
@@ -108,11 +111,9 @@ pucCreateBlankSprite(const imagedata_type *pImg, size_t *ptSize)
 		*pucTmp++ = pImg->aucPalette[iIndex][2];
 	}
 
-	if (ptSize != NULL) {
-		*ptSize = tSize;
-	}
-	return (UCHAR *)pArea;
-} /* end of pucCreateBlankSprite */
+	*pSize = tSize;
+	return pArea;
+} /* end of pCreateBlankSprite */
 
 /*
  * iReduceColor - reduce from 24 bit to 8 bit color
@@ -505,7 +506,8 @@ vCopy2File(UCHAR *pucSprite, size_t tSpriteSize)
 static void
 vDecodeDIB(diagram_type *pDiag, FILE *pFile, const imagedata_type *pImg)
 {
-	UCHAR	*pucSprite, *pucPalette, *pucData;
+	sprite_areainfo	*pSprite;
+	UCHAR	*pucPalette, *pucData;
 	size_t	tSpriteSize;
 	int	iHeaderSize;
 
@@ -518,9 +520,10 @@ vDecodeDIB(diagram_type *pDiag, FILE *pFile, const imagedata_type *pImg)
 			pImg->iColorsUsed * ((iHeaderSize > 12) ? 4 : 3));
 	}
 
-	/* Create an empty sprite */
-	pucSprite = pucCreateBlankSprite(pImg, &tSpriteSize);
-	pucPalette = pucSprite + sizeof(sprite_area) + sizeof(sprite_header);
+	/* Create an blank sprite */
+	pSprite = pCreateBlankSprite(pImg, &tSpriteSize);
+	pucPalette = (UCHAR *)pSprite +
+			pSprite->firstoffset + sizeof(sprite_header);
 
 	/* Add the pixel information */
 	switch (pImg->uiBitsPerComponent) {
@@ -542,7 +545,7 @@ vDecodeDIB(diagram_type *pDiag, FILE *pFile, const imagedata_type *pImg)
 	case  8:
 		fail(pImg->eCompression != compression_none &&
 				pImg->eCompression != compression_rle8);
-		pucData = pucPalette;
+		pucData = pucPalette + 0 * 8;
 		if (pImg->eCompression == compression_rle8) {
 			vDecodeRle8(pFile, pucData, pImg);
 		} else {
@@ -551,7 +554,7 @@ vDecodeDIB(diagram_type *pDiag, FILE *pFile, const imagedata_type *pImg)
 		break;
 	case 24:
 		fail(pImg->eCompression != compression_none);
-		pucData = pucPalette;
+		pucData = pucPalette + 0 * 8;
 		vDecode24bpp(pFile, pucData, pImg);
 		break;
 	default:
@@ -560,16 +563,16 @@ vDecodeDIB(diagram_type *pDiag, FILE *pFile, const imagedata_type *pImg)
 	}
 
 #if 0 /* defined(DEBUG) */
-	vCopy2File(pucSprite, tSpriteSize);
+	vCopy2File((UCHAR *)pSprite, tSpriteSize);
 #endif /* DEBUG */
 
 	/* Add the sprite to the Draw file */
 	vImage2Diagram(pDiag, pImg,
-		pucSprite + sizeof(sprite_area),
-		tSpriteSize - sizeof(sprite_area));
+		(UCHAR *)pSprite + pSprite->firstoffset,
+		tSpriteSize - pSprite->firstoffset);
 
 	/* Clean up before you leave */
-	pucSprite = xfree(pucSprite);
+	pSprite = xfree(pSprite);
 } /* end of vDecodeDIB */
 
 /*

+ 75 - 0
sys/src/cmd/aux/antiword/doclist.c

@@ -0,0 +1,75 @@
+/*
+ * doclist.c
+ * Copyright (C) 2004 A.J. van Os; Released under GNU GPL
+ *
+ * Description:
+ * Build, read and destroy list(s) of Word document information
+ *
+ * Note:
+ * There is no real list there is always one document per document
+ */
+
+#include "antiword.h"
+
+#define HALF_INCH	36000L  /* In millipoints */
+
+/* Variables needed to write the Document Information List */
+static document_block_type *pAnchor = NULL;
+static document_block_type tInfo;
+
+
+/*
+ * vDestroyDocumentInfoList - destroy the Document Information List
+ */
+void
+vDestroyDocumentInfoList(void)
+{
+        DBG_MSG("vDestroyDocumentInfoList");
+
+	pAnchor = NULL;
+} /* end of vDestoryDocumentInfoList */
+
+/*
+ * vCreateDocumentInfoList - create the Document Information List
+ */
+void
+vCreateDocumentInfoList(const document_block_type *pDocument)
+{
+	fail(pDocument == NULL);
+	fail(pAnchor != NULL);
+
+	tInfo = *pDocument;
+	pAnchor = &tInfo;
+} /* end of vCreateDocumentInfoList */
+
+/*
+ * lGetDefaultTabWidth - get the default tabwidth in millipoints
+ */
+long
+lGetDefaultTabWidth(void)
+{
+	long	lDefaultTabWidth;
+	USHORT	usTmp;
+
+	if (pAnchor == NULL) {
+		DBG_FIXME();
+		return HALF_INCH;
+	}
+	usTmp = pAnchor->usDefaultTabWidth;
+	lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp);
+	NO_DBG_DEC(lDefaultTabWidth);
+	return lDefaultTabWidth;
+} /* end of lGetDefaultTabWidth */
+
+/*
+ * ucGetDopHdrFtrSpecification - get the Heder/footer specification
+ */
+UCHAR
+ucGetDopHdrFtrSpecification(void)
+{
+	if (pAnchor == NULL) {
+		DBG_FIXME();
+		return 0x00;
+	}
+	return pAnchor->ucHdrFtrSpecification;
+} /* end of ucGetDopHdrFtrSpecification */

File diff suppressed because it is too large
+ 433 - 435
sys/src/cmd/aux/antiword/draw.c


+ 422 - 0
sys/src/cmd/aux/antiword/drawfile.c

@@ -0,0 +1,422 @@
+/*
+ * drawfile.c
+ * Copyright (C) 2005 A.J. van Os; Released under GPL
+ *
+ * Description:
+ * Functions to process with the Draw diagram
+ */
+
+#include <string.h>
+#include "DeskLib:Error.h"
+#include "DeskLib:SWI.h"
+#include "drawfile.h"
+#include "antiword.h"
+
+#define DRAWFILE_OBJECT_TOO_SMALL	200
+#define DRAWFILE_NO_TEXT		201
+#define DRAWFILE_BAD_CHARACTER		202
+#define DRAWFILE_SMALL_MEMORY		203
+#define DRAWFILE_PATH_WITHOUT_LINES	204
+#define DRAWFILE_BAD_PATH_TYPE		205
+#define DRAWFILE_PATH_WITHOUT_END	206
+#define DRAWFILE_BAD_SPRITE_SIZE	207
+#define DRAWFILE_BAD_JPEG_SIZE		208
+#define DRAWFILE_TOO_SMALL		209
+#define DRAWFILE_NOT_A_DRAWFILE		210
+#define DRAWFILE_OBJECT_SIZE		211
+#define DRAWFILE_MANY_FONTTABLES	212
+#define DRAWFILE_TEXT_NO_FONT		213
+#define DRAWFILE_OBJECT_UNEXPECTED	214
+#define DRAWFILE_SIZE_ERROR		215
+
+typedef struct drawfile_error_tag {
+	int		iErrorNumber;
+	const char	*szErrorText;
+} drawfile_error_type;
+
+static const drawfile_error_type atErrors[] = {
+	{ DRAWFILE_OBJECT_TOO_SMALL, "Object too small"},
+	{ DRAWFILE_NO_TEXT, "Text object without text"},
+	{ DRAWFILE_BAD_CHARACTER, "Bad character in string"},
+	{ DRAWFILE_SMALL_MEMORY, "Not enough memory reserved"},
+	{ DRAWFILE_PATH_WITHOUT_LINES, "This path has no lines"},
+	{ DRAWFILE_BAD_PATH_TYPE, "Bad path-type in path"},
+	{ DRAWFILE_PATH_WITHOUT_END, "No end of path seen"},
+	{ DRAWFILE_BAD_SPRITE_SIZE, "Bad sprite size"},
+	{ DRAWFILE_BAD_JPEG_SIZE, "Bad jpeg size"},
+	{ DRAWFILE_TOO_SMALL, "Too small to be a drawfile"},
+	{ DRAWFILE_NOT_A_DRAWFILE, "Not a drawfile"},
+	{ DRAWFILE_OBJECT_SIZE, "Object with incorrect size"},
+	{ DRAWFILE_MANY_FONTTABLES, "More than one font table"},
+	{ DRAWFILE_TEXT_NO_FONT, "Text, but no font table seen"},
+	{ DRAWFILE_OBJECT_UNEXPECTED, "Unexpected object type"},
+	{ DRAWFILE_SIZE_ERROR, "Sizes don't match"},
+};
+
+
+/*
+ * pFillError - error number to error struct
+ */
+static os_error *
+pFillError(int iErrorNumber)
+{
+	static os_error		tError;
+	const drawfile_error_type	*pTmp;
+	const char	*szErrorText;
+
+	szErrorText = "Unknown error";
+	for (pTmp = atErrors; pTmp < atErrors + elementsof(atErrors); pTmp++) {
+		if (iErrorNumber == pTmp->iErrorNumber) {
+			szErrorText = pTmp->szErrorText;
+			break;
+		}
+	}
+	tError.errnum = iErrorNumber;
+	strncpy(tError.errmess, szErrorText, sizeof(tError.errmess) - 1);
+	tError.errmess[sizeof(tError.errmess) - 1] = '\0';
+	DBG_DEC(tError.errnum);
+	DBG_MSG(tError.errmess);
+	return &tError;
+} /* end of pFillError */
+
+/*
+ * Drawfile_BBox - Find the bounding box of a diagram
+ */
+os_error *
+Drawfile_Bbox(drawfile_bbox_flags flags,
+	drawfile_diagram const *diagram,
+	int size,
+	os_trfm const *trfm,
+	wimp_box *bbox)
+{
+	return SWI(5, 0, DrawFile_BBox | XOS_Bit,
+		flags, diagram, size, trfm, bbox);
+} /* end of Drawfile_Bbox */
+
+/*
+ * Drawfile_CreateDiagram - create an empty drawfile diagram
+ */
+os_error *
+Drawfile_CreateDiagram(drawfile_info *pInfo, size_t tMemorySize,
+	const char *szCreator, wimp_box tBbox)
+{
+	drawfile_diagram	*pDiag;
+
+	if (tMemorySize < offsetof(drawfile_diagram, objects)) {
+		return pFillError(DRAWFILE_SMALL_MEMORY);
+	}
+	pDiag = (drawfile_diagram *)pInfo->data;
+	strncpy(pDiag->tag, "Draw", 4);
+	pDiag->major_version = 201;
+	pDiag->minor_version = 0;
+	strncpy(pDiag->source, szCreator, sizeof(pDiag->source));
+	pDiag->bbox = tBbox;
+	/* Memory in use */
+	pInfo->length = offsetof(drawfile_diagram, objects);
+	return NULL;
+} /* end of Drawfile_CreateDiagram */
+
+/*
+ * Drawfile_AppendObject - append an object to a diagram
+ */
+os_error *
+Drawfile_AppendObject(drawfile_info *pInfo, size_t tMemorySize,
+	const drawfile_object *pObject, BOOL bRebind)
+{
+	wimp_box	*pMainBbox;
+	const wimp_box	*pBbox;
+	byte		*pAfter;
+
+	if (tMemorySize < pInfo->length + pObject->size) {
+		return pFillError(DRAWFILE_OBJECT_TOO_SMALL);
+	}
+	/* After the last object */
+	pAfter = (byte *)pInfo->data + pInfo->length;
+	/* Copy in the new data */
+	memcpy(pAfter, pObject, pObject->size);
+	/* Rebind if needed */
+	if (bRebind) {
+		pMainBbox = &((drawfile_diagram *)pInfo->data)->bbox;
+		switch (pObject->type) {
+		case drawfile_TYPE_FONT_TABLE:
+			pBbox = NULL;
+			break;
+		case drawfile_TYPE_TEXT:
+			pBbox = &pObject->data.text.bbox;
+			break;
+		case drawfile_TYPE_PATH:
+			pBbox = &pObject->data.path.bbox;
+			break;
+		case drawfile_TYPE_SPRITE:
+			pBbox = &pObject->data.sprite.bbox;
+			break;
+		case drawfile_TYPE_GROUP:
+			pBbox = &pObject->data.group.bbox;
+			break;
+		case drawfile_TYPE_TAGGED:
+			pBbox = &pObject->data.tagged.bbox;
+			break;
+		case drawfile_TYPE_TEXT_AREA:
+			pBbox = &pObject->data.text_area.bbox;
+			break;
+		case drawfile_TYPE_TEXT_COLUMN:
+			pBbox = NULL;
+			break;
+		case drawfile_TYPE_OPTIONS:
+			pBbox = &pObject->data.options.bbox;
+			break;
+		case drawfile_TYPE_TRFM_TEXT:
+			pBbox = &pObject->data.trfm_text.bbox;
+			break;
+		case drawfile_TYPE_TRFM_SPRITE:
+			pBbox = &pObject->data.trfm_sprite.bbox;
+			break;
+		case drawfile_TYPE_JPEG:
+			pBbox = &pObject->data.jpeg.bbox;
+			break;
+		default:
+			pBbox = NULL;
+			break;
+		}
+		if (pBbox != NULL) {
+			if (pBbox->min.x < pMainBbox->min.x) {
+				pMainBbox->min.x = pBbox->min.x;
+			}
+			if (pBbox->min.y < pMainBbox->min.y) {
+				pMainBbox->min.y = pBbox->min.y;
+			}
+			if (pBbox->max.x > pMainBbox->max.x) {
+				pMainBbox->max.x = pBbox->max.x;
+			}
+			if (pBbox->max.y > pMainBbox->max.y) {
+				pMainBbox->max.y = pBbox->max.y;
+			}
+		}
+	}
+	/* Memory in use */
+	pInfo->length += pObject->size;
+	return NULL;
+} /* end of Drawfile_AppendObject */
+
+/*
+ * Replaces the draw_render_diag function from RISC_OSLib
+ */
+os_error *
+Drawfile_RenderDiagram(drawfile_info *pInfo, window_redrawblock *pRedraw,
+	double dScale)
+{
+	int	aiTransform[6];
+
+	fail(pInfo == NULL);
+	fail(pInfo->data == NULL);
+	fail(pRedraw == NULL);
+	fail(dScale < 0.01);
+
+	aiTransform[0] = (int)(dScale * 0x10000);
+	aiTransform[1] = 0;
+	aiTransform[2] = 0;
+	aiTransform[3] = (int)(dScale * 0x10000);
+	aiTransform[4] = (pRedraw->rect.min.x - pRedraw->scroll.x) * 256;
+	aiTransform[5] = (pRedraw->rect.max.y - pRedraw->scroll.y) * 256;
+
+	return SWI(6, 0, DrawFile_Render | XOS_Bit,
+		0, pInfo->data, pInfo->length, aiTransform, &pRedraw->rect, 0);
+} /* end of Drawfile_RenderDiagram */
+
+/*
+ * pVerifyText - verify a text object
+ */
+static os_error *
+pVerifyText(const drawfile_text *pText)
+{
+	const unsigned char	*pucTmp;
+
+	if (pText->text[0] == '\0') {
+		return pFillError(DRAWFILE_NO_TEXT);
+	}
+	pucTmp = (const unsigned char *)pText->text;
+	while (*pucTmp != '\0') {
+		if (*pucTmp < 0x20 || *pucTmp == 0x7f) {
+			return pFillError(DRAWFILE_BAD_CHARACTER);
+		}
+		pucTmp++;
+	}
+	return NULL;
+} /* end of pVerifyText */
+
+/*
+ * pVerifyPath - verify a path object
+ */
+static os_error *
+pVerifyPath(const drawfile_path *pPath, int iSize)
+{
+	const int	*piTmp;
+	int	iElements;
+	BOOL	bLine;
+
+	bLine = FALSE;
+	iElements = (iSize - offsetof(drawfile_path, path)) / 4;
+
+	for (piTmp = pPath->path; piTmp < pPath->path + iElements; piTmp++) {
+		switch(*piTmp) {
+		case drawfile_PATH_END_PATH:
+			if (bLine) {
+				return NULL;
+			}
+			return pFillError(DRAWFILE_PATH_WITHOUT_LINES);
+		case drawfile_PATH_LINE_TO:
+			bLine = TRUE;
+			piTmp += 2;
+			break;
+		case drawfile_PATH_MOVE_TO:
+			piTmp += 2;
+			break;
+		case drawfile_PATH_CLOSE_LINE:
+			bLine = TRUE;
+			break;
+		default:
+			return pFillError(DRAWFILE_BAD_PATH_TYPE);
+		}
+	}
+	return pFillError(DRAWFILE_PATH_WITHOUT_END);
+} /* end of pVerifyPath */
+
+/*
+ * pVerifySprite - verify a sprite object
+ */
+static os_error *
+pVerifySprite(const drawfile_sprite *pSprite, int iSize)
+{
+	iSize -= offsetof(drawfile_sprite, header);
+	if (iSize < pSprite->header.offset_next) {
+		DBG_DEC(iSize);
+		DBG_DEC(pSprite->header.offset_next);
+		return pFillError(DRAWFILE_BAD_SPRITE_SIZE);
+	}
+	return NULL;
+} /* end of pVerifySprite */
+
+/*
+ * pVerifyJpeg - verify a jpeg object
+ */
+static os_error *
+pVerifyJpeg(const drawfile_jpeg *pJpeg, int iSize)
+{
+	iSize -= offsetof(drawfile_jpeg, data);
+	if (iSize < pJpeg->len) {
+		DBG_DEC(iSize);
+		DBG_DEC(pJpeg->len);
+		return pFillError(DRAWFILE_BAD_JPEG_SIZE);
+	}
+	return NULL;
+} /* end of pVerifyJpeg */
+
+/*
+ * Drawfile_VerifyDiagram - Verify the diagram generated from the Word file
+ *
+ * returns NULL if the diagram is correct
+ */
+os_error *
+Drawfile_VerifyDiagram(drawfile_info *pInfo)
+{
+	drawfile_diagram	*pDiag;
+	drawfile_object	*pObj;
+	os_error	*pError;
+	const char	*pcTmp;
+	int		iToGo, iFontTables;
+	BOOL		bTypeFontTable;
+
+	TRACE_MSG("Drawfile_VerifyDiagram");
+
+	fail(pInfo == NULL);
+
+  	if (pInfo->length < offsetof(drawfile_diagram, objects)) {
+		return pFillError(DRAWFILE_TOO_SMALL);
+  	}
+
+	pDiag = (drawfile_diagram *)pInfo->data;
+	if (strncmp(pDiag->tag, "Draw", 4) != 0 ||
+	    pDiag->major_version != 201 ||
+	    pDiag->minor_version != 0) {
+		return pFillError(DRAWFILE_NOT_A_DRAWFILE);
+	}
+
+	iToGo = pInfo->length - offsetof(drawfile_diagram, objects);
+	pcTmp = (const char *)pInfo->data + offsetof(drawfile_diagram, objects);
+	iFontTables = 0;
+	bTypeFontTable = FALSE;
+
+	while (iToGo > 0) {
+		pObj = (drawfile_object *)pcTmp;
+		if (pObj->size < 0 || pObj->size % 4 != 0) {
+			return pFillError(DRAWFILE_OBJECT_SIZE);
+		}
+		switch (pObj->type) {
+		case drawfile_TYPE_FONT_TABLE:
+			if (bTypeFontTable) {
+				return pFillError(DRAWFILE_MANY_FONTTABLES);
+			}
+			bTypeFontTable = TRUE;
+			break;
+		case drawfile_TYPE_TEXT:
+			if (pObj->data.text.style.font_ref != 0 &&
+			    !bTypeFontTable) {
+				return pFillError(DRAWFILE_TEXT_NO_FONT);
+			}
+			pError = pVerifyText(&pObj->data.text);
+			if (pError != NULL) {
+				return pError;
+			}
+			break;
+		case drawfile_TYPE_PATH:
+			pError = pVerifyPath(&pObj->data.path,
+				pObj->size - offsetof(drawfile_object, data));
+			if (pError != NULL) {
+				return pError;
+			}
+			break;
+		case drawfile_TYPE_SPRITE:
+			pError = pVerifySprite(&pObj->data.sprite,
+				pObj->size - offsetof(drawfile_object, data));
+			if (pError != NULL) {
+				return pError;
+			}
+			break;
+		case drawfile_TYPE_JPEG:
+			pError = pVerifyJpeg(&pObj->data.jpeg,
+				pObj->size - offsetof(drawfile_object, data));
+			if (pError != NULL) {
+				return pError;
+			}
+			break;
+		default:
+			DBG_DEC(pObj->type);
+			return pFillError(DRAWFILE_OBJECT_UNEXPECTED);
+		}
+		pcTmp += pObj->size;
+		iToGo -= pObj->size;
+	}
+	if (iToGo < 0) {
+		return pFillError(DRAWFILE_SIZE_ERROR);
+	}
+	return NULL;
+} /* end of Drawfile_VerifyDiagram */
+
+/*
+ * Drawfile_QueryBox - Find the bounding box of a diagram
+ */
+void
+Drawfile_QueryBox(drawfile_info *pInfo, wimp_box *pRect, BOOL bScreenUnits)
+{
+	fail(pInfo == NULL);
+	fail(pRect == NULL);
+
+	Error_CheckFatal(Drawfile_Bbox(0,
+		pInfo->data, pInfo->length, NULL, pRect));
+	if (bScreenUnits) {
+		pRect->min.x = Drawfile_DrawToScreen(pRect->min.x);
+		pRect->min.y = Drawfile_DrawToScreen(pRect->min.y);
+		pRect->max.x = Drawfile_DrawToScreen(pRect->max.x);
+		pRect->max.y = Drawfile_DrawToScreen(pRect->max.y);
+	}
+} /* end of Drawfile_QueryBox */

+ 433 - 0
sys/src/cmd/aux/antiword/drawfile.h

@@ -0,0 +1,433 @@
+/*
+ * drawfile.h
+ * Copyright (C) 2005 A.J. van Os; Released under GNU GPL
+ *
+ * Description:
+ * Include file to deal with drawfiles
+ *
+ * Based on:
+ * C header file for DrawFile
+ * written by DefMod (May  4 2004) on Tue May  4 13:34:17 2004
+ * Jonathan Coxhead, jonathan@doves.demon.co.uk, 21 Aug 1995
+ * OSLib---efficient, type-safe, transparent, extensible,
+ * register-safe A P I coverage of RISC O S
+ * Copyright (C) 1994 Jonathan Coxhead
+ *
+ * All credit should go to him, but all the bugs are mine
+ */
+
+#if !defined(__drawfile_h)
+#define __drawfile_h
+
+#include "DeskLib:Sprite.h"
+#include "DeskLib:Wimp.h"
+
+#if !defined(BOOL)
+#define BOOL int
+#define TRUE 1
+#define FALSE 0
+#endif /* !BOOL */
+
+/*********************
+ * Conversion macros *
+ *********************/
+#define Drawfile_DrawToScreen(i) ((i) / 256)
+#define Drawfile_ScreenToDraw(i) ((i) * 256)
+
+/**********************************
+ * SWI names and SWI reason codes *
+ **********************************/
+#define DrawFile_Render                         0x45540
+#define DrawFile_BBox                           0x45541
+#define DrawFile_DeclareFonts                   0x45542
+
+/********************
+ * Type definitions *
+ ********************/
+typedef unsigned int                            bits;
+typedef unsigned char                           byte;
+
+typedef byte drawfile_fontref;
+
+typedef byte drawfile_path_style_flags;
+
+typedef bits drawfile_text_flags;
+
+typedef bits drawfile_render_flags;
+
+typedef bits drawfile_declare_fonts_flags;
+
+typedef bits drawfile_paper_options;
+
+typedef bits drawfile_entry_mode;
+
+typedef enum {
+  drawfile_TYPE_FONT_TABLE = 0,
+  drawfile_TYPE_TEXT = 1,
+  drawfile_TYPE_PATH = 2,
+  drawfile_TYPE_SPRITE = 5,
+  drawfile_TYPE_GROUP = 6,
+  drawfile_TYPE_TAGGED = 7,
+  drawfile_TYPE_TEXT_AREA = 9,
+  drawfile_TYPE_TEXT_COLUMN = 10,
+  drawfile_TYPE_OPTIONS = 11,
+  drawfile_TYPE_TRFM_TEXT = 12,
+  drawfile_TYPE_TRFM_SPRITE = 13,
+  drawfile_TYPE_JPEG = 16
+} drawfile_type;
+
+typedef enum {
+  drawfile_PATH_END_PATH = 0,
+  drawfile_PATH_CONTINUATION = 1,
+  drawfile_PATH_MOVE_TO = 2,
+  drawfile_PATH_SPECIAL_MOVE_TO = 3,
+  drawfile_PATH_CLOSE_GAP = 4,
+  drawfile_PATH_CLOSE_LINE = 5,
+  drawfile_PATH_BEZIER_TO = 6,
+  drawfile_PATH_GAP_TO = 7,
+  drawfile_PATH_LINE_TO = 8
+} drawfile_path_type;
+
+typedef struct {
+  int start;
+  int element_count;
+  int elements [6];
+} draw_dash_pattern;
+
+typedef struct {
+  int entries [3] [2];
+} os_trfm;
+
+typedef struct {
+  void *data;
+  size_t length;
+} drawfile_info;
+
+typedef struct {
+  drawfile_fontref font_ref;
+  char font_name [1];
+} drawfile_font_def;
+
+typedef struct {
+  drawfile_fontref font_ref;
+  byte reserved [3];
+} drawfile_text_style;
+
+typedef struct {
+  drawfile_path_style_flags flags;
+  byte reserved;
+  byte cap_width;
+  byte cap_length;
+} drawfile_path_style;
+
+typedef struct {
+  drawfile_font_def font_def[1];
+} drawfile_font_table;
+
+typedef struct {
+  wimp_box bbox;
+  palette_entry fill;
+  palette_entry bg_hint;
+  drawfile_text_style style;
+  int xsize;
+  int ysize;
+  wimp_coord base;
+  char text [1];
+} drawfile_text;
+
+typedef struct {
+  wimp_box bbox;
+  palette_entry fill;
+  palette_entry outline;
+  int width;
+  drawfile_path_style style;
+  int path [1];
+} drawfile_path;
+
+typedef struct {
+  wimp_box bbox;
+  palette_entry fill;
+  palette_entry outline;
+  int width;
+  drawfile_path_style style;
+  draw_dash_pattern pattern;
+  int path [1];
+} drawfile_path_with_pattern;
+
+typedef struct {
+  wimp_box bbox;
+  sprite_header header;
+  byte data [1];
+} drawfile_sprite;
+
+typedef struct  {
+  wimp_box bbox;
+  char name [12];
+  int objects [1];
+} drawfile_group;
+
+typedef struct {
+  wimp_box bbox;
+  drawfile_type tag;
+  int object [1];
+} drawfile_tagged;
+
+typedef struct {
+  wimp_box box;
+} drawfile_text_column;
+
+typedef struct {
+  struct {
+    drawfile_type type;
+    int size;
+    drawfile_text_column data;
+  } columns [1];
+} drawfile_text_column_list;
+
+typedef struct {
+  drawfile_type type;
+  int reserved [2];
+  palette_entry fill;
+  palette_entry bg_hint;
+  char text [1];
+} drawfile_area_text;
+
+typedef struct {
+  wimp_box bbox;
+  drawfile_text_column_list header;
+  drawfile_area_text area_text;
+} drawfile_text_area;
+
+typedef struct {
+  wimp_box bbox;
+  int paper_size;
+  drawfile_paper_options paper_options;
+  double grid_spacing;
+  int grid_division;
+  BOOL isometric;
+  BOOL auto_adjust;
+  BOOL show;
+  BOOL lock;
+  BOOL cm;
+  int zoom_mul;
+  int zoom_div;
+  BOOL zoom_lock;
+  BOOL toolbox;
+  drawfile_entry_mode entry_mode;
+  int undo_size;
+} drawfile_options;
+
+typedef struct {
+  wimp_box bbox;
+  os_trfm trfm;
+  drawfile_text_flags flags;
+  palette_entry fill;
+  palette_entry bg_hint;
+  drawfile_text_style style;
+  int xsize;
+  int ysize;
+  wimp_coord base;
+  char text [1];
+} drawfile_trfm_text;
+
+typedef struct {
+  wimp_box bbox;
+  os_trfm trfm;
+  sprite_header header;
+  byte data [1];
+} drawfile_trfm_sprite;
+
+typedef struct {
+  wimp_box bbox;
+  int width;
+  int height;
+  int xdpi;
+  int ydpi;
+  os_trfm trfm;
+  int len;
+  byte data [1];
+} drawfile_jpeg;
+
+/* ------------------------------------------------------------------------
+ * Type:          drawfile_object
+ *
+ * Description:   This type is used to declare pointers rather than objects
+ */
+
+typedef struct {
+  drawfile_type type;
+  int size;
+  union {
+    drawfile_font_table font_table;
+    drawfile_text text;
+    drawfile_path path;
+    drawfile_path_with_pattern path_with_pattern;
+    drawfile_sprite sprite;
+    drawfile_group group;
+    drawfile_tagged tagged;
+    drawfile_text_column text_column;
+    drawfile_text_area text_area;
+    drawfile_options options;
+    drawfile_trfm_text trfm_text;
+    drawfile_trfm_sprite trfm_sprite;
+    drawfile_jpeg jpeg;
+  } data;
+} drawfile_object;
+
+typedef struct {
+  char tag [4];
+  int major_version;
+  int minor_version;
+  char source [12];
+  wimp_box bbox;
+  drawfile_object objects [1];
+} drawfile_diagram;
+
+typedef bits drawfile_bbox_flags;
+
+typedef struct {
+  drawfile_object *object;
+  drawfile_diagram *diagram;
+  drawfile_object *font_table;
+  drawfile_declare_fonts_flags flags;
+  os_error *error;
+} drawfile_declare_fonts_state;
+
+/************************
+ * Constant definitions *
+ ************************/
+#define error_DRAW_FILE_NOT_DRAW                0x20C00u
+#define error_DRAW_FILE_VERSION                 0x20C01u
+#define error_DRAW_FILE_FONT_TAB                0x20C02u
+#define error_DRAW_FILE_BAD_FONT_NO             0x20C03u
+#define error_DRAW_FILE_BAD_MODE                0x20C04u
+#define error_DRAW_FILE_BAD_FILE                0x20C05u
+#define error_DRAW_FILE_BAD_GROUP               0x20C06u
+#define error_DRAW_FILE_BAD_TAG                 0x20C07u
+#define error_DRAW_FILE_SYNTAX                  0x20C08u
+#define error_DRAW_FILE_FONT_NO                 0x20C09u
+#define error_DRAW_FILE_AREA_VER                0x20C0Au
+#define error_DRAW_FILE_NO_AREA_VER             0x20C0Bu
+
+#define drawfile_PATH_MITRED                    ((drawfile_path_style_flags) 0x0u)
+#define drawfile_PATH_ROUND                     ((drawfile_path_style_flags) 0x1u)
+#define drawfile_PATH_BEVELLED                  ((drawfile_path_style_flags) 0x2u)
+#define drawfile_PATH_BUTT                      ((drawfile_path_style_flags) 0x0u)
+#define drawfile_PATH_SQUARE                    ((drawfile_path_style_flags) 0x2u)
+#define drawfile_PATH_TRIANGLE                  ((drawfile_path_style_flags) 0x3u)
+#define drawfile_PATH_JOIN_SHIFT                0
+#define drawfile_PATH_JOIN                      ((drawfile_path_style_flags) 0x3u)
+#define drawfile_PATH_END_SHIFT                 2
+#define drawfile_PATH_END                       ((drawfile_path_style_flags) 0xCu)
+#define drawfile_PATH_START_SHIFT               4
+#define drawfile_PATH_START                     ((drawfile_path_style_flags) 0x30u)
+#define drawfile_PATH_WINDING_EVEN_ODD          ((drawfile_path_style_flags) 0x40u)
+#define drawfile_PATH_DASHED                    ((drawfile_path_style_flags) 0x80u)
+#define drawfile_PATH_CAP_WIDTH_SHIFT           16
+#define drawfile_PATH_CAP_WIDTH                 ((drawfile_path_style_flags) 0xFF0000u)
+#define drawfile_PATH_CAP_LENGTH_SHIFT          24
+#define drawfile_PATH_CAP_LENGTH                ((drawfile_path_style_flags) 0xFF000000u)
+#define drawfile_TEXT_KERN                      ((drawfile_text_flags) 0x1u)
+#define drawfile_TEXT_RIGHT_TO_LEFT             ((drawfile_text_flags) 0x2u)
+#define drawfile_TEXT_UNDERLINE                 ((drawfile_text_flags) 0x4u)
+#define drawfile_RENDER_BBOXES                  ((drawfile_render_flags) 0x1u)
+#define drawfile_RENDER_SUPPRESS                ((drawfile_render_flags) 0x2u)
+#define drawfile_RENDER_GIVEN_FLATNESS          ((drawfile_render_flags) 0x4u)
+#define drawfile_RENDER_GIVEN_COLOUR_MAPPING    ((drawfile_render_flags) 0x8u)
+#define drawfile_NO_DOWNLOAD                    ((drawfile_declare_fonts_flags) 0x1u)
+#define drawfile_PAPER_SHOW                     ((drawfile_paper_options) 0x1u)
+#define drawfile_PAPER_LANDSCAPE                ((drawfile_paper_options) 0x10u)
+#define drawfile_PAPER_DEFAULT                  ((drawfile_paper_options) 0x100u)
+#define drawfile_ENTRY_MODE_LINE                ((drawfile_entry_mode) 0x1u)
+#define drawfile_ENTRY_MODE_CLOSED_LINE         ((drawfile_entry_mode) 0x2u)
+#define drawfile_ENTRY_MODE_CURVE               ((drawfile_entry_mode) 0x4u)
+#define drawfile_ENTRY_MODE_CLOSED_CURVE        ((drawfile_entry_mode) 0x8u)
+#define drawfile_ENTRY_MODE_RECTANGLE           ((drawfile_entry_mode) 0x10u)
+#define drawfile_ENTRY_MODE_ELLIPSE             ((drawfile_entry_mode) 0x20u)
+#define drawfile_ENTRY_MODE_TEXT_LINE           ((drawfile_entry_mode) 0x40u)
+#define drawfile_ENTRY_MODE_SELECT              ((drawfile_entry_mode) 0x80u)
+
+/*************************
+ * Function declarations *
+ *************************/
+
+#if defined(__cplusplus)
+   extern "C" {
+#endif /* __cplusplus */
+
+/* ------------------------------------------------------------------------
+ * Function:      drawfile_render()
+ *
+ * Description:   Calls SWI 0x45540
+ *
+ * Input:         flags - value of R0 on entry
+ *                diagram - value of R1 on entry
+ *                size - value of R2 on entry
+ *                trfm - value of R3 on entry
+ *                clip - value of R4 on entry
+ *                flatness - value of R5 on entry
+ */
+
+extern os_error *Drawfile_Render (drawfile_render_flags flags,
+      drawfile_diagram const *diagram,
+      int size,
+      os_trfm const *trfm,
+      wimp_box const *clip,
+      int flatness);
+
+/* ------------------------------------------------------------------------
+ * Function:      drawfile_bbox()
+ *
+ * Description:   Calls SWI 0x45541
+ *
+ * Input:         flags - value of R0 on entry
+ *                diagram - value of R1 on entry
+ *                size - value of R2 on entry
+ *                trfm - value of R3 on entry
+ *                bbox - value of R4 on entry
+ */
+
+extern os_error *Drawfile_Bbox (drawfile_bbox_flags flags,
+      drawfile_diagram const *diagram,
+      int size,
+      os_trfm const *trfm,
+      wimp_box *bbox);
+
+/* ------------------------------------------------------------------------
+ * Function:      Drawfile_DeclareFonts()
+ *
+ * Description:   Calls SWI 0x45542
+ *
+ * Input:         flags - value of R0 on entry
+ *                diagram - value of R1 on entry
+ *                size - value of R2 on entry
+ */
+
+extern os_error *Drawfile_DeclareFonts (drawfile_declare_fonts_flags flags,
+      drawfile_diagram const *diagram,
+      int size);
+
+/* ------------------------------------------------------------------------
+ * Function:      Drawfile_CreateDiagram()
+ *
+ */
+
+extern os_error * Drawfile_CreateDiagram(drawfile_info *info, size_t memory,
+	const char *creator, wimp_box box);
+
+extern os_error *Drawfile_AppendObject(drawfile_info *info, size_t memory,
+	const drawfile_object *object, BOOL rebind);
+
+extern os_error *Drawfile_RenderDiagram(drawfile_info *info,
+	window_redrawblock *redraw, double scale);
+
+extern os_error *Drawfile_VerifyDiagram(drawfile_info *info);
+
+extern void	Drawfile_QueryBox(drawfile_info *info,
+	wimp_box *rect, BOOL screenUnits);
+
+#if defined(__cplusplus)
+   }
+#endif /* __cplusplus */
+
+#endif /* __drawfile.h */

+ 8 - 18
sys/src/cmd/aux/antiword/findtext.c

@@ -1,6 +1,6 @@
 /*
  * findtext.c
- * Copyright (C) 1998-2001 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Find the blocks that contain the text of MS Word files
@@ -183,12 +183,11 @@ bGet8DocumentText(FILE *pFile, const pps_info_type *pPPS,
 	UCHAR	*aucBuffer;
 	ULONG	ulTextOffset, ulBeginTextInfo;
 	ULONG	ulTotLength, ulLen;
-	ULONG	ulTableStartBlock, ulTableSize;
 	long	lIndex, lPieces, lOff;
 	size_t	tTextInfoLen, tBlockDepotLen, tBlockSize;
 	int	iType, iLen;
 	BOOL	bUsesUnicode;
-	USHORT	usDocStatus, usPropMod;
+	USHORT	usPropMod;
 
 	DBG_MSG("bGet8DocumentText");
 
@@ -201,22 +200,13 @@ bGet8DocumentText(FILE *pFile, const pps_info_type *pPPS,
 	tTextInfoLen = (size_t)ulGetLong(0x1a6, aucHeader);	/* lcbClx */
 	DBG_DEC(tTextInfoLen);
 
-	/* Use 0Table or 1Table? */
-	usDocStatus = usGetWord(0x0a, aucHeader);
-	if (usDocStatus & BIT(9)) {
-		ulTableStartBlock = pPPS->t1Table.ulSB;
-		ulTableSize = pPPS->t1Table.ulSize;
-	} else {
-		ulTableStartBlock = pPPS->t0Table.ulSB;
-		ulTableSize = pPPS->t0Table.ulSize;
-	}
-	DBG_DEC(ulTableStartBlock);
-	if (ulTableStartBlock == 0) {
-		DBG_DEC(ulTableStartBlock);
+	DBG_DEC(pPPS->tTable.ulSB);
+	DBG_HEX(pPPS->tTable.ulSize);
+	if (pPPS->tTable.ulSize == 0) {
 		return FALSE;
 	}
-	DBG_HEX(ulTableSize);
-	if (ulTableSize < MIN_SIZE_FOR_BBD_USE) {
+
+	if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
 	  	/* Use the Small Block Depot */
 		aulBlockDepot = aulSBD;
 		tBlockDepotLen = tSBDLen;
@@ -228,7 +218,7 @@ bGet8DocumentText(FILE *pFile, const pps_info_type *pPPS,
 		tBlockSize = BIG_BLOCK_SIZE;
 	}
 	aucBuffer = xmalloc(tTextInfoLen);
-	if (!bReadBuffer(pFile, ulTableStartBlock,
+	if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
 			aulBlockDepot, tBlockDepotLen, tBlockSize,
 			aucBuffer, ulBeginTextInfo, tTextInfoLen)) {
 		aucBuffer = xfree(aucBuffer);

+ 167 - 0
sys/src/cmd/aux/antiword/fmt_text.c

@@ -0,0 +1,167 @@
+/*
+ * fmt_text.c
+ * Copyright (C) 2004 A.J. van Os; Released under GNU GPL
+ *
+ * Description:
+ * Functions to deal with the Formatted Text format
+ *
+ * Based on patches send by: Ofir Reichenberg <ofir@qlusters.com>
+ *
+ * The credit should go to him, but all the bugs are mine.
+ */
+
+#include <string.h>
+#include "antiword.h"
+
+/* The character set */
+static encoding_type	eEncoding = encoding_neutral;
+/* Current vertical position information */
+static long		lYtopCurr = 0;
+/* Local representation of the non-breaking space */
+static UCHAR		ucNbsp = 0;
+
+
+/*
+ * vPrologueFMT - set options and perform the Formatted Text initialization
+ */
+void
+vPrologueFMT(diagram_type *pDiag, const options_type *pOptions)
+{
+	fail(pDiag == NULL);
+	fail(pOptions == NULL);
+
+	eEncoding = pOptions->eEncoding;
+	pDiag->lXleft = 0;
+	pDiag->lYtop = 0;
+	lYtopCurr = 0;
+} /* end of vPrologueFMT */
+
+/*
+ * vPrintFMT - print a Formatted Text string
+ */
+static void
+vPrintFMT(FILE *pFile,
+	const char *szString, size_t tStringLength, USHORT usFontstyle)
+{
+	const UCHAR	*pucByte, *pucStart, *pucLast, *pucNonSpace;
+
+	fail(szString == NULL);
+
+	if (szString == NULL || szString[0] == '\0' || tStringLength == 0) {
+		return;
+	}
+
+	if (eEncoding == encoding_utf_8) {
+		fprintf(pFile, "%.*s", (int)tStringLength, szString);
+		return;
+	}
+
+	if (ucNbsp == 0) {
+		ucNbsp = ucGetNbspCharacter();
+		DBG_HEX_C(ucNbsp != 0xa0, ucNbsp);
+	}
+
+	pucStart = (UCHAR *)szString;
+	pucLast = pucStart + tStringLength - 1;
+	pucNonSpace = pucLast;
+	while ((*pucNonSpace == (UCHAR)' ' || *pucNonSpace == ucNbsp) &&
+	       pucNonSpace > pucStart) {
+		pucNonSpace--;
+	}
+
+	/* 1: The spaces at the start */
+	pucByte = pucStart;
+	while ((*pucByte == (UCHAR)' ' || *pucByte == ucNbsp) &&
+	       pucByte <= pucLast) {
+		(void)putc(' ', pFile);
+		pucByte++;
+	}
+
+	if (pucByte > pucLast) {
+		/* There is no text, just spaces */
+		return;
+	}
+
+	/* 2: Start the *bold*, /italic/ and _underline_ */
+	if (bIsBold(usFontstyle)) {
+		(void)putc('*', pFile);
+	}
+	if (bIsItalic(usFontstyle)) {
+		(void)putc('/', pFile);
+	}
+	if (bIsUnderline(usFontstyle)) {
+		(void)putc('_', pFile);
+	}
+
+	/* 3: The text itself */
+	while (pucByte <= pucNonSpace) {
+		if (*pucByte == ucNbsp) {
+			(void)putc(' ', pFile);
+		} else {
+			(void)putc((char)*pucByte, pFile);
+		}
+		pucByte++;
+	}
+
+	/* 4: End the *bold*, /italic/ and _underline_ */
+	if (bIsUnderline(usFontstyle)) {
+		(void)putc('_', pFile);
+	}
+	if (bIsItalic(usFontstyle)) {
+		(void)putc('/', pFile);
+	}
+	if (bIsBold(usFontstyle)) {
+		(void)putc('*', pFile);
+	}
+
+	/* 5: The spaces at the end */
+	while (pucByte <= pucLast) {
+		(void)putc(' ', pFile);
+		pucByte++;
+	}
+} /* end of vPrintFMT */
+
+/*
+ * vMoveTo - move to the given X,Y coordinates
+ *
+ * Move the current position of the given diagram to its X,Y coordinates,
+ * start on a new page if needed
+ */
+static void
+vMoveTo(diagram_type *pDiag)
+{
+	int	iCount, iNbr;
+
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+
+	if (pDiag->lYtop != lYtopCurr) {
+		iNbr = iDrawUnits2Char(pDiag->lXleft);
+		for (iCount = 0; iCount < iNbr; iCount++) {
+			(void)putc(FILLER_CHAR, pDiag->pOutFile);
+		}
+		lYtopCurr = pDiag->lYtop;
+	}
+} /* end of vMoveTo */
+
+/*
+ * vSubstringFMT - print a sub string
+ */
+void
+vSubstringFMT(diagram_type *pDiag,
+	const char *szString, size_t tStringLength, long lStringWidth,
+	USHORT usFontstyle)
+{
+	fail(pDiag == NULL || szString == NULL);
+	fail(pDiag->pOutFile == NULL);
+	fail(pDiag->lXleft < 0);
+	fail(tStringLength != strlen(szString));
+
+	if (szString[0] == '\0' || tStringLength == 0) {
+		return;
+	}
+
+	vMoveTo(pDiag);
+	vPrintFMT(pDiag->pOutFile, szString, tStringLength, usFontstyle);
+	pDiag->lXleft += lStringWidth;
+} /* end of vSubstringFMT */

+ 0 - 207
sys/src/cmd/aux/antiword/fontinfo.pl

@@ -1,207 +0,0 @@
-#! /usr/bin/perl -w
-#
-# Generate the fontinformation tables for the required fonts (Linux version)
-#
-
-@charnames1 = (
-"ellipsis", "trademark", "perthousand", "bullet",
-"quoteleft", "quoteright", "guilsinglleft", "guilsinglright",
-"quotedblleft", "quotedblright", "quotedblbase", "endash", "emdash",
-"minus", "OE", "oe", "dagger", "daggerdbl", "fi", "fl",
-"space", "exclamdown", "cent", "sterling", "currency",
-"yen", "brokenbar", "section", "dieresis", "copyright",
-"ordfeminine", "guillemotleft", "logicalnot", "hyphen", "registered",
-"macron", "degree", "plusminus", "twosuperior", "threesuperior",
-"acute", "mu", "paragraph", "periodcentered", "cedilla",
-"onesuperior", "ordmasculine", "guillemotright", "onequarter",
-"onehalf", "threequarters", "questiondown", "Agrave", "Aacute",
-"Acircumflex", "Atilde", "Adieresis", "Aring", "AE", "Ccedilla",
-"Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave", "Iacute",
-"Icircumflex", "Idieresis", "Eth", "Ntilde", "Ograve", "Oacute",
-"Ocircumflex", "Otilde", "Odieresis", "multiply", "Oslash",
-"Ugrave", "Uacute", "Ucircumflex", "Udieresis", "Yacute", "Thorn",
-"germandbls", "agrave", "aacute", "acircumflex", "atilde",
-"adieresis", "aring", "ae", "ccedilla", "egrave", "eacute",
-"ecircumflex", "edieresis", "igrave", "iacute", "icircumflex",
-"idieresis", "eth", "ntilde", "ograve", "oacute", "ocircumflex",
-"otilde", "odieresis", "divide", "oslash", "ugrave", "uacute",
-"ucircumflex", "udieresis", "yacute", "thorn", "ydieresis"
-);
-
-@charnames2 = (
-"space", "Aogonek", "breve", "Lslash", "currency", "Lcaron",
-"Sacute", "section", "dieresis", "Scaron", "Scedilla",
-"Tcaron", "Zacute", "hyphen", "Zcaron", "Zdotaccent", "ring",
-"aogonek", "ogonek", "lslash", "acute", "lcaron", "sacute",
-"caron", "cedilla", "scaron", "scedilla", "tcaron",
-"zacute", "hungarumlaut", "zcaron", "zdotaccent", "Racute",
-"Aacute", "Acircumflex", "Abreve", "Adieresis", "Lacute",
-"Cacute", "Ccedilla", "Ccaron", "Eacute", "Eogonek",
-"Edieresis", "Ecaron", "Iacute", "Icircumflex", "Dcaron",
-"Dslash", "Nacute", "Ncaron", "Oacute", "Ocircumflex",
-"Ohungarumlaut", "Odieresis", "multiply", "Rcaron", "Uring",
-"Uacute", "Uhungarumlaut", "Udieresis", "Yacute", "Tcommaaccent",
-"germandbls", "racute", "aacute", "acircumflex", "abreve",
-"adieresis", "lacute", "cacute", "ccedilla", "ccaron", "eacute",
-"eogonek", "edieresis", "ecaron", "iacute", "icircumflex",
-"dcaron", "dmacron", "nacute", "ncaron", "oacute", "ocircumflex",
-"ohungarumlaut", "odieresis", "divide", "rcaron", "uring",
-"uacute", "uhungarumlaut", "udieresis", "yacute", "tcommaaccent",
-"dotaccent"
-);
-
-$gs_dir1 = '/usr/share/ghostscript/fonts';
-$gs_dir2 = '/usr/share/ghostscript/fonts2';
-
-@fontnames = (
-"Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique",
-"Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",
-"Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique",
-"Palatino-Roman", "Palatino-Bold", "Palatino-Italic", "Palatino-BoldItalic",
-"Helvetica-Narrow", "Helvetica-Narrow-Bold", "Helvetica-Narrow-Oblique", "Helvetica-Narrow-BoldOblique",
-"Bookman-Light", "Bookman-Demi", "Bookman-LightItalic", "Bookman-DemiItalic",
-"AvantGarde-Book", "AvantGarde-Demi", "AvantGarde-BookOblique", "AvantGarde-DemiOblique",
-"NewCenturySchlbk-Roman", "NewCenturySchlbk-Bold", "NewCenturySchlbk-Italic", "NewCenturySchlbk-BoldItalic",
-);
-
-@files = (
-"n022003l.afm", "n022004l.afm", "n022023l.afm", "n022024l.afm",
-"n021003l.afm", "n021004l.afm", "n021023l.afm", "n021024l.afm",
-"n019003l.afm", "n019004l.afm", "n019023l.afm", "n019024l.afm",
-"p052003l.afm", "p052004l.afm", "p052023l.afm", "p052024l.afm",
-"n019043l.afm", "n019044l.afm", "n019063l.afm", "n019064l.afm",
-"b018012l.afm", "b018015l.afm", "b018032l.afm", "b018035l.afm",
-"a010013l.afm", "a010015l.afm", "a010033l.afm", "a010035l.afm",
-"c059013l.afm", "c059016l.afm", "c059033l.afm", "c059036l.afm",
-);
-
-
-# Generate the array with the fontnames
-sub generate_fontnames
-{
-	printf STDOUT "static const char *szFontnames[%d] = {\n", $#fontnames + 1;
-	for ($n = 0; $n <= $#fontnames; $n++) {
-		printf STDOUT "\t\"%s\",\n", $fontnames[$n];
-	}
-	printf STDOUT "};\n";
-}
-
-# Generate the array with the character widths
-sub generate_character_widths
-{
-	my ($char_set, $gs_dir, @charnames) = @_;
-	my ($n, $i, $file, $name, $start);
-	my (@a, @charwidth);
-
-	if ($char_set == 1) {
-		$start = 140;
-	} else {
-		$start = 160;
-	}
-	printf STDOUT "static unsigned short ausCharacterWidths%d[%d][256] = {\n", $char_set, $#files + 1;
-	for ($n = 0; $n <= $#files; $n++) {
-		$file = $files[$n];
-		$name = $fontnames[$n];
-		open(F_IN, "<$gs_dir/$file") || die "Cannot open $gs_dir/$file";
-		printf STDOUT "\t{\t/* %s */\n", $name;
-		while (<F_IN>) {
-			chop();
-			@a = split(/\s+/);
-			if ($a[0] eq 'UnderlinePosition') {
-				$underlineposition[$n] = $a[1];
-			} elsif ($a[0] eq 'UnderlineThickness') {
-				#printf STDERR "%d %d\n", $a[0], $a[1];
-				$underlinethickness[$n] = $a[1];
-			} elsif ($a[0] eq 'C' && $a[2] eq ';' && $a[3] eq 'WX') {
-				#printf STDERR "%d %d %s\n", $a[1], $a[4], $a[7];
-				if (($a[1] < 0 || $a[1] >= 129) && defined($a[7])) {
-					for ($i = 0; $i <= $#charnames; $i++) {
-						if ($charnames[$i] eq $a[7]) {
-							$charwidth[$start + $i] = $a[4];
-							last;
-						}
-					}
-				}
-				if ($a[1] >= 0 && $a[1] <= 128 && !defined($charwidth[$a[1]])) {
-					$charwidth[$a[1]] = $a[4];
-				}
-			}
-			if (defined($a[7])) {
-				for ($i = 0; $i <= $#charnames; $i++) {
-					if ($charnames[$i] eq $a[7]) {
-						$charwidth[$start + $i] = $a[4];
-						last;
-					}
-				}
-			}
-		}
-		close(F_IN);
-
-		# Set the width of the control characters zero
-		for ($i = 0; $i < 32; $i++) {
-			$charwidth[$i] = 0;
-		}
-		# Set the width of the unused characters to zero
-		for ($i = 127; $i < $start; $i++) {
-			$charwidth[$i] = 0;
-		}
-
-		# Print the results
-		for ($i = 0; $i < 256; $i += 8) {
-			printf STDOUT "\t/* %3d */ ", $i;
-			for ($j = 0; $j < 8; $j++) {
-				if (!defined($charwidth[$i + $j])) {
-					printf STDERR "%d:%s: character %3d is undefined\n", $char_set, $name, $i + $j;
-					$charwidth[$i + $j] = 0;
-				}
-				printf STDOUT "%5d,", $charwidth[$i + $j];
-			}
-			printf STDOUT "\n";
-		}
-		printf STDOUT "\t},\n";
-		undef @charwidth;
-	}
-	printf STDOUT "};\n";
-}
-
-# Generate the array with the underline information
-sub generate_underline_information
-{
-	printf STDOUT "#if 0 /* Until this array is needed */\n";
-
-	printf STDOUT "static int aiUnderlineInfo[%d][2] = {\n", $#fontnames + 1;
-	for ($n = 0; $n <= $#fontnames; $n++) {
-		if (!defined($underlineposition[$n])) {
-			$underlineposition[$n] = 0;
-		}
-		if (!defined($underlinethickness[$n])) {
-			$underlinethickness[$n] = 0;
-		}
-		printf STDOUT "\t{ %d, %d },\n", $underlineposition[$n], $underlinethickness[$n];
-	}
-	printf STDOUT "};\n";
-
-	printf STDOUT "#endif /* 0 */\n";
-}
-
-
-# main()
-
-if ($#fontnames != $#files) {
-	die "The fontnames-array and the files-array are of unequel length";
-}
-if ($#charnames1 != 255 - 140) {
-	die "The charname1 table length is $#charnames1";
-}
-if ($#charnames2 != 255 - 160) {
-	die "The charname2 table length is $#charnames2";
-}
-
-printf STDOUT "/* THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT! */\n";
-
-&generate_fontnames();
-&generate_character_widths(1, $gs_dir1, @charnames1);
-&generate_character_widths(2, $gs_dir2, @charnames2);
-&generate_underline_information();
-
-exit 0;

+ 18 - 9
sys/src/cmd/aux/antiword/fontlist.c

@@ -1,6 +1,6 @@
 /*
  * fontlist.c
- * Copyright (C) 1998-2002 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Build, read and destroy a list of Word font information
@@ -11,9 +11,18 @@
 #include "antiword.h"
 
 
+/*
+ * Private structure to hide the way the information
+ * is stored from the rest of the program
+ */
+typedef struct font_desc_tag {
+	font_block_type tInfo;
+	struct font_desc_tag    *pNext;
+} font_mem_type;
+
 /* Variables needed to write the Font Information List */
-static font_desc_type	*pAnchor = NULL;
-static font_desc_type	*pFontLast = NULL;
+static font_mem_type	*pAnchor = NULL;
+static font_mem_type	*pFontLast = NULL;
 
 
 /*
@@ -22,7 +31,7 @@ static font_desc_type	*pFontLast = NULL;
 void
 vDestroyFontInfoList(void)
 {
-	font_desc_type	*pCurr, *pNext;
+	font_mem_type	*pCurr, *pNext;
 
 	DBG_MSG("vDestroyFontInfoList");
 
@@ -83,7 +92,7 @@ vCorrectFontValues(font_block_type *pFontBlock)
 void
 vAdd2FontInfoList(const font_block_type *pFontBlock)
 {
-	font_desc_type	*pListMember;
+	font_mem_type	*pListMember;
 
 	fail(pFontBlock == NULL);
 
@@ -119,7 +128,7 @@ vAdd2FontInfoList(const font_block_type *pFontBlock)
 	}
 
 	/* Create list member */
-	pListMember = xmalloc(sizeof(font_desc_type));
+	pListMember = xmalloc(sizeof(font_mem_type));
 	/* Fill the list member */
 	pListMember->tInfo = *pFontBlock;
 	pListMember->pNext = NULL;
@@ -141,7 +150,7 @@ vAdd2FontInfoList(const font_block_type *pFontBlock)
 const font_block_type *
 pGetNextFontInfoListItem(const font_block_type *pCurr)
 {
-	const font_desc_type	*pRecord;
+	const font_mem_type	*pRecord;
 	size_t	tOffset;
 
 	if (pCurr == NULL) {
@@ -152,9 +161,9 @@ pGetNextFontInfoListItem(const font_block_type *pCurr)
 		/* The first record is the only one without a predecessor */
 		return &pAnchor->tInfo;
 	}
-	tOffset = offsetof(font_desc_type, tInfo);
+	tOffset = offsetof(font_mem_type, tInfo);
 	/* Many casts to prevent alignment warnings */
-	pRecord = (font_desc_type *)(void *)((char *)pCurr - tOffset);
+	pRecord = (font_mem_type *)(void *)((char *)pCurr - tOffset);
 	fail(pCurr != &pRecord->tInfo);
 	if (pRecord->pNext == NULL) {
 		/* The last record has no successor */

+ 243 - 74
sys/src/cmd/aux/antiword/fonts.c

@@ -1,6 +1,6 @@
 /*
  * fonts.c
- * Copyright (C) 1998-2002 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Functions to deal with fonts (generic)
@@ -85,6 +85,55 @@ iFontname2Fontnumber(const char *szOurFontname, USHORT usFontStyle)
 	return -1;
 } /* end of iFontname2Fontnumber */
 
+/*
+ * szGetDefaultFont - get the default font that matches the parameters
+ */
+static const char *
+szGetDefaultFont(UCHAR ucFFN, int iEmphasis)
+{
+	UCHAR	ucPrq, ucFf;
+
+	fail(iEmphasis < 0 || iEmphasis > 3);
+
+	ucPrq = ucFFN & 0x03;
+	ucFf = (ucFFN & 0x70) >> 4;
+	NO_DBG_DEC(ucPrq);
+	NO_DBG_DEC(ucFf);
+	if (ucPrq == PITCH_FIXED) {
+		/* Set to the default monospaced font */
+		switch (iEmphasis) {
+		case 1: return FONT_MONOSPACED_BOLD;
+		case 2: return FONT_MONOSPACED_ITALIC;
+		case 3: return FONT_MONOSPACED_BOLDITALIC;
+		default: return FONT_MONOSPACED_PLAIN;
+		}
+	} else if (ucFf == FAMILY_ROMAN) {
+		/* Set to the default serif font */
+		switch (iEmphasis) {
+		case 1: return FONT_SERIF_BOLD;
+		case 2: return FONT_SERIF_ITALIC;
+		case 3: return FONT_SERIF_BOLDITALIC;
+		default: return FONT_SERIF_PLAIN;
+		}
+	} else if (ucFf == FAMILY_SWISS) {
+		/* Set to the default sans serif font */
+		switch (iEmphasis) {
+		case 1: return FONT_SANS_SERIF_BOLD;
+		case 2: return FONT_SANS_SERIF_ITALIC;
+		case 3: return FONT_SANS_SERIF_BOLDITALIC;
+		default: return FONT_SANS_SERIF_PLAIN;
+		}
+	} else {
+		/* Set to the default default font */
+		switch (iEmphasis) {
+		case 1: return FONT_SERIF_BOLD;
+		case 2: return FONT_SERIF_ITALIC;
+		case 3: return FONT_SERIF_BOLDITALIC;
+		default: return FONT_SERIF_PLAIN;
+		}
+	}
+} /* end of szGetDefaultFont */
+
 /*
  * See if the fontname from the Word file matches the fontname from the
  * font translation file.
@@ -112,7 +161,7 @@ bFontEqual(const UCHAR *aucWord, const char *szTable, int iBytesPerChar)
 } /* end of bFontEqual */
 
 /*
- *
+ * vFontname2Table - add fontnames to the font table
  */
 static void
 vFontname2Table(const UCHAR *aucFont, const UCHAR *aucAltFont,
@@ -121,7 +170,6 @@ vFontname2Table(const UCHAR *aucFont, const UCHAR *aucAltFont,
 	font_table_type *pFontTableRecord)
 {
 	BOOL	bMatchFound;
-	UCHAR	ucPrq, ucFf;
 
 	fail(aucFont == NULL || aucFont[0] == 0);
 	fail(aucAltFont != NULL && aucAltFont[0] == 0);
@@ -145,38 +193,7 @@ vFontname2Table(const UCHAR *aucFont, const UCHAR *aucAltFont,
 		 * szWordFont contains a "*", so szOurFont will contain the
 		 * "default default" font. See if we can do better than that.
 		 */
-		ucPrq = ucFFN & 0x03;
-		ucFf = (ucFFN & 0x70) >> 4;
-		NO_DBG_DEC(ucPrq);
-		NO_DBG_DEC(ucFf);
-		if (ucPrq == PITCH_FIXED) {
-			/* Set to the default monospaced font */
-			switch (iEmphasis) {
-			case 0: szOurFont = FONT_MONOSPACED_PLAIN; break;
-			case 1: szOurFont = FONT_MONOSPACED_BOLD; break;
-			case 2: szOurFont = FONT_MONOSPACED_ITALIC; break;
-			case 3: szOurFont = FONT_MONOSPACED_BOLDITALIC; break;
-			default: break;
-			}
-		} else if (ucFf == FAMILY_ROMAN) {
-			/* Set to the default serif font */
-			switch (iEmphasis) {
-			case 0: szOurFont = FONT_SERIF_PLAIN; break;
-			case 1: szOurFont = FONT_SERIF_BOLD; break;
-			case 2: szOurFont = FONT_SERIF_ITALIC; break;
-			case 3: szOurFont = FONT_SERIF_BOLDITALIC; break;
-			default: break;
-			}
-		} else if (ucFf == FAMILY_SWISS) {
-			/* Set to the default sans serif font */
-			switch (iEmphasis) {
-			case 0: szOurFont = FONT_SANS_SERIF_PLAIN; break;
-			case 1: szOurFont = FONT_SANS_SERIF_BOLD; break;
-			case 2: szOurFont = FONT_SANS_SERIF_ITALIC; break;
-			case 3: szOurFont = FONT_SANS_SERIF_BOLDITALIC; break;
-			default: break;
-			}
-		}
+		szOurFont = szGetDefaultFont(ucFFN, iEmphasis);
 		bMatchFound = TRUE;
 	}
 
@@ -205,6 +222,8 @@ vFontname2Table(const UCHAR *aucFont, const UCHAR *aucAltFont,
 			sizeof(pFontTableRecord->szOurFontname) - 1] = '\0';
 		NO_DBG_MSG(pFontTableRecord->szWordFontname);
 		NO_DBG_MSG(pFontTableRecord->szOurFontname);
+		pFontTableRecord->ucFFN = ucFFN;
+		pFontTableRecord->ucEmphasis = (UCHAR)iEmphasis;
 	}
 } /* end of vFontname2Table */
 
@@ -270,6 +289,9 @@ vMinimizeFontTable(void)
 		return;
 	}
 
+	/* See if we must add a font for our tables */
+	bMustAddTableFont = TRUE;
+
 #if 0
 	DBG_MSG("Before");
 	DBG_DEC(tFontTableRecords);
@@ -283,13 +305,12 @@ vMinimizeFontTable(void)
 	}
 #endif /* DEBUG */
 
+	/* See which fonts/styles we really need */
+
 	/* Default font/style is by definition in use */
 	pFontTable[0].ucInUse = 1;
 
-	/* See which fonts/styles are really being used */
-	bMustAddTableFont = TRUE;
-
-	/* The fonts/styles that will be used */
+	/* Make InUse 1 for all the fonts/styles that WILL be used */
 	pFont = NULL;
 	while((pFont = pGetNextFontInfoListItem(pFont)) != NULL) {
 		pTmp = pFontTable + 4 * (int)pFont->ucFontNumber;
@@ -309,7 +330,7 @@ vMinimizeFontTable(void)
 		pTmp->ucInUse = 1;
 	}
 
-	/* The fonts/styles that might be used */
+	/* Make InUse 1 for all the fonts/styles that MIGHT be used */
 	pStyle = NULL;
 	while((pStyle = pGetNextStyleInfoListItem(pStyle)) != NULL) {
 		vFillFontFromStylesheet(pStyle->usIstdNext, &tFontNext);
@@ -345,11 +366,13 @@ vMinimizeFontTable(void)
 			*(pTmp - iUnUsed) = *pTmp;
 		}
 	}
+	fail(iUnUsed < 0);
+	fail(tFontTableRecords <= (size_t)iUnUsed);
 	tFontTableRecords -= (size_t)iUnUsed;
-	fail(tFontTableRecords == 0);
 
 	if (bMustAddTableFont) {
 		pTmp = pFontTable + tFontTableRecords;
+		fail(pTmp <= pFontTable);
 		pTmp->ucWordFontNumber = (pTmp - 1)->ucWordFontNumber + 1;
 		pTmp->usFontStyle = FONT_REGULAR;
 		pTmp->ucInUse = 1;
@@ -460,6 +483,9 @@ vCreate0FontTable(void)
 	vCreateFontTable();
 
 	/* Read the font translation file */
+	iItalic = 0;
+	iBold = 0;
+	iSpecial = 0;
 	while (bReadFontFile(pFontTableFile, szWordFont,
 			&iItalic, &iBold, szOurFont, &iSpecial)) {
 		iEmphasis = 0;
@@ -494,7 +520,7 @@ vCreate0FontTable(void)
  * vCreate2FontTable - create a font table from WinWord 1/2
  */
 void
-vCreate2FontTable(FILE *pFile, const UCHAR *aucHeader)
+vCreate2FontTable(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 {
 	FILE	*pFontTableFile;
 	font_table_type	*pTmp;
@@ -502,12 +528,13 @@ vCreate2FontTable(FILE *pFile, const UCHAR *aucHeader)
 	UCHAR	*aucBuffer;
 	ULONG	ulBeginFontInfo;
 	size_t	tFontInfoLen;
-	int	iPos, iRecLen;
+	int	iPos, iOff, iRecLen;
 	int	iBold, iItalic, iSpecial, iEmphasis;
 	UCHAR	ucFFN;
 	char	szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH];
 
 	fail(pFile == NULL || aucHeader == NULL);
+	fail(iWordVersion != 1 && iWordVersion != 2);
 
 	tFontTableRecords = 0;
 	pFontTable = xfree(pFontTable);
@@ -522,11 +549,10 @@ vCreate2FontTable(FILE *pFile, const UCHAR *aucHeader)
 	DBG_HEX(ulBeginFontInfo);
 	tFontInfoLen = (size_t)usGetWord(0xb6, aucHeader); /* cbSttbfffn */
 	DBG_DEC(tFontInfoLen);
-	fail(tFontInfoLen < 6);
 
-	if (ulBeginFontInfo > (ULONG)LONG_MAX) {
+	if (ulBeginFontInfo > (ULONG)LONG_MAX || tFontInfoLen == 0) {
 		/* Don't ask me why this is needed */
-		DBG_HEX(ulBeginFontInfo);
+		DBG_HEX_C(tFontInfoLen != 0, ulBeginFontInfo);
 		(void)fclose(pFontTableFile);
 		return;
 	}
@@ -541,20 +567,74 @@ vCreate2FontTable(FILE *pFile, const UCHAR *aucHeader)
 	DBG_DEC(usGetWord(0, aucBuffer));
 
 	/* Compute the maximum number of entries in the font table */
-	tFontTableRecords = 0;
+	if (iWordVersion == 1) {
+		fail(tFontInfoLen < 2);
+		/* WinWord 1 has three implicit fonts */
+		tFontTableRecords = 3;
+		iOff = 2;
+	} else {
+		fail(tFontInfoLen < 6);
+		/* WinWord 2 and up have no implicit fonts */
+		tFontTableRecords = 0;
+		iOff = 3;
+	}
 	iPos = 2;
-	while (iPos + 3 < (int)tFontInfoLen) {
+	while (iPos + iOff < (int)tFontInfoLen) {
 		iRecLen = (int)ucGetByte(iPos, aucBuffer);
 		NO_DBG_DEC(iRecLen);
-		NO_DBG_MSG(aucBuffer + iPos + 3);
+		NO_DBG_MSG(aucBuffer + iPos + iOff);
 		iPos += iRecLen + 1;
 		tFontTableRecords++;
 	}
-	tFontTableRecords *= 4;	/* Plain, Bold, Italic and Bold/italic */
+	tFontTableRecords *= 4;	/* Plain, Bold, Italic and Bold/Italic */
 	tFontTableRecords++;	/* One extra for the table-font */
 	vCreateFontTable();
 
+	/* Add the tree implicit fonts (in four variations) */
+	if (iWordVersion == 1) {
+		fail(tFontTableRecords < 13);
+		vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 0,
+			(UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE),
+			"*", "Times-Roman", pFontTable + 0);
+		vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 1,
+			(UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE),
+			"*", "Times-Bold", pFontTable + 1);
+		vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 2,
+			(UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE),
+			"*", "Times-Italic", pFontTable + 2);
+		vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 3,
+			(UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE),
+			"*", "Times-BoldItalic", pFontTable + 3);
+		vFontname2Table((UCHAR *)"Symbol", NULL, 1, 0,
+			(UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE),
+			"*", "Times-Roman", pFontTable + 4);
+		vFontname2Table((UCHAR *)"Symbol", NULL, 1, 1,
+			(UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE),
+			"*", "Times-Bold", pFontTable + 5);
+		vFontname2Table((UCHAR *)"Symbol", NULL, 1, 2,
+			(UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE),
+			"*", "Times-Italic", pFontTable + 6);
+		vFontname2Table((UCHAR *)"Symbol", NULL, 1, 3,
+			(UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE),
+			"*", "Times-BoldItalic", pFontTable + 7);
+		vFontname2Table((UCHAR *)"Helv", NULL, 1, 0,
+			(UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE),
+			"*", "Helvetica", pFontTable + 8);
+		vFontname2Table((UCHAR *)"Helv", NULL, 1, 1,
+			(UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE),
+			"*", "Helvetica-Bold", pFontTable + 9);
+		vFontname2Table((UCHAR *)"Helv", NULL, 1, 2,
+			(UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE),
+			"*", "Helvetica-Oblique", pFontTable + 10);
+		vFontname2Table((UCHAR *)"Helv", NULL, 1, 3,
+			(UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE),
+			"*", "Helvetica-BoldOblique", pFontTable + 11);
+	}
+
 	/* Read the font translation file */
+	iItalic = 0;
+	iBold = 0;
+	iSpecial = 0;
 	while (bReadFontFile(pFontTableFile, szWordFont,
 			&iItalic, &iBold, szOurFont, &iSpecial)) {
 		iEmphasis = 0;
@@ -566,10 +646,10 @@ vCreate2FontTable(FILE *pFile, const UCHAR *aucHeader)
 		}
 		pTmp = pFontTable + iEmphasis;
 		iPos = 2;
-		while (iPos + 3 < (int)tFontInfoLen) {
+		while (iPos + iOff < (int)tFontInfoLen) {
 			iRecLen = (int)ucGetByte(iPos, aucBuffer);
 			ucFFN = ucGetByte(iPos + 1, aucBuffer);
-			aucFont = aucBuffer + iPos + 3;
+			aucFont = aucBuffer + iPos + iOff;
 			vFontname2Table(aucFont, NULL, 1, iEmphasis,
 					ucFFN, szWordFont, szOurFont, pTmp);
 			pTmp += 4;
@@ -647,6 +727,9 @@ vCreate6FontTable(FILE *pFile, ULONG ulStartBlock,
 	vCreateFontTable();
 
 	/* Read the font translation file */
+	iItalic = 0;
+	iBold = 0;
+	iSpecial = 0;
 	while (bReadFontFile(pFontTableFile, szWordFont,
 			&iItalic, &iBold, szOurFont, &iSpecial)) {
 		iEmphasis = 0;
@@ -696,11 +779,9 @@ vCreate8FontTable(FILE *pFile, const pps_info_type *pPPS,
 	UCHAR	*aucFont, *aucAltFont;
 	UCHAR	*aucBuffer;
 	ULONG	ulBeginFontInfo;
-	ULONG	ulTableSize, ulTableStartBlock;
 	size_t	tFontInfoLen, tBlockDepotLen, tBlockSize;
 	int	iPos, iRecLen, iOffsetAltName;
 	int	iBold, iItalic, iSpecial, iEmphasis;
-	USHORT	usDocStatus;
 	UCHAR	ucFFN;
 	char	szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH];
 
@@ -722,24 +803,15 @@ vCreate8FontTable(FILE *pFile, const pps_info_type *pPPS,
 	DBG_DEC(tFontInfoLen);
 	fail(tFontInfoLen < 46);
 
-	/* Use 0Table or 1Table? */
-	usDocStatus = usGetWord(0x0a, aucHeader);
-	if (usDocStatus & BIT(9)) {
-		ulTableStartBlock = pPPS->t1Table.ulSB;
-		ulTableSize = pPPS->t1Table.ulSize;
-	} else {
-		ulTableStartBlock = pPPS->t0Table.ulSB;
-		ulTableSize = pPPS->t0Table.ulSize;
-	}
-	DBG_DEC(ulTableStartBlock);
-	if (ulTableStartBlock == 0) {
-		DBG_DEC(ulTableStartBlock);
+	DBG_DEC(pPPS->tTable.ulSB);
+	DBG_HEX(pPPS->tTable.ulSize);
+	if (pPPS->tTable.ulSize == 0) {
 		DBG_MSG("No fontname table");
 		(void)fclose(pFontTableFile);
 		return;
 	}
-	DBG_HEX(ulTableSize);
-	if (ulTableSize < MIN_SIZE_FOR_BBD_USE) {
+
+	if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
 		/* Use the Small Block Depot */
 		aulBlockDepot = aulSBD;
 		tBlockDepotLen = tSBDLen;
@@ -751,7 +823,7 @@ vCreate8FontTable(FILE *pFile, const pps_info_type *pPPS,
 		tBlockSize = BIG_BLOCK_SIZE;
 	}
 	aucBuffer = xmalloc(tFontInfoLen);
-	if (!bReadBuffer(pFile, ulTableStartBlock,
+	if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
 			aulBlockDepot, tBlockDepotLen, tBlockSize,
 			aucBuffer, ulBeginFontInfo, tFontInfoLen)) {
 		aucBuffer = xfree(aucBuffer);
@@ -767,6 +839,9 @@ vCreate8FontTable(FILE *pFile, const pps_info_type *pPPS,
 	vCreateFontTable();
 
 	/* Read the font translation file */
+	iItalic = 0;
+	iBold = 0;
+	iSpecial = 0;
 	while (bReadFontFile(pFontTableFile, szWordFont,
 			&iItalic, &iBold, szOurFont, &iSpecial)) {
 		iEmphasis = 0;
@@ -821,17 +896,25 @@ vDestroyFontTable(void)
 const font_table_type *
 pGetNextFontTableRecord(const font_table_type *pRecordCurr)
 {
-	int	iIndexCurr;
+	size_t	tIndexCurr;
 
 	if (pRecordCurr == NULL) {
-		/* No current record, so start with the first */
+		/* No current record, so start with the first one */
 		return &pFontTable[0];
 	}
 
-	iIndexCurr = pRecordCurr - pFontTable;
-	if (iIndexCurr + 1 < (int)tFontTableRecords) {
+	if (pRecordCurr < pFontTable ||
+	    pRecordCurr >= pFontTable + tFontTableRecords) {
+		/* Not a pointer in the array */
+		DBG_HEX(pRecordCurr);
+		DBG_HEX(pFontTable);
+		return NULL;
+	}
+
+	tIndexCurr = (size_t)(pRecordCurr - pFontTable);
+	if (tIndexCurr + 1 < tFontTableRecords) {
 		/* There is a next record, so return it */
-		return &pFontTable[iIndexCurr + 1];
+		return &pFontTable[tIndexCurr + 1];
 	}
 	/* There is no next record */
 	return NULL;
@@ -847,3 +930,89 @@ tGetFontTableLength(void)
 {
 	return tFontTableRecords;
 } /* end of tGetFontTableLength */
+
+#if !defined(__riscos)
+/*
+ * vCorrect4PDF - only include PDF default fonts
+ */
+static void
+vCorrect4PDF(void)
+{
+	font_table_type	*pTmp;
+	const char	*szOurFont;
+
+	for (pTmp = pFontTable; pTmp < pFontTable + tFontTableRecords; pTmp++) {
+		if (STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_PLAIN) ||
+		    STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_BOLD) ||
+		    STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_ITALIC) ||
+		    STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_BOLDITALIC) ||
+		    STRCEQ(pTmp->szOurFontname, FONT_SERIF_PLAIN) ||
+		    STRCEQ(pTmp->szOurFontname, FONT_SERIF_BOLD) ||
+		    STRCEQ(pTmp->szOurFontname, FONT_SERIF_ITALIC) ||
+		    STRCEQ(pTmp->szOurFontname, FONT_SERIF_BOLDITALIC) ||
+		    STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_PLAIN) ||
+		    STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_BOLD) ||
+		    STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_ITALIC) ||
+		    STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_BOLDITALIC)) {
+			/* Already a default font */
+			continue;
+		}
+		szOurFont =
+			szGetDefaultFont(pTmp->ucFFN, (int)pTmp->ucEmphasis);
+		(void)strncpy(pTmp->szOurFontname, szOurFont,
+			sizeof(pTmp->szOurFontname) - 1);
+		pTmp->szOurFontname[sizeof(pTmp->szOurFontname) - 1] = '\0';
+	}
+} /* end of vCorrect4PDF */
+
+/*
+ * vCorrect4CyrPS - only include monospaced fonts
+ */
+static void
+vCorrect4CyrPS(void)
+{
+	font_table_type	*pTmp;
+	const char	*szOurFont;
+	UCHAR	ucFFN;
+
+	ucFFN = (FAMILY_UNKNOWN << 4) | PITCH_FIXED;
+	for (pTmp = pFontTable; pTmp < pFontTable + tFontTableRecords; pTmp++) {
+		szOurFont = szGetDefaultFont(ucFFN, (int)pTmp->ucEmphasis);
+		(void)strncpy(pTmp->szOurFontname, szOurFont,
+			sizeof(pTmp->szOurFontname) - 1);
+		pTmp->szOurFontname[sizeof(pTmp->szOurFontname) - 1] = '\0';
+	}
+} /* end of vCorrect4CyrPS */
+#endif /* __riscos */
+
+/*
+ * vCorrectFontTable - correct the font table in special cases
+ */
+void
+vCorrectFontTable(conversion_type eConversionType, encoding_type eEncoding)
+{
+#if !defined(__riscos)
+	if (eConversionType == conversion_pdf) {
+		vCorrect4PDF();
+	}
+	if (eConversionType == conversion_ps &&
+	    eEncoding == encoding_cyrillic) {
+		vCorrect4CyrPS();
+	}
+#endif /* __riscos */
+} /* end of vCorrectFontTable */
+
+/*
+ * lComputeSpaceWidth - compute the width of a space character
+ *
+ * Returns the space width in millipoints
+ */
+long
+lComputeSpaceWidth(drawfile_fontref tFontRef, USHORT usFontSize)
+{
+	char	szSpace[] = " ";
+
+	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
+
+        return lComputeStringWidth(szSpace, 1, tFontRef, usFontSize);
+} /* end of lComputeSpaceWidth */

+ 21 - 19
sys/src/cmd/aux/antiword/fonts_r.c

@@ -8,9 +8,11 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include "DeskLib:Font.h"
+#include "drawfile.h"
 #include "antiword.h"
 
-static font		tFontCurr = (font)-1;
+static font_handle	tFontCurr = (font_handle)-1;
 
 /*
  * pOpenFontTableFile - open the Font translation file
@@ -97,14 +99,14 @@ vCloseFont(void)
 
 	NO_DBG_MSG("vCloseFont");
 
-	if (tFontCurr == (font)-1) {
+	if (tFontCurr == (font_handle)-1) {
 		return;
 	}
-	e = font_lose(tFontCurr);
+	e = Font_LoseFont(tFontCurr);
 	if (e != NULL) {
 		werr(0, "Close font error %d: %s", e->errnum, e->errmess);
 	}
-	tFontCurr = -1;
+	tFontCurr = (font_handle)-1;
 } /* end of vCloseFont */
 
 /*
@@ -112,12 +114,12 @@ vCloseFont(void)
  *
  * Returns the font reference number for use in a draw file
  */
-draw_fontref
+drawfile_fontref
 tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
 {
 	os_error	*e;
 	const char	*szOurFontname;
-	font	tFont;
+	font_handle	tFont;
 	int	iFontnumber;
 
 	NO_DBG_MSG("tOpenFont");
@@ -132,13 +134,13 @@ tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
 	iFontnumber = iGetFontByNumber(ucWordFontNumber, usFontStyle);
 	szOurFontname = szGetOurFontname(iFontnumber);
 	if (szOurFontname == NULL || szOurFontname[0] == '\0') {
-		tFontCurr = (font)-1;
-		return (draw_fontref)0;
+		tFontCurr = (font_handle)-1;
+		return (byte)0;
 	}
 	NO_DBG_MSG(szOurFontname);
-	e = font_find((char *)szOurFontname,
+	e = Font_FindFont(&tFont, (char *)szOurFontname,
 			(int)usWordFontSize * 8, (int)usWordFontSize * 8,
-			0, 0, &tFont);
+			0, 0);
 	if (e != NULL) {
 		switch (e->errnum) {
 		case 523:
@@ -149,12 +151,12 @@ tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
 				e->errnum, e->errmess);
 			break;
 		}
-		tFontCurr = (font)-1;
-		return (draw_fontref)0;
+		tFontCurr = (font_handle)-1;
+		return (drawfile_fontref)0;
 	}
 	tFontCurr = tFont;
 	NO_DBG_DEC(tFontCurr);
-	return (draw_fontref)(iFontnumber + 1);
+	return (drawfile_fontref)(iFontnumber + 1);
 } /* end of tOpenFont */
 
 /*
@@ -162,7 +164,7 @@ tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
  *
  * Returns the font reference number for use in a draw file
  */
-draw_fontref
+drawfile_fontref
 tOpenTableFont(USHORT usWordFontSize)
 {
 	int	iWordFontnumber;
@@ -172,8 +174,8 @@ tOpenTableFont(USHORT usWordFontSize)
 	iWordFontnumber = iFontname2Fontnumber(TABLE_FONT, FONT_REGULAR);
 	if (iWordFontnumber < 0 || iWordFontnumber > (int)UCHAR_MAX) {
 		DBG_DEC(iWordFontnumber);
-		tFontCurr = (font)-1;
-		return (draw_fontref)0;
+		tFontCurr = (font_handle)-1;
+		return (drawfile_fontref)0;
 	}
 
 	return tOpenFont((UCHAR)iWordFontnumber, FONT_REGULAR, usWordFontSize);
@@ -186,7 +188,7 @@ tOpenTableFont(USHORT usWordFontSize)
  */
 long
 lComputeStringWidth(const char *szString, size_t tStringLength,
-		draw_fontref tFontRef, USHORT usFontSize)
+	drawfile_fontref tFontRef, USHORT usFontSize)
 {
 	font_string	tStr;
 	os_error	*e;
@@ -202,7 +204,7 @@ lComputeStringWidth(const char *szString, size_t tStringLength,
 		/* Font_strwidth doesn't like control characters */
 		return 0;
 	}
-	if (tFontCurr == (font)-1) {
+	if (tFontCurr == (font_handle)-1) {
 		/* No current font, use systemfont */
 		return lChar2MilliPoints(tStringLength);
 	}
@@ -211,7 +213,7 @@ lComputeStringWidth(const char *szString, size_t tStringLength,
 	tStr.y = INT_MAX;
 	tStr.split = -1;
 	tStr.term = tStringLength;
-	e = font_strwidth(&tStr);
+	e = Font_StringWidth(&tStr);
 	if (e == NULL) {
 		return (long)tStr.x;
 	}

+ 54 - 36
sys/src/cmd/aux/antiword/fonts_u.c

@@ -1,6 +1,6 @@
 /*
  * fonts_u.c
- * Copyright (C) 1999-2002 A.J. van Os; Released under GPL
+ * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Functions to deal with fonts (Unix version)
@@ -27,11 +27,13 @@ FILE *
 pOpenFontTableFile(void)
 {
 	FILE		*pFile;
-	const char	*szHome, *szAntiword;
-	const char	*szGlobalFile;
+	const char	*szHome, *szAntiword, *szGlobalFile;
 	char		szEnvironmentFile[PATH_MAX+1];
 	char		szLocalFile[PATH_MAX+1];
 
+	szEnvironmentFile[0] = '\0';
+	szLocalFile[0] = '\0';
+
 	/* Try the environment version of the fontnames file */
 	szAntiword = szGetAntiwordDirectory();
 	if (szAntiword != NULL && szAntiword[0] != '\0') {
@@ -47,7 +49,7 @@ pOpenFontTableFile(void)
 			FILE_SEPARATOR FONTNAMES_FILE);
 		DBG_MSG(szEnvironmentFile);
 
-		pFile = fopen(szLocalFile, "r");
+		pFile = fopen(szEnvironmentFile, "r");
 		if (pFile != NULL) {
 			return pFile;
 		}
@@ -81,10 +83,18 @@ pOpenFontTableFile(void)
 		return pFile;
 	}
 
-	werr(0, "I can not open your fontnames file.\n"
-		"Neither '%s' nor\n"
-		"'%s' can be opened for reading.",
-		szLocalFile, szGlobalFile);
+	if (szEnvironmentFile[0] != '\0') {
+		werr(0, "I can not open your fontnames file.\n"
+			"Neither '%s' nor\n"
+			"'%s' nor\n"
+			"'%s' can be opened for reading.",
+			szEnvironmentFile, szLocalFile, szGlobalFile);
+	} else {
+		werr(0, "I can not open your fontnames file.\n"
+			"Neither '%s' nor\n"
+			"'%s' can be opened for reading.",
+			szLocalFile, szGlobalFile);
+	}
 	return NULL;
 } /* end of pOpenFontTableFile */
 
@@ -96,8 +106,8 @@ vCloseFont(void)
 {
 	NO_DBG_MSG("vCloseFont");
 	/* For safety: to be overwritten at the next call of tOpenfont() */
-	bUsePlainText = TRUE;
 	eEncoding = encoding_neutral;
+	bUsePlainText = TRUE;
 } /* end of vCloseFont */
 
 /*
@@ -105,12 +115,13 @@ vCloseFont(void)
  *
  * Returns the font reference number
  */
-draw_fontref
+drawfile_fontref
 tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
 {
 	options_type	tOptions;
 	const char	*szOurFontname;
-	int	iIndex, iFontnumber;
+	size_t	tIndex;
+	int	iFontnumber;
 
 	NO_DBG_MSG("tOpenFont");
 	NO_DBG_DEC(ucWordFontNumber);
@@ -122,30 +133,31 @@ tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
 	NO_DBG_HEX(usFontStyle);
 
 	vGetOptions(&tOptions);
-	bUsePlainText = tOptions.eConversionType != conversion_draw &&
-			tOptions.eConversionType != conversion_ps;
 	eEncoding = tOptions.eEncoding;
+	bUsePlainText = tOptions.eConversionType != conversion_draw &&
+			tOptions.eConversionType != conversion_ps &&
+			tOptions.eConversionType != conversion_pdf;
 
 	if (bUsePlainText) {
 		/* Plain text, no fonts */
-		return (draw_fontref)0;
+		return (drawfile_fontref)0;
 	}
 
 	iFontnumber = iGetFontByNumber(ucWordFontNumber, usFontStyle);
 	szOurFontname = szGetOurFontname(iFontnumber);
 	if (szOurFontname == NULL || szOurFontname[0] == '\0') {
 		DBG_DEC(iFontnumber);
-		return (draw_fontref)0;
+		return (drawfile_fontref)0;
 	}
 	NO_DBG_MSG(szOurFontname);
 
-	for (iIndex = 0; iIndex < (int)elementsof(szFontnames); iIndex++) {
-		if (STREQ(szFontnames[iIndex], szOurFontname)) {
-			NO_DBG_DEC(iIndex);
-			return (draw_fontref)iIndex;
+	for (tIndex = 0; tIndex < elementsof(szFontnames); tIndex++) {
+		if (STREQ(szFontnames[tIndex], szOurFontname)) {
+			NO_DBG_DEC(tIndex);
+			return (drawfile_fontref)tIndex;
 		}
 	}
-	return (draw_fontref)0;
+	return (drawfile_fontref)0;
 } /* end of tOpenFont */
 
 /*
@@ -153,7 +165,7 @@ tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
  *
  * Returns the font reference number
  */
-draw_fontref
+drawfile_fontref
 tOpenTableFont(USHORT usWordFontSize)
 {
 	options_type	tOptions;
@@ -162,19 +174,20 @@ tOpenTableFont(USHORT usWordFontSize)
 	NO_DBG_MSG("tOpenTableFont");
 
 	vGetOptions(&tOptions);
-	bUsePlainText = tOptions.eConversionType != conversion_draw &&
-			tOptions.eConversionType != conversion_ps;
 	eEncoding = tOptions.eEncoding;
+	bUsePlainText = tOptions.eConversionType != conversion_draw &&
+			tOptions.eConversionType != conversion_ps &&
+			tOptions.eConversionType != conversion_pdf;
 
 	if (bUsePlainText) {
 		/* Plain text, no fonts */
-		return (draw_fontref)0;
+		return (drawfile_fontref)0;
 	}
 
 	iWordFontnumber = iFontname2Fontnumber(TABLE_FONT, FONT_REGULAR);
 	if (iWordFontnumber < 0 || iWordFontnumber > (int)UCHAR_MAX) {
 		DBG_DEC(iWordFontnumber);
-		return (draw_fontref)0;
+		return (drawfile_fontref)0;
 	}
 
 	return tOpenFont((UCHAR)iWordFontnumber, FONT_REGULAR, usWordFontSize);
@@ -184,7 +197,7 @@ tOpenTableFont(USHORT usWordFontSize)
  * szGetFontname - get the fontname
  */
 const char *
-szGetFontname(draw_fontref tFontRef)
+szGetFontname(drawfile_fontref tFontRef)
 {
 	fail((size_t)(UCHAR)tFontRef >= elementsof(szFontnames));
 	return szFontnames[(int)(UCHAR)tFontRef];
@@ -200,7 +213,7 @@ szGetFontname(draw_fontref tFontRef)
  */
 long
 lComputeStringWidth(const char *szString, size_t tStringLength,
-		draw_fontref tFontRef, USHORT usFontSize)
+	drawfile_fontref tFontRef, USHORT usFontSize)
 {
 	USHORT	*ausCharWidths;
 	UCHAR	*pucChar;
@@ -216,7 +229,7 @@ lComputeStringWidth(const char *szString, size_t tStringLength,
 		return 0;
 	}
 
-	if (eEncoding == encoding_utf8) {
+	if (eEncoding == encoding_utf_8) {
 		fail(!bUsePlainText);
 		return lChar2MilliPoints(
 			utf8_strwidth(szString, tStringLength));
@@ -227,14 +240,19 @@ lComputeStringWidth(const char *szString, size_t tStringLength,
 		return lChar2MilliPoints(tStringLength);
 	}
 
-	DBG_DEC_C(eEncoding != encoding_iso_8859_1 &&
-		eEncoding != encoding_iso_8859_2, eEncoding);
-	fail(eEncoding != encoding_iso_8859_1 &&
-		eEncoding != encoding_iso_8859_2);
+	if (eEncoding == encoding_cyrillic) {
+		/* FIXME: until the character tables are available */
+		return (tStringLength * 600L * (long)usFontSize + 1) / 2;
+	}
+
+	DBG_DEC_C(eEncoding != encoding_latin_1 &&
+		eEncoding != encoding_latin_2, eEncoding);
+	fail(eEncoding != encoding_latin_1 &&
+		eEncoding != encoding_latin_2);
 
 	/* Compute the relative string width */
 	iFontRef = (int)(UCHAR)tFontRef;
-	if (eEncoding == encoding_iso_8859_2) {
+	if (eEncoding == encoding_latin_2) {
 		ausCharWidths = ausCharacterWidths2[iFontRef];
 	} else {
 		ausCharWidths = ausCharacterWidths1[iFontRef];
@@ -247,7 +265,7 @@ lComputeStringWidth(const char *szString, size_t tStringLength,
 	}
 
 	/* Compute the absolute string width */
-	return (lRelWidth * usFontSize + 1) / 2;
+	return (lRelWidth * (long)usFontSize + 1) / 2;
 } /* end of lComputeStringWidth */
 
 /*
@@ -263,7 +281,7 @@ tCountColumns(const char *szString, size_t tLength)
 {
 	fail(szString == NULL);
 
-	if (eEncoding != encoding_utf8) {
+	if (eEncoding != encoding_utf_8) {
 		/* One byte, one character, one column */
 		return tLength;
 	}
@@ -280,7 +298,7 @@ tGetCharacterLength(const char *szString)
 {
 	fail(szString == NULL);
 
-	if (eEncoding != encoding_utf8) {
+	if (eEncoding != encoding_utf_8) {
 		return 1;
 	}
 	return (size_t)utf8_chrlength(szString);

+ 371 - 0
sys/src/cmd/aux/antiword/hdrftrlist.c

@@ -0,0 +1,371 @@
+/*
+ * hdrftrlist.c
+ * Copyright (C) 2004,2005 A.J. van Os; Released under GNU GPL
+ *
+ * Description:
+ * Build, read and destroy list(s) of Word Header/footer information
+ */
+
+#include <string.h>
+#include "antiword.h"
+
+
+#define HDR_EVEN_PAGES	0
+#define HDR_ODD_PAGES	1
+#define FTR_EVEN_PAGES	2
+#define FTR_ODD_PAGES	3
+#define HDR_FIRST_PAGE	4
+#define FTR_FIRST_PAGE	5
+
+/*
+ * Private structures to hide the way the information
+ * is stored from the rest of the program
+ */
+typedef struct hdrftr_local_tag {
+	hdrftr_block_type	tInfo;
+	ULONG			ulCharPosStart;
+	ULONG			ulCharPosNext;
+	BOOL			bUseful;
+	BOOL			bTextOriginal;
+} hdrftr_local_type;
+typedef struct hdrftr_mem_tag {
+	hdrftr_local_type	atElement[6];
+} hdrftr_mem_type;
+
+/* Variables needed to write the Header/footer Information List */
+static hdrftr_mem_type	*pHdrFtrList = NULL;
+static size_t		tHdrFtrLen = 0;
+
+
+/*
+ * vDestroyHdrFtrInfoList - destroy the Header/footer Information List
+ */
+void
+vDestroyHdrFtrInfoList(void)
+{
+	hdrftr_mem_type *pRecord;
+	output_type	*pCurr, *pNext;
+	size_t		tHdrFtr, tIndex;
+
+	DBG_MSG("vDestroyHdrFtrInfoList");
+
+	/* Free the Header/footer Information List */
+	for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
+		pRecord = pHdrFtrList + tHdrFtr;
+		for (tIndex = 0;
+		     tIndex < elementsof(pRecord->atElement);
+		     tIndex++) {
+			if (!pRecord->atElement[tIndex].bTextOriginal) {
+				continue;
+			}
+			pCurr = pRecord->atElement[tIndex].tInfo.pText;
+			while (pCurr != NULL) {
+				pCurr->szStorage = xfree(pCurr->szStorage);
+				pNext = pCurr->pNext;
+				pCurr = xfree(pCurr);
+				pCurr = pNext;
+			}
+		}
+	}
+	pHdrFtrList = xfree(pHdrFtrList);
+	/* Reset all control variables */
+	tHdrFtrLen = 0;
+} /* end of vDestroyHdrFtrInfoList */
+
+/*
+ * vCreat8HdrFtrInfoList - Create the Header/footer Information List
+ */
+void
+vCreat8HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength)
+{
+	hdrftr_mem_type	*pListMember;
+	size_t	tHdrFtr, tIndex, tMainIndex;
+
+	fail(aulCharPos == NULL);
+
+	DBG_DEC(tLength);
+	if (tLength <= 1) {
+		return;
+	}
+	tHdrFtrLen = tLength / 12;
+	if (tLength % 12 != 0 && tLength % 12 != 1) {
+		tHdrFtrLen++;
+	}
+	DBG_DEC(tHdrFtrLen);
+
+	pHdrFtrList = xcalloc(tHdrFtrLen, sizeof(hdrftr_mem_type));
+
+	for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
+		pListMember = pHdrFtrList + tHdrFtr;
+		for (tIndex = 0, tMainIndex = tHdrFtr * 12;
+		     tIndex < 6 && tMainIndex < tLength;
+		     tIndex++, tMainIndex++) {
+			pListMember->atElement[tIndex].tInfo.pText = NULL;
+			pListMember->atElement[tIndex].ulCharPosStart =
+						aulCharPos[tMainIndex];
+			if (tMainIndex + 1 < tLength) {
+				pListMember->atElement[tIndex].ulCharPosNext =
+					aulCharPos[tMainIndex + 1];
+			} else {
+				pListMember->atElement[tIndex].ulCharPosNext =
+					aulCharPos[tMainIndex];
+			}
+		}
+	}
+} /* end of vCreat8HdrFtrInfoList */
+
+/*
+ * vCreat6HdrFtrInfoList - Create the Header/footer Information List
+ */
+void
+vCreat6HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength)
+{
+	static const size_t	atIndex[] =
+		{ SIZE_T_MAX, SIZE_T_MAX, FTR_FIRST_PAGE, HDR_FIRST_PAGE,
+		  FTR_ODD_PAGES, FTR_EVEN_PAGES, HDR_ODD_PAGES, HDR_EVEN_PAGES,
+		};
+	hdrftr_mem_type	*pListMember;
+	size_t	tHdrFtr, tTmp, tIndex, tMainIndex, tBit;
+	UCHAR	ucDopSpecification, ucSepSpecification;
+
+	fail(aulCharPos == NULL);
+
+	DBG_DEC(tLength);
+	if (tLength <= 1) {
+		return;
+	}
+	tHdrFtrLen = tGetNumberOfSections();
+	if (tHdrFtrLen == 0) {
+		tHdrFtrLen = 1;
+	}
+	DBG_DEC(tHdrFtrLen);
+
+	pHdrFtrList = xcalloc(tHdrFtrLen, sizeof(hdrftr_mem_type));
+
+	/* Get the start index in aulCharPos */
+	ucDopSpecification = ucGetDopHdrFtrSpecification();
+	DBG_HEX(ucDopSpecification & 0xe0);
+	tMainIndex = 0;
+	for (tBit = 7; tBit >= 5; tBit--) {
+		if ((ucDopSpecification & BIT(tBit)) != 0) {
+			tMainIndex++;
+		}
+	}
+	DBG_DEC(tMainIndex);
+
+	for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
+		ucSepSpecification = ucGetSepHdrFtrSpecification(tHdrFtr);
+		DBG_HEX(ucSepSpecification & 0xfc);
+		pListMember = pHdrFtrList + tHdrFtr;
+		for (tTmp = 0;
+		     tTmp < elementsof(pListMember->atElement);
+		     tTmp++) {
+			pListMember->atElement[tTmp].tInfo.pText = NULL;
+		}
+		for (tBit = 7; tBit >= 2; tBit--) {
+			if (tMainIndex >= tLength) {
+				break;
+			}
+			if ((ucSepSpecification & BIT(tBit)) == 0) {
+				continue;
+			}
+			tIndex = atIndex[tBit];
+			fail(tIndex >= 6);
+			pListMember->atElement[tIndex].ulCharPosStart =
+				aulCharPos[tMainIndex];
+			if (tMainIndex + 1 < tLength) {
+				pListMember->atElement[tIndex].ulCharPosNext =
+					aulCharPos[tMainIndex + 1];
+			} else {
+				pListMember->atElement[tIndex].ulCharPosNext =
+					aulCharPos[tMainIndex];
+			}
+			tMainIndex++;
+		}
+	}
+} /* end of vCreat6HdrFtrInfoList */
+
+/*
+ * vCreat2HdrFtrInfoList - Create the Header/footer Information List
+ */
+void
+vCreat2HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength)
+{
+	vCreat6HdrFtrInfoList(aulCharPos, tLength);
+} /* end of vCreat2HdrFtrInfoList */
+
+/*
+ * pGetHdrFtrInfo - get the Header/footer information
+ */
+const hdrftr_block_type *
+pGetHdrFtrInfo(int iSectionIndex,
+	BOOL bWantHeader, BOOL bOddPage, BOOL bFirstInSection)
+{
+	hdrftr_mem_type	*pCurr;
+
+	fail(iSectionIndex < 0);
+	fail(pHdrFtrList == NULL && tHdrFtrLen != 0);
+
+	if (pHdrFtrList == NULL || tHdrFtrLen == 0) {
+		/* No information */
+		return NULL;
+	}
+
+	if (iSectionIndex < 0) {
+		iSectionIndex = 0;
+	} else if (iSectionIndex >= (int)tHdrFtrLen) {
+		iSectionIndex = (int)(tHdrFtrLen - 1);
+	}
+
+	pCurr = pHdrFtrList + iSectionIndex;
+
+	if (bFirstInSection) {
+		if (bWantHeader) {
+			return &pCurr->atElement[HDR_FIRST_PAGE].tInfo;
+		} else {
+			return &pCurr->atElement[FTR_FIRST_PAGE].tInfo;
+		}
+	} else {
+		if (bWantHeader) {
+			if (bOddPage) {
+				return &pCurr->atElement[HDR_ODD_PAGES].tInfo;
+			} else {
+				return &pCurr->atElement[HDR_EVEN_PAGES].tInfo;
+			}
+		} else {
+			if (bOddPage) {
+				return &pCurr->atElement[FTR_ODD_PAGES].tInfo;
+			} else {
+				return &pCurr->atElement[FTR_EVEN_PAGES].tInfo;
+			}
+		}
+	}
+} /* end of pGetHdrFtrInfo */
+
+/*
+ * lComputeHdrFtrHeight - compute the height of a header or footer
+ *
+ * Returns the height in DrawUnits
+ */
+static long
+lComputeHdrFtrHeight(const output_type *pAnchor)
+{
+	const output_type *pCurr;
+	long	lTotal;
+	USHORT	usFontSizeMax;
+
+	lTotal = 0;
+	usFontSizeMax = 0;
+	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
+		if (pCurr->tNextFree == 1) {
+			if (pCurr->szStorage[0] == PAR_END) {
+				/* End of a paragraph */
+				lTotal += lComputeLeading(usFontSizeMax);
+				lTotal += lMilliPoints2DrawUnits(
+						(long)pCurr->usFontSize * 200);
+				usFontSizeMax = 0;
+				continue;
+			}
+			if (pCurr->szStorage[0] == HARD_RETURN) {
+				/* End of a line */
+				lTotal += lComputeLeading(usFontSizeMax);
+				usFontSizeMax = 0;
+				continue;
+			}
+		}
+		if (pCurr->usFontSize > usFontSizeMax) {
+			usFontSizeMax = pCurr->usFontSize;
+		}
+	}
+	if (usFontSizeMax != 0) {
+		/* Height of the last paragraph */
+		lTotal += lComputeLeading(usFontSizeMax);
+	}
+	return lTotal;
+} /* end of lComputeHdrFtrHeight */
+
+/*
+ * vPrepareHdrFtrText - prepare the header/footer text
+ */
+void
+vPrepareHdrFtrText(FILE *pFile)
+{
+	hdrftr_mem_type		*pCurr, *pPrev;
+	hdrftr_local_type	*pTmp;
+	output_type		*pText;
+	size_t		tHdrFtr, tIndex;
+
+	fail(pFile == NULL);
+	fail(pHdrFtrList == NULL && tHdrFtrLen != 0);
+
+	if (pHdrFtrList == NULL || tHdrFtrLen == 0) {
+		/* No information */
+		return;
+	}
+
+	/* Fill text, text height and useful-ness */
+	for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
+		pCurr = pHdrFtrList + tHdrFtr;
+		for (tIndex = 0;
+		     tIndex < elementsof(pHdrFtrList->atElement);
+		     tIndex++) {
+			pTmp = &pCurr->atElement[tIndex];
+			pTmp->bUseful =
+				pTmp->ulCharPosStart != pTmp->ulCharPosNext;
+			if (pTmp->bUseful) {
+				pText = pHdrFtrDecryptor(pFile,
+						pTmp->ulCharPosStart,
+						pTmp->ulCharPosNext);
+				pTmp->tInfo.pText = pText;
+				pTmp->tInfo.lHeight =
+						lComputeHdrFtrHeight(pText);
+				pTmp->bTextOriginal = pText != NULL;
+			} else {
+				pTmp->tInfo.pText = NULL;
+				pTmp->tInfo.lHeight = 0;
+				pTmp->bTextOriginal = FALSE;
+			}
+		}
+	}
+
+	/* Replace not-useful records by using inheritance */
+	if (pHdrFtrList->atElement[HDR_FIRST_PAGE].bUseful) {
+		pTmp = &pHdrFtrList->atElement[HDR_ODD_PAGES];
+		if (!pTmp->bUseful) {
+			*pTmp = pHdrFtrList->atElement[HDR_FIRST_PAGE];
+			pTmp->bTextOriginal = FALSE;
+		}
+		pTmp = &pHdrFtrList->atElement[HDR_EVEN_PAGES];
+		if (!pTmp->bUseful) {
+			*pTmp = pHdrFtrList->atElement[HDR_FIRST_PAGE];
+			pTmp->bTextOriginal = FALSE;
+		}
+	}
+	if (pHdrFtrList->atElement[FTR_FIRST_PAGE].bUseful) {
+		pTmp = &pHdrFtrList->atElement[FTR_ODD_PAGES];
+		if (!pTmp->bUseful) {
+			*pTmp = pHdrFtrList->atElement[FTR_FIRST_PAGE];
+			pTmp->bTextOriginal = FALSE;
+		}
+		pTmp = &pHdrFtrList->atElement[FTR_EVEN_PAGES];
+		if (!pTmp->bUseful) {
+			*pTmp = pHdrFtrList->atElement[FTR_FIRST_PAGE];
+			pTmp->bTextOriginal = FALSE;
+		}
+	}
+	for (tHdrFtr = 1, pCurr = &pHdrFtrList[1];
+	     tHdrFtr < tHdrFtrLen;
+	     tHdrFtr++, pCurr++) {
+		pPrev = pCurr - 1;
+		for (tIndex = 0;
+		     tIndex < elementsof(pHdrFtrList->atElement);
+		     tIndex++) {
+			if (!pCurr->atElement[tIndex].bUseful &&
+			    pPrev->atElement[tIndex].bUseful) {
+				pCurr->atElement[tIndex] =
+						pPrev->atElement[tIndex];
+				pCurr->atElement[tIndex].bTextOriginal = FALSE;
+			}
+		}
+	}
+} /* end of vPrepareHdrFtrText */

+ 30 - 28
sys/src/cmd/aux/antiword/icons.c

@@ -7,39 +7,40 @@
  */
 
 #include <string.h>
-#include "wimpt.h"
+#include "DeskLib:Error.h"
+#include "DeskLib:WimpSWIs.h"
 #include "antiword.h"
 
 void
-vUpdateIcon(wimp_w tWindow, wimp_icon *pIcon)
+vUpdateIcon(window_handle tWindow, icon_block *pIcon)
 {
-	wimp_redrawstr	r;
+	window_redrawblock	tRedraw;
 	BOOL		bMore;
 
-	r.w = tWindow;
-	r.box = pIcon->box;
-	wimpt_noerr(wimp_update_wind(&r, &bMore));
+	tRedraw.window = tWindow;
+	tRedraw.rect = pIcon->workarearect;
+	Error_CheckFatal(Wimp_UpdateWindow(&tRedraw, &bMore));
 	while (bMore) {
-		(void)wimp_ploticon(pIcon);
-		wimpt_noerr(wimp_get_rectangle(&r, &bMore));
+		Error_CheckFatal(Wimp_PlotIcon(pIcon));
+		Error_CheckFatal(Wimp_GetRectangle(&tRedraw, &bMore));
 	}
 } /* end of vUpdateIcon */
 
 void
-vUpdateRadioButton(wimp_w tWindow, wimp_i tIconNumber, BOOL bSelected)
+vUpdateRadioButton(window_handle tWindow, icon_handle tIconNumber,
+	BOOL bSelected)
 {
-	wimp_icon	tIcon;
+	icon_block	tIcon;
 
-	wimpt_noerr(wimp_get_icon_info(tWindow, tIconNumber, &tIcon));
+	Error_CheckFatal(Wimp_GetIconState(tWindow, tIconNumber, &tIcon));
 	DBG_DEC(tIconNumber);
-	DBG_HEX(tIcon.flags);
-	if (bSelected ==
-	    ((tIcon.flags & wimp_ISELECTED) == wimp_ISELECTED)) {
+	DBG_HEX(tIcon.flags.data.selected);
+	if (bSelected == (tIcon.flags.data.selected == 1)) {
 		/* No update needed */
 		return;
 	}
-	wimpt_noerr(wimp_set_icon_state(tWindow, tIconNumber,
-			bSelected ? wimp_ISELECTED : 0, wimp_ISELECTED));
+	Error_CheckFatal(Wimp_SetIconState(tWindow, tIconNumber,
+			bSelected ? 0x00200000 : 0, 0x00200000));
 	vUpdateIcon(tWindow, &tIcon);
 } /* end of vUpdateRadioButton */
 
@@ -47,10 +48,11 @@ vUpdateRadioButton(wimp_w tWindow, wimp_i tIconNumber, BOOL bSelected)
  * vUpdateWriteable - update a writeable icon with a string
  */
 void
-vUpdateWriteable(wimp_w tWindow, wimp_i tIconNumber, char *szString)
+vUpdateWriteable(window_handle tWindow, icon_handle tIconNumber,
+	const char *szString)
 {
-	wimp_icon	tIcon;
-	wimp_caretstr	tCaret;
+	icon_block	tIcon;
+	caret_block	tCaret;
 	int		iLen;
 
 	fail(szString == NULL);
@@ -58,10 +60,9 @@ vUpdateWriteable(wimp_w tWindow, wimp_i tIconNumber, char *szString)
 	NO_DBG_DEC(tIconNumber);
 	NO_DBG_MSG(szString);
 
-	wimpt_noerr(wimp_get_icon_info(tWindow, tIconNumber, &tIcon));
+	Error_CheckFatal(Wimp_GetIconState(tWindow, tIconNumber, &tIcon));
 	NO_DBG_HEX(tIcon.flags);
-	if ((tIcon.flags & (wimp_ITEXT|wimp_INDIRECT)) !=
-	    (wimp_ITEXT|wimp_INDIRECT)) {
+	if (!tIcon.flags.data.text || !tIcon.flags.data.indirected) {
 		werr(1, "Icon %d must be indirected text", (int)tIconNumber);
 		return;
 	}
@@ -69,15 +70,15 @@ vUpdateWriteable(wimp_w tWindow, wimp_i tIconNumber, char *szString)
 		szString,
 		tIcon.data.indirecttext.bufflen - 1);
 	/* Ensure the caret is behind the last character of the text */
-	wimpt_noerr(wimp_get_caret_pos(&tCaret));
-	if (tCaret.w == tWindow && tCaret.i == tIconNumber) {
+	Error_CheckFatal(Wimp_GetCaretPosition(&tCaret));
+	if (tCaret.window == tWindow && tCaret.icon == tIconNumber) {
 		iLen = strlen(tIcon.data.indirecttext.buffer);
 		if (tCaret.index != iLen) {
 			tCaret.index = iLen;
-			wimpt_noerr(wimp_set_caret_pos(&tCaret));
+			Error_CheckFatal(Wimp_SetCaretPosition(&tCaret));
 		}
 	}
-	wimpt_noerr(wimp_set_icon_state(tWindow, tIconNumber, 0,0));
+	Error_CheckFatal(Wimp_SetIconState(tWindow, tIconNumber, 0, 0));
 	vUpdateIcon(tWindow, &tIcon);
 } /* end of vUpdateWriteable */
 
@@ -85,9 +86,10 @@ vUpdateWriteable(wimp_w tWindow, wimp_i tIconNumber, char *szString)
  * vUpdateWriteableNumber - update a writeable icon with a number
  */
 void
-vUpdateWriteableNumber(wimp_w tWindow, wimp_i tIconNumber, int iNumber)
+vUpdateWriteableNumber(window_handle tWindow, icon_handle tIconNumber,
+	int iNumber)
 {
-	char	szTmp[12];
+	char	szTmp[1+3*sizeof(int)+1];
 
 	(void)sprintf(szTmp, "%d", iNumber);
 	vUpdateWriteable(tWindow, tIconNumber, szTmp);

+ 57 - 27
sys/src/cmd/aux/antiword/imgexam.c

@@ -1,6 +1,6 @@
 /*
  * imgexam.c
- * Copyright (C) 2000-2003 A.J. van Os; Released under GPL
+ * Copyright (C) 2000-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Functions to examine image headers
@@ -28,6 +28,14 @@
 #define PNG_CB_COLOR		0x02
 #define PNG_CB_ALPHA		0x04
 
+/* Instance signature */
+#define MSOBI_WMF	0x0216
+#define MSOBI_EMF	0x03d4
+#define MSOBI_PICT	0x0542
+#define MSOBI_PNG	0x06e0
+#define MSOBI_JPEG	0x046a
+#define MSOBI_DIB	0x07a8
+
 /* The following enum is stolen from the IJG JPEG library */
 typedef enum {		/* JPEG marker codes			*/
 	M_SOF0	= 0xc0,	/* baseline DCT				*/
@@ -687,7 +695,7 @@ tFind6Image(FILE *pFile, size_t tPosition, size_t tLength,
 	imagetype_enum *peImageType)
 {
 	ULONG	ulMarker;
-	size_t	tElementLen, tToSkip;
+	size_t	tRecordLength, tToSkip;
 	USHORT	usMarker;
 
 	fail(pFile == NULL);
@@ -717,10 +725,10 @@ tFind6Image(FILE *pFile, size_t tPosition, size_t tLength,
 	tPosition += 18;
 
 	while (tPosition + 6 <= tLength) {
-		tElementLen = (size_t)ulNextLong(pFile);
+		tRecordLength = (size_t)ulNextLong(pFile);
 		usMarker = usNextWord(pFile);
 		tPosition += 6;
-		NO_DBG_DEC(tElementLen);
+		NO_DBG_DEC(tRecordLength);
 		NO_DBG_HEX(usMarker);
 		switch (usMarker) {
 		case 0x0000:
@@ -737,20 +745,20 @@ tFind6Image(FILE *pFile, size_t tPosition, size_t tLength,
 			tPosition += tSkipBytes(pFile, 22);
 			return tPosition;
 		default:
-			if (tElementLen < 3) {
+			if (tRecordLength < 3) {
 				break;
 			}
-			if (tElementLen > SIZE_T_MAX / 2) {
+			if (tRecordLength > SIZE_T_MAX / 2) {
 				/*
 				 * No need to compute the number of bytes
 				 * to skip
 				 */
-				DBG_DEC(tElementLen);
-				DBG_HEX(tElementLen);
+				DBG_DEC(tRecordLength);
+				DBG_HEX(tRecordLength);
 				DBG_FIXME();
 				return (size_t)-1;
 			}
-			tToSkip = tElementLen * 2 - 6;
+			tToSkip = tRecordLength * 2 - 6;
 			if (tToSkip > tLength - tPosition) {
 				/* You can't skip this number of bytes */
 				DBG_DEC(tToSkip);
@@ -776,22 +784,26 @@ static size_t
 tFind8Image(FILE *pFile, size_t tPosition, size_t tLength,
 	imagetype_enum *peImageType)
 {
-	size_t	tElementLen, tNameLen;
-	USHORT	usID, usElementTag;
+	size_t	tRecordLength, tNameLen;
+	USHORT	usRecordVersion, usRecordType, usRecordInstance;
+	USHORT	usTmp;
 
 	fail(pFile == NULL);
 	fail(peImageType == NULL);
 
 	*peImageType = imagetype_is_unknown;
 	while (tPosition + 8 <= tLength) {
-		usID = usNextWord(pFile) >> 4;
-		usElementTag = usNextWord(pFile);
-		tElementLen = (size_t)ulNextLong(pFile);
+		usTmp = usNextWord(pFile);
+		usRecordVersion = usTmp & 0x000f;
+		usRecordInstance = usTmp >> 4;
+		usRecordType = usNextWord(pFile);
+		tRecordLength = (size_t)ulNextLong(pFile);
 		tPosition += 8;
-		NO_DBG_HEX(usID);
-		NO_DBG_HEX(usElementTag);
-		NO_DBG_DEC(tElementLen);
-		switch (usElementTag) {
+		NO_DBG_HEX(usRecordVersion);
+		NO_DBG_HEX(usRecordInstance);
+		NO_DBG_HEX(usRecordType);
+		NO_DBG_DEC(tRecordLength);
+		switch (usRecordType) {
 		case 0xf000: case 0xf001: case 0xf002: case 0xf003:
 		case 0xf004: case 0xf005:
 			break;
@@ -811,43 +823,61 @@ tFind8Image(FILE *pFile, size_t tPosition, size_t tLength,
 		case 0xf006: case 0xf00a: case 0xf00b: case 0xf00d:
 		case 0xf00e: case 0xf00f: case 0xf010: case 0xf011:
 		case 0xf122:
-			tPosition += tSkipBytes(pFile, tElementLen);
+			tPosition += tSkipBytes(pFile, tRecordLength);
 			break;
 		case 0xf01a:
 			DBG_MSG("EMF");
 			*peImageType = imagetype_is_emf;
-			tPosition += tSkipBytes(pFile, usID == 0x3d4 ? 50 : 66);
+			tPosition += tSkipBytes(pFile, 50);
+			if ((usRecordInstance ^ MSOBI_EMF) == 1) {
+				tPosition += tSkipBytes(pFile, 16);
+			}
 			return tPosition;
 		case 0xf01b:
 			DBG_MSG("WMF");
 			*peImageType = imagetype_is_wmf;
-			tPosition += tSkipBytes(pFile, usID == 0x216 ? 50 : 66);
+			tPosition += tSkipBytes(pFile, 50);
+			if ((usRecordInstance ^ MSOBI_WMF) == 1) {
+				tPosition += tSkipBytes(pFile, 16);
+			}
 			return tPosition;
 		case 0xf01c:
 			DBG_MSG("PICT");
 			*peImageType = imagetype_is_pict;
-			tPosition += tSkipBytes(pFile, usID == 0x542 ? 17 : 33);
+			tPosition += tSkipBytes(pFile, 50);
+			if ((usRecordInstance ^ MSOBI_PICT) == 1) {
+				tPosition += tSkipBytes(pFile, 16);
+			}
 			return tPosition;
 		case 0xf01d:
 			DBG_MSG("JPEG");
 			*peImageType = imagetype_is_jpeg;
-			tPosition += tSkipBytes(pFile, usID == 0x46a ? 17 : 33);
+			tPosition += tSkipBytes(pFile, 17);
+			if ((usRecordInstance ^ MSOBI_JPEG) == 1) {
+				tPosition += tSkipBytes(pFile, 16);
+			}
 			return tPosition;
 		case 0xf01e:
 			DBG_MSG("PNG");
 			*peImageType = imagetype_is_png;
-			tPosition += tSkipBytes(pFile, usID == 0x6e0 ? 17 : 33);
+			tPosition += tSkipBytes(pFile, 17);
+			if ((usRecordInstance ^ MSOBI_PNG) == 1) {
+				tPosition += tSkipBytes(pFile, 16);
+			}
 			return tPosition;
 		case 0xf01f:
 			DBG_MSG("DIB");
 			/* DIB is a BMP minus its 14 byte header */
 			*peImageType = imagetype_is_dib;
-			tPosition += tSkipBytes(pFile, usID == 0x7a8 ? 17 : 33);
+			tPosition += tSkipBytes(pFile, 17);
+			if ((usRecordInstance ^ MSOBI_DIB) == 1) {
+				tPosition += tSkipBytes(pFile, 16);
+			}
 			return tPosition;
 		case 0xf00c:
 		default:
-			DBG_HEX(usElementTag);
-			DBG_DEC_C(tElementLen % 4 != 0, tElementLen);
+			DBG_HEX(usRecordType);
+			DBG_DEC_C(tRecordLength % 4 != 0, tRecordLength);
 			DBG_FIXME();
 			return (size_t)-1;
 		}

+ 0 - 386
sys/src/cmd/aux/antiword/main_r.c

@@ -1,386 +0,0 @@
-/*
- * main_r.c
- *
- * Released under GPL
- *
- * Copyright (C) 1998-2003 A.J. van Os
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * Description:
- * The main program of !Antiword (RISC OS version)
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "baricon.h"
-#include "dbox.h"
-#include "event.h"
-#include "flex.h"
-#include "kernel.h"
-#include "menu.h"
-#include "res.h"
-#include "resspr.h"
-#include "wimp.h"
-#include "template.h"
-#include "wimpt.h"
-#include "win.h"
-#include "xferrecv.h"
-#include "version.h"
-#include "antiword.h"
-
-/* The name of this program */
-static char	*szTask = "!Antiword";
-
-/* The window handle of the choices window */
-static wimp_w	tChoicesWindow;
-
-/* Info box fields */
-#define PURPOSE_INFO_FIELD	2
-#define AUTHOR_INFO_FIELD	3
-#define VERSION_INFO_FIELD	4
-#define STATUS_INFO_FIELD	5
-
-
-static void
-vBarInfo(void)
-{
-	dbox		d;
-
-	d = dbox_new("ProgInfo");
-	if (d != NULL) {
-		dbox_setfield(d, PURPOSE_INFO_FIELD, PURPOSESTRING);
-		dbox_setfield(d, AUTHOR_INFO_FIELD, AUTHORSTRING);
-		dbox_setfield(d, VERSION_INFO_FIELD, VERSIONSTRING);
-		dbox_setfield(d, STATUS_INFO_FIELD, STATUSSTRING);
-		dbox_show(d);
-		dbox_fillin(d);
-		dbox_dispose(&d);
-	}
-} /* end of vBarInfo */
-
-static void
-vMouseButtonClick(wimp_mousestr *m)
-{
-	if (m->w == tChoicesWindow) {
-		vChoicesMouseClick(m);
-		return;
-	}
-	DBG_DEC(m->w);
-} /* end of vMouseButtonClick */
-
-static void
-vKeyPressed(int chcode, wimp_caretstr *c)
-{
-	DBG_MSG("vKeyPressed");
-
-	if (chcode != '\r') {
-		wimpt_noerr(wimp_processkey(chcode));
-		return;
-	}
-	if (c->w == tChoicesWindow) {
-		vChoicesKeyPressed(c);
-	}
-} /* end of vKeyPressed */
-
-/*
- * Move the given window to the top of the pile.
- */
-static void
-vWindowToFront(wimp_w tWindow)
-{
-	wimp_wstate	tWindowState;
-
-	wimpt_noerr(wimp_get_wind_state(tWindow, &tWindowState));
-	tWindowState.o.behind = -1;
-	wimpt_noerr(wimp_open_wind(&tWindowState.o));
-} /* end of vWindowToFront */
-
-/*
- *
- */
-static void
-vIconclick(wimp_i tUnused)
-{
-} /* end of vIconclick */
-
-static void
-vSaveSelect(void *pvHandle, char *pcInput)
-{
-	diagram_type	*pDiag;
-
-	fail(pvHandle == NULL || pcInput == NULL);
-
-	pDiag = (diagram_type *)pvHandle;
-	switch (pcInput[0]) {
-	case 1:
-		vScaleOpenAction(pDiag);
-		break;
-	case 2:
-		vSaveDrawfile(pDiag);
-		break;
-	case 3:
-		vSaveTextfile(pDiag);
-		break;
-	default:
-		DBG_DEC(pcInput[0]);
-		break;
-	}
-} /* end of vMenuSelect */
-
-/*
- * Create the window for the text from the given file
- */
-static diagram_type *
-pCreateTextWindow(const char *szFilename)
-{
-	diagram_type	*pDiag;
-	menu		pSaveMenu;
-
-	DBG_MSG("pCreateTextWindow");
-
-	fail(szFilename == NULL || szFilename[0] == '\0');
-
-	pDiag = pCreateDiagram(szTask+1, szFilename);
-	if (pDiag == NULL) {
-		werr(0, "No new diagram object");
-		return NULL;
-	}
-	win_register_event_handler(pDiag->tMainWindow,
-				vMainEventHandler, pDiag);
-	win_register_event_handler(pDiag->tScaleWindow,
-				vScaleEventHandler, pDiag);
-	pSaveMenu = menu_new(szTask+1,
-		">Scale view,"
-		">Save (Drawfile)   F3,"
-		">Save (Text only) \213F3");
-	if (pSaveMenu == NULL) {
-		werr(0, "No new menu object");
-		return NULL;
-	}
-	if (!event_attachmenu(pDiag->tMainWindow,
-				pSaveMenu, vSaveSelect, pDiag)) {
-		werr(0, "I can't attach to event");
-		return NULL;
-	}
-	/* Set the window title */
-	vSetTitle(pDiag);
-	return pDiag;
-} /* end of pCreateTextWindow */
-
-static void
-vProcessFile(const char *szFilename, int iFiletype)
-{
-	options_type	tOptions;
-	FILE		*pFile;
-	diagram_type	*pDiag;
-	long		lFilesize;
-	int		iWordVersion;
-
-	fail(szFilename == NULL || szFilename[0] == '\0');
-
-	DBG_MSG(szFilename);
-
-	pFile = fopen(szFilename, "rb");
-	if (pFile == NULL) {
-		werr(0, "I can't open '%s' for reading", szFilename);
-		return;
-	}
-
-	lFilesize = lGetFilesize(szFilename);
-	if (lFilesize < 0) {
-		(void)fclose(pFile);
-		werr(0, "I can't get the size of '%s'", szFilename);
-		return;
-	}
-
-	iWordVersion = iGuessVersionNumber(pFile, lFilesize);
-	if (iWordVersion < 0 || iWordVersion == 3) {
-		if (bIsRtfFile(pFile)) {
-			werr(0, "%s is not a Word Document."
-				" It is probably a Rich Text Format file",
-				szFilename);
-		} if (bIsWordPerfectFile(pFile)) {
-			werr(0, "%s is not a Word Document."
-				" It is probably a Word Perfect file",
-				szFilename);
-		} else {
-			werr(0, "%s is not a Word Document.", szFilename);
-		}
-		(void)fclose(pFile);
-		return;
-	}
-	/* Reset any reading done during file testing */
-	rewind(pFile);
-
-	if (iFiletype != FILETYPE_MSWORD) {
-		vGetOptions(&tOptions);
-		if (tOptions.bAutofiletypeAllowed) {
-			vSetFiletype(szFilename, FILETYPE_MSWORD);
-		}
-	}
-
-	pDiag = pCreateTextWindow(szFilename);
-	if (pDiag == NULL) {
-		(void)fclose(pFile);
-		return;
-	}
-
-	(void)bWordDecryptor(pFile, lFilesize, pDiag);
-	if (bVerifyDiagram(pDiag)) {
-		vShowDiagram(pDiag);
-	}
-
-	(void)fclose(pFile);
-} /* end of vProcessFile */
-
-static void
-vProcessDraggedFile(void)
-{
-	char	*szTmp;
-	int	iFiletype;
-	char	szFilename[PATH_MAX+1];
-
-	iFiletype = xferrecv_checkinsert(&szTmp);
-	if (iFiletype == -1) {
-		werr(0, "I failed to import a file");
-		return;
-	}
-	DBG_HEX(iFiletype);
-	if (strlen(szTmp) >= sizeof(szFilename)) {
-		werr(1, "Internal error: filename too long");
-	}
-	(void)strcpy(szFilename, szTmp);
-	DBG_MSG(szFilename);
-	vProcessFile(szFilename, iFiletype);
-	xferrecv_insertfileok();
-} /* end of vProcessDraggedFile */
-
-static void
-vEventHandler(wimp_eventstr *pEvent, void *pvUnused)
-{
-	switch (pEvent->e) {
-	case wimp_ENULL:
-		break;
-	case wimp_EREDRAW:
-		/* handled by the WIMP */
-		break;
-	case wimp_EOPEN:
-		wimpt_noerr(wimp_open_wind(&pEvent->data.o));
-		break;
-	case wimp_ECLOSE:
-		wimpt_noerr(wimp_close_wind(pEvent->data.o.w));
-		break;
-	case wimp_EBUT:
-		vMouseButtonClick(&pEvent->data.but.m);
-		break;
-	case wimp_EKEY:
-		vKeyPressed(pEvent->data.key.chcode, &pEvent->data.key.c);
-		break;
-	case wimp_ESEND:
-	case wimp_ESENDWANTACK:
-		switch (pEvent->data.msg.hdr.action) {
-		case wimp_MCLOSEDOWN:
-			exit(EXIT_SUCCESS);
-			break;
-		case wimp_MDATALOAD:
-		case wimp_MDATAOPEN:
-			vProcessDraggedFile();
-			break;
-		}
-	}
-} /* end of vEventHandler */
-
-static void
-vMenuSelect(void *pvUnused, char *Input)
-{
-	switch (*Input) {
-	case 1:
-		vBarInfo();
-		break;
-	case 2:
-		vChoicesOpenAction(tChoicesWindow);
-		vWindowToFront(tChoicesWindow);
-		break;
-	case 3:
-		exit(EXIT_SUCCESS);
-		break;
-	default:
-		break;
-	}
-} /* end of vMenuSelect */
-
-static void
-vTemplates(void)
-{
-	wimp_wind	*pw;
-
-	pw = template_syshandle("Choices");
-	if (pw == NULL) {
-		werr(1, "Template 'Choices' can't be found");
-	}
-	wimpt_noerr(wimp_create_wind(pw, &tChoicesWindow));
-	win_register_event_handler(tChoicesWindow, vEventHandler, NULL);
-} /* end of vTemplates */
-
-static void
-vInitialise(void)
-{
-	menu	pBarMenu;
-
-	(void)wimpt_init(szTask+1);
-	res_init(szTask+1);
-	template_init();
-	dbox_init();
-	flex_init();
-	_kernel_register_slotextend(flex_budge);
-	drawfobj_init();
-	vTemplates();
-	pBarMenu = menu_new(szTask+1, ">Info,Choices...,Quit");
-	if (pBarMenu == NULL) {
-		werr(1, "I can't initialise (menu_new)");
-	}
-	baricon(szTask, (int)resspr_area(), vIconclick);
-	if (!event_attachmenu(win_ICONBAR, pBarMenu, vMenuSelect, NULL)) {
-		werr(1, "I can't initialise (event_attachmenu)");
-	}
-	win_register_event_handler(win_ICONBARLOAD, vEventHandler, NULL);
-} /* end of vInitialise */
-
-int
-main(int argc, char **argv)
-{
-	int	iFirst, iFiletype;
-
-	vInitialise();
-	iFirst = iReadOptions(argc, argv);
-	if (iFirst != 1) {
-		return EXIT_FAILURE;
-	}
-
-	if (argc > 1) {
-		iFiletype = iGetFiletype(argv[1]);
-		if (iFiletype < 0) {
-			return EXIT_FAILURE;
-		}
-		vProcessFile(argv[1], iFiletype);
-	}
-
-	event_setmask(wimp_EMNULL|wimp_EMPTRENTER|wimp_EMPTRLEAVE);
-	for (;;) {
-		event_process();
-	}
-} /* end of main */

+ 520 - 0
sys/src/cmd/aux/antiword/main_ros.c

@@ -0,0 +1,520 @@
+/*
+ * main_ros.c
+ *
+ * Released under GPL
+ *
+ * Copyright (C) 1998-2005 A.J. van Os
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Description:
+ * The main program of !Antiword (RISC OS version)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "DeskLib:Dialog2.h"
+#include "DeskLib:Error.h"
+#include "DeskLib:Event.h"
+#include "DeskLib:EventMsg.h"
+#include "DeskLib:Handler.h"
+#include "DeskLib:Menu.h"
+#include "DeskLib:Resource.h"
+#include "DeskLib:Screen.h"
+#include "DeskLib:Template.h"
+#include "DeskLib:Window.h"
+#if defined(__GNUC__)
+#include "flexlib:flex.h"
+#endif /* __GNUC__ */
+#include "version.h"
+#include "antiword.h"
+
+
+/* The name of this program */
+static char	*szTask = "!Antiword";
+
+/* The window handle of the choices window */
+static window_handle	tChoicesWindow = 0;
+
+/* Dummy diagram with the iconbar menu pointer */
+static diagram_type	tDummyDiagram;
+
+/* Program information Box */
+static dialog2_block	*pInfoBox = NULL;
+
+/* Info box fields */
+#define PURPOSE_INFO_FIELD	2
+#define AUTHOR_INFO_FIELD	3
+#define VERSION_INFO_FIELD	4
+#define STATUS_INFO_FIELD	5
+
+/* Iconbar menu fields */
+#define ICONBAR_INFO_FIELD	0
+#define ICONBAR_CHOICES_FIELD	1
+#define ICONBAR_QUIT_FIELD	2
+
+
+/*
+ * bBarInfo - Show iconbar information
+ */
+static BOOL
+bBarInfo(event_pollblock *pEvent, void *pvReference)
+{
+	diagram_type	*pDiag;
+
+	TRACE_MSG("bBarInfo");
+
+	fail(pEvent == NULL);
+	fail(pEvent->type != event_SEND);
+	fail(pEvent->data.message.header.action != message_MENUWARN);
+	fail(pvReference == NULL);
+
+	pDiag = (diagram_type *)pvReference;
+
+	if (menu_currentopen != pDiag->pSaveMenu ||
+	    pEvent->data.message.data.menuwarn.selection[0] != ICONBAR_INFO_FIELD) {
+		return FALSE;
+	}
+
+	Dialog2_OpenDialogMenuLeaf(pEvent, pInfoBox);
+	return TRUE;
+} /* end of bBarInfo */
+
+/*
+ * vBarInfoSetText - Set the iconbar infobox text
+ */
+static void
+vBarInfoSetText(dialog2_block *pBox)
+{
+	TRACE_MSG("vBarInfoSetText");
+
+	fail(pBox == NULL);
+	fail(pBox != pInfoBox);
+
+	Icon_SetText(pBox->window, PURPOSE_INFO_FIELD, PURPOSESTRING);
+	Icon_SetText(pBox->window, AUTHOR_INFO_FIELD, AUTHORSTRING);
+	Icon_SetText(pBox->window, VERSION_INFO_FIELD, VERSIONSTRING);
+	Icon_SetText(pBox->window, STATUS_INFO_FIELD, STATUSSTRING);
+} /* end of vBarInfoSetText */
+
+/*
+ * bMouseButtonClick - respond to mouse button click
+ */
+static BOOL
+bMouseButtonClick(event_pollblock *pEvent, void *pvReference)
+{
+	diagram_type	*pDiag;
+	menu_ptr	pMenu;
+	int		iPosY;
+
+	TRACE_MSG("bMouseButtonClick");
+
+	fail(pEvent == NULL);
+	fail(pEvent->type != event_CLICK);
+	fail(pvReference == NULL);
+
+	pDiag = (diagram_type *)pvReference;
+
+	if (pEvent->data.mouse.button.data.menu) {
+		pMenu = pDiag->pSaveMenu;
+		iPosY = (pMenu == tDummyDiagram.pSaveMenu) ?
+					-1 : pEvent->data.mouse.pos.y;
+		Menu_Show(pMenu, pEvent->data.mouse.pos.x, iPosY);
+		return TRUE;
+	}
+	if (pEvent->data.mouse.window == pDiag->tMainWindow &&
+	    pEvent->data.mouse.icon == -1) {
+		vMainButtonClick(&pEvent->data.mouse);
+		return TRUE;
+	}
+	if (pEvent->data.mouse.window == pDiag->tScaleWindow &&
+	    pEvent->data.mouse.icon >= 0) {
+		vScaleButtonClick(&pEvent->data.mouse, pDiag);
+		return TRUE;
+	}
+	return FALSE;
+} /* end of bMouseButtonClick */
+
+/*
+ * bAutoRedrawWindow - the redraw is handled by the WIMP
+ */
+static BOOL
+bAutoRedrawWindow(event_pollblock *pEvent, void *pvReference)
+{
+	return TRUE;
+} /* end of bAutoRedrawWindow */
+
+static BOOL
+bSaveSelect(event_pollblock *pEvent, void *pvReference)
+{
+	TRACE_MSG("bSaveSelect");
+
+	fail(pEvent == NULL);
+	fail(pEvent->type != event_MENU);
+	fail(pvReference == NULL);
+
+	DBG_DEC(pEvent->data.selection[0]);
+
+	switch (pEvent->data.selection[0]) {
+	case SAVEMENU_SCALEVIEW:
+		return bScaleOpenAction(pEvent, pvReference);
+	case SAVEMENU_SAVEDRAW:
+		return bSaveDrawfile(pEvent, pvReference);
+	case SAVEMENU_SAVETEXT:
+		return bSaveTextfile(pEvent, pvReference);
+	default:
+		DBG_DEC(pEvent->data.selection[0]);
+		return FALSE;
+	}
+} /* end of bSaveSelect */
+
+/*
+ * Create the window for the text from the given file
+ */
+static diagram_type *
+pCreateTextWindow(const char *szFilename)
+{
+	diagram_type	*pDiag;
+
+	TRACE_MSG("pCreateTextWindow");
+
+	fail(szFilename == NULL || szFilename[0] == '\0');
+
+	/* Create the diagram */
+	pDiag = pCreateDiagram(szTask+1, szFilename);
+	if (pDiag == NULL) {
+		werr(0, "Sorry, no new diagram object");
+		return NULL;
+	}
+
+	/* Prepare a save menu for this diagram */
+	pDiag->pSaveMenu = Menu_New(szTask+1,
+		">Scale view,"
+		">Save (Drawfile)   F3,"
+		">Save (Text only) \213F3");
+	if (pDiag->pSaveMenu == NULL) {
+		werr(1, "Sorry, no Savemenu object");
+	}
+	Menu_Warn(pDiag->pSaveMenu, SAVEMENU_SCALEVIEW,
+					TRUE, bScaleOpenAction, pDiag);
+	Menu_Warn(pDiag->pSaveMenu, SAVEMENU_SAVEDRAW,
+					TRUE, bSaveDrawfile, pDiag);
+	Menu_Warn(pDiag->pSaveMenu, SAVEMENU_SAVETEXT,
+					TRUE, bSaveTextfile, pDiag);
+
+	/* Claim events for the main window */
+        Event_Claim(event_REDRAW, pDiag->tMainWindow, icon_ANY,
+                                        bRedrawMainWindow, pDiag);
+        Event_Claim(event_CLOSE, pDiag->tMainWindow, icon_ANY,
+                                        bDestroyDiagram, pDiag);
+        Event_Claim(event_CLICK, pDiag->tMainWindow, icon_ANY,
+                                        bMouseButtonClick, pDiag);
+        Event_Claim(event_KEY, pDiag->tMainWindow, icon_ANY,
+                                        bMainKeyPressed, pDiag);
+
+	/* Claim events for the scale window */
+	Event_Claim(event_REDRAW, pDiag->tScaleWindow, icon_ANY,
+					bAutoRedrawWindow, NULL);
+        Event_Claim(event_CLICK, pDiag->tScaleWindow, icon_ANY,
+                                        bMouseButtonClick, pDiag);
+        Event_Claim(event_KEY, pDiag->tScaleWindow, icon_ANY,
+                                        bScaleKeyPressed, pDiag);
+
+	/* Set the window title */
+	vSetTitle(pDiag);
+	return pDiag;
+} /* end of pCreateTextWindow */
+
+/*
+ * vProcessFile - process one file
+ */
+static void
+vProcessFile(const char *szFilename, int iFiletype)
+{
+	options_type	tOptions;
+	FILE		*pFile;
+	diagram_type	*pDiag;
+	long		lFilesize;
+	int		iWordVersion;
+
+	TRACE_MSG("vProcessFile");
+
+	fail(szFilename == NULL || szFilename[0] == '\0');
+
+	DBG_MSG(szFilename);
+
+	pFile = fopen(szFilename, "rb");
+	if (pFile == NULL) {
+		werr(0, "I can't open '%s' for reading", szFilename);
+		return;
+	}
+
+	lFilesize = lGetFilesize(szFilename);
+	if (lFilesize < 0) {
+		(void)fclose(pFile);
+		werr(0, "I can't get the size of '%s'", szFilename);
+		return;
+	}
+
+	iWordVersion = iGuessVersionNumber(pFile, lFilesize);
+	if (iWordVersion < 0 || iWordVersion == 3) {
+		if (bIsRtfFile(pFile)) {
+			werr(0, "%s is not a Word Document."
+				" It is probably a Rich Text Format file",
+				szFilename);
+		} if (bIsWordPerfectFile(pFile)) {
+			werr(0, "%s is not a Word Document."
+				" It is probably a Word Perfect file",
+				szFilename);
+		} else {
+			werr(0, "%s is not a Word Document.", szFilename);
+		}
+		(void)fclose(pFile);
+		return;
+	}
+	/* Reset any reading done during file-testing */
+	rewind(pFile);
+
+	if (iFiletype != FILETYPE_MSWORD) {
+		vGetOptions(&tOptions);
+		if (tOptions.bAutofiletypeAllowed) {
+			vSetFiletype(szFilename, FILETYPE_MSWORD);
+		}
+	}
+
+	pDiag = pCreateTextWindow(szFilename);
+	if (pDiag == NULL) {
+		(void)fclose(pFile);
+		return;
+	}
+
+	(void)bWordDecryptor(pFile, lFilesize, pDiag);
+	Error_CheckFatal(Drawfile_VerifyDiagram(&pDiag->tInfo));
+	vShowDiagram(pDiag);
+	TRACE_MSG("After vShowDiagram");
+
+	TRACE_MSG("before debug print");
+	DBG_HEX(pFile);
+	TRACE_MSG("before fclose");
+	(void)fclose(pFile);
+	TRACE_MSG("after fclose");
+} /* end of vProcessFile */
+
+/*
+ * vSendAck - send an acknowledge
+ */
+static void
+vSendAck(event_pollblock *pEvent)
+{
+	message_block	tMessage;
+
+	TRACE_MSG("vSendAck");
+
+	fail(pEvent == NULL);
+	fail(pEvent->type != event_SEND && pEvent->type != event_SENDWANTACK);
+	fail(pEvent->data.message.header.action != message_DATALOAD &&
+		pEvent->data.message.header.action != message_DATAOPEN);
+
+	tMessage.header.action = message_DATALOADACK;
+	tMessage.header.size = sizeof(tMessage);
+	tMessage.header.yourref = pEvent->data.message.header.myref;
+	Error_CheckFatal(Wimp_SendMessage(event_SEND, &tMessage,
+				pEvent->data.message.header.sender, 0));
+} /* end of vSendAck */
+
+static BOOL
+bEventMsgHandler(event_pollblock *pEvent, void *pvReference)
+{
+	TRACE_MSG("bEventMsgHandler");
+
+	fail(pEvent == NULL);
+
+	switch (pEvent->type) {
+	case event_SEND:
+	case event_SENDWANTACK:
+		switch (pEvent->data.message.header.action) {
+		case message_CLOSEDOWN:
+			exit(EXIT_SUCCESS);
+			break;
+		case message_DATALOAD:
+		case message_DATAOPEN:
+			vProcessFile(
+				pEvent->data.message.data.dataload.filename,
+				pEvent->data.message.data.dataload.filetype);
+			vSendAck(pEvent);
+			break;
+		default:
+			DBG_DEC(pEvent->data.message.header.action);
+			break;
+		}
+		return TRUE;
+	default:
+		DBG_DEC(pEvent->type);
+		return FALSE;
+	}
+} /* end of bEventMsgHandler */
+
+/*
+ * bMenuSelect - select from the iconbar menu
+ */
+static BOOL
+bMenuSelect(event_pollblock *pEvent, void *pvReference)
+{
+	TRACE_MSG("bMenuSelect");
+
+	fail(pEvent == NULL);
+	fail(pEvent->type != event_MENU);
+
+	DBG_DEC(pEvent->data.selection[0]);
+
+	switch (pEvent->data.selection[0]) {
+	case ICONBAR_INFO_FIELD:
+		return bBarInfo(pEvent, pvReference);
+	case ICONBAR_CHOICES_FIELD:
+		vChoicesOpenAction(tChoicesWindow);
+		Window_BringToFront(tChoicesWindow);
+		break;
+	case ICONBAR_QUIT_FIELD:
+		TRACE_MSG("before exit");
+		exit(EXIT_SUCCESS);
+		break;
+	default:
+		DBG_DEC(pEvent->data.selection[0]);
+		break;
+	}
+	return TRUE;
+} /* end of bMenuSelect */
+
+/*
+ * bMenuClick - respond to an menu click
+ */
+static BOOL
+bMenuClick(event_pollblock *pEvent, void *pvReference)
+{
+	TRACE_MSG("bMenuClick");
+
+	fail(pEvent == NULL);
+	fail(pEvent->type != event_MENU);
+
+	if (menu_currentopen == tDummyDiagram.pSaveMenu) {
+		return bMenuSelect(pEvent, pvReference);
+	} else if (pvReference == NULL) {
+		return FALSE;
+	}
+	return bSaveSelect(pEvent, pvReference);
+} /* end of bMenuClick */
+
+static void
+vTemplates(void)
+{
+	TRACE_MSG("vTemplates");
+
+	Template_Initialise();
+	Template_LoadFile("Templates");
+
+	tChoicesWindow = Window_Create("Choices", template_TITLEMIN);
+	if (tChoicesWindow == 0) {
+		werr(1, "I can't find the 'Choices' template");
+	}
+
+	/* Claim events for the choices window */
+	Event_Claim(event_REDRAW, tChoicesWindow, icon_ANY,
+					bAutoRedrawWindow, NULL);
+	Event_Claim(event_CLICK, tChoicesWindow, icon_ANY,
+					bChoicesMouseClick, NULL);
+	Event_Claim(event_KEY, tChoicesWindow, icon_ANY,
+					bChoicesKeyPressed, NULL);
+} /* end of vTemplates */
+
+static void
+vInitialise(void)
+{
+	int	aiMessages[] = {0};
+	icon_handle	tBarIcon;
+
+
+	TRACE_MSG("vInitialise");
+
+	Resource_Initialise(szTask+1);
+	Event_Initialise3(szTask+1, 310, aiMessages);
+	EventMsg_Initialise();
+	Screen_CacheModeInfo();
+#if defined(__GNUC__)
+	flex_init(szTask+1, 0, 0);
+	flex_set_budge(1);
+#endif /* __GNUC__ */
+	vTemplates();
+
+	/* Prepare iconbar menu */
+	tDummyDiagram.tInfo.data = NULL;
+	tDummyDiagram.tInfo.length = 0;
+	tDummyDiagram.pSaveMenu = Menu_New(szTask+1, ">Info,Choices...,Quit");
+	if (tDummyDiagram.pSaveMenu == NULL) {
+		werr(1, "Sorry, no Barmenu object");
+	}
+	pInfoBox = Dialog2_CreateDialogBlock("ProgInfo", -1, -1,
+					vBarInfoSetText, NULL, NULL);
+
+	if (pInfoBox == NULL) {
+		werr(1, "Sorry, no Infobox object");
+	}
+	Menu_Warn(tDummyDiagram.pSaveMenu, ICONBAR_INFO_FIELD,
+					TRUE, bBarInfo, &tDummyDiagram);
+
+	/* Create an icon on the icon bar */
+	tBarIcon = Icon_BarIcon(szTask, iconbar_RIGHT);
+	Event_Claim(event_CLICK, window_ICONBAR, tBarIcon,
+					bMouseButtonClick, &tDummyDiagram);
+
+	/* Generic claims */
+	Event_Claim(event_OPEN, window_ANY, icon_ANY,
+					Handler_OpenWindow, NULL);
+	Event_Claim(event_CLOSE, window_ANY, icon_ANY,
+					Handler_CloseWindow, NULL);
+	Event_Claim(event_MENU, window_ANY, icon_ANY,
+					bMenuClick, NULL);
+	EventMsg_Claim(message_DATALOAD, window_ICONBAR,
+					bEventMsgHandler, NULL);
+	EventMsg_Claim(message_MODECHANGE, window_ANY,
+					Handler_ModeChange, NULL);
+} /* end of vInitialise */
+
+int
+main(int argc, char **argv)
+{
+	int	iFirst, iFiletype;
+
+	TRACE_MSG("main");
+
+	vInitialise();
+	iFirst = iReadOptions(argc, argv);
+	if (iFirst != 1) {
+		return EXIT_FAILURE;
+	}
+
+	if (argc > 1) {
+		iFiletype = iGetFiletype(argv[1]);
+		if (iFiletype < 0) {
+			return EXIT_FAILURE;
+		}
+		vProcessFile(argv[1], iFiletype);
+		TRACE_MSG("main after vProcessFile");
+	}
+
+	for (;;) {
+		Event_Poll();
+	}
+} /* end of main */

+ 60 - 17
sys/src/cmd/aux/antiword/main_u.c

@@ -3,7 +3,7 @@
  *
  * Released under GPL
  *
- * Copyright (C) 1998-2003 A.J. van Os
+ * Copyright (C) 1998-2004 A.J. van Os
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -29,9 +29,21 @@
 #include <fcntl.h>
 #include <io.h>
 #endif /* __dos */
-#if defined(__STDC_ISO_10646__)
+#if defined(__CYGWIN__) || defined(__CYGMING__)
+#  ifdef X_LOCALE
+#    include <X11/Xlocale.h>
+#  else
+#    include <locale.h>
+#  endif
+#else
 #include <locale.h>
-#endif /* __STDC_ISO_10646__ */
+#endif /* __CYGWIN__ || __CYGMING__ */
+#if defined(N_PLAT_NLM)
+#if !defined(_VA_LIST)
+#include "NW-only/nw_os.h"
+#endif /* !_VA_LIST */
+#include "getopt.h"
+#endif /* N_PLAT_NLM */
 #include "version.h"
 #include "antiword.h"
 
@@ -45,22 +57,29 @@ vUsage(void)
 	fprintf(stderr, "\tName: %s\n", szTask);
 	fprintf(stderr, "\tPurpose: "PURPOSESTRING"\n");
 	fprintf(stderr, "\tAuthor: "AUTHORSTRING"\n");
-	fprintf(stderr, "\tVersion: "VERSIONSTRING"\n");
+	fprintf(stderr, "\tVersion: "VERSIONSTRING);
+#if defined(__dos)
+	fprintf(stderr, VERSIONSTRING2);
+#endif /* __dos */
+	fprintf(stderr, "\n");
 	fprintf(stderr, "\tStatus: "STATUSSTRING"\n");
 	fprintf(stderr,
 		"\tUsage: %s [switches] wordfile1 [wordfile2 ...]\n", szTask);
 	fprintf(stderr,
-		"\tSwitches: [-t|-p papersize|-x dtd][-m mapping][-w #][-i #]"
-		"[-Ls]\n");
+		"\tSwitches: [-f|-t|-a papersize|-p papersize|-x dtd]"
+		"[-m mapping][-w #][-i #][-Ls]\n");
+	fprintf(stderr, "\t\t-f formatted text output\n");
 	fprintf(stderr, "\t\t-t text output (default)\n");
+	fprintf(stderr, "\t\t-a <paper size name> Adobe PDF output\n");
 	fprintf(stderr, "\t\t-p <paper size name> PostScript output\n");
-	fprintf(stderr, "\t\t   like: a4, letter or legal\n");
+	fprintf(stderr, "\t\t   paper size like: a4, letter or legal\n");
 	fprintf(stderr, "\t\t-x <dtd> XML output\n");
 	fprintf(stderr, "\t\t   like: db (DocBook)\n");
 	fprintf(stderr, "\t\t-m <mapping> character mapping file\n");
 	fprintf(stderr, "\t\t-w <width> in characters of text output\n");
 	fprintf(stderr, "\t\t-i <level> image level (PostScript only)\n");
 	fprintf(stderr, "\t\t-L use landscape mode (PostScript only)\n");
+	fprintf(stderr, "\t\t-r Show removed text\n");
 	fprintf(stderr, "\t\t-s Show hidden (by Word) text\n");
 } /* end of vUsage */
 
@@ -225,27 +244,51 @@ main(int argc, char **argv)
 		return iFirst < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 	}
 
+#if defined(N_PLAT_NLM) && !defined(_VA_LIST)
+	nwinit();
+#endif /* N_PLAT_NLM && !_VA_LIST */
+
 	vGetOptions(&tOptions);
 
+#if !defined(__dos)
+	if (is_locale_utf8()) {
 #if defined(__STDC_ISO_10646__)
-	/*
-	 * If the user wants UTF-8 and the envirionment variables support
-	 * UTF-8, than set the locale accordingly
-	 */
-	if (tOptions.eEncoding == encoding_utf8 && is_locale_utf8()) {
+		/*
+		 * If the user wants UTF-8 and the envirionment variables
+		 * support UTF-8, than set the locale accordingly
+		 */
+		if (tOptions.eEncoding == encoding_utf_8) {
+			if (setlocale(LC_CTYPE, "") == NULL) {
+				werr(1, "Can't set the UTF-8 locale! "
+					"Check LANG, LC_CTYPE, LC_ALL.");
+			}
+			DBG_MSG("The UTF-8 locale has been set");
+		} else {
+			(void)setlocale(LC_CTYPE, "C");
+		}
+#endif /* __STDC_ISO_10646__ */
+	} else {
 		if (setlocale(LC_CTYPE, "") == NULL) {
-			werr(1, "Can't set the UTF-8 locale! "
-				"Check LANG, LC_CTYPE, LC_ALL.");
+			werr(0, "Can't set the locale! Will use defaults");
+			(void)setlocale(LC_CTYPE, "C");
 		}
-		DBG_MSG("The UTF-8 locale has been set");
+		DBG_MSG("The locale has been set");
 	}
-#endif /* __STDC_ISO_10646__ */
+#endif /* !__dos */
 
 	bMultiple = argc - iFirst > 1;
-	bUseTXT = tOptions.eConversionType == conversion_text;
+	bUseTXT = tOptions.eConversionType == conversion_text ||
+		tOptions.eConversionType == conversion_fmt_text;
 	bUseXML = tOptions.eConversionType == conversion_xml;
 	iGoodCount = 0;
 
+#if defined(__dos)
+	if (tOptions.eConversionType == conversion_pdf) {
+		/* PDF must be written as a binary stream */
+		setmode(fileno(stdout), O_BINARY);
+	}
+#endif /* __dos */
+
 	if (bUseXML) {
 		fprintf(stdout,
 	"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"

+ 280 - 33
sys/src/cmd/aux/antiword/misc.c

@@ -1,6 +1,6 @@
 /*
  * misc.c
- * Copyright (C) 1998-2003 A.J. van Os; Released under GNU GPL
+ * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Miscellaneous functions
@@ -12,19 +12,19 @@
 #include <ctype.h>
 #include <time.h>
 #if defined(__riscos)
-#include "kernel.h"
-#include "swis.h"
+#include "DeskLib:SWI.h"
 #else
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #endif /* __riscos */
-#if defined(__dos)
-#define S_ISDIR(x)	(((x) & S_IFMT) == S_IFDIR)
+#if !defined(S_ISREG)
 #define S_ISREG(x)	(((x) & S_IFMT) == S_IFREG)
-#endif /* __dos */
+#endif /* !S_ISREG */
 #include "antiword.h"
-
+#if defined(__vms)
+#include <unixlib.h>
+#endif
 
 #if !defined(__riscos)
 /*
@@ -36,16 +36,17 @@ szGetHomeDirectory(void)
 	const char	*szHome;
 
 #if defined(__vms)
-#include <unixlib.h>
 	szHome = decc$translate_vms(getenv("HOME"));
 #elif defined(__Plan9__)
 	szHome = getenv("home");
-#else 
+#else
 	szHome = getenv("HOME");
-#endif
+#endif /* __vms */
 
 	if (szHome == NULL || szHome[0] == '\0') {
-#if defined(__dos)
+#if defined(N_PLAT_NLM)
+		szHome = "SYS:";
+#elif defined(__dos)
 		szHome = "C:";
 #else
 		werr(0, "I can't find the name of your HOME directory");
@@ -62,12 +63,11 @@ const char *
 szGetAntiwordDirectory(void)
 {
 #if defined(__vms)
-#include <unixlib.h>
 	return decc$translate_vms(getenv("ANTIWORDHOME"));
 #else
 	return getenv("ANTIWORDHOME");
 #endif /* __vms */
-} /* end of szGetHomeDirectory */
+} /* end of szGetAntiwordDirectory */
 #endif /* !__riscos */
 
 /*
@@ -78,26 +78,26 @@ long
 lGetFilesize(const char *szFilename)
 {
 #if defined(__riscos)
-	_kernel_swi_regs	regs;
-	_kernel_oserror		*e;
+	os_error	*e;
+	int	iType, iSize;
 
-	(void)memset(&regs, 0, sizeof(regs));
-	regs.r[0] = 17;
-	regs.r[1] = (int)szFilename;
-	e = _kernel_swi(OS_File, &regs, &regs);
+	e = SWI(2, 5, SWI_OS_File | XOS_Bit,
+		17, szFilename,
+		&iType, NULL, NULL, NULL, &iSize);
 	if (e != NULL) {
 		werr(0, "Get Filesize error %d: %s",
 			e->errnum, e->errmess);
 		return -1;
 	}
-	if (regs.r[0] != 1) {
+	if (iType != 1) {
 		/* It's not a proper file or the file does not exist */
 		return -1;
 	}
-	return (long)regs.r[4];
+	return (long)iSize;
 #else
 	struct stat	tBuffer;
 
+	errno = 0;
 	if (stat(szFilename, &tBuffer) != 0) {
 		werr(0, "Get Filesize error %d", errno);
 		return -1;
@@ -136,7 +136,7 @@ vPrintBlock(const char	*szFile, int iLine,
 } /* end of vPrintBlock */
 
 void
-vPrintUnicode(const char  *szFile, int iLine, const UCHAR *aucUni, size_t tLen)
+vPrintUnicode(const char *szFile, int iLine, const UCHAR *aucUni, size_t tLen)
 {
 	char	*szASCII;
 
@@ -249,7 +249,7 @@ bReadBuffer(FILE *pFile, ULONG ulStartBlock,
 } /* end of bReadBuffer */
 
 /*
- * Translate a Word colornumber into a true color for use in a drawfile
+ * Convert a Word colornumber into a true color for use in a drawfile
  *
  * Returns the true color
  */
@@ -469,12 +469,12 @@ tNumber2Alpha(UINT uiNumber, BOOL bUpperCase, char *szOutput)
 char *
 unincpy(char *s1, const UCHAR *s2, size_t n)
 {
-	char	*dest;
+	char	*pcDest;
 	ULONG	ulChar;
 	size_t	tLen;
 	USHORT	usUni;
 
-	for (dest = s1, tLen = 0; tLen < n; dest++, tLen++) {
+	for (pcDest = s1, tLen = 0; tLen < n; pcDest++, tLen++) {
 		usUni = usGetWord(tLen * 2, s2);
 		if (usUni == 0) {
 			break;
@@ -484,10 +484,10 @@ unincpy(char *s1, const UCHAR *s2, size_t n)
 		if (ulChar == IGNORE_CHARACTER) {
 			ulChar = (ULONG)'?';
 		}
-		*dest = (char)ulChar;
+		*pcDest = (char)ulChar;
 	}
 	for (; tLen < n; tLen++) {
-		*dest++ = '\0';
+		*pcDest++ = '\0';
 	}
 	return s1;
 } /* end of unincpy */
@@ -614,14 +614,11 @@ vGetBulletValue(conversion_type eConversionType, encoding_type eEncoding,
 	fail(szResult == NULL);
 	fail(tMaxResultLen < 2);
 
-	if (eEncoding == encoding_utf8) {
+	if (eEncoding == encoding_utf_8) {
 		(void)tUcs2Utf8(UNICODE_BULLET, szResult, tMaxResultLen);
-	} else if (eEncoding == encoding_iso_8859_1 &&
-		   eConversionType == conversion_ps) {
-		szResult[0] = OUR_BULLET_PS;
-		szResult[1] = '\0';
 	} else {
-		szResult[0] = OUR_BULLET_TEXT;
+		szResult[0] = (char)ucGetBulletCharacter(eConversionType,
+							eEncoding);
 		szResult[1] = '\0';
 	}
 } /* end of vGetBulletValue */
@@ -645,3 +642,253 @@ bAllZero(const UCHAR *aucBytes, size_t tLength)
 	}
 	return TRUE;
 } /* end of bAllZero */
+
+#if !defined(__riscos)
+/*
+ * GetCodesetFromLocale - get the codeset from the current locale
+ *
+ * Original version: Copyright (C) 1999  Bruno Haible
+ * Syntax:
+ * language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]]
+ *
+ * Returns TRUE when sucessful, otherwise FALSE
+ */
+static BOOL
+bGetCodesetFromLocale(char *szCodeset, size_t tMaxCodesetLength, BOOL *pbEuro)
+{
+#if !defined(__dos)
+	const char	*szLocale;
+	const char	*pcTmp;
+	size_t		tIndex;
+	char		szModifier[6];
+#endif /* __dos */
+
+	if (pbEuro != NULL) {
+		*pbEuro = FALSE;	/* Until proven otherwise */
+	}
+	if (szCodeset == NULL || tMaxCodesetLength == 0) {
+		return FALSE;
+	}
+
+#if defined(__dos)
+	if (tMaxCodesetLength < 2 + sizeof(int) * 3 + 1) {
+		DBG_DEC(tMaxCodesetLength);
+		DBG_DEC(2 + sizeof(int) * 3 + 1);
+		return FALSE;
+	}
+	/* Get the active codepage from DOS */
+	sprintf(szCodeset, "cp%d", iGetCodepage());
+	DBG_MSG(szCodeset);
+#else
+	/* Get the locale from the environment */
+	szLocale = getenv("LC_ALL");
+	if (szLocale == NULL || szLocale[0] == '\0') {
+		szLocale = getenv("LC_CTYPE");
+		if (szLocale == NULL || szLocale[0] == '\0') {
+			szLocale = getenv("LANG");
+		}
+	}
+	if (szLocale == NULL || szLocale[0] == '\0') {
+		/* No locale, so no codeset name and no modifier */
+		return FALSE;
+	}
+	DBG_MSG(szLocale);
+	pcTmp = strchr(szLocale, '.');
+	if (pcTmp == NULL) {
+		/* No codeset name */
+		szCodeset[0] = '\0';
+	} else {
+		/* Copy the codeset name */
+		pcTmp++;
+		for (tIndex = 0; tIndex < tMaxCodesetLength; tIndex++) {
+			if (*pcTmp == '@' || *pcTmp == '+' ||
+			    *pcTmp == ',' || *pcTmp == '_' ||
+			    *pcTmp == '\0') {
+				szCodeset[tIndex] = '\0';
+				break;
+			}
+			szCodeset[tIndex] = *pcTmp;
+			pcTmp++;
+		}
+		szCodeset[tMaxCodesetLength - 1] = '\0';
+	}
+	if (pbEuro == NULL) {
+		/* No need to get the modifier */
+		return TRUE;
+	}
+	pcTmp = strchr(szLocale, '@');
+	if (pcTmp != NULL) {
+		/* Copy the modifier */
+		pcTmp++;
+		for (tIndex = 0; tIndex < sizeof(szModifier); tIndex++) {
+			if (*pcTmp == '+' || *pcTmp == ',' ||
+			    *pcTmp == '_' || *pcTmp == '\0') {
+				szModifier[tIndex] = '\0';
+				break;
+			}
+			szModifier[tIndex] = *pcTmp;
+			pcTmp++;
+		}
+		szModifier[sizeof(szModifier) - 1] = '\0';
+		*pbEuro = STRCEQ(szModifier, "Euro");
+	}
+#endif /* __dos */
+	return TRUE;
+} /* end of bGetCodesetFromLocale */
+
+/*
+ * GetNormalizedCodeset - get the normalized codeset from the current locale
+ *
+ * Returns TRUE when sucessful, otherwise FALSE
+ */
+BOOL
+bGetNormalizedCodeset(char *szCodeset, size_t tMaxCodesetLength, BOOL *pbEuro)
+{
+	BOOL	bOnlyDigits;
+	const char	*pcSrc;
+	char	*pcDest;
+	char	*szTmp, *szCodesetNorm;
+
+	if (pbEuro != NULL) {
+		*pbEuro = FALSE;	/* Until proven otherwise */
+	}
+	if (szCodeset == NULL || tMaxCodesetLength < 4) {
+		return FALSE;
+	}
+
+	/* Get the codeset name */
+	szTmp = xmalloc(tMaxCodesetLength - 3);
+	if (!bGetCodesetFromLocale(szTmp, tMaxCodesetLength - 3, pbEuro)) {
+		szTmp = xfree(szTmp);
+		return FALSE;
+	}
+	/* Normalize the codeset name */
+	szCodesetNorm = xmalloc(tMaxCodesetLength - 3);
+	bOnlyDigits = TRUE;
+	pcDest = szCodesetNorm;
+	for (pcSrc = szTmp; *pcSrc != '\0'; pcSrc++) {
+		if (isalnum(*pcSrc)) {
+			*pcDest = tolower(*pcSrc);
+			if (!isdigit(*pcDest)) {
+				bOnlyDigits = FALSE;
+			}
+			pcDest++;
+		}
+	}
+	*pcDest = '\0';
+	DBG_MSG(szCodesetNorm);
+	/* Add "iso" when szCodesetNorm contains all digits */
+	if (bOnlyDigits && szCodesetNorm[0] != '\0') {
+		fail(strlen(szCodesetNorm) + 3 >= tMaxCodesetLength);
+		sprintf(szCodeset, "iso%s", szCodesetNorm);
+	} else {
+		fail(strlen(szCodesetNorm) >= tMaxCodesetLength);
+		strncpy(szCodeset, szCodesetNorm, pcDest - szCodesetNorm + 1);
+		szCodeset[tMaxCodesetLength - 1] = '\0';
+	}
+	DBG_MSG(szCodeset);
+	/* Clean up and leave */
+	szCodesetNorm = xfree(szCodesetNorm);
+	szTmp = xfree(szTmp);
+	return TRUE;
+} /* end of bGetNormalizedCodeset */
+
+/*
+ * szGetDefaultMappingFile - get the default mapping file
+ *
+ * Returns the basename of the default mapping file
+ */
+const char *
+szGetDefaultMappingFile(void)
+{
+	static const struct {
+		const char	*szCodeset;
+		const char	*szMappingFile;
+	} atMappingFile[] = {
+		{ "iso88591",	MAPPING_FILE_8859_1 },
+		{ "iso88592",	MAPPING_FILE_8859_2 },
+		{ "iso88593",	"8859-3.txt" },
+		{ "iso88594",	"8859-4.txt" },
+		{ "iso88595",	"8859-5.txt" },
+		{ "iso88596",	MAPPING_FILE_8859_5 },
+		{ "iso88597",	"8859-7.txt" },
+		{ "iso88598",	"8859-8.txt" },
+		{ "iso88599",	"8859-9.txt" },
+		{ "iso885910",	"8859-10.txt" },
+		{ "iso885913",	"8859-13.txt" },
+		{ "iso885914",	"8859-14.txt" },
+		{ "iso885915",	MAPPING_FILE_8859_15 },
+		{ "iso885916",	"8859-16.txt" },
+		{ "koi8r",	MAPPING_FILE_KOI8_R },
+		{ "koi8u",	MAPPING_FILE_KOI8_U },
+		{ "utf8",	MAPPING_FILE_UTF_8 },
+		{ "cp437",	MAPPING_FILE_CP437 },
+		{ "cp850",	"cp850.txt" },
+		{ "cp852",	MAPPING_FILE_CP852 },
+		{ "cp862",	"cp862.txt" },
+		{ "cp864",	"cp864.txt" },
+		{ "cp866",	MAPPING_FILE_CP866 },
+		{ "cp1250",	MAPPING_FILE_CP1250 },
+		{ "cp1251",	MAPPING_FILE_CP1251 },
+		{ "cp1252",	"cp1252.txt" },
+	};
+	size_t	tIndex;
+	BOOL	bEuro;
+	char	szCodeset[20];
+
+	szCodeset[0] = '\0';
+	bEuro = FALSE;
+	/* Get the normalized codeset name */
+	if (!bGetNormalizedCodeset(szCodeset, sizeof(szCodeset), &bEuro)) {
+		return MAPPING_FILE_8859_1;
+	}
+	if (szCodeset[0] == '\0') {
+		if (bEuro) {
+			/* Default mapping file (with Euro sign) */
+			return MAPPING_FILE_8859_15;
+		} else {
+			/* Default mapping file (without Euro sign) */
+			return MAPPING_FILE_8859_1;
+		}
+	}
+	/* Find the name in the table */
+	for (tIndex = 0; tIndex < elementsof(atMappingFile); tIndex++) {
+		if (STREQ(atMappingFile[tIndex].szCodeset, szCodeset)) {
+			return atMappingFile[tIndex].szMappingFile;
+		}
+	}
+	/* Default default mapping file */
+#if defined(__dos)
+	return MAPPING_FILE_CP437;
+#else
+	return MAPPING_FILE_8859_1;
+#endif /* __dos */
+} /* end of szGetDefaultMappingFile */
+#endif /* !__riscos */
+
+/*
+ * tConvertDTTM - convert Windows Date and Time format
+ *
+ * returns Unix time_t or -1
+ */
+time_t
+tConvertDTTM(ULONG ulDTTM)
+{
+	struct tm	tTime;
+	time_t		tResult;
+
+	if (ulDTTM == 0) {
+		return (time_t)-1;
+	}
+	memset(&tTime, 0, sizeof(tTime));
+	tTime.tm_min = (int)(ulDTTM & 0x0000003f);
+	tTime.tm_hour = (int)((ulDTTM & 0x000007c0) >> 6);
+	tTime.tm_mday = (int)((ulDTTM & 0x0000f800) >> 11);
+	tTime.tm_mon = (int)((ulDTTM & 0x000f0000) >> 16);
+	tTime.tm_year = (int)((ulDTTM & 0x1ff00000) >> 20);
+	tTime.tm_isdst = -1;
+	tTime.tm_mon--;         /* From 01-12 to 00-11 */
+	tResult = mktime(&tTime);
+	NO_DBG_MSG(ctime(&tResult));
+	return tResult;
+} /* end of tConvertDTTM */

+ 8 - 6
sys/src/cmd/aux/antiword/mkfile

@@ -6,12 +6,13 @@ CFLAGS=-Bp -I/sys/include/ape -I/$objtype/include/ape -DNDEBUG -D_POSIX_SOURCE -
 
 TARG=antiword
 OFILES= main_u.$O asc85enc.$O blocklist.$O chartrans.$O datalist.$O depot.$O\
-	dib2eps.$O fail.$O finddata.$O findtext.$O fontlist.$O fonts.$O fonts_u.$O\
-	imgexam.$O imgtrans.$O jpeg2eps.$O listlist.$O misc.$O notes.$O options.$O\
-	out2window.$O output.$O pictlist.$O png2eps.$O postscript.$O prop0.$O prop2.$O\
-	prop6.$O prop8.$O properties.$O propmod.$O rowlist.$O sectlist.$O stylelist.$O\
-	stylesheet.$O summary.$O tabstop.$O text.$O unix.$O utf8.$O word2text.$O\
-	worddos.$O wordlib.$O wordmac.$O wordole.$O wordwin.$O xmalloc.$O xml.$O
+	dib2eps.$O doclist.$O fail.$O finddata.$O findtext.$O fmt_text.$O fontlist.$O\
+	fonts.$O fonts_u.$O hdrftrlist.$O imgexam.$O imgtrans.$O jpeg2eps.$O\
+	listlist.$O misc.$O notes.$O options.$O out2window.$O output.$O pdf.$O\
+	pictlist.$O png2eps.$O postscript.$O prop0.$O prop2.$O prop6.$O prop8.$O\
+	properties.$O propmod.$O rowlist.$O sectlist.$O stylelist.$O stylesheet.$O\
+	summary.$O tabstop.$O text.$O unix.$O utf8.$O word2text.$O worddos.$O\
+	wordlib.$O wordmac.$O wordole.$O wordwin.$O xmalloc.$O xml.$O
 
 HFILES=antiword.h debug.h draw.h fail.h fontinfo.h version.h wordconst.h wordtypes.h
 
@@ -21,6 +22,7 @@ BIN=/$objtype/bin/aux
 
 main_u.$O: version.h
 postscript.$O: version.h
+pdf.$O: version.h
 fonts_u.$O: fontinfo.h
 
 # fontinfo.h: Unix-fontinfo.pl

+ 548 - 69
sys/src/cmd/aux/antiword/notes.c

@@ -1,6 +1,6 @@
 /*
  * notes.c
- * Copyright (C) 1998-2003 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Functions to tell the difference between footnotes and endnotes
@@ -8,11 +8,25 @@
 
 #include "antiword.h"
 
-/* Variables needed to write the Footnote and Endnote Lists */
+/*
+ * Private structures to hide the way the information
+ * is stored from the rest of the program
+ */
+typedef struct footnote_local_tag {
+        footnote_block_type	tInfo;
+        ULONG			ulCharPosStart;
+        ULONG			ulCharPosNext;
+        BOOL			bUseful;
+} footnote_local_type;
+
+/* Variables needed to write the Footnote and Endnote information */
 static ULONG	*aulFootnoteList = NULL;
 static size_t	tFootnoteListLength = 0;
 static ULONG	*aulEndnoteList = NULL;
 static size_t	tEndnoteListLength = 0;
+/* Variables needed to write the Footnote Text */
+static footnote_local_type	*pFootnoteText = NULL;
+static size_t			tFootnoteTextLength = 0;
 
 
 /*
@@ -21,15 +35,262 @@ static size_t	tEndnoteListLength = 0;
 void
 vDestroyNotesInfoLists(void)
 {
-	DBG_MSG("vDestroyNotesInfoLists");
+	footnote_local_type	*pRecord;
+	size_t			tFootnote;
+
+	TRACE_MSG("vDestroyNotesInfoLists");
 
 	/* Free the lists and reset all control variables */
 	aulEndnoteList = xfree(aulEndnoteList);
 	aulFootnoteList = xfree(aulFootnoteList);
 	tEndnoteListLength = 0;
 	tFootnoteListLength = 0;
+	for (tFootnote = 0; tFootnote < tFootnoteTextLength; tFootnote++) {
+		pRecord = pFootnoteText + tFootnote;
+		pRecord->tInfo.szText = xfree(pRecord->tInfo.szText);
+	}
+	pFootnoteText = xfree(pFootnoteText);
+	tFootnoteTextLength = 0;
 } /* end of vDestroyNotesInfoLists */
 
+/*
+ * Build the list with footnote information for Word for DOS files
+ */
+static void
+vGet0FootnotesInfoAndText(FILE *pFile, const UCHAR *aucHeader)
+{
+	footnote_local_type	*pCurr;
+	UCHAR	*aucBuffer;
+	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
+	ULONG	ulCharPos, ulBeginNextBlock;
+	size_t	tFootnotes, tFootnoteInfoLen;
+	size_t	tIndex;
+	UCHAR   aucTmp[2];
+
+	TRACE_MSG("vGet0FootnotesInfoAndText");
+
+	fail(pFile == NULL || aucHeader == NULL);
+
+	ulBeginOfText = 128;
+	NO_DBG_HEX(ulBeginOfText);
+	ulBeginFootnoteInfo =  128 * (ULONG)usGetWord(0x14, aucHeader);
+	DBG_HEX(ulBeginFootnoteInfo);
+	ulBeginNextBlock = 128 * (ULONG)usGetWord(0x16, aucHeader);
+	DBG_HEX(ulBeginNextBlock);
+
+	if (ulBeginFootnoteInfo == ulBeginNextBlock) {
+		DBG_MSG("No Footnotes in this document");
+		return;
+	}
+
+	/* Read the the number of footnotes + 1 */
+	if (!bReadBytes(aucTmp, 2, ulBeginFootnoteInfo, pFile)) {
+		return;
+	}
+	tFootnotes = (size_t)usGetWord(0, aucTmp);
+	if (tFootnotes < 2) {
+		DBG_MSG("No Footnotes in this document (2)");
+	}
+	DBG_DEC(tFootnotes);
+	tFootnoteInfoLen =  8 * tFootnotes;
+
+	aucBuffer = xmalloc(tFootnoteInfoLen);
+	if (!bReadBytes(aucBuffer,
+			tFootnoteInfoLen, ulBeginFootnoteInfo + 4, pFile)) {
+		aucBuffer = xfree(aucBuffer);
+		return;
+	}
+	DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
+
+	/* Get footnote information */
+	fail(tFootnoteListLength != 0);
+	tFootnoteListLength = tFootnotes - 1;
+	fail(tFootnoteListLength == 0);
+
+	fail(aulFootnoteList != NULL);
+	aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
+
+	for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
+		ulOffset = ulGetLong(tIndex * 8, aucBuffer);
+		DBG_HEX(ulOffset);
+		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
+		DBG_HEX(ulFileOffset);
+		aulFootnoteList[tIndex] = ulFileOffset;
+	}
+
+	/* Get footnote text */
+	fail(tFootnoteTextLength != 0);
+	tFootnoteTextLength = tFootnotes - 1;
+	fail(tFootnoteTextLength == 0);
+
+	fail(pFootnoteText != NULL);
+	pFootnoteText = xcalloc(tFootnoteTextLength,
+				sizeof(footnote_local_type));
+
+	for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
+		pCurr = pFootnoteText + tIndex;
+		pCurr->tInfo.szText = NULL;
+		ulOffset = ulGetLong(tIndex * 8 + 4, aucBuffer);
+		DBG_HEX(ulOffset);
+		ulCharPos = ulBeginOfText + ulOffset;
+		DBG_HEX(ulCharPos);
+		DBG_HEX(ulCharPos2FileOffset(ulCharPos));
+		pCurr->ulCharPosStart = ulCharPos;
+		ulOffset = ulGetLong((tIndex + 1) * 8 + 4, aucBuffer);
+		DBG_HEX(ulOffset);
+		ulCharPos = ulBeginOfText + ulOffset;
+		DBG_HEX(ulCharPos);
+		DBG_HEX(ulCharPos2FileOffset(ulCharPos));
+		pCurr->ulCharPosNext = ulCharPos;
+		pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
+	}
+	aucBuffer = xfree(aucBuffer);
+} /* end of vGet0FootnotesInfoAndText */
+
+/*
+ * Build the lists note information for Word for DOS files
+ */
+static void
+vGet0NotesInfo(FILE *pFile, const UCHAR *aucHeader)
+{
+	TRACE_MSG("vGet0NotesInfo");
+
+	vGet0FootnotesInfoAndText(pFile, aucHeader);
+	/* There are no endnotes in a Word for DOS file */
+} /* end of vGet0NotesInfo */
+
+/*
+ * Build the list with footnote information for WinWord 1/2 files
+ */
+static void
+vGet2FootnotesInfo(FILE *pFile, const UCHAR *aucHeader)
+{
+	UCHAR	*aucBuffer;
+	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
+	size_t	tFootnoteInfoLen;
+	size_t	tIndex;
+
+	TRACE_MSG("vGet2FootnotesInfo");
+
+	fail(pFile == NULL || aucHeader == NULL);
+
+	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
+	NO_DBG_HEX(ulBeginOfText);
+	ulBeginFootnoteInfo = ulGetLong(0x64, aucHeader); /* fcPlcffndRef */
+	NO_DBG_HEX(ulBeginFootnoteInfo);
+	tFootnoteInfoLen = (size_t)usGetWord(0x68, aucHeader); /* cbPlcffndRef */
+	NO_DBG_DEC(tFootnoteInfoLen);
+
+	if (tFootnoteInfoLen < 10) {
+		DBG_MSG("No Footnotes in this document");
+		return;
+	}
+
+	aucBuffer = xmalloc(tFootnoteInfoLen);
+	if (!bReadBytes(aucBuffer,
+			tFootnoteInfoLen, ulBeginFootnoteInfo, pFile)) {
+		aucBuffer = xfree(aucBuffer);
+		return;
+	}
+	NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
+
+	fail(tFootnoteListLength != 0);
+	tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
+	fail(tFootnoteListLength == 0);
+
+	fail(aulFootnoteList != NULL);
+	aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
+
+	for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
+		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
+		NO_DBG_HEX(ulOffset);
+		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
+		NO_DBG_HEX(ulFileOffset);
+		aulFootnoteList[tIndex] = ulFileOffset;
+	}
+	aucBuffer = xfree(aucBuffer);
+} /* end of vGet2FootnotesInfo */
+
+/*
+ * Build the list with footnote text information for WinWord 1/2 files
+ */
+static void
+vGet2FootnotesText(FILE *pFile, const UCHAR *aucHeader)
+{
+	footnote_local_type	*pCurr;
+	UCHAR	*aucBuffer;
+	ULONG	ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
+	size_t	tFootnoteTextLen;
+	size_t	tIndex;
+
+	TRACE_MSG("vGet2FootnotesText");
+
+	fail(pFile == NULL || aucHeader == NULL);
+
+	ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
+	ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */
+	NO_DBG_HEX(ulBeginOfFootnotes);
+
+	ulBeginFootnoteText = ulGetLong(0x6a, aucHeader); /* fcPlcffndTxt */
+	NO_DBG_HEX(ulBeginFootnoteText);
+	tFootnoteTextLen =
+		(size_t)usGetWord(0x6e, aucHeader); /* cbPlcffndTxt */
+	NO_DBG_DEC(tFootnoteTextLen);
+
+	if (tFootnoteTextLen < 12) {
+		DBG_MSG("No Footnote text in this document");
+		return;
+	}
+
+	aucBuffer = xmalloc(tFootnoteTextLen);
+	if (!bReadBytes(aucBuffer,
+			tFootnoteTextLen, ulBeginFootnoteText, pFile)) {
+		aucBuffer = xfree(aucBuffer);
+		return;
+	}
+	NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
+
+	fail(tFootnoteTextLength != 0);
+	tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
+	fail(tFootnoteTextLength == 0);
+
+	fail(pFootnoteText != NULL);
+	pFootnoteText = xcalloc(tFootnoteTextLength,
+				sizeof(footnote_local_type));
+
+	for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
+		pCurr = pFootnoteText + tIndex;
+		pCurr->tInfo.szText = NULL;
+		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
+		NO_DBG_HEX(ulOffset);
+		ulCharPos = ulBeginOfFootnotes + ulOffset;
+		NO_DBG_HEX(ulCharPos);
+		NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
+		pCurr->ulCharPosStart = ulCharPos;
+		ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
+		NO_DBG_HEX(ulOffset);
+		ulCharPos = ulBeginOfFootnotes + ulOffset;
+		NO_DBG_HEX(ulCharPos);
+		NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
+		pCurr->ulCharPosNext = ulCharPos;
+		pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
+	}
+	aucBuffer = xfree(aucBuffer);
+} /* end of vGet2FootnotesText */
+
+/*
+ * Build the lists note information for WinWord 1/2 files
+ */
+static void
+vGet2NotesInfo(FILE *pFile, const UCHAR *aucHeader)
+{
+	TRACE_MSG("vGet2NotesInfo");
+
+	vGet2FootnotesInfo(pFile, aucHeader);
+	vGet2FootnotesText(pFile, aucHeader);
+	/* There are no endnotes in a WinWord 1/2 file */
+} /* end of vGet2NotesInfo */
+
 /*
  * Build the list with footnote information for Word 6/7 files
  */
@@ -41,17 +302,20 @@ vGet6FootnotesInfo(FILE *pFile, ULONG ulStartBlock,
 	UCHAR	*aucBuffer;
 	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
 	size_t	tFootnoteInfoLen;
-	int	iIndex;
+	size_t	tIndex;
+
+	TRACE_MSG("vGet6FootnotesInfo");
 
 	fail(pFile == NULL || aucHeader == NULL);
 	fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
 	fail(aulBBD == NULL);
 
-	ulBeginOfText = ulGetLong(0x18, aucHeader);
+	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
 	NO_DBG_HEX(ulBeginOfText);
-	ulBeginFootnoteInfo = ulGetLong(0x68, aucHeader);
+	ulBeginFootnoteInfo = ulGetLong(0x68, aucHeader); /* fcPlcffndRef */
 	NO_DBG_HEX(ulBeginFootnoteInfo);
-	tFootnoteInfoLen = (size_t)ulGetLong(0x6c, aucHeader);
+	tFootnoteInfoLen =
+		(size_t)ulGetLong(0x6c, aucHeader); /* lcbPlcffndRef */
 	NO_DBG_DEC(tFootnoteInfoLen);
 
 	if (tFootnoteInfoLen < 10) {
@@ -75,16 +339,88 @@ vGet6FootnotesInfo(FILE *pFile, ULONG ulStartBlock,
 	fail(aulFootnoteList != NULL);
 	aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
 
-	for (iIndex = 0; iIndex < (int)tFootnoteListLength; iIndex++) {
-		ulOffset = ulGetLong(iIndex * 4, aucBuffer);
+	for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
+		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
 		NO_DBG_HEX(ulOffset);
 		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
 		NO_DBG_HEX(ulFileOffset);
-		aulFootnoteList[iIndex] = ulFileOffset;
+		aulFootnoteList[tIndex] = ulFileOffset;
 	}
 	aucBuffer = xfree(aucBuffer);
 } /* end of vGet6FootnotesInfo */
 
+/*
+ * Build the list with footnote text information for Word 6/7 files
+ */
+static void
+vGet6FootnotesText(FILE *pFile, ULONG ulStartBlock,
+	const ULONG *aulBBD, size_t tBBDLen,
+	const UCHAR *aucHeader)
+{
+	footnote_local_type	*pCurr;
+	UCHAR	*aucBuffer;
+	ULONG	ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
+	size_t	tFootnoteTextLen;
+	size_t	tIndex;
+
+	TRACE_MSG("vGet6FootnotesText");
+
+	fail(pFile == NULL || aucHeader == NULL);
+	fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
+	fail(aulBBD == NULL);
+
+	ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
+	ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */
+	NO_DBG_HEX(ulBeginOfFootnotes);
+
+	ulBeginFootnoteText = ulGetLong(0x70, aucHeader); /* fcPlcffndTxt */
+	NO_DBG_HEX(ulBeginFootnoteText);
+	tFootnoteTextLen =
+		(size_t)ulGetLong(0x74, aucHeader); /* lcbPlcffndTxt */
+	NO_DBG_DEC(tFootnoteTextLen);
+
+	if (tFootnoteTextLen < 12) {
+		DBG_MSG("No Footnote text in this document");
+		return;
+	}
+
+	aucBuffer = xmalloc(tFootnoteTextLen);
+	if (!bReadBuffer(pFile, ulStartBlock,
+			aulBBD, tBBDLen, BIG_BLOCK_SIZE,
+			aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) {
+		aucBuffer = xfree(aucBuffer);
+		return;
+	}
+	NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
+
+	fail(tFootnoteTextLength != 0);
+	tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
+	fail(tFootnoteTextLength == 0);
+
+	fail(pFootnoteText != NULL);
+	pFootnoteText = xcalloc(tFootnoteTextLength,
+				sizeof(footnote_local_type));
+
+	for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
+		pCurr = pFootnoteText + tIndex;
+		pCurr->tInfo.szText = NULL;
+		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
+		NO_DBG_HEX(ulOffset);
+		ulCharPos = ulBeginOfFootnotes + ulOffset;
+		NO_DBG_HEX(ulCharPos);
+		NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
+		pCurr->ulCharPosStart = ulCharPos;
+		ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
+		NO_DBG_HEX(ulOffset);
+		ulCharPos = ulBeginOfFootnotes + ulOffset;
+		NO_DBG_HEX(ulCharPos);
+		NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
+		pCurr->ulCharPosNext = ulCharPos;
+		pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
+	}
+	aucBuffer = xfree(aucBuffer);
+} /* end of vGet6FootnotesText */
+
 /*
  * Build the list with endnote information for Word 6/7 files
  */
@@ -96,17 +432,20 @@ vGet6EndnotesInfo(FILE *pFile, ULONG ulStartBlock,
 	UCHAR	*aucBuffer;
 	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo;
 	size_t	tEndnoteInfoLen;
-	int	iIndex;
+	size_t	tIndex;
+
+	TRACE_MSG("vGet6EndnotesInfo");
 
 	fail(pFile == NULL || aucHeader == NULL);
 	fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
 	fail(aulBBD == NULL);
 
-	ulBeginOfText = ulGetLong(0x18, aucHeader);
+	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
 	NO_DBG_HEX(ulBeginOfText);
-	ulBeginEndnoteInfo = ulGetLong(0x1d2, aucHeader);
+	ulBeginEndnoteInfo = ulGetLong(0x1d2, aucHeader); /* fcPlcfendRef */
 	NO_DBG_HEX(ulBeginEndnoteInfo);
-	tEndnoteInfoLen = (size_t)ulGetLong(0x1d6, aucHeader);
+	tEndnoteInfoLen =
+		(size_t)ulGetLong(0x1d6, aucHeader); /* lcbPlcfendRef */
 	NO_DBG_DEC(tEndnoteInfoLen);
 
 	if (tEndnoteInfoLen < 10) {
@@ -130,12 +469,12 @@ vGet6EndnotesInfo(FILE *pFile, ULONG ulStartBlock,
 	fail(aulEndnoteList != NULL);
 	aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG));
 
-	for (iIndex = 0; iIndex < (int)tEndnoteListLength; iIndex++) {
-		ulOffset = ulGetLong(iIndex * 4, aucBuffer);
+	for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
+		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
 		NO_DBG_HEX(ulOffset);
 		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
 		NO_DBG_HEX(ulFileOffset);
-		aulEndnoteList[iIndex] = ulFileOffset;
+		aulEndnoteList[tIndex] = ulFileOffset;
 	}
 	aucBuffer = xfree(aucBuffer);
 } /* end of vGet6EndnotesInfo */
@@ -148,8 +487,12 @@ vGet6NotesInfo(FILE *pFile, ULONG ulStartBlock,
 	const ULONG *aulBBD, size_t tBBDLen,
 	const UCHAR *aucHeader)
 {
+	TRACE_MSG("vGet6NotesInfo");
+
 	vGet6FootnotesInfo(pFile, ulStartBlock,
 			aulBBD, tBBDLen, aucHeader);
+	vGet6FootnotesText(pFile, ulStartBlock,
+			aulBBD, tBBDLen, aucHeader);
 	vGet6EndnotesInfo(pFile, ulStartBlock,
 			aulBBD, tBBDLen, aucHeader);
 } /* end of vGet6NotesInfo */
@@ -166,16 +509,17 @@ vGet8FootnotesInfo(FILE *pFile, const pps_info_type *pPPS,
 	const ULONG	*aulBlockDepot;
 	UCHAR	*aucBuffer;
 	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
-	ULONG	ulTableSize, ulTableStartBlock;
 	size_t	tFootnoteInfoLen, tBlockDepotLen, tBlockSize;
-	int	iIndex;
-	USHORT	usDocStatus;
+	size_t	tIndex;
+
+	TRACE_MSG("vGet8FootnotesInfo");
 
-	ulBeginOfText = ulGetLong(0x18, aucHeader);
+	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
 	NO_DBG_HEX(ulBeginOfText);
-	ulBeginFootnoteInfo = ulGetLong(0xaa, aucHeader);
+	ulBeginFootnoteInfo = ulGetLong(0xaa, aucHeader); /* fcPlcffndRef */
 	NO_DBG_HEX(ulBeginFootnoteInfo);
-	tFootnoteInfoLen = (size_t)ulGetLong(0xae, aucHeader);
+	tFootnoteInfoLen =
+		(size_t)ulGetLong(0xae, aucHeader); /* lcbPlcffndRef */
 	NO_DBG_DEC(tFootnoteInfoLen);
 
 	if (tFootnoteInfoLen < 10) {
@@ -183,22 +527,14 @@ vGet8FootnotesInfo(FILE *pFile, const pps_info_type *pPPS,
 		return;
 	}
 
-	/* Use 0Table or 1Table? */
-	usDocStatus = usGetWord(0x0a, aucHeader);
-	if (usDocStatus & BIT(9)) {
-		ulTableStartBlock = pPPS->t1Table.ulSB;
-		ulTableSize = pPPS->t1Table.ulSize;
-	} else {
-		ulTableStartBlock = pPPS->t0Table.ulSB;
-		ulTableSize = pPPS->t0Table.ulSize;
-	}
-	NO_DBG_DEC(ulTableStartBlock);
-	if (ulTableStartBlock == 0) {
-		DBG_MSG("No notes information");
+	NO_DBG_DEC(pPPS->tTable.ulSB);
+	NO_DBG_HEX(pPPS->tTable.ulSize);
+	if (pPPS->tTable.ulSize == 0) {
+		DBG_MSG("No footnotes information");
 		return;
 	}
-	NO_DBG_HEX(ulTableSize);
-	if (ulTableSize < MIN_SIZE_FOR_BBD_USE) {
+
+	if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
 	  	/* Use the Small Block Depot */
 		aulBlockDepot = aulSBD;
 		tBlockDepotLen = tSBDLen;
@@ -210,7 +546,7 @@ vGet8FootnotesInfo(FILE *pFile, const pps_info_type *pPPS,
 		tBlockSize = BIG_BLOCK_SIZE;
 	}
 	aucBuffer = xmalloc(tFootnoteInfoLen);
-	if (!bReadBuffer(pFile, ulTableStartBlock,
+	if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
 			aulBlockDepot, tBlockDepotLen, tBlockSize,
 			aucBuffer, ulBeginFootnoteInfo, tFootnoteInfoLen)) {
 		aucBuffer = xfree(aucBuffer);
@@ -225,16 +561,104 @@ vGet8FootnotesInfo(FILE *pFile, const pps_info_type *pPPS,
 	fail(aulFootnoteList != NULL);
 	aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
 
-	for (iIndex = 0; iIndex < (int)tFootnoteListLength; iIndex++) {
-		ulOffset = ulGetLong(iIndex * 4, aucBuffer);
+	for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
+		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
 		NO_DBG_HEX(ulOffset);
 		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
 		NO_DBG_HEX(ulFileOffset);
-		aulFootnoteList[iIndex] = ulFileOffset;
+		aulFootnoteList[tIndex] = ulFileOffset;
 	}
 	aucBuffer = xfree(aucBuffer);
 } /* end of vGet8FootnotesInfo */
 
+/*
+ * Build the list with footnote text information for Word 8/9/10 files
+ */
+static void
+vGet8FootnotesText(FILE *pFile, const pps_info_type *pPPS,
+	const ULONG *aulBBD, size_t tBBDLen,
+	const ULONG *aulSBD, size_t tSBDLen,
+	const UCHAR *aucHeader)
+{
+	footnote_local_type	*pCurr;
+	const ULONG	*aulBlockDepot;
+	UCHAR	*aucBuffer;
+	ULONG	ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
+	size_t	tFootnoteTextLen, tBlockDepotLen, tBlockSize;
+	size_t	tIndex;
+
+	TRACE_MSG("vGet8FootnotesText");
+
+	ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
+	ulBeginOfFootnotes += ulGetLong(0x4c, aucHeader); /* ccpText */
+	NO_DBG_HEX(ulBeginOfFootnotes);
+
+	ulBeginFootnoteText = ulGetLong(0xb2, aucHeader); /* fcPlcffndTxt */
+	NO_DBG_HEX(ulBeginFootnoteText);
+	tFootnoteTextLen =
+		(size_t)ulGetLong(0xb6, aucHeader); /* lcbPlcffndTxt */
+	NO_DBG_DEC(tFootnoteTextLen);
+
+	if (tFootnoteTextLen < 12) {
+		DBG_MSG("No Footnote text in this document");
+		return;
+	}
+
+	NO_DBG_DEC(pPPS->tTable.ulSB);
+	NO_DBG_HEX(pPPS->tTable.ulSize);
+	if (pPPS->tTable.ulSize == 0) {
+		DBG_MSG("No footnote text information");
+		return;
+	}
+
+	if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
+	  	/* Use the Small Block Depot */
+		aulBlockDepot = aulSBD;
+		tBlockDepotLen = tSBDLen;
+		tBlockSize = SMALL_BLOCK_SIZE;
+	} else {
+	  	/* Use the Big Block Depot */
+		aulBlockDepot = aulBBD;
+		tBlockDepotLen = tBBDLen;
+		tBlockSize = BIG_BLOCK_SIZE;
+	}
+	aucBuffer = xmalloc(tFootnoteTextLen);
+	if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
+			aulBlockDepot, tBlockDepotLen, tBlockSize,
+			aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) {
+		aucBuffer = xfree(aucBuffer);
+		return;
+	}
+	NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
+
+	fail(tFootnoteTextLength != 0);
+	tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
+	fail(tFootnoteTextLength == 0);
+
+	fail(pFootnoteText != NULL);
+	pFootnoteText = xcalloc(tFootnoteTextLength,
+				sizeof(footnote_local_type));
+
+	for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
+		pCurr = pFootnoteText + tIndex;
+		pCurr->tInfo.szText = NULL;
+		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
+		NO_DBG_HEX(ulOffset);
+		ulCharPos = ulBeginOfFootnotes + ulOffset;
+		NO_DBG_HEX(ulCharPos);
+		NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
+		pCurr->ulCharPosStart = ulCharPos;
+		ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
+		NO_DBG_HEX(ulOffset);
+		ulCharPos = ulBeginOfFootnotes + ulOffset;
+		NO_DBG_HEX(ulCharPos);
+		NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
+		pCurr->ulCharPosNext = ulCharPos;
+		pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
+	}
+	aucBuffer = xfree(aucBuffer);
+} /* end of vGet8FootnotesText */
+
 /*
  * Build the list with endnote information for Word 8/9/10 files
  */
@@ -247,39 +671,31 @@ vGet8EndnotesInfo(FILE *pFile, const pps_info_type *pPPS,
 	const ULONG	*aulBlockDepot;
 	UCHAR	*aucBuffer;
 	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo;
-	ULONG	ulTableSize, ulTableStartBlock;
 	size_t	tEndnoteInfoLen, tBlockDepotLen, tBlockSize;
-	int	iIndex;
-	USHORT	usDocStatus;
+	size_t	tIndex;
+
+	TRACE_MSG("vGet8EndnotesInfo");
 
-	ulBeginOfText = ulGetLong(0x18, aucHeader);
+	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
 	NO_DBG_HEX(ulBeginOfText);
-	ulBeginEndnoteInfo = ulGetLong(0x20a, aucHeader);
+	ulBeginEndnoteInfo = ulGetLong(0x20a, aucHeader); /* fcPlcfendRef */
 	NO_DBG_HEX(ulBeginEndnoteInfo);
-	tEndnoteInfoLen = (size_t)ulGetLong(0x20e, aucHeader);
+	tEndnoteInfoLen = (size_t)ulGetLong(0x20e, aucHeader); /* lcbPlcfendRef */
 	NO_DBG_DEC(tEndnoteInfoLen);
 
 	if (tEndnoteInfoLen < 10) {
-		DBG_MSG("No Endnotes in this document");
+		DBG_MSG("No endnotes in this document");
 		return;
 	}
 
-	/* Use 0Table or 1Table? */
-	usDocStatus = usGetWord(0x0a, aucHeader);
-	if (usDocStatus & BIT(9)) {
-		ulTableStartBlock = pPPS->t1Table.ulSB;
-		ulTableSize = pPPS->t1Table.ulSize;
-	} else {
-		ulTableStartBlock = pPPS->t0Table.ulSB;
-		ulTableSize = pPPS->t0Table.ulSize;
-	}
-	NO_DBG_DEC(ulTableStartBlock);
-	if (ulTableStartBlock == 0) {
-		DBG_MSG("No notes information");
+	NO_DBG_DEC(pPPS->tTable.ulSB);
+	NO_DBG_HEX(pPPS->tTable.ulSize);
+	if (pPPS->tTable.ulSize == 0) {
+		DBG_MSG("No endnotes information");
 		return;
 	}
-	NO_DBG_HEX(ulTableSize);
-	if (ulTableSize < MIN_SIZE_FOR_BBD_USE) {
+
+	if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
 	  	/* Use the Small Block Depot */
 		aulBlockDepot = aulSBD;
 		tBlockDepotLen = tSBDLen;
@@ -291,7 +707,7 @@ vGet8EndnotesInfo(FILE *pFile, const pps_info_type *pPPS,
 		tBlockSize = BIG_BLOCK_SIZE;
 	}
 	aucBuffer = xmalloc(tEndnoteInfoLen);
-	if (!bReadBuffer(pFile, ulTableStartBlock,
+	if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
 			aulBlockDepot, tBlockDepotLen, tBlockSize,
 			aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) {
 		aucBuffer = xfree(aucBuffer);
@@ -306,12 +722,12 @@ vGet8EndnotesInfo(FILE *pFile, const pps_info_type *pPPS,
 	fail(aulEndnoteList != NULL);
 	aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG));
 
-	for (iIndex = 0; iIndex < (int)tEndnoteListLength; iIndex++) {
-		ulOffset = ulGetLong(iIndex * 4, aucBuffer);
+	for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
+		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
 		NO_DBG_HEX(ulOffset);
 		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
 		NO_DBG_HEX(ulFileOffset);
-		aulEndnoteList[iIndex] = ulFileOffset;
+		aulEndnoteList[tIndex] = ulFileOffset;
 	}
 	aucBuffer = xfree(aucBuffer);
 } /* end of vGet8EndnotesInfo */
@@ -325,8 +741,12 @@ vGet8NotesInfo(FILE *pFile, const pps_info_type *pPPS,
 	const ULONG *aulSBD, size_t tSBDLen,
 	const UCHAR *aucHeader)
 {
+	TRACE_MSG("vGet8NotesInfo");
+
 	vGet8FootnotesInfo(pFile, pPPS,
 			aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
+	vGet8FootnotesText(pFile, pPPS,
+			aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
 	vGet8EndnotesInfo(pFile, pPPS,
 			aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
 } /* end of vGet8NotesInfo */
@@ -340,11 +760,25 @@ vGetNotesInfo(FILE *pFile, const pps_info_type *pPPS,
 	const ULONG *aulSBD, size_t tSBDLen,
 	const UCHAR *aucHeader, int iWordVersion)
 {
-	fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
-	fail(iWordVersion < 6 || iWordVersion > 8);
-	fail(aulBBD == NULL || aulSBD == NULL);
+	TRACE_MSG("vGetNotesInfo");
+
+	fail(pFile == NULL);
+	fail(pPPS == NULL && iWordVersion >= 6);
+	fail(aulBBD == NULL && tBBDLen != 0);
+	fail(aulSBD == NULL && tSBDLen != 0);
+	fail(aucHeader == NULL);
 
 	switch (iWordVersion) {
+	case 0:
+		vGet0NotesInfo(pFile, aucHeader);
+		break;
+	case 1:
+	case 2:
+		vGet2NotesInfo(pFile, aucHeader);
+		break;
+	case 4:
+	case 5:
+		break;
 	case 6:
 	case 7:
 		vGet6NotesInfo(pFile, pPPS->tWordDocument.ulSB,
@@ -360,6 +794,49 @@ vGetNotesInfo(FILE *pFile, const pps_info_type *pPPS,
 	}
 } /* end of vGetNotesInfo */
 
+/*
+ *  vPrepareFootnoteText - prepare the footnote text
+ */
+void
+vPrepareFootnoteText(FILE *pFile)
+{ 
+	footnote_local_type	*pCurr;
+	size_t		tFootnote;
+
+	fail(pFile == NULL);
+	fail(pFootnoteText == NULL && tFootnoteTextLength != 0);
+
+	if (pFootnoteText == NULL || tFootnoteTextLength == 0) {
+		/* No information */
+		return;
+	}
+
+	/* Fill text and useful-ness */
+	for (tFootnote = 0; tFootnote < tFootnoteTextLength; tFootnote++) {
+		pCurr = pFootnoteText + tFootnote;
+		pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
+		if (pCurr->bUseful) {
+			pCurr->tInfo.szText = szFootnoteDecryptor(pFile,
+							pCurr->ulCharPosStart,
+							pCurr->ulCharPosNext);
+		} else {
+			pCurr->tInfo.szText = NULL;
+		}
+	}
+} /* end of vPrepareFootnoteText */
+
+/*
+ * szGetFootnootText - get the text of the spefified footnote
+ */
+const char *
+szGetFootnootText(UINT uiFootnoteIndex)
+{
+	if ((size_t)uiFootnoteIndex >= tFootnoteTextLength) {
+		return NULL;
+	}
+	return pFootnoteText[uiFootnoteIndex].tInfo.szText;
+} /* end of szGetFootnootText */
+
 /*
  * Get the notetype of the note at the given fileoffset
  */
@@ -368,6 +845,8 @@ eGetNotetype(ULONG ulFileOffset)
 {
 	size_t	tIndex;
 
+	TRACE_MSG("eGetNotetype");
+
 	fail(aulFootnoteList == NULL && tFootnoteListLength != 0);
 	fail(aulEndnoteList == NULL && tEndnoteListLength != 0);
 

+ 317 - 153
sys/src/cmd/aux/antiword/options.c

@@ -1,6 +1,6 @@
 /*
  * options.c
- * Copyright (C) 1998-2003 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Read and write the options
@@ -10,10 +10,11 @@
 #include <stdlib.h>
 #include <string.h>
 #if defined(__riscos)
-#include "wimpt.h"
+#include "DeskLib:Error.h"
+#include "DeskLib:Wimp.h"
 #else
 #include <stdlib.h>
-#if defined(__dos)
+#if defined(__dos) || defined(N_PLAT_NLM)
 extern int getopt(int, char **, const char *);
 #else
 #include <unistd.h>
@@ -28,6 +29,8 @@ extern int getopt(int, char **, const char *);
 #define SHOW_IMAGES		"set show_images=%d"
 #define HIDE_HIDDEN_TEXT	"set hide_hidden_text=%d"
 #define SCALE_FACTOR_START	"set scale_factor_start=%d"
+#else
+#define LEAFNAME_SIZE		(32+1)
 #endif /* __riscos */
 
 /* Current values for options */
@@ -68,9 +71,10 @@ static const options_type	tOptionsDefault = {
 #else
 	conversion_text,
 #endif /* __riscos */
+	TRUE,
 	TRUE,
 	FALSE,
-	encoding_iso_8859_1,
+	encoding_latin_1,
 	INT_MAX,
 	INT_MAX,
 	level_default,
@@ -81,6 +85,189 @@ static const options_type	tOptionsDefault = {
 };
 
 
+#if !defined(__riscos)
+/*
+ * bCorrectPapersize - see if the papersize is correct
+ *
+ * TRUE if the papersize is correct, otherwise FALSE
+ */
+static BOOL
+bCorrectPapersize(const char *szName, conversion_type eConversionType)
+{
+	const papersize_type	*pPaperSize;
+
+	for (pPaperSize = atPaperSizes;
+	     pPaperSize->szName[0] != '\0';
+	     pPaperSize++) {
+		if (!STRCEQ(pPaperSize->szName,  szName)) {
+			continue;
+		}
+		DBG_DEC(pPaperSize->usWidth);
+		DBG_DEC(pPaperSize->usHeight);
+		tOptionsCurr.eConversionType = eConversionType;
+		tOptionsCurr.iPageHeight = (int)pPaperSize->usHeight;
+		tOptionsCurr.iPageWidth = (int)pPaperSize->usWidth;
+		return TRUE;
+	}
+	return FALSE;
+} /* end of bCorrectPapersize */
+
+/*
+ * szCreateSuffix - create a suffix for the file
+ *
+ * Returns the suffix
+ */
+static const char *
+szCreateSuffix(const char *szLeafname)
+{
+	const char	*pcDot;
+
+	pcDot = strrchr(szLeafname, '.');
+	if (pcDot != NULL && STRCEQ(pcDot, ".txt")) {
+		/* There is already a .txt suffix, no need for another one */
+		return "";
+	}
+	return ".txt";
+} /* end of szCreateSuffix */
+
+/*
+ * eMappingFile2Encoding - convert the mapping file to an encoding
+ */
+static encoding_type
+eMappingFile2Encoding(const char *szLeafname)
+{
+	char	szMappingFile[LEAFNAME_SIZE+4];
+
+	fail(szLeafname == NULL);
+
+	if (strlen(szLeafname) + 4 >= sizeof(szMappingFile)) {
+		DBG_MSG(szLeafname);
+		return encoding_latin_1;
+	}
+
+	sprintf(szMappingFile, "%s%s", szLeafname, szCreateSuffix(szLeafname));
+
+	DBG_MSG(szMappingFile);
+
+	if (STRCEQ(szMappingFile, MAPPING_FILE_UTF_8)) {
+		return encoding_utf_8;
+	}
+	if (STRCEQ(szMappingFile, MAPPING_FILE_CP852) ||
+	    STRCEQ(szMappingFile, MAPPING_FILE_CP1250) ||
+	    STRCEQ(szMappingFile, MAPPING_FILE_8859_2)) {
+		return encoding_latin_2;
+	}
+	if (STRCEQ(szMappingFile, MAPPING_FILE_KOI8_R) ||
+	    STRCEQ(szMappingFile, MAPPING_FILE_KOI8_U) ||
+	    STRCEQ(szMappingFile, MAPPING_FILE_CP866) ||
+	    STRCEQ(szMappingFile, MAPPING_FILE_CP1251) ||
+	    STRCEQ(szMappingFile, MAPPING_FILE_8859_5)) {
+		return encoding_cyrillic;
+	}
+	return encoding_latin_1;
+} /* end of eMappingFile2Encoding */
+#endif /* !__riscos */
+
+/*
+ * pOpenCharacterMappingFile - open the mapping file
+ *
+ * Returns the file pointer or NULL
+ */
+static FILE *
+pOpenCharacterMappingFile(const char *szLeafname)
+{
+#if !defined(__riscos)
+	FILE	*pFile;
+	const char	*szHome, *szAntiword, *szSuffix;
+	size_t	tFilenameLen;
+	char	szMappingFile[PATH_MAX+1];
+#endif /* !__riscos */
+
+	if (szLeafname == NULL || szLeafname[0] == '\0') {
+		return NULL;
+	}
+
+	DBG_MSG(szLeafname);
+
+#if defined(__riscos)
+	return fopen(szLeafname, "r");
+#else
+	/* Set the suffix */
+	szSuffix = szCreateSuffix(szLeafname);
+
+	/* Set length */
+	tFilenameLen = strlen(szLeafname) + strlen(szSuffix);
+
+	/* Try the environment version of the mapping file */
+	szAntiword = szGetAntiwordDirectory();
+	if (szAntiword != NULL && szAntiword[0] != '\0') {
+	    if (strlen(szAntiword) + tFilenameLen <
+		sizeof(szMappingFile) -
+		sizeof(FILE_SEPARATOR)) {
+			sprintf(szMappingFile,
+				"%s" FILE_SEPARATOR "%s%s",
+				szAntiword, szLeafname, szSuffix);
+			DBG_MSG(szMappingFile);
+			pFile = fopen(szMappingFile, "r");
+			if (pFile != NULL) {
+				return pFile;
+			}
+		} else {
+			werr(0, "Environment mappingfilename ignored");
+		}
+	}
+
+	/* Try the local version of the mapping file */
+	szHome = szGetHomeDirectory();
+	if (strlen(szHome) + tFilenameLen <
+	    sizeof(szMappingFile) -
+	    sizeof(ANTIWORD_DIR) -
+	    2 * sizeof(FILE_SEPARATOR)) {
+		sprintf(szMappingFile,
+			"%s" FILE_SEPARATOR ANTIWORD_DIR FILE_SEPARATOR "%s%s",
+			szHome, szLeafname, szSuffix);
+		DBG_MSG(szMappingFile);
+		pFile = fopen(szMappingFile, "r");
+		if (pFile != NULL) {
+			return pFile;
+		}
+	} else {
+		werr(0, "Local mappingfilename too long, ignored");
+	}
+
+	/* Try the global version of the mapping file */
+	if (tFilenameLen <
+	    sizeof(szMappingFile) -
+	    sizeof(GLOBAL_ANTIWORD_DIR) -
+	    sizeof(FILE_SEPARATOR)) {
+		sprintf(szMappingFile,
+			GLOBAL_ANTIWORD_DIR FILE_SEPARATOR "%s%s",
+			szLeafname, szSuffix);
+		DBG_MSG(szMappingFile);
+		pFile = fopen(szMappingFile, "r");
+		if (pFile != NULL) {
+			return pFile;
+		}
+	} else {
+		werr(0, "Global mappingfilename too long, ignored");
+	}
+	werr(0, "I can't open your mapping file (%s%s)\n"
+		"It is not in '%s" FILE_SEPARATOR ANTIWORD_DIR "' nor in '"
+		GLOBAL_ANTIWORD_DIR "'.", szLeafname, szSuffix, szHome);
+	return NULL;
+#endif /* __riscos */
+} /* end of pOpenCharacterMappingFile */
+
+/*
+ * vCloseCharacterMappingFile - close the mapping file
+ */
+static void
+vCloseCharacterMappingFile(FILE *pFile)
+{
+	(void)fclose(pFile);
+} /* end of pCloseCharacterMappingFile */
+
+
 /*
  * iReadOptions - read options
  *
@@ -99,15 +286,13 @@ iReadOptions(int argc, char **argv)
 #else
 	extern	char	*optarg;
 	extern int	optind;
-	const papersize_type	*pPaperSize;
-	const char	*szHome, *szAntiword;
 	char	*pcChar, *szTmp;
 	int	iChar;
-	BOOL	bFound;
-	char	szLeafname[32+1];
-	char	szMappingFile[PATH_MAX+1];
+	char	szLeafname[LEAFNAME_SIZE];
 #endif /* __riscos */
+	FILE	*pCharacterMappingFile;
 	int	iTmp;
+	BOOL	bSuccess;
 
 	DBG_MSG("iReadOptions");
 
@@ -175,10 +360,14 @@ iReadOptions(int argc, char **argv)
 		werr(0, "Alphabet '%d' is not supported", iAlphabet);
 		return -1;
 	}
-	if (bReadCharacterMappingTable(szAlphabet)) {
-		return 1;
+	pCharacterMappingFile = pOpenCharacterMappingFile(szAlphabet);
+	if (pCharacterMappingFile != NULL) {
+		bSuccess = bReadCharacterMappingTable(pCharacterMappingFile);
+		vCloseCharacterMappingFile(pCharacterMappingFile);
+	} else {
+		bSuccess = FALSE;
 	}
-	return -1;
+	return bSuccess ? 1 : -1;
 #else
 /* Environment */
 	szTmp = getenv("COLUMNS");
@@ -196,19 +385,23 @@ iReadOptions(int argc, char **argv)
 			DBG_DEC(tOptionsCurr.iParagraphBreak);
 		}
 	}
-	if (is_locale_utf8()) {
-		tOptionsCurr.eEncoding = encoding_utf8;
-		strcpy(szLeafname, MAPPING_FILE_DEFAULT_8);
-	} else {
-		tOptionsCurr.eEncoding = encoding_iso_8859_1;
-		strcpy(szLeafname, MAPPING_FILE_DEFAULT_1);
-	}
+	strncpy(szLeafname, szGetDefaultMappingFile(), sizeof(szLeafname) - 1);
+	szLeafname[sizeof(szLeafname) - 1] = '\0';
 /* Command line */
-	while ((iChar = getopt(argc, argv, "Lhi:m:p:stw:x:")) != -1) {
+	while ((iChar = getopt(argc, argv, "La:fhi:m:p:rstw:x:")) != -1) {
 		switch (iChar) {
 		case 'L':
 			tOptionsCurr.bUseLandscape = TRUE;
 			break;
+		case 'a':
+			if (!bCorrectPapersize(optarg, conversion_pdf)) {
+				werr(0, "-a without a valid papersize");
+				return -1;
+			}
+			break;
+		case 'f':
+			tOptionsCurr.eConversionType = conversion_fmt_text;
+			break;
 		case 'h':
 			return 0;
 		case 'i':
@@ -243,38 +436,16 @@ iReadOptions(int argc, char **argv)
 			strncpy(szLeafname, optarg, sizeof(szLeafname) - 1);
 			szLeafname[sizeof(szLeafname) - 1] = '\0';
 			DBG_MSG(szLeafname);
-			if (STRCEQ(szLeafname, MAPPING_FILE_DEFAULT_8)) {
-				tOptionsCurr.eEncoding = encoding_utf8;
-			} else if (STRCEQ(szLeafname, MAPPING_FILE_DEFAULT_2)) {
-				tOptionsCurr.eEncoding = encoding_iso_8859_2;
-			} else {
-				tOptionsCurr.eEncoding = encoding_iso_8859_1;
-			}
-			DBG_DEC(tOptionsCurr.eEncoding);
 			break;
 		case 'p':
-			bFound = FALSE;
-			for (pPaperSize = atPaperSizes;
-			     pPaperSize->szName[0] != '\0';
-			     pPaperSize++) {
-				if (!STREQ(pPaperSize->szName,  optarg)) {
-					continue;
-				}
-				DBG_DEC(pPaperSize->usWidth);
-				DBG_DEC(pPaperSize->usHeight);
-				tOptionsCurr.eConversionType = conversion_ps;
-				tOptionsCurr.iPageHeight =
-						(int)pPaperSize->usHeight;
-				tOptionsCurr.iPageWidth =
-						(int)pPaperSize->usWidth;
-				bFound = TRUE;
-				break;
-			}
-			if (!bFound) {
+			if (!bCorrectPapersize(optarg, conversion_ps)) {
 				werr(0, "-p without a valid papersize");
 				return -1;
 			}
 			break;
+		case 'r':
+			tOptionsCurr.bRemoveRemovedText = FALSE;
+			break;
 		case 's':
 			tOptionsCurr.bHideHiddenText = FALSE;
 			break;
@@ -297,7 +468,7 @@ iReadOptions(int argc, char **argv)
 			if (STREQ(optarg, "db")) {
 				tOptionsCurr.iParagraphBreak = 0;
 				tOptionsCurr.eConversionType = conversion_xml;
-				tOptionsCurr.eEncoding = encoding_utf8;
+				strcpy(szLeafname, MAPPING_FILE_UTF_8);
 			} else {
 				werr(0, "-x %s is not supported", optarg);
 				return -1;
@@ -308,15 +479,33 @@ iReadOptions(int argc, char **argv)
 		}
 	}
 
+	tOptionsCurr.eEncoding = eMappingFile2Encoding(szLeafname);
+	DBG_DEC(tOptionsCurr.eEncoding);
+
 	if (tOptionsCurr.eConversionType == conversion_ps &&
-	    tOptionsCurr.eEncoding == encoding_utf8) {
+	    tOptionsCurr.eEncoding == encoding_utf_8) {
 		werr(0,
 		"The combination PostScript and UTF-8 is not supported");
 		return -1;
 	}
 
-	if (tOptionsCurr.eConversionType == conversion_ps) {
-		/* PostScript mode */
+	if (tOptionsCurr.eConversionType == conversion_pdf &&
+	    tOptionsCurr.eEncoding == encoding_utf_8) {
+		werr(0,
+		"The combination PDF and UTF-8 is not supported");
+		return -1;
+	}
+
+	if (tOptionsCurr.eConversionType == conversion_pdf &&
+	    tOptionsCurr.eEncoding == encoding_cyrillic) {
+		werr(0,
+		"The combination PDF and Cyrillic is not supported");
+		return -1;
+	}
+
+	if (tOptionsCurr.eConversionType == conversion_ps ||
+	    tOptionsCurr.eConversionType == conversion_pdf) {
+		/* PostScript or PDF mode */
 		if (tOptionsCurr.bUseLandscape) {
 			/* Swap the page height and width */
 			iTmp = tOptionsCurr.iPageHeight;
@@ -331,58 +520,14 @@ iReadOptions(int argc, char **argv)
 		DBG_DEC(tOptionsCurr.iParagraphBreak);
 	}
 
-	/* Try the environment version of the mapping file */
-	szAntiword = szGetAntiwordDirectory();
-	if (szAntiword != NULL && szAntiword[0] != '\0') {
-	    if (strlen(szAntiword) + strlen(szLeafname) <
-		sizeof(szMappingFile) -
-		sizeof(FILE_SEPARATOR)) {
-			sprintf(szMappingFile,
-				"%s" FILE_SEPARATOR "%s",
-				szAntiword, szLeafname);
-			DBG_MSG(szMappingFile);
-			if (bReadCharacterMappingTable(szMappingFile)) {
-				return optind;
-			}
-		} else {
-			werr(0, "Environment mappingfilename ignored");
-		}
-	}
-	/* Try the local version of the mapping file */
-	szHome = szGetHomeDirectory();
-	if (strlen(szHome) + strlen(szLeafname) <
-	    sizeof(szMappingFile) -
-	    sizeof(ANTIWORD_DIR) -
-	    2 * sizeof(FILE_SEPARATOR)) {
-		sprintf(szMappingFile,
-			"%s" FILE_SEPARATOR ANTIWORD_DIR FILE_SEPARATOR "%s",
-			szHome, szLeafname);
-		DBG_MSG(szMappingFile);
-		if (bReadCharacterMappingTable(szMappingFile)) {
-			return optind;
-		}
+	pCharacterMappingFile = pOpenCharacterMappingFile(szLeafname);
+	if (pCharacterMappingFile != NULL) {
+		bSuccess = bReadCharacterMappingTable(pCharacterMappingFile);
+		vCloseCharacterMappingFile(pCharacterMappingFile);
 	} else {
-		werr(0, "Local mappingfilename too long, ignored");
+		bSuccess = FALSE;
 	}
-	/* Try the global version of the mapping file */
-	if (strlen(szLeafname) <
-	    sizeof(szMappingFile) -
-	    sizeof(GLOBAL_ANTIWORD_DIR) -
-	    sizeof(FILE_SEPARATOR)) {
-		sprintf(szMappingFile,
-			GLOBAL_ANTIWORD_DIR FILE_SEPARATOR "%s",
-			szLeafname);
-		DBG_MSG(szMappingFile);
-		if (bReadCharacterMappingTable(szMappingFile)) {
-			return optind;
-		}
-	} else {
-		werr(0, "Global mappingfilename too long, ignored");
-	}
-	werr(0, "I can't open your mapping file (%s)\n"
-		"It is not in '%s" FILE_SEPARATOR ANTIWORD_DIR "' nor in '"
-		GLOBAL_ANTIWORD_DIR "'.", szLeafname, szHome);
-	return -1;
+	return bSuccess ? optind : -1;
 #endif /* __riscos */
 } /* end of iReadOptions */
 
@@ -407,7 +552,7 @@ vWriteOptions(void)
 	FILE	*pFile;
 	char	*szOptionsFile;
 
-	DBG_MSG("vWriteOptions");
+	TRACE_MSG("vWriteOptions");
 
 	szOptionsFile = getenv("AntiWord$ChoicesSave");
 	if (szOptionsFile == NULL) {
@@ -443,9 +588,9 @@ vWriteOptions(void)
  * vChoicesOpenAction - action to be taken when the Choices window opens
  */
 void
-vChoicesOpenAction(wimp_w tWindow)
+vChoicesOpenAction(window_handle tWindow)
 {
-	DBG_MSG("vChoicesOpenAction");
+	TRACE_MSG("vChoicesOpenAction");
 
 	tOptionsTemp = tOptionsCurr;
 	if (tOptionsTemp.iParagraphBreak == 0) {
@@ -483,15 +628,16 @@ vChoicesOpenAction(wimp_w tWindow)
 	}
 	vUpdateWriteableNumber(tWindow,
 		CHOICES_SCALE_WRITEABLE, tOptionsTemp.iScaleFactor);
+	TRACE_MSG("end of vChoicesOpenAction");
 } /* end of vChoicesOpenAction */
 
 /*
  * vDefaultButtonAction - action when the default button is clicked
  */
 static void
-vDefaultButtonAction(wimp_w tWindow)
+vDefaultButtonAction(window_handle tWindow)
 {
-	DBG_MSG("vDefaultButtonAction");
+	TRACE_MSG("vDefaultButtonAction");
 
 	tOptionsTemp = tOptionsDefault;
 	vUpdateRadioButton(tWindow, CHOICES_BREAK_BUTTON, TRUE);
@@ -520,7 +666,7 @@ vDefaultButtonAction(wimp_w tWindow)
 static void
 vApplyButtonAction(void)
 {
-	DBG_MSG("vApplyButtonAction");
+	TRACE_MSG("vApplyButtonAction");
 
 	tOptionsCurr = tOptionsTemp;
 } /* end of vApplyButtonAction */
@@ -531,7 +677,7 @@ vApplyButtonAction(void)
 static void
 vSaveButtonAction(void)
 {
-	DBG_MSG("vSaveButtonAction");
+	TRACE_MSG("vSaveButtonAction");
 
 	vApplyButtonAction();
 	vWriteOptions();
@@ -541,7 +687,7 @@ vSaveButtonAction(void)
  * vSetParagraphBreak - set the paragraph break to the given number
  */
 static void
-vSetParagraphBreak(wimp_w tWindow, int iNumber)
+vSetParagraphBreak(window_handle tWindow, int iNumber)
 {
 	tOptionsTemp.iParagraphBreak = iNumber;
 	if (tOptionsTemp.iParagraphBreak == 0) {
@@ -556,7 +702,7 @@ vSetParagraphBreak(wimp_w tWindow, int iNumber)
  * vChangeParagraphBreak - change the paragraph break with the given number
  */
 static void
-vChangeParagraphBreak(wimp_w tWindow, int iNumber)
+vChangeParagraphBreak(window_handle tWindow, int iNumber)
 {
 	int	iTmp;
 
@@ -575,7 +721,7 @@ vChangeParagraphBreak(wimp_w tWindow, int iNumber)
  * vChangeAutofiletype - invert the permission to autofiletype
  */
 static void
-vChangeAutofiletype(wimp_w tWindow)
+vChangeAutofiletype(window_handle tWindow)
 {
 	tOptionsTemp.bAutofiletypeAllowed =
 				!tOptionsTemp.bAutofiletypeAllowed;
@@ -588,7 +734,7 @@ vChangeAutofiletype(wimp_w tWindow)
  * vChangeHiddenText - invert the hide/show hidden text
  */
 static void
-vChangeHiddenText(wimp_w tWindow)
+vChangeHiddenText(window_handle tWindow)
 {
 	tOptionsTemp.bHideHiddenText = !tOptionsTemp.bHideHiddenText;
 	vUpdateRadioButton(tWindow,
@@ -613,7 +759,7 @@ vUseFontsImages(BOOL bUseOutlineFonts, BOOL bShowImages)
  * vSetScaleFactor - set the scale factor to the given number
  */
 static void
-vSetScaleFactor(wimp_w tWindow, int iNumber)
+vSetScaleFactor(window_handle tWindow, int iNumber)
 {
   	tOptionsTemp.iScaleFactor = iNumber;
 	vUpdateWriteableNumber(tWindow,
@@ -625,7 +771,7 @@ vSetScaleFactor(wimp_w tWindow, int iNumber)
  * vChangeScaleFactor - change the scale factor with the given number
  */
 static void
-vChangeScaleFactor(wimp_w tWindow, int iNumber)
+vChangeScaleFactor(window_handle tWindow, int iNumber)
 {
 	int	iTmp;
 
@@ -643,24 +789,30 @@ vChangeScaleFactor(wimp_w tWindow, int iNumber)
 /*
  * bChoicesMouseClick - handle a mouse click in the Choices window
  */
-void
-vChoicesMouseClick(wimp_mousestr *m)
+BOOL
+bChoicesMouseClick(event_pollblock *pEvent, void *pvReference)
 {
-	wimp_i	tAction;
-	BOOL	bCloseWindow, bLeft, bRight;
+	icon_handle	tAction;
+	mouse_block	*pMouse;
+	BOOL		bCloseWindow;
 
-	bLeft = (m->bbits & wimp_BLEFT) == wimp_BLEFT;
-	bRight = (m->bbits & wimp_BRIGHT) == wimp_BRIGHT;
-	if (!bLeft && !bRight) {
-		DBG_HEX(m->bbits);
-		return;
+	TRACE_MSG("bChoicesMouseClick");
+
+	fail(pEvent == NULL);
+	fail(pEvent->type != event_CLICK);
+
+	pMouse = &pEvent->data.mouse;
+	if (!pMouse->button.data.select && !pMouse->button.data.adjust) {
+		/* Not handled here */
+		DBG_HEX(pMouse->button.value);
+		return FALSE;
 	}
 
 	/* Which action should be taken */
-	tAction = m->i;
-	if (bRight) {
-	  	/* The right button reverses the direction */
-		switch (m->i) {
+	tAction = pMouse->icon;
+	if (pMouse->button.data.adjust) {
+	  	/* The adjust button reverses the direction */
+		switch (pMouse->icon) {
 		case CHOICES_BREAK_UP_BUTTON:
 			tAction = CHOICES_BREAK_DOWN_BUTTON;
 			break;
@@ -682,7 +834,7 @@ vChoicesMouseClick(wimp_mousestr *m)
 	bCloseWindow = FALSE;
 	switch (tAction) {
 	case CHOICES_DEFAULT_BUTTON:
-		vDefaultButtonAction(m->w);
+		vDefaultButtonAction(pMouse->window);
 		break;
 	case CHOICES_SAVE_BUTTON:
 		vSaveButtonAction();
@@ -695,22 +847,22 @@ vChoicesMouseClick(wimp_mousestr *m)
 		bCloseWindow = TRUE;
 		break;
 	case CHOICES_BREAK_BUTTON:
-		vSetParagraphBreak(m->w, DEFAULT_SCREEN_WIDTH);
+		vSetParagraphBreak(pMouse->window, DEFAULT_SCREEN_WIDTH);
 		break;
 	case CHOICES_BREAK_UP_BUTTON:
-		vChangeParagraphBreak(m->w, 1);
+		vChangeParagraphBreak(pMouse->window, 1);
 		break;
 	case CHOICES_BREAK_DOWN_BUTTON:
-		vChangeParagraphBreak(m->w, -1);
+		vChangeParagraphBreak(pMouse->window, -1);
 		break;
 	case CHOICES_NO_BREAK_BUTTON:
-		vSetParagraphBreak(m->w, 0);
+		vSetParagraphBreak(pMouse->window, 0);
 		break;
 	case CHOICES_AUTOFILETYPE_BUTTON:
-		vChangeAutofiletype(m->w);
+		vChangeAutofiletype(pMouse->window);
 		break;
 	case CHOICES_HIDDEN_TEXT_BUTTON:
-		vChangeHiddenText(m->w);
+		vChangeHiddenText(pMouse->window);
 		break;
 	case CHOICES_WITH_IMAGES_BUTTON:
 		vUseFontsImages(TRUE, TRUE);
@@ -722,40 +874,51 @@ vChoicesMouseClick(wimp_mousestr *m)
 		vUseFontsImages(FALSE, FALSE);
 		break;
 	case CHOICES_SCALE_UP_BUTTON:
-		vChangeScaleFactor(m->w, 5);
+		vChangeScaleFactor(pMouse->window, 5);
 		break;
 	case CHOICES_SCALE_DOWN_BUTTON:
-		vChangeScaleFactor(m->w, -5);
+		vChangeScaleFactor(pMouse->window, -5);
 		break;
 	default:
-		DBG_DEC(m->i);
+		DBG_DEC(pMouse->icon);
 		break;
 	}
 	if (bCloseWindow) {
-		wimpt_noerr(wimp_close_wind(m->w));
+		Error_CheckFatal(Wimp_CloseWindow(pMouse->window));
 	}
-} /* end of vChoicesMouseClick */
+	return TRUE;
+} /* end of bChoicesMouseClick */
 
-void
-vChoicesKeyPressed(wimp_caretstr *c)
+/*
+ * bChoicesKeyPressed - handle a key in the Choices window
+ */
+BOOL
+bChoicesKeyPressed(event_pollblock *pEvent, void *pvReference)
 {
-	wimp_icon	tIcon;
+	icon_block	tIcon;
+	caret_block	*pCaret;
 	char		*pcChar;
 	int		iNumber;
 
-	DBG_MSG("vChoicesKeyPressed");
+	DBG_MSG("bChoicesKeyPressed");
 
-	fail(c == NULL);
+	fail(pEvent == NULL);
+	fail(pEvent->type != event_KEY);
 
-	wimpt_noerr(wimp_get_icon_info(c->w, c->i, &tIcon));
-	if ((tIcon.flags & (wimp_ITEXT|wimp_INDIRECT)) !=
-	    (wimp_ITEXT|wimp_INDIRECT)) {
-		werr(1, "Icon %d must be indirected text", (int)c->i);
-		return;
+	if (pEvent->data.key.code != '\r') {
+		Error_CheckFatal(Wimp_ProcessKey(pEvent->data.key.code));
+		return TRUE;
+	}
+
+	pCaret = &pEvent->data.key.caret;
+
+	Error_CheckFatal(Wimp_GetIconState(pCaret->window, pCaret->icon, &tIcon));
+	if (!tIcon.flags.data.text || !tIcon.flags.data.indirected) {
+		werr(1, "Icon %d must be indirected text", (int)pCaret->icon);
 	}
 	iNumber = (int)strtol(tIcon.data.indirecttext.buffer, &pcChar, 10);
 
-	switch(c->i) {
+	switch(pCaret->icon) {
 	case CHOICES_BREAK_WRITEABLE:
 		if (*pcChar != '\0' && *pcChar != '\r') {
 			DBG_DEC(*pcChar);
@@ -765,7 +928,7 @@ vChoicesKeyPressed(wimp_caretstr *c)
 		} else if (iNumber > MAX_SCREEN_WIDTH) {
 			iNumber = MAX_SCREEN_WIDTH;
 		}
-		vSetParagraphBreak(c->w, iNumber);
+		vSetParagraphBreak(pCaret->window, iNumber);
 		break;
 	case CHOICES_SCALE_WRITEABLE:
 		if (*pcChar != '\0' && *pcChar != '\r') {
@@ -776,11 +939,12 @@ vChoicesKeyPressed(wimp_caretstr *c)
 		} else if (iNumber > MAX_SCALE_FACTOR) {
 			iNumber = MAX_SCALE_FACTOR;
 		}
-		vSetScaleFactor(c->w, iNumber);
+		vSetScaleFactor(pCaret->window, iNumber);
 		break;
 	default:
-		DBG_DEC(c->i);
+		DBG_DEC(pCaret->icon);
 		break;
 	}
-} /* end of vChoicesKeyPressed */
+	return TRUE;
+} /* end of bChoicesKeyPressed */
 #endif /* __riscos */

+ 150 - 52
sys/src/cmd/aux/antiword/out2window.c

@@ -1,6 +1,6 @@
 /*
  * out2window.c
- * Copyright (C) 1998-2003 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2005 A.J. van Os; Released under GPL
  *
  * Description:
  * Output to a text window
@@ -11,7 +11,6 @@
 #include <ctype.h>
 #include "antiword.h"
 
-
 /* Used for numbering the chapters */
 static unsigned int	auiHdrCounter[9];
 
@@ -26,6 +25,8 @@ vString2Diagram(diagram_type *pDiag, output_type *pAnchor)
 	long		lWidth;
 	USHORT		usMaxFontSize;
 
+	TRACE_MSG("vString2Diagram");
+
 	fail(pDiag == NULL);
 	fail(pAnchor == NULL);
 
@@ -51,6 +52,7 @@ vString2Diagram(diagram_type *pDiag, output_type *pAnchor)
 
 	/* Goto the start of the line */
 	pDiag->lXleft = 0;
+	TRACE_MSG("leaving vString2Diagram");
 } /* end of vString2Diagram */
 
 /*
@@ -61,6 +63,8 @@ vSetLeftIndentation(diagram_type *pDiag, long lLeftIndentation)
 {
 	long	lX;
 
+	TRACE_MSG("vSetLeftIndentation");
+
 	fail(pDiag == NULL);
 	fail(lLeftIndentation < 0);
 
@@ -81,6 +85,8 @@ lComputeNetWidth(output_type *pAnchor)
 	output_type	*pTmp;
 	long		lNetWidth;
 
+	TRACE_MSG("lComputeNetWidth");
+
 	fail(pAnchor == NULL);
 
 	/* Step 1: Count all but the last sub-string */
@@ -124,6 +130,8 @@ iComputeHoles(output_type *pAnchor)
 	int	iCounter;
 	BOOL	bWasSpace, bIsSpace;
 
+	TRACE_MSG("iComputeHoles");
+
 	fail(pAnchor == NULL);
 
 	iCounter = 0;
@@ -143,7 +151,7 @@ iComputeHoles(output_type *pAnchor)
 } /* end of iComputeHoles */
 
 /*
- * Align a string and insert it into the text
+ * vAlign2Window - Align a string and insert it into the text
  */
 void
 vAlign2Window(diagram_type *pDiag, output_type *pAnchor,
@@ -151,11 +159,11 @@ vAlign2Window(diagram_type *pDiag, output_type *pAnchor,
 {
 	long	lNetWidth, lLeftIndentation;
 
+	TRACE_MSG("vAlign2Window");
+
 	fail(pDiag == NULL || pAnchor == NULL);
 	fail(lScreenWidth < lChar2MilliPoints(MIN_SCREEN_WIDTH));
 
-	NO_DBG_MSG("vAlign2Window");
-
 	lNetWidth = lComputeNetWidth(pAnchor);
 
 	if (lScreenWidth > lChar2MilliPoints(MAX_SCREEN_WIDTH) ||
@@ -165,6 +173,7 @@ vAlign2Window(diagram_type *pDiag, output_type *pAnchor,
 		 * Don't bother to align an empty line
 		 */
 		vString2Diagram(pDiag, pAnchor);
+		TRACE_MSG("leaving vAlign2Window #1");
 		return;
 	}
 
@@ -189,10 +198,11 @@ vAlign2Window(diagram_type *pDiag, output_type *pAnchor,
 		break;
 	}
 	vString2Diagram(pDiag, pAnchor);
+	TRACE_MSG("leaving vAlign2Window #2");
 } /* end of vAlign2Window */
 
 /*
- * vJustify2Window
+ * vJustify2Window - Justify a string and insert it into the text
  */
 void
 vJustify2Window(diagram_type *pDiag, output_type *pAnchor,
@@ -203,12 +213,12 @@ vJustify2Window(diagram_type *pDiag, output_type *pAnchor,
 	long	lNetWidth, lSpaceWidth, lToAdd;
 	int	iFillerLen, iHoles;
 
+	TRACE_MSG("vJustify2Window");
+
 	fail(pDiag == NULL || pAnchor == NULL);
 	fail(lScreenWidth < MIN_SCREEN_WIDTH);
 	fail(lRightIndentation > 0);
 
-	NO_DBG_MSG("vJustify2Window");
-
 	if (ucAlignment != ALIGNMENT_JUSTIFY) {
 		vAlign2Window(pDiag, pAnchor, lScreenWidth, ucAlignment);
 		return;
@@ -220,9 +230,10 @@ vJustify2Window(diagram_type *pDiag, output_type *pAnchor,
 	    lNetWidth <= 0) {
 		/*
 		 * Screenwidth is "infinite", so justify is not possible
-		 * Don't bother to align an empty line
+		 * Don't bother to justify an empty line
 		 */
 		vString2Diagram(pDiag, pAnchor);
+		TRACE_MSG("leaving vJustify2Window #1");
 		return;
 	}
 
@@ -249,11 +260,12 @@ vJustify2Window(diagram_type *pDiag, output_type *pAnchor,
 	DBG_DEC_C(lToAdd < 0, lToAdd);
 	if (lToAdd <= 0) {
 		vString2Diagram(pDiag, pAnchor);
+		TRACE_MSG("leaving vJustify2Window #2");
 		return;
 	}
 
-	iHoles = iComputeHoles(pAnchor);
 	/* Justify by adding spaces */
+	iHoles = iComputeHoles(pAnchor);
 	for (pTmp = pAnchor; pTmp != NULL; pTmp = pTmp->pNext) {
 		fail(pTmp->tNextFree != strlen(pTmp->szStorage));
 		fail(lToAdd < 0);
@@ -285,6 +297,7 @@ vJustify2Window(diagram_type *pDiag, output_type *pAnchor,
 	}
 	DBG_DEC_C(lToAdd != 0, lToAdd);
 	vString2Diagram(pDiag, pAnchor);
+	TRACE_MSG("leaving vJustify2Window #3");
 } /* end of vJustify2Window */
 
 /*
@@ -293,25 +306,28 @@ vJustify2Window(diagram_type *pDiag, output_type *pAnchor,
 void
 vResetStyles(void)
 {
+	TRACE_MSG("vResetStyles");
+
 	(void)memset(auiHdrCounter, 0, sizeof(auiHdrCounter));
 } /* end of vResetStyles */
 
 /*
- * Add the style characters to the line
+ * tStyle2Window - Add the style characters to the line
  *
  * Returns the length of the resulting string
  */
 size_t
-tStyle2Window(char *szLine, const style_block_type *pStyle,
+tStyle2Window(char *szLine, size_t tLineSize, const style_block_type *pStyle,
 	const section_block_type *pSection)
 {
 	char	*pcTxt;
-	int	iIndex;
+	size_t	tIndex, tStyleIndex;
 	BOOL	bNeedPrevLvl;
 	level_type_enum	eNumType;
-	USHORT	usStyleIndex;
 	UCHAR	ucNFC;
 
+	TRACE_MSG("tStyle2Window");
+
 	fail(szLine == NULL || pStyle == NULL || pSection == NULL);
 
 	if (pStyle->usIstd == 0 || pStyle->usIstd > 9) {
@@ -319,15 +335,15 @@ tStyle2Window(char *szLine, const style_block_type *pStyle,
 		return 0;
 	}
 
-	usStyleIndex = pStyle->usIstd - 1;
 	/* Set the numbers */
-	for (iIndex = 0; iIndex < 9; iIndex++) {
-		if (iIndex == (int)usStyleIndex) {
-			auiHdrCounter[iIndex]++;
-		} else if (iIndex > (int)usStyleIndex) {
-			auiHdrCounter[iIndex] = 0;
-		} else if (auiHdrCounter[iIndex] == 0) {
-			auiHdrCounter[iIndex] = 1;
+	tStyleIndex = (size_t)pStyle->usIstd - 1;
+	for (tIndex = 0; tIndex < 9; tIndex++) {
+		if (tIndex == tStyleIndex) {
+			auiHdrCounter[tIndex]++;
+		} else if (tIndex > tStyleIndex) {
+			auiHdrCounter[tIndex] = 0;
+		} else if (auiHdrCounter[tIndex] == 0) {
+			auiHdrCounter[tIndex] = 1;
 		}
 	}
 
@@ -337,42 +353,56 @@ tStyle2Window(char *szLine, const style_block_type *pStyle,
 		return 0;
 	}
 
-	pcTxt = szLine;
-	bNeedPrevLvl = (pSection->usNeedPrevLvl & BIT(usStyleIndex)) != 0;
 	/* Print the numbers */
-	for (iIndex = 0; iIndex <= (int)usStyleIndex; iIndex++) {
-		if (iIndex == (int)usStyleIndex ||
-		    (bNeedPrevLvl && iIndex < (int)usStyleIndex)) {
-			ucNFC = pSection->aucNFC[iIndex];
+	pcTxt = szLine;
+	bNeedPrevLvl = (pSection->usNeedPrevLvl & BIT(tStyleIndex)) != 0;
+	for (tIndex = 0; tIndex <= tStyleIndex; tIndex++) {
+		if (tIndex == tStyleIndex ||
+		    (bNeedPrevLvl && tIndex < tStyleIndex)) {
+			if (pcTxt - szLine >= tLineSize - 25) {
+				/* Prevent a possible buffer overflow */
+				DBG_DEC(pcTxt - szLine);
+				DBG_DEC(tLineSize - 25);
+				DBG_FIXME();
+				szLine[0] = '\0';
+				return 0;
+			}
+			ucNFC = pSection->aucNFC[tIndex];
 			switch(ucNFC) {
 			case LIST_ARABIC_NUM:
+			case LIST_NUMBER_TXT:
+			case LIST_ORDINAL_TXT:
 				pcTxt += sprintf(pcTxt, "%u",
-					auiHdrCounter[iIndex]);
+					auiHdrCounter[tIndex]);
 				break;
 			case LIST_UPPER_ROMAN:
 			case LIST_LOWER_ROMAN:
 				pcTxt += tNumber2Roman(
-					auiHdrCounter[iIndex],
+					auiHdrCounter[tIndex],
 					ucNFC == LIST_UPPER_ROMAN,
 					pcTxt);
 				break;
 			case LIST_UPPER_ALPHA:
 			case LIST_LOWER_ALPHA:
 				pcTxt += tNumber2Alpha(
-					auiHdrCounter[iIndex],
+					auiHdrCounter[tIndex],
 					ucNFC == LIST_UPPER_ALPHA,
 					pcTxt);
 				break;
+			case LIST_OUTLINE_NUM:
+				pcTxt += sprintf(pcTxt, "%02u",
+					auiHdrCounter[tIndex]);
+				break;
 			default:
 				DBG_DEC(ucNFC);
 				DBG_FIXME();
 				pcTxt += sprintf(pcTxt, "%u",
-					auiHdrCounter[iIndex]);
+					auiHdrCounter[tIndex]);
 				break;
 			}
-			if (iIndex < (int)usStyleIndex) {
+			if (tIndex < tStyleIndex) {
 				*pcTxt++ = '.';
-			} else if (iIndex == (int)usStyleIndex) {
+			} else if (tIndex == tStyleIndex) {
 				*pcTxt++ = ' ';
 			}
 		}
@@ -398,19 +428,21 @@ vRemoveRowEnd(char *szRowTxt)
 {
 	int	iLastIndex;
 
+	TRACE_MSG("vRemoveRowEnd");
+
 	fail(szRowTxt == NULL || szRowTxt[0] == '\0');
 
 	iLastIndex = (int)strlen(szRowTxt) - 1;
 
 	if (szRowTxt[iLastIndex] == TABLE_SEPARATOR ||
-	    szRowTxt[iLastIndex] == '\n') {
+	    szRowTxt[iLastIndex] == (char)0x0a) {
 		szRowTxt[iLastIndex] = '\0';
 		iLastIndex--;
 	} else {
 		DBG_HEX(szRowTxt[iLastIndex]);
 	}
 
-	if (iLastIndex >= 0 && szRowTxt[iLastIndex] == '\n') {
+	if (iLastIndex >= 0 && szRowTxt[iLastIndex] == (char)0x0a) {
 		szRowTxt[iLastIndex] = '\0';
 		iLastIndex--;
 	}
@@ -436,6 +468,8 @@ tComputeStringLengthMax(const char *szString, size_t tColumnWidthMax)
 	const char	*pcTmp;
 	size_t	tLengthMax, tLenPrev, tLen, tWidth;
 
+	TRACE_MSG("tComputeStringLengthMax");
+
 	fail(szString == NULL);
 	fail(tColumnWidthMax == 0);
 
@@ -478,6 +512,8 @@ tGetBreakingPoint(const char *szString,
 {
 	int	iIndex;
 
+	TRACE_MSG("tGetBreakingPoint");
+
 	fail(szString == NULL);
 	fail(tLen > strlen(szString));
 	fail(tWidth > tColumnWidthMax);
@@ -500,24 +536,59 @@ tGetBreakingPoint(const char *szString,
 	return tLen;
 } /* end of tGetBreakingPoint */
 
+/*
+ * tComputeColumnWidthMax - compute the maximum column width
+ */
+static size_t
+tComputeColumnWidthMax(short sWidth, long lCharWidth, double dFactor)
+{
+	size_t	tColumnWidthMax;
+
+	TRACE_MSG("tComputeColumnWidthMax");
+
+	fail(sWidth < 0);
+	fail(lCharWidth <= 0);
+	fail(dFactor <= 0.0);
+
+	tColumnWidthMax = (size_t)(
+		(lTwips2MilliPoints(sWidth) * dFactor + lCharWidth / 2.0) /
+		 lCharWidth);
+	if (tColumnWidthMax == 0) {
+		/* Minimum column width */
+		return 1;
+	}
+	if (tColumnWidthMax > 1) {
+		/* Make room for the TABLE_SEPARATOR_CHAR */
+		tColumnWidthMax--;
+	}
+	NO_DBG_DEC(tColumnWidthMax);
+	return tColumnWidthMax;
+} /* end of tComputeColumnWidthMax */
+
 /*
  * vTableRow2Window - put a table row into a diagram
  */
 void
 vTableRow2Window(diagram_type *pDiag, output_type *pOutput,
-		const row_block_type *pRowInfo)
+	const row_block_type *pRowInfo,
+	conversion_type eConversionType, int iParagraphBreak)
 {
 	output_type	tRow;
 	char	*aszColTxt[TABLE_COLUMN_MAX];
 	char	*szLine, *pcTxt;
+	double	dMagnify;
 	long	lCharWidthLarge, lCharWidthSmall;
+	size_t	tColumnWidthTotal, atColumnWidthMax[TABLE_COLUMN_MAX];
 	size_t	tSize, tColumnWidthMax, tWidth, tLen;
 	int	iIndex, iNbrOfColumns, iTmp;
 	BOOL	bNotReady;
 
+	TRACE_MSG("vTableRow2Window");
+
 	fail(pDiag == NULL || pOutput == NULL || pRowInfo == NULL);
 	fail(pOutput->szStorage == NULL);
 	fail(pOutput->pNext != NULL);
+	fail(iParagraphBreak < 0);
 
 	/* Character sizes */
 	lCharWidthLarge = lComputeStringWidth("W", 1,
@@ -548,6 +619,12 @@ vTableRow2Window(diagram_type *pDiag, output_type *pOutput,
 		NO_DBG_MSG(aszColTxt[iNbrOfColumns]);
 	}
 
+	/* Work around a bug in Word */
+	while (iNbrOfColumns > (int)pRowInfo->ucNumberOfColumns &&
+	       pRowInfo->asColumnWidth[iNbrOfColumns] == 0) {
+		iNbrOfColumns--;
+	}
+
 	DBG_DEC_C(iNbrOfColumns != (int)pRowInfo->ucNumberOfColumns,
 		iNbrOfColumns);
 	DBG_DEC_C(iNbrOfColumns != (int)pRowInfo->ucNumberOfColumns,
@@ -557,19 +634,48 @@ vTableRow2Window(diagram_type *pDiag, output_type *pOutput,
 		return;
 	}
 
+#if defined(__FULL_TEXT_SEARCH)
+	/* No table formatting: use for full-text search (untested) */
+	for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) {
+		fprintf(pDiag->pOutFile, "%s\n" , aszColTxt[iIndex]);
+	}
+#else
 	if (bAddTableRow(pDiag, aszColTxt, iNbrOfColumns,
 			pRowInfo->asColumnWidth, pRowInfo->ucBorderInfo)) {
 		/* All work has been done */
 		return;
 	}
 
+	/* Fill the table with maximum column widths */
+	if (eConversionType == conversion_text ||
+	    eConversionType == conversion_fmt_text) {
+		if (iParagraphBreak == 0 ||
+		    iParagraphBreak >= MAX_SCREEN_WIDTH) {
+			dMagnify = (double)MAX_SCREEN_WIDTH;
+		} else if (iParagraphBreak <= MIN_SCREEN_WIDTH) {
+			dMagnify = (double)MIN_SCREEN_WIDTH;
+		} else {
+			dMagnify = (double)iParagraphBreak;
+		}
+		dMagnify /= (double)DEFAULT_SCREEN_WIDTH;
+		DBG_FLT_C(dMagnify < 0.99 || dMagnify > 1.01, dMagnify);
+	} else {
+		dMagnify = 1.0;
+	}
+	tColumnWidthTotal = 0;
+	for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) {
+		atColumnWidthMax[iIndex] = tComputeColumnWidthMax(
+					pRowInfo->asColumnWidth[iIndex],
+					lCharWidthLarge,
+					dMagnify);
+		tColumnWidthTotal += atColumnWidthMax[iIndex];
+	}
+
 	/*
 	 * Get enough space for the row.
 	 * Worst case: three bytes per UTF-8 character
 	 */
-	tSize = 3 * (size_t)(lTwips2MilliPoints(pRowInfo->iColumnWidthSum) /
-				lCharWidthSmall +
-				(long)pRowInfo->ucNumberOfColumns + 3);
+	tSize = 3 * (1 + tColumnWidthTotal + (size_t)iNbrOfColumns + 3);
 	szLine = xmalloc(tSize);
 
 	do {
@@ -578,18 +684,7 @@ vTableRow2Window(diagram_type *pDiag, output_type *pOutput,
 		pcTxt = szLine;
 		*pcTxt++ = TABLE_SEPARATOR_CHAR;
 		for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) {
-			tColumnWidthMax =
-				(size_t)(lTwips2MilliPoints(
-					pRowInfo->asColumnWidth[iIndex]) /
-					lCharWidthLarge);
-			if (tColumnWidthMax == 0) {
-				/* Minimum column width */
-				tColumnWidthMax = 1;
-			} else if (tColumnWidthMax > 1) {
-				/* Make room for the TABLE_SEPARATOR_CHAR */
-				tColumnWidthMax--;
-			}
-			NO_DBG_DEC(tColumnWidthMax);
+			tColumnWidthMax = atColumnWidthMax[iIndex];
 			if (aszColTxt[iIndex] == NULL) {
 				/* Add an empty column */
 				for (iTmp = 0;
@@ -664,7 +759,10 @@ vTableRow2Window(diagram_type *pDiag, output_type *pOutput,
 					tRow.tFontRef,
 					tRow.usFontSize);
 		vString2Diagram(pDiag, &tRow);
+		TRACE_MSG("after vString2Diagram in vTableRow2Window");
 	} while (bNotReady);
 	/* Clean up before you leave */
 	szLine = xfree(szLine);
+	TRACE_MSG("leaving vTableRow2Window");
+#endif /* __FULL_TEXT_SEARCH */
 } /* end of vTableRow2Window */

+ 82 - 10
sys/src/cmd/aux/antiword/output.c

@@ -1,6 +1,6 @@
 /*
  * output.c
- * Copyright (C) 2002,2003 A.J. van Os; Released under GPL
+ * Copyright (C) 2002-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Generic output generating functions
@@ -31,11 +31,17 @@ vPrologue1(diagram_type *pDiag, const char *szTask, const char *szFilename)
 	case conversion_text:
 		vPrologueTXT(pDiag, &tOptions);
 		break;
+	case conversion_fmt_text:
+		vPrologueFMT(pDiag, &tOptions);
+		break;
 	case conversion_ps:
 		vProloguePS(pDiag, szTask, szFilename, &tOptions);
 		break;
 	case conversion_xml:
-		vPrologueXML(pDiag);
+		vPrologueXML(pDiag, &tOptions);
+		break;
+	case conversion_pdf:
+		vProloguePDF(pDiag, szTask, &tOptions);
 		break;
 	default:
 		DBG_DEC(eConversionType);
@@ -51,6 +57,7 @@ vEpilogue(diagram_type *pDiag)
 {
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		vEpilogueTXT(pDiag->pOutFile);
 		break;
 	case conversion_ps:
@@ -59,6 +66,9 @@ vEpilogue(diagram_type *pDiag)
 	case conversion_xml:
 		vEpilogueXML(pDiag);
 		break;
+	case conversion_pdf:
+		vEpiloguePDF(pDiag);
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -73,12 +83,16 @@ vImagePrologue(diagram_type *pDiag, const imagedata_type *pImg)
 {
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		break;
 	case conversion_ps:
 		vImageProloguePS(pDiag, pImg);
 		break;
 	case conversion_xml:
 		break;
+	case conversion_pdf:
+		vImageProloguePDF(pDiag, pImg);
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -93,12 +107,16 @@ vImageEpilogue(diagram_type *pDiag)
 {
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		break;
 	case conversion_ps:
 		vImageEpiloguePS(pDiag);
 		break;
 	case conversion_xml:
 		break;
+	case conversion_pdf:
+		vImageEpiloguePDF(pDiag);
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -115,11 +133,14 @@ bAddDummyImage(diagram_type *pDiag, const imagedata_type *pImg)
 {
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		return FALSE;
 	case conversion_ps:
 		return bAddDummyImagePS(pDiag, pImg);
 	case conversion_xml:
 		return FALSE;
+	case conversion_pdf:
+		return bAddDummyImagePDF(pDiag, pImg);
 	default:
 		DBG_DEC(eConversionType);
 		return FALSE;
@@ -173,12 +194,17 @@ vPrologue2(diagram_type *pDiag, int iWordVersion)
 {
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		break;
 	case conversion_ps:
 		vAddFontsPS(pDiag);
 		break;
 	case conversion_xml:
-		vCreateBookIntro(pDiag, iWordVersion, eEncoding);
+		vCreateBookIntro(pDiag, iWordVersion);
+		break;
+	case conversion_pdf:
+		vCreateInfoDictionary(pDiag, iWordVersion);
+		vAddFontsPDF(pDiag);
 		break;
 	default:
 		DBG_DEC(eConversionType);
@@ -190,7 +216,8 @@ vPrologue2(diagram_type *pDiag, int iWordVersion)
  * vMove2NextLine - move to the next line
  */
 void
-vMove2NextLine(diagram_type *pDiag, draw_fontref tFontRef, USHORT usFontSize)
+vMove2NextLine(diagram_type *pDiag, drawfile_fontref tFontRef,
+	USHORT usFontSize)
 {
 	fail(pDiag == NULL);
 	fail(pDiag->pOutFile == NULL);
@@ -198,6 +225,7 @@ vMove2NextLine(diagram_type *pDiag, draw_fontref tFontRef, USHORT usFontSize)
 
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		vMove2NextLineTXT(pDiag);
 		break;
 	case conversion_ps:
@@ -206,6 +234,9 @@ vMove2NextLine(diagram_type *pDiag, draw_fontref tFontRef, USHORT usFontSize)
 	case conversion_xml:
 		vMove2NextLineXML(pDiag);
 		break;
+	case conversion_pdf:
+		vMove2NextLinePDF(pDiag, usFontSize);
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -218,13 +249,17 @@ vMove2NextLine(diagram_type *pDiag, draw_fontref tFontRef, USHORT usFontSize)
 void
 vSubstring2Diagram(diagram_type *pDiag,
 	char *szString, size_t tStringLength, long lStringWidth,
-	UCHAR ucFontColor, USHORT usFontstyle, draw_fontref tFontRef,
+	UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef,
 	USHORT usFontSize, USHORT usMaxFontSize)
 {
 	switch (eConversionType) {
 	case conversion_text:
 		vSubstringTXT(pDiag, szString, tStringLength, lStringWidth);
 		break;
+	case conversion_fmt_text:
+		vSubstringFMT(pDiag, szString, tStringLength, lStringWidth,
+				usFontstyle);
+		break;
 	case conversion_ps:
 		vSubstringPS(pDiag, szString, tStringLength, lStringWidth,
 				ucFontColor, usFontstyle, tFontRef,
@@ -234,6 +269,11 @@ vSubstring2Diagram(diagram_type *pDiag,
 		vSubstringXML(pDiag, szString, tStringLength, lStringWidth,
 				usFontstyle);
 		break;
+	case conversion_pdf:
+		vSubstringPDF(pDiag, szString, tStringLength, lStringWidth,
+				ucFontColor, usFontstyle, tFontRef,
+				usFontSize, usMaxFontSize);
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -252,6 +292,7 @@ vStartOfParagraph1(diagram_type *pDiag, long lBeforeIndentation)
 
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		vStartOfParagraphTXT(pDiag, lBeforeIndentation);
 		break;
 	case conversion_ps:
@@ -259,6 +300,9 @@ vStartOfParagraph1(diagram_type *pDiag, long lBeforeIndentation)
 		break;
 	case conversion_xml:
 		break;
+	case conversion_pdf:
+		vStartOfParagraphPDF(pDiag, lBeforeIndentation);
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -276,12 +320,15 @@ vStartOfParagraph2(diagram_type *pDiag)
 
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		break;
 	case conversion_ps:
 		break;
 	case conversion_xml:
 		vStartOfParagraphXML(pDiag, 1);
 		break;
+	case conversion_pdf:
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -293,7 +340,7 @@ vStartOfParagraph2(diagram_type *pDiag)
  */
 void
 vEndOfParagraph(diagram_type *pDiag,
-	draw_fontref tFontRef, USHORT usFontSize, long lAfterIndentation)
+	drawfile_fontref tFontRef, USHORT usFontSize, long lAfterIndentation)
 {
 	fail(pDiag == NULL);
 	fail(pDiag->pOutFile == NULL);
@@ -302,15 +349,18 @@ vEndOfParagraph(diagram_type *pDiag,
 
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		vEndOfParagraphTXT(pDiag, lAfterIndentation);
 		break;
 	case conversion_ps:
-		vEndOfParagraphPS(pDiag,
-				tFontRef, usFontSize, lAfterIndentation);
+		vEndOfParagraphPS(pDiag, usFontSize, lAfterIndentation);
 		break;
 	case conversion_xml:
 		vEndOfParagraphXML(pDiag, 1);
 		break;
+	case conversion_pdf:
+		vEndOfParagraphPDF(pDiag, usFontSize, lAfterIndentation);
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -321,18 +371,22 @@ vEndOfParagraph(diagram_type *pDiag,
  * Create an end of page
  */
 void
-vEndOfPage(diagram_type *pDiag, long lAfterIndentation)
+vEndOfPage(diagram_type *pDiag, long lAfterIndentation, BOOL bNewSection)
 {
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		vEndOfPageTXT(pDiag, lAfterIndentation);
 		break;
 	case conversion_ps:
-		vEndOfPagePS(pDiag);
+		vEndOfPagePS(pDiag, bNewSection);
 		break;
 	case conversion_xml:
 		vEndOfPageXML(pDiag);
 		break;
+	case conversion_pdf:
+		vEndOfPagePDF(pDiag, bNewSection);
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -347,12 +401,15 @@ vSetHeaders(diagram_type *pDiag, USHORT usIstd)
 {
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		break;
 	case conversion_ps:
 		break;
 	case conversion_xml:
 		vSetHeadersXML(pDiag, usIstd);
 		break;
+	case conversion_pdf:
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -367,12 +424,15 @@ vStartOfList(diagram_type *pDiag, UCHAR ucNFC, BOOL bIsEndOfTable)
 {
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		break;
 	case conversion_ps:
 		break;
 	case conversion_xml:
 		vStartOfListXML(pDiag, ucNFC, bIsEndOfTable);
 		break;
+	case conversion_pdf:
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -387,12 +447,15 @@ vEndOfList(diagram_type *pDiag)
 {
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		break;
 	case conversion_ps:
 		break;
 	case conversion_xml:
 		vEndOfListXML(pDiag);
 		break;
+	case conversion_pdf:
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -407,12 +470,15 @@ vStartOfListItem(diagram_type *pDiag, BOOL bNoMarks)
 {
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		break;
 	case conversion_ps:
 		break;
 	case conversion_xml:
 		vStartOfListItemXML(pDiag, bNoMarks);
 		break;
+	case conversion_pdf:
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -427,12 +493,15 @@ vEndOfTable(diagram_type *pDiag)
 {
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		break;
 	case conversion_ps:
 		break;
 	case conversion_xml:
 		vEndOfTableXML(pDiag);
 		break;
+	case conversion_pdf:
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;
@@ -450,6 +519,7 @@ bAddTableRow(diagram_type *pDiag, char **aszColTxt,
 {
 	switch (eConversionType) {
 	case conversion_text:
+	case conversion_fmt_text:
 		break;
 	case conversion_ps:
 		break;
@@ -458,6 +528,8 @@ bAddTableRow(diagram_type *pDiag, char **aszColTxt,
 				iNbrOfColumns, asColumnWidth,
 				ucBorderInfo);
 		return TRUE;
+	case conversion_pdf:
+		break;
 	default:
 		DBG_DEC(eConversionType);
 		break;

+ 1148 - 0
sys/src/cmd/aux/antiword/pdf.c

@@ -0,0 +1,1148 @@
+/*
+ * pdf.c
+ * Copyright (C) 2003-2005 A.J. van Os; Released under GNU GPL
+ *
+ * Description:
+ * Functions to deal with the Adobe Portable Document Format (pdf)
+ *
+ */
+
+#include <stdarg.h>
+#include <string.h>
+#include "version.h"
+#include "antiword.h"
+
+
+/* Constants for the file positions */
+#define INITIAL_LOCATION_SIZE	20
+#define INITIAL_PAGEOBJECT_SIZE	 5
+#if defined(DEBUG)
+#define EXTENSION_ARRAY_SIZE	10
+#else
+#define EXTENSION_ARRAY_SIZE	30
+#endif /* DEBUG */
+
+/* The character set */
+static encoding_type	eEncoding = encoding_neutral;
+/* Current creator for a PDF header */
+static const char	*szProducer = NULL;
+/* The height and width of a PDF page (in DrawUnits) */
+static long		lPageHeight = LONG_MAX;
+static long		lPageWidth = LONG_MAX;
+/* The height of the footer on the current page (in DrawUnits) */
+static long		lFooterHeight = 0;
+/* Inside a footer (to prevent an infinite loop when the footer is too big) */
+static BOOL		bInFtrSpace = FALSE;
+/* Current font information */
+static drawfile_fontref	tFontRefCurr = (drawfile_fontref)-1;
+static USHORT		usFontSizeCurr = 0;
+static int		iFontColorCurr = -1;
+/* Current vertical position information */
+static long		lYtopCurr = -1;
+/* Image counter */
+static int		iImageCount = 0;
+/* Section index */
+static int		iSectionIndex = 0;
+/* Are we on the first page of the section? */
+static BOOL		bFirstInSection = TRUE;
+/* File positions */
+static long		lFilePosition = 0;
+static long		*alLocation = NULL;
+static size_t		tLocations = 0;
+static int		iMaxLocationNumber = 0;
+/* File position at the start of a page */
+static long		lStreamStart = -1;
+/* Page objects */
+static int		*aiPageObject = NULL;
+static int		iPageCount = 0;
+static size_t		tMaxPageObjects = 0;
+/* Current object number */
+/* 1 = root; 2 = info; 3 = pages; 4 = encoding; 5-16 = fonts; 17 = resources */
+static int		iObjectNumberCurr = 17;
+
+static void		vMoveTo(diagram_type *, long);
+
+static const struct {
+	const char	*szPDFname;
+	const char	*szPSname;
+} atFontname[] = {
+	{ "Courier",			FONT_MONOSPACED_PLAIN },
+	{ "Courier-Bold",		FONT_MONOSPACED_BOLD },
+	{ "Courier-Oblique",		FONT_MONOSPACED_ITALIC },
+	{ "Courier-BoldOblique",	FONT_MONOSPACED_BOLDITALIC },
+	{ "Helvetica",			FONT_SANS_SERIF_PLAIN },
+	{ "Helvetica-Bold",		FONT_SANS_SERIF_BOLD },
+	{ "Helvetica-Oblique",		FONT_SANS_SERIF_ITALIC },
+	{ "Helvetica-BoldOblique",	FONT_SANS_SERIF_BOLDITALIC },
+	{ "Times-Roman",		FONT_SERIF_PLAIN },
+	{ "Times-Bold",			FONT_SERIF_BOLD },
+	{ "Times-Italic",		FONT_SERIF_ITALIC },
+	{ "Times-BoldItalic",		FONT_SERIF_BOLDITALIC },
+};
+
+static const char *iso_8859_1[] = {
+"128 /Euro",
+"140 /ellipsis /trademark /perthousand /bullet",
+"    /quoteleft /quoteright /guilsinglleft /guilsinglright",
+"    /quotedblleft /quotedblright /quotedblbase /endash /emdash",
+"    /minus /OE /oe /dagger /daggerdbl /fi /fl",
+"160 /space /exclamdown /cent /sterling /currency",
+"    /yen /brokenbar /section /dieresis /copyright",
+"    /ordfeminine /guillemotleft /logicalnot /hyphen /registered",
+"    /macron /degree /plusminus /twosuperior /threesuperior",
+"    /acute /mu /paragraph /periodcentered /cedilla",
+"    /onesuperior /ordmasculine /guillemotright /onequarter",
+"    /onehalf /threequarters /questiondown /Agrave /Aacute",
+"    /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla",
+"    /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute",
+"    /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute",
+"    /Ocircumflex /Otilde /Odieresis /multiply /Oslash",
+"    /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn",
+"    /germandbls /agrave /aacute /acircumflex /atilde",
+"    /adieresis /aring /ae /ccedilla /egrave /eacute",
+"    /ecircumflex /edieresis /igrave /iacute /icircumflex",
+"    /idieresis /eth /ntilde /ograve /oacute /ocircumflex",
+"    /otilde /odieresis /divide /oslash /ugrave /uacute",
+"    /ucircumflex /udieresis /yacute /thorn /ydieresis",
+};
+
+static const char *iso_8859_2[] = {
+"160 /space /Aogonek /breve /Lslash /currency /Lcaron",
+"    /Sacute /section /dieresis /Scaron /Scommaaccent",
+"    /Tcaron /Zacute /hyphen /Zcaron /Zdotaccent /degree",
+"    /aogonek /ogonek /lslash /acute /lcaron /sacute",
+"    /caron /cedilla /scaron /scommaaccent /tcaron",
+"    /zacute /hungarumlaut /zcaron /zdotaccent /Racute",
+"    /Aacute /Acircumflex /Abreve /Adieresis /Lacute",
+"    /Cacute /Ccedilla /Ccaron /Eacute /Eogonek",
+"    /Edieresis /Ecaron /Iacute /Icircumflex /Dcaron",
+"    /.notdef /Nacute /Ncaron /Oacute /Ocircumflex",
+"    /Ohungarumlaut /Odieresis /multiply /Rcaron /Uring",
+"    /Uacute /Uhungarumlaut /Udieresis /Yacute /Tcommaaccent",
+"    /germandbls /racute /aacute /acircumflex /abreve",
+"    /adieresis /lacute /cacute /ccedilla /ccaron /eacute",
+"    /eogonek /edieresis /ecaron /iacute /icircumflex",
+"    /dcaron /.notdef /nacute /ncaron /oacute /ocircumflex",
+"    /ohungarumlaut /odieresis /divide /rcaron /uring",
+"    /uacute /uhungarumlaut /udieresis /yacute /tcommaaccent",
+"    /dotaccent",
+};
+
+
+/*
+ * tGetFontIndex - get the font index
+ */
+static size_t
+tGetFontIndex(drawfile_fontref tFontRef)
+{
+	const char	*szFontname;
+	size_t		tIndex;
+
+	/* Get the font name */
+	szFontname = szGetFontname(tFontRef);
+	fail(szFontname == NULL);
+	if (szFontname == NULL) {
+		return 0;
+	}
+
+	/* Find the name in the table */
+	for (tIndex = 0; tIndex < elementsof(atFontname); tIndex++) {
+		if (STRCEQ(atFontname[tIndex].szPSname, szFontname)) {
+			return tIndex;
+		}
+	}
+	/* Not found */
+	DBG_DEC(tFontRef);
+	DBG_MSG(szFontname);
+	return 0;
+} /* end of tGetFontIndex */
+
+/*
+ * vSetLocation - store the location of objects
+ */
+static void
+vSetLocation(int iLocationNumber)
+{
+	fail(iLocationNumber <= 0);
+
+	if ((size_t)iLocationNumber >= tLocations) {
+		/* Extend and set to zero */
+		tLocations += EXTENSION_ARRAY_SIZE;
+		alLocation = xrealloc(alLocation, tLocations * sizeof(long));
+		memset(alLocation + tLocations - EXTENSION_ARRAY_SIZE,
+			0,
+			EXTENSION_ARRAY_SIZE * sizeof(long));
+		DBG_DEC(tLocations);
+	}
+	if (iLocationNumber > iMaxLocationNumber) {
+		iMaxLocationNumber = iLocationNumber;
+	}
+
+	DBG_DEC_C((size_t)iLocationNumber >= tLocations, iLocationNumber);
+	DBG_DEC_C((size_t)iLocationNumber >= tLocations, tLocations);
+	fail((size_t)iLocationNumber >= tLocations);
+
+	alLocation[iLocationNumber] = lFilePosition;
+} /* end of vSetLocation */
+
+/*
+ * vFillNextPageObject - fil the next page object with the current object number
+ */
+static void
+vFillNextPageObject(void)
+{
+	iPageCount++;
+	if ((size_t)iPageCount >= tMaxPageObjects) {
+		/* Extend the array */
+		tMaxPageObjects += EXTENSION_ARRAY_SIZE;
+		aiPageObject = xrealloc(aiPageObject,
+					tMaxPageObjects * sizeof(int));
+		DBG_DEC(tMaxPageObjects);
+	}
+	aiPageObject[iPageCount] = iObjectNumberCurr;
+} /* end of vFillNextPageObject */
+
+/*
+ * vFPprintf - printf and update the fileposition
+ *
+ * called with arguments like fprintf(3)
+ */
+static void
+vFPprintf(FILE *pOutFile, const char *szFormat, ...)
+{
+	va_list	tArg;
+
+	va_start(tArg, szFormat);
+	lFilePosition += vfprintf(pOutFile, szFormat, tArg);
+	va_end(tArg);
+} /* end of vFPprintf */
+
+/*
+ * vCreateInfoDictionary - create the document information dictionary
+ */
+void
+vCreateInfoDictionary(diagram_type *pDiag, int iWordVersion)
+{
+	FILE	*pOutFile;
+	const char	*szTitle, *szAuthor, *szSubject, *szCreator;
+	const char	*szCreationDate, *szModDate;
+
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+	fail(iWordVersion < 0);
+	fail(szProducer == NULL || szProducer[0] == '\0');
+
+	szTitle = szGetTitle();
+	szAuthor = szGetAuthor();
+	szSubject = szGetSubject();
+	szCreationDate = szGetCreationDate();
+	szModDate = szGetModDate();
+
+	switch (iWordVersion) {
+	case 0: szCreator = "Word for DOS"; break;
+	case 1: szCreator = "WinWord 1.x"; break;
+	case 2: szCreator = "WinWord 2.0"; break;
+	case 4: szCreator = "MacWord 4"; break;
+	case 5: szCreator = "MacWord 5"; break;
+	case 6: szCreator = "Word 6"; break;
+	case 7: szCreator = "Word 7/95"; break;
+	case 8: szCreator = "Word 97 or later"; break;
+	default: szCreator = NULL; break;
+	}
+
+	pOutFile = pDiag->pOutFile;
+
+	vSetLocation(2);
+	vFPprintf(pOutFile, "2 0 obj\n");
+	vFPprintf(pOutFile, "<<\n");
+	if (szTitle != NULL && szTitle[0] != '\0') {
+		vFPprintf(pOutFile, "/Title (%s)\n", szTitle);
+	}
+	if (szAuthor != NULL && szAuthor[0] != '\0') {
+		vFPprintf(pOutFile, "/Author (%s)\n", szAuthor);
+	}
+	if (szSubject != NULL && szSubject[0] != '\0') {
+		vFPprintf(pOutFile, "/Subject (%s)\n", szSubject);
+	}
+	if (szCreator != NULL && szCreator[0] != '\0') {
+		vFPprintf(pOutFile, "/Creator (%s)\n", szCreator);
+	}
+	vFPprintf(pOutFile, "/Producer (%s %s)\n", szProducer, VERSIONSTRING);
+	if (szCreationDate != NULL && szCreationDate[0] != '\0') {
+		vFPprintf(pOutFile, "/CreationDate (%s)\n", szCreationDate);
+	}
+	if (szModDate != NULL && szModDate[0] != '\0') {
+		vFPprintf(pOutFile, "/ModDate (%s)\n", szModDate);
+	}
+	vFPprintf(pOutFile, ">>\n");
+	vFPprintf(pOutFile, "endobj\n");
+} /* end of vCreateInfoDictionary */
+
+/*
+ * vAddHdrFtr - add a header or footer
+ */
+static void
+vAddHdrFtr(diagram_type *pDiag, const hdrftr_block_type *pHdrFtrInfo)
+{
+	output_type	*pStart, *pPrev, *pNext;
+
+	fail(pDiag == NULL);
+	fail(pHdrFtrInfo == NULL);
+
+	vStartOfParagraphPDF(pDiag, 0);
+	pStart = pHdrFtrInfo->pText;
+	while (pStart != NULL) {
+		pNext = pStart;
+		while (pNext != NULL &&
+		       (pNext->tNextFree != 1 ||
+		        (pNext->szStorage[0] != PAR_END &&
+		         pNext->szStorage[0] != HARD_RETURN))) {
+			pNext = pNext->pNext;
+		}
+		if (pNext == NULL) {
+			if (bOutputContainsText(pStart)) {
+				vAlign2Window(pDiag, pStart,
+					lChar2MilliPoints(DEFAULT_SCREEN_WIDTH),
+					ALIGNMENT_LEFT);
+			} else {
+				vMove2NextLinePDF(pDiag, pStart->usFontSize);
+			}
+			break;
+		}
+		fail(pNext->tNextFree != 1);
+		fail(pNext->szStorage[0] != PAR_END &&
+			pNext->szStorage[0] != HARD_RETURN);
+
+		if (pStart != pNext) {
+			/* There is something to print */
+			pPrev = pNext->pPrev;
+			fail(pPrev->pNext != pNext);
+			/* Cut the chain */
+			pPrev->pNext = NULL;
+			if (bOutputContainsText(pStart)) {
+				/* Print it */
+				vAlign2Window(pDiag, pStart,
+					lChar2MilliPoints(DEFAULT_SCREEN_WIDTH),
+					ALIGNMENT_LEFT);
+			} else {
+				/* Just an empty line */
+				vMove2NextLinePDF(pDiag, pStart->usFontSize);
+			}
+			/* Repair the chain */
+			pPrev->pNext = pNext;
+		}
+		if (pNext->szStorage[0] == PAR_END) {
+			vEndOfParagraphPDF(pDiag, pNext->usFontSize,
+					(long)pNext->usFontSize * 200);
+		}
+		pStart = pNext->pNext;
+	}
+} /* end of vAddHdrFtr */
+
+/*
+ * vAddHeader - add a page header
+ */
+static void
+vAddHeader(diagram_type *pDiag)
+{
+	const hdrftr_block_type *pHdrInfo;
+	const hdrftr_block_type *pFtrInfo;
+
+	fail(pDiag == NULL);
+
+	NO_DBG_MSG("vAddHeader");
+
+	pHdrInfo = pGetHdrFtrInfo(iSectionIndex, TRUE,
+					odd(iPageCount), bFirstInSection);
+	pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE,
+					odd(iPageCount), bFirstInSection);
+	/* Set the height of the footer of this page */
+	lFooterHeight = pFtrInfo == NULL ? 0 : pFtrInfo->lHeight;
+	fail(lFooterHeight < 0);
+
+	if (pHdrInfo == NULL ||
+	    pHdrInfo->pText == NULL ||
+	    pHdrInfo->lHeight <= 0) {
+		fail(pHdrInfo != NULL && pHdrInfo->lHeight < 0);
+		fail(pHdrInfo != NULL &&
+			pHdrInfo->pText != NULL &&
+			pHdrInfo->lHeight == 0);
+		return;
+	}
+
+	vAddHdrFtr(pDiag, pHdrInfo);
+
+	DBG_DEC_C(pHdrInfo->lHeight !=
+		lPageHeight - PS_TOP_MARGIN - pDiag->lYtop,
+		pHdrInfo->lHeight);
+	DBG_DEC_C(pHdrInfo->lHeight !=
+		lPageHeight - PS_TOP_MARGIN - pDiag->lYtop,
+		lPageHeight - PS_TOP_MARGIN - pDiag->lYtop);
+} /* end of vAddHeader */
+
+/*
+ * vAddFooter - add a page footer
+ */
+static void
+vAddFooter(diagram_type *pDiag)
+{
+	const hdrftr_block_type *pFtrInfo;
+
+	fail(pDiag == NULL);
+
+	NO_DBG_MSG("vAddFooter");
+
+	pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE,
+					odd(iPageCount), bFirstInSection);
+	bFirstInSection = FALSE;
+	if (pFtrInfo == NULL ||
+	    pFtrInfo->pText == NULL ||
+	    pFtrInfo->lHeight <= 0) {
+		fail(pFtrInfo != NULL && pFtrInfo->lHeight < 0);
+		fail(pFtrInfo != NULL &&
+			pFtrInfo->pText != NULL &&
+			pFtrInfo->lHeight == 0);
+		return;
+	}
+
+	bInFtrSpace = TRUE;
+
+	DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, pFtrInfo->lHeight);
+	DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, lFooterHeight);
+	DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN,
+			pDiag->lYtop);
+	DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN,
+			lFooterHeight + PS_BOTTOM_MARGIN);
+
+	if (pDiag->lYtop > lFooterHeight + PS_BOTTOM_MARGIN) {
+		/* Move down to the start of the footer */
+		pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN;
+		vMoveTo(pDiag, 0);
+	} else if (pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN / 2) {
+		DBG_FIXME();
+		/*
+		 * Move up to the start of the footer, to prevent moving
+		 * of the bottom edge of the paper
+		 */
+		pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN;
+		vMoveTo(pDiag, 0);
+	}
+
+	DBG_FLT_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN,
+	dDrawUnits2Points(lFooterHeight + PS_BOTTOM_MARGIN - pDiag->lYtop));
+
+	vAddHdrFtr(pDiag, pFtrInfo);
+	bInFtrSpace = FALSE;
+} /* end of vAddFooter */
+
+/*
+ * vEndPageObject - end the current page object
+ */
+static void
+vEndPageObject(FILE *pOutFile)
+{
+	long	lStreamEnd;
+
+	if (lStreamStart < 0) {
+		/* There is no current page object */
+		return;
+	}
+
+	vFPprintf(pOutFile, "ET\n");
+	lStreamEnd = lFilePosition;
+	vFPprintf(pOutFile, "endstream\n");
+	vFPprintf(pOutFile, "endobj\n");
+
+	iObjectNumberCurr++;
+	vSetLocation(iObjectNumberCurr);
+	vFPprintf(pOutFile, "%d 0 obj\n", iObjectNumberCurr);
+	vFPprintf(pOutFile, "%lu\n", lStreamEnd - lStreamStart);
+	vFPprintf(pOutFile, "endobj\n");
+} /* end of vEndPageObject */
+
+/*
+ * vMove2NextPage - move to the start of the next page
+ */
+static void
+vMove2NextPage(diagram_type *pDiag, BOOL bNewSection)
+{
+	FILE	*pOutFile;
+
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+
+	pOutFile = pDiag->pOutFile;
+
+	vAddFooter(pDiag);
+	/* End the old page object */
+	vEndPageObject(pOutFile);
+	if (bNewSection) {
+		iSectionIndex++;
+		bFirstInSection = TRUE;
+	}
+
+	/* Start the new page object */
+	iObjectNumberCurr++;
+	vSetLocation(iObjectNumberCurr);
+	vFillNextPageObject();
+	vFPprintf(pOutFile, "%d 0 obj\n", iObjectNumberCurr);
+	vFPprintf(pOutFile, "<<\n");
+	vFPprintf(pOutFile, "/Type /Page\n");
+	vFPprintf(pOutFile, "/Parent 3 0 R\n");
+	vFPprintf(pOutFile, "/Resources 17 0 R\n");
+	vFPprintf(pOutFile, "/Contents %d 0 R\n", iObjectNumberCurr + 1);
+	vFPprintf(pOutFile, ">>\n");
+	vFPprintf(pOutFile, "endobj\n");
+
+	/* Start the new text object */
+	iObjectNumberCurr++;
+	vSetLocation(iObjectNumberCurr);
+	vFPprintf(pOutFile, "%d 0 obj\n", iObjectNumberCurr);
+	vFPprintf(pOutFile, "<<\n");
+	vFPprintf(pOutFile, "/Length %d 0 R\n", iObjectNumberCurr + 1);
+	vFPprintf(pOutFile, ">>\n");
+	vFPprintf(pOutFile, "stream\n");
+	lStreamStart = lFilePosition;
+	vFPprintf(pOutFile, "BT\n");
+
+	/* Set variables to their start of page values */
+	pDiag->lYtop = lPageHeight - PS_TOP_MARGIN;
+	tFontRefCurr = (drawfile_fontref)-1;
+	usFontSizeCurr = 0;
+	iFontColorCurr = -1;
+	lYtopCurr = -1;
+	vAddHeader(pDiag);
+} /* end of vMove2NextPage */
+
+/*
+ * vMoveTo - move to the specified X,Y coordinates
+ *
+ * Move the current position of the specified diagram to its X,Y coordinates,
+ * start on a new page if needed
+ */
+static void
+vMoveTo(diagram_type *pDiag, long lLastVerticalMovement)
+{
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+
+	if (pDiag->lYtop <= lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace) {
+		vMove2NextPage(pDiag, FALSE);
+		/* Repeat the last vertical movement on the new page */
+		pDiag->lYtop -= lLastVerticalMovement;
+	}
+
+	fail(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace);
+	DBG_DEC_C(pDiag->lYtop < PS_BOTTOM_MARGIN, pDiag->lYtop);
+	fail(pDiag->lYtop < PS_BOTTOM_MARGIN / 3);
+
+	if (pDiag->lYtop != lYtopCurr) {
+		vFPprintf(pDiag->pOutFile, "1 0 0 1 %.2f %.2f Tm\n",
+			dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN),
+			dDrawUnits2Points(pDiag->lYtop));
+		lYtopCurr = pDiag->lYtop;
+	}
+} /* end of vMoveTo */
+
+/*
+ * vProloguePDF - set options and perform the PDF initialization
+ */
+void
+vProloguePDF(diagram_type *pDiag,
+	const char *szTask, const options_type *pOptions)
+{
+	FILE	*pOutFile;
+
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+	fail(pOptions == NULL);
+
+	pOutFile = pDiag->pOutFile;
+
+	eEncoding = pOptions->eEncoding;
+
+	/* Create an empty location array */
+	tLocations = INITIAL_LOCATION_SIZE;
+	alLocation = xcalloc(tLocations, sizeof(long));
+
+	/* Create an empty pageobject array */
+	tMaxPageObjects = INITIAL_PAGEOBJECT_SIZE;
+	aiPageObject = xcalloc(tMaxPageObjects, sizeof(int));
+
+	if (pOptions->iPageHeight == INT_MAX) {
+		lPageHeight = LONG_MAX;
+	} else {
+		lPageHeight = lPoints2DrawUnits(pOptions->iPageHeight);
+	}
+	DBG_DEC(lPageHeight);
+	if (pOptions->iPageWidth == INT_MAX) {
+		lPageWidth = LONG_MAX;
+	} else {
+		lPageWidth = lPoints2DrawUnits(pOptions->iPageWidth);
+	}
+	DBG_DEC(lPageWidth);
+	lFooterHeight = 0;
+	bInFtrSpace = FALSE;
+
+	tFontRefCurr = (drawfile_fontref)-1;
+	usFontSizeCurr = 0;
+	iFontColorCurr = -1;
+	lYtopCurr = -1;
+	iPageCount = 0;
+	iImageCount = 0;
+	iSectionIndex = 0;
+	bFirstInSection = TRUE;
+	lFilePosition = 0;
+	iMaxLocationNumber = 0;
+	lStreamStart = -1;
+	iObjectNumberCurr = 17;
+	pDiag->lXleft = 0;
+	pDiag->lYtop = 0;
+
+	szProducer = szTask;
+
+	vFPprintf(pOutFile, "%%PDF-1.3\n");
+	vFPprintf(pOutFile, "%%%c%c%c%c\n", 0xe2, 0xe3, 0xcf, 0xd3);
+
+	/* Root catalog */
+	vSetLocation(1);
+	vFPprintf(pOutFile, "1 0 obj\n");
+	vFPprintf(pOutFile, "<<\n");
+	vFPprintf(pOutFile, "/Type /Catalog\n");
+	vFPprintf(pOutFile, "/Pages 3 0 R\n");
+	vFPprintf(pOutFile, ">>\n");
+	vFPprintf(pOutFile, "endobj\n");
+} /* end of vProloguePDF */
+
+/*
+ * vEpiloguePDF - clean up after everything is done
+ */
+void
+vEpiloguePDF(diagram_type *pDiag)
+{
+	FILE	*pOutFile;
+	long	lXref;
+	int	iIndex;
+
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+
+	pOutFile = pDiag->pOutFile;
+
+	vAddFooter(pDiag);
+	/* End the old page object */
+	vEndPageObject(pOutFile);
+
+	vSetLocation(3);
+	vFPprintf(pOutFile, "3 0 obj\n");
+	vFPprintf(pOutFile, "<<\n");
+	vFPprintf(pOutFile, "/Type /Pages\n");
+	vFPprintf(pOutFile, "/Count %d\n", iPageCount);
+	vFPprintf(pOutFile, "/MediaBox [ 0 0 %.0f %.0f ]\n",
+			dDrawUnits2Points(lPageWidth),
+			dDrawUnits2Points(lPageHeight));
+	vFPprintf(pOutFile, "/Kids [ ");
+	for (iIndex = 1; iIndex <= iPageCount; iIndex++) {
+		vFPprintf(pOutFile, "\t%d 0 R\n", aiPageObject[iIndex]);
+	}
+	vFPprintf(pOutFile, "]\n");
+	vFPprintf(pOutFile, ">>\n");
+	vFPprintf(pOutFile, "endobj\n");
+
+	lXref = lFilePosition;
+
+	vFPprintf(pOutFile, "xref\n");
+	vFPprintf(pOutFile, "0 %d\n", iMaxLocationNumber + 1);
+	vFPprintf(pOutFile, "0000000000 65535 f \n");
+	for (iIndex = 1; iIndex <= iMaxLocationNumber; iIndex++) {
+		vFPprintf(pOutFile, "%.10ld 00000 n \n", alLocation[iIndex]);
+	}
+
+	vFPprintf(pOutFile, "trailer\n");
+	vFPprintf(pOutFile, "<<\n");
+	vFPprintf(pOutFile, "/Size %d\n", iMaxLocationNumber + 1);
+	vFPprintf(pOutFile, "/Root 1 0 R\n");
+	vFPprintf(pOutFile, "/Info 2 0 R\n");
+	vFPprintf(pOutFile, ">>\n");
+
+	vFPprintf(pOutFile, "startxref\n");
+	vFPprintf(pOutFile, "%ld\n", lXref);
+	vFPprintf(pOutFile, "%%%%EOF\n");
+
+	szProducer = NULL;
+	aiPageObject = xfree(aiPageObject);
+	alLocation = xfree(alLocation);
+} /* end of vEpiloguePDF */
+
+/*
+ * vPrintPalette - print a pdf color space (palette)
+ */
+static void
+vPrintPalette(FILE *pOutFile, const imagedata_type *pImg)
+{
+	int	iIndex;
+
+	fail(pOutFile == NULL);
+	fail(pImg == NULL);
+	fail(pImg->iColorsUsed < 2);
+	fail(pImg->iColorsUsed > 256);
+
+	vFPprintf(pOutFile, "\t/ColorSpace [ /Indexed\n");
+	vFPprintf(pOutFile, "\t/Device%s %d\n",
+		pImg->bColorImage ? "RGB" : "Gray", pImg->iColorsUsed - 1);
+	vFPprintf(pOutFile, "<");
+	for (iIndex = 0; iIndex < pImg->iColorsUsed; iIndex++) {
+		vFPprintf(pOutFile, "%02x",
+				(unsigned int)pImg->aucPalette[iIndex][0]);
+		if (pImg->bColorImage) {
+			vFPprintf(pOutFile, "%02x%02x",
+				(unsigned int)pImg->aucPalette[iIndex][1],
+				(unsigned int)pImg->aucPalette[iIndex][2]);
+		}
+		if (iIndex % 8 == 7) {
+			vFPprintf(pOutFile, "\n");
+		} else {
+			vFPprintf(pOutFile, " ");
+		}
+	}
+	vFPprintf(pOutFile, "> ]\n");
+} /* end of vPrintPalette */
+
+/*
+ * vImageProloguePDF - perform the image initialization
+ */
+void
+vImageProloguePDF(diagram_type *pDiag, const imagedata_type *pImg)
+{
+	FILE	*pOutFile;
+
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+	fail(pImg == NULL);
+
+	if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) {
+		return;
+	}
+
+	iImageCount++;
+
+	DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);
+
+	pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled);
+	vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled));
+
+	pOutFile = pDiag->pOutFile;
+
+	vFPprintf(pOutFile, "ET\n");
+	vFPprintf(pOutFile, "q %% Image %03d\n", iImageCount);
+	if (pImg->eImageType == imagetype_is_dib) {
+		/* Scanning from left to right and bottom to top */
+		vFPprintf(pOutFile, "%d 0 0 %d %.2f %.2f cm\n",
+			pImg->iHorSizeScaled, -pImg->iVerSizeScaled,
+			dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN),
+			dDrawUnits2Points(pDiag->lYtop) + pImg->iVerSizeScaled);
+	} else {
+		/* Scanning from left to right and top to bottom */
+		vFPprintf(pOutFile, "%d 0 0 %d %.2f %.2f cm\n",
+			pImg->iHorSizeScaled, pImg->iVerSizeScaled,
+			dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN),
+			dDrawUnits2Points(pDiag->lYtop));
+	}
+	vFPprintf(pOutFile, "BI\n");
+	vFPprintf(pOutFile, "\t/Width %d\n", pImg->iWidth);
+	vFPprintf(pOutFile, "\t/Height %d\n", pImg->iHeight);
+	switch (pImg->eImageType) {
+	case imagetype_is_jpeg:
+		switch (pImg->iComponents) {
+		case 1:
+			vFPprintf(pOutFile, "\t/ColorSpace /DeviceGray\n");
+			break;
+		case 3:
+			vFPprintf(pOutFile, "\t/ColorSpace /DeviceRGB\n");
+			break;
+		case 4:
+			vFPprintf(pOutFile, "\t/ColorSpace /DeviceCMYK\n");
+			if (pImg->bAdobe) {
+				/*
+				 * Adobe-conforming CMYK file
+				 * applying workaround for color inversion
+				 */
+				vFPprintf(pOutFile,
+					"\t/Decode [1 0 1 0 1 0 1 0]\n");
+			}
+			break;
+		default:
+			DBG_DEC(pImg->iComponents);
+			break;
+		}
+		vFPprintf(pOutFile, "\t/BitsPerComponent 8\n");
+		vFPprintf(pOutFile,
+			"\t/Filter [ /ASCII85Decode /DCTDecode ]\n");
+		break;
+	case imagetype_is_png:
+		if (pImg->iComponents == 3 || pImg->iComponents == 4) {
+			vFPprintf(pOutFile, "\t/ColorSpace /DeviceRGB\n");
+			vFPprintf(pOutFile, "\t/BitsPerComponent 8\n");
+		} else if (pImg->iColorsUsed > 0) {
+			vPrintPalette(pOutFile, pImg);
+			fail(pImg->uiBitsPerComponent > 8);
+			vFPprintf(pOutFile, "\t/BitsPerComponent %u\n",
+					pImg->uiBitsPerComponent);
+		} else {
+			vFPprintf(pOutFile, "\t/ColorSpace /DeviceGray\n");
+			vFPprintf(pOutFile, "\t/BitsPerComponent 8\n");
+		}
+		vFPprintf(pOutFile,
+			"\t/Filter [ /ASCII85Decode /FlateDecode ]\n");
+		vFPprintf(pOutFile, "\t/DecodeParms [ null <<\n");
+		vFPprintf(pOutFile, "\t\t/Predictor 10\n");
+		vFPprintf(pOutFile, "\t\t/Colors %d\n", pImg->iComponents);
+		vFPprintf(pOutFile, "\t\t/BitsPerComponent %u\n",
+						pImg->uiBitsPerComponent);
+		vFPprintf(pOutFile, "\t\t/Columns %d\n", pImg->iWidth);
+		vFPprintf(pOutFile, "\t\t>> ]\n");
+		break;
+	case imagetype_is_dib:
+		if (pImg->uiBitsPerComponent <= 8) {
+			vPrintPalette(pOutFile, pImg);
+		} else {
+			vFPprintf(pOutFile, "\t/ColorSpace /DeviceRGB\n");
+		}
+		vFPprintf(pOutFile, "\t/BitsPerComponent 8\n");
+		vFPprintf(pOutFile, "\t/Filter /ASCII85Decode\n");
+		break;
+	default:
+		vFPprintf(pOutFile, "\t/ColorSpace /Device%s\n",
+			pImg->bColorImage ? "RGB" : "Gray");
+		vFPprintf(pOutFile, "\t/BitsPerComponent 8\n");
+		vFPprintf(pOutFile, "\t/Filter /ASCIIHexDecode\n");
+		break;
+	}
+	vFPprintf(pOutFile, "ID\n");
+} /* end of vImageProloguePDF */
+
+/*
+ * vImageEpiloguePDF - clean up after the image
+ */
+void
+vImageEpiloguePDF(diagram_type *pDiag)
+{
+	FILE	*pOutFile;
+
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+
+	pOutFile = pDiag->pOutFile;
+
+	/* Correction for the image bytes */
+	lFilePosition = ftell(pOutFile);
+
+	vFPprintf(pOutFile, "EI\n");
+	vFPprintf(pOutFile, "Q\n");
+	vFPprintf(pOutFile, "BT\n");
+
+	pDiag->lXleft = 0;
+} /* end of vImageEpiloguePDF */
+
+/*
+ * bAddDummyImagePDF - add a dummy image
+ *
+ * return TRUE when successful, otherwise FALSE
+ */
+BOOL
+bAddDummyImagePDF(diagram_type *pDiag, const imagedata_type *pImg)
+{
+	FILE	*pOutFile;
+
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+	fail(pImg == NULL);
+
+	if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) {
+		return FALSE;
+	}
+
+	iImageCount++;
+
+	DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);
+
+	pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled);
+	vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled));
+
+	pOutFile = pDiag->pOutFile;
+
+	vFPprintf(pOutFile, "ET\n");
+	vFPprintf(pOutFile, "q %% Image %03d\n", iImageCount);
+	vFPprintf(pOutFile, "\t1.0 w\n");
+	vFPprintf(pOutFile, "\t0.3 G\n");
+	vFPprintf(pOutFile, "\t%.2f %.2f %d %d re\n",
+			dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN),
+			dDrawUnits2Points(pDiag->lYtop),
+			pImg->iHorSizeScaled,
+			pImg->iVerSizeScaled);
+	vFPprintf(pOutFile, "\tS\n");
+	vFPprintf(pOutFile, "Q\n");
+	vFPprintf(pOutFile, "BT\n");
+
+	pDiag->lXleft = 0;
+
+	return TRUE;
+} /* end of bAddDummyImagePDF */
+
+/*
+ * vAddFontsPDF - add the font information
+ */
+void
+vAddFontsPDF(diagram_type *pDiag)
+{
+	FILE	*pOutFile;
+	size_t	tIndex;
+
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+
+	pOutFile = pDiag->pOutFile;
+
+	/* The font encoding */
+	vSetLocation(4);
+	vFPprintf(pOutFile, "4 0 obj\n");
+	vFPprintf(pOutFile, "<<\n");
+	vFPprintf(pOutFile, "/Type /Encoding\n");
+	vFPprintf(pOutFile, "/BaseEncoding /StandardEncoding\n");
+	vFPprintf(pOutFile, "/Differences [\n");
+	switch (eEncoding) {
+	case encoding_latin_1:
+		for (tIndex = 0;
+		     tIndex < elementsof(iso_8859_1);
+		     tIndex++) {
+			vFPprintf(pOutFile, "%s\n", iso_8859_1[tIndex]);
+		}
+		break;
+	case encoding_latin_2:
+		for (tIndex = 0;
+		     tIndex < elementsof(iso_8859_2);
+		     tIndex++) {
+			vFPprintf(pOutFile, "%s\n", iso_8859_2[tIndex]);
+		}
+		break;
+	case encoding_cyrillic:
+		werr(1,
+		"The combination PDF and Cyrillic is not supported");
+		break;
+	case encoding_utf_8:
+		werr(1,
+		"The combination PDF and UTF-8 is not supported");
+		break;
+	default:
+		DBG_DEC(eEncoding);
+		break;
+	}
+	vFPprintf(pOutFile, "]\n");
+	vFPprintf(pOutFile, ">>\n");
+	vFPprintf(pOutFile, "endobj\n");
+
+	/* Twelve of the standard type 1 fonts */
+	for (tIndex = 0; tIndex < 12; tIndex++) {
+		vSetLocation(5 + tIndex);
+		vFPprintf(pOutFile, "%u 0 obj\n", 5 + tIndex);
+		vFPprintf(pOutFile, "<<\n");
+		vFPprintf(pOutFile, "/Type /Font\n");
+		vFPprintf(pOutFile, "/Subtype /Type1\n");
+		vFPprintf(pOutFile, "/Name /F%u\n", 1 + tIndex);
+		vFPprintf(pOutFile, "/BaseFont /%s\n",
+						atFontname[tIndex].szPDFname);
+		vFPprintf(pOutFile, "/Encoding 4 0 R\n");
+		vFPprintf(pOutFile, ">>\n");
+		vFPprintf(pOutFile, "endobj\n");
+	}
+
+	/* The Resources */
+	vSetLocation(17);
+	vFPprintf(pOutFile, "17 0 obj\n");
+	vFPprintf(pOutFile, "<<\n");
+	vFPprintf(pOutFile, "/ProcSet [ /PDF /Text ]\n");
+	vFPprintf(pOutFile, "/Font <<\n");
+	for (tIndex = 0; tIndex < 12; tIndex++) {
+		vFPprintf(pOutFile, "\t/F%u %u 0 R\n", 1 + tIndex, 5 + tIndex);
+	}
+	vFPprintf(pOutFile, "\t>>\n");
+	vFPprintf(pOutFile, ">>\n");
+	vFPprintf(pOutFile, "endobj\n");
+	vAddHeader(pDiag);
+} /* end of vAddFontsPDF */
+
+/*
+ * vPrintPDF - print a PDF string
+ */
+static void
+vPrintPDF(FILE *pFile, const char *szString, size_t tStringLength,
+	USHORT usFontstyle)
+{
+	const UCHAR	*aucBytes;
+	double	dMove;
+	size_t	tCount;
+
+	fail(szString == NULL);
+
+	if (szString == NULL || szString[0] == '\0' || tStringLength == 0) {
+		return;
+	}
+	DBG_DEC_C(usFontSizeCurr < MIN_FONT_SIZE, usFontSizeCurr);
+
+	dMove = 0.0;
+
+	/* Up for superscript */
+	if (bIsSuperscript(usFontstyle) && usFontSizeCurr != 0) {
+		dMove = (double)((usFontSizeCurr + 1) / 2) * 0.375;
+		vFPprintf(pFile, "%.2f Ts\n", dMove);
+	}
+
+	/* Down for subscript */
+	if (bIsSubscript(usFontstyle) && usFontSizeCurr != 0) {
+		dMove = (double)usFontSizeCurr * 0.125;
+		vFPprintf(pFile, "%.2f Ts\n", -dMove);
+	}
+
+	/* Generate and print the PDF output */
+	aucBytes = (UCHAR *)szString;
+	vFPprintf(pFile, "(");
+	for (tCount = 0; tCount < tStringLength ; tCount++) {
+		switch (aucBytes[tCount]) {
+		case '(':
+		case ')':
+		case '\\':
+			vFPprintf(pFile, "\\%c", szString[tCount]);
+			break;
+		default:
+			if (aucBytes[tCount] < 0x20 ||
+			    aucBytes[tCount] == 0x7f ||
+			    (aucBytes[tCount] >= 0x81 &&
+			     aucBytes[tCount] < 0x8c)) {
+				DBG_HEX(aucBytes[tCount]);
+				vFPprintf(pFile, " ");
+			} else if (aucBytes[tCount] >= 0x80) {
+				vFPprintf(pFile, "\\%03o",
+						(UINT)aucBytes[tCount]);
+			} else {
+				vFPprintf(pFile, "%c", szString[tCount]);
+			}
+			break;
+		}
+	}
+	vFPprintf(pFile, ") Tj\n");
+
+	/* Undo the superscript/subscript move */
+	if (dMove != 0.0) {
+		vFPprintf(pFile, "0 Ts\n");
+	}
+} /* end of vPrintPDF */
+
+/*
+ * vSetColor - move to the specified color
+ */
+static void
+vSetColor(FILE *pFile, UCHAR ucFontColor)
+{
+	ULONG	ulTmp, ulRed, ulGreen, ulBlue;
+
+	ulTmp = ulColor2Color(ucFontColor);
+	ulRed   = (ulTmp & 0x0000ff00) >> 8;
+	ulGreen = (ulTmp & 0x00ff0000) >> 16;
+	ulBlue  = (ulTmp & 0xff000000) >> 24;
+	vFPprintf(pFile, "%.3f %.3f %.3f rg\n",
+			ulRed / 255.0, ulGreen / 255.0, ulBlue / 255.0);
+} /* end of vSetColor */
+
+/*
+ * vMove2NextLinePDF - move to the next line
+ */
+void
+vMove2NextLinePDF(diagram_type *pDiag, USHORT usFontSize)
+{
+	fail(pDiag == NULL);
+	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
+
+	pDiag->lYtop -= lComputeLeading(usFontSize);
+} /* end of vMove2NextLinePDF */
+
+/*
+ * vSubstringPDF - print a sub string
+ */
+void
+vSubstringPDF(diagram_type *pDiag,
+	char *szString, size_t tStringLength, long lStringWidth,
+	UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef,
+	USHORT usFontSize, USHORT usMaxFontSize)
+{
+	size_t	tFontIndex;
+
+	fail(pDiag == NULL || szString == NULL);
+	fail(pDiag->pOutFile == NULL);
+	fail(pDiag->lXleft < 0);
+	fail(tStringLength != strlen(szString));
+	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
+	fail(usMaxFontSize < MIN_FONT_SIZE || usMaxFontSize > MAX_FONT_SIZE);
+	fail(usFontSize > usMaxFontSize);
+
+	if (szString[0] == '\0' || tStringLength == 0) {
+		return;
+	}
+
+	vMoveTo(pDiag, lComputeLeading(usMaxFontSize));
+	if (tFontRef != tFontRefCurr || usFontSize != usFontSizeCurr) {
+		tFontIndex = tGetFontIndex(tFontRef);
+		vFPprintf(pDiag->pOutFile, "/F%u %.1f Tf\n",
+			 1 + tFontIndex, (double)usFontSize / 2.0);
+		tFontRefCurr = tFontRef;
+		usFontSizeCurr = usFontSize;
+	}
+	if ((int)ucFontColor != iFontColorCurr) {
+		vSetColor(pDiag->pOutFile, ucFontColor);
+		iFontColorCurr = (int)ucFontColor;
+	}
+	vPrintPDF(pDiag->pOutFile, szString, tStringLength, usFontstyle);
+	pDiag->lXleft += lStringWidth;
+} /* end of vSubstringPDF */
+
+/*
+ * Create an start of paragraph by moving the y-top mark
+ */
+void
+vStartOfParagraphPDF(diagram_type *pDiag, long lBeforeIndentation)
+{
+	fail(pDiag == NULL);
+	fail(lBeforeIndentation < 0);
+
+	pDiag->lXleft = 0;
+	pDiag->lYtop -= lMilliPoints2DrawUnits(lBeforeIndentation);
+} /* end of vStartOfParagraphPDF */
+
+/*
+ * Create an end of paragraph by moving the y-top mark
+ */
+void
+vEndOfParagraphPDF(diagram_type *pDiag,
+	USHORT usFontSize, long lAfterIndentation)
+{
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
+	fail(lAfterIndentation < 0);
+
+	if (pDiag->lXleft > 0) {
+		/* To the start of the line */
+		vMove2NextLinePDF(pDiag, usFontSize);
+	}
+
+	pDiag->lXleft = 0;
+	pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation);
+} /* end of vEndOfParagraphPDF */
+
+/*
+ * Create an end of page
+ */
+void
+vEndOfPagePDF(diagram_type *pDiag, BOOL bNewSection)
+{
+	vMove2NextPage(pDiag, bNewSection);
+} /* end of vEndOfPagePDF */

+ 16 - 7
sys/src/cmd/aux/antiword/pictlist.c

@@ -1,6 +1,6 @@
 /*
  * pictlist.c
- * Copyright (C) 2000,2001 A.J. van Os; Released under GPL
+ * Copyright (C) 2000-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Build, read and destroy a list of Word picture information
@@ -10,9 +10,18 @@
 #include "antiword.h"
 
 
+/*
+ * Private structure to hide the way the information
+ * is stored from the rest of the program
+ */
+typedef struct picture_mem_tag {
+	picture_block_type      tInfo;
+	struct picture_mem_tag *pNext;
+} picture_mem_type;
+
 /* Variables needed to write the Picture Information List */
-static picture_desc_type	*pAnchor = NULL;
-static picture_desc_type	*pPictureLast = NULL;
+static picture_mem_type	*pAnchor = NULL;
+static picture_mem_type	*pPictureLast = NULL;
 
 
 /*
@@ -21,7 +30,7 @@ static picture_desc_type	*pPictureLast = NULL;
 void
 vDestroyPictInfoList(void)
 {
-	picture_desc_type	*pCurr, *pNext;
+	picture_mem_type	*pCurr, *pNext;
 
 	DBG_MSG("vDestroyPictInfoList");
 
@@ -43,7 +52,7 @@ vDestroyPictInfoList(void)
 void
 vAdd2PictInfoList(const picture_block_type *pPictureBlock)
 {
-	picture_desc_type	*pListMember;
+	picture_mem_type	*pListMember;
 
 	fail(pPictureBlock == NULL);
 
@@ -69,7 +78,7 @@ vAdd2PictInfoList(const picture_block_type *pPictureBlock)
 	NO_DBG_HEX(pPictureBlock->ulPictureOffset);
 
 	/* Create list member */
-	pListMember = xmalloc(sizeof(picture_desc_type));
+	pListMember = xmalloc(sizeof(picture_mem_type));
 	/* Fill the list member */
 	pListMember->tInfo = *pPictureBlock;
 	pListMember->pNext = NULL;
@@ -89,7 +98,7 @@ vAdd2PictInfoList(const picture_block_type *pPictureBlock)
 ULONG
 ulGetPictInfoListItem(ULONG ulFileOffset)
 {
-	picture_desc_type	*pCurr;
+	picture_mem_type	*pCurr;
 
 	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
 		if (pCurr->tInfo.ulFileOffset == ulFileOffset) {

+ 268 - 26
sys/src/cmd/aux/antiword/postscript.c

@@ -1,6 +1,6 @@
 /*
  * postscript.c
- * Copyright (C) 1999-2003 A.J. van Os; Released under GNU GPL
+ * Copyright (C) 1999-2005 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Functions to deal with the PostScript format
@@ -29,12 +29,16 @@ static BOOL		bUseLandscape = FALSE;
 /* The height and width of a PostScript page (in DrawUnits) */
 static long		lPageHeight = LONG_MAX;
 static long		lPageWidth = LONG_MAX;
+/* The height of the footer on the current page (in DrawUnits) */
+static long		lFooterHeight = 0;
+/* Inside a footer (to prevent an infinite loop when the footer is too big) */
+static BOOL		bInFtrSpace = FALSE;
 /* Current time for a PS header */
 static const char	*szCreationDate = NULL;
 /* Current creator for a PS header */
 static const char	*szCreator = NULL;
 /* Current font information */
-static draw_fontref	tFontRefCurr = (draw_fontref)-1;
+static drawfile_fontref	tFontRefCurr = (drawfile_fontref)-1;
 static USHORT		usFontSizeCurr = 0;
 static int		iFontColorCurr = -1;
 /* Current vertical position information */
@@ -43,6 +47,12 @@ static long		lYtopCurr = -1;
 static int		iPageCount = 0;
 /* Image counter */
 static int		iImageCount = 0;
+/* Section index */
+static int		iSectionIndex = 0;
+/* Are we on the first page of the section? */
+static BOOL		bFirstInSection = TRUE;
+
+static void		vMoveTo(diagram_type *, long);
 
 static const char *iso_8859_1_data[] = {
 "/newcodes	% ISO-8859-1 character encodings",
@@ -103,6 +113,35 @@ static const char *iso_8859_2_data[] = {
 "",
 };
 
+static const char *iso_8859_5_data[] = {
+"/newcodes	% ISO-8859-5 character encodings",
+"[",
+"160/space     161/afii10023 162/afii10051 163/afii10052 164/afii10053",
+"165/afii10054 166/afii10055 167/afii10056 168/afii10057 169/afii10058",
+"170/afii10059 171/afii10060 172/afii10061 173/hyphen    174/afii10062",
+"175/afii10145 176/afii10017 177/afii10018 178/afii10019 179/afii10020",
+"180/afii10021 181/afii10022 182/afii10024 183/afii10025 184/afii10026",
+"185/afii10027 186/afii10028 187/afii10029 188/afii10030 189/afii10031",
+"190/afii10032 191/afii10033 192/afii10034 193/afii10035 194/afii10036",
+"195/afii10037 196/afii10038 197/afii10039 198/afii10040 199/afii10041",
+"200/afii10042 201/afii10043 202/afii10044 203/afii10045 204/afii10046",
+"205/afii10047 206/afii10048 207/afii10049 208/afii10065 209/afii10066",
+"210/afii10067 211/afii10068 212/afii10069 213/afii10070 214/afii10072",
+"215/afii10073 216/afii10074 217/afii10075 218/afii10076 219/afii10077",
+"220/afii10078 221/afii10079 222/afii10080 223/afii10081 224/afii10082",
+"225/afii10083 226/afii10084 227/afii10085 228/afii10086 229/afii10087",
+"230/afii10088 231/afii10089 232/afii10090 233/afii10091 234/afii10092",
+"235/afii10093 236/afii10094 237/afii10095 238/afii10096 239/afii10097",
+"240/afii61352 241/afii10071 242/afii10099 243/afii10100 244/afii10101",
+"245/afii10102 246/afii10103 247/afii10104 248/afii10105 249/afii10106",
+"250/afii10107 251/afii10108 252/afii10109 253/section   254/afii10110",
+"255/afii10193",
+"] bind def",
+"",
+"/reencdict 12 dict def",
+"",
+};
+
 static const char *iso_8859_x_func[] = {
 "% change fonts using ISO-8859-x characters",
 "/ChgFnt		% size psname natname => font",
@@ -190,40 +229,222 @@ vAddPageSetup(FILE *pOutFile)
 	}
 } /* end of vAddPageSetup */
 
+/*
+ * vAddHdrFtr - add a header or footer
+ */
+static void
+vAddHdrFtr(diagram_type *pDiag, const hdrftr_block_type *pHdrFtrInfo)
+{
+	output_type	*pStart, *pPrev, *pNext;
+
+	fail(pDiag == NULL);
+	fail(pHdrFtrInfo == NULL);
+
+	vStartOfParagraphPS(pDiag, 0);
+	pStart = pHdrFtrInfo->pText;
+	while (pStart != NULL) {
+		pNext = pStart;
+		while (pNext != NULL &&
+		       (pNext->tNextFree != 1 ||
+		        (pNext->szStorage[0] != PAR_END &&
+		         pNext->szStorage[0] != HARD_RETURN))) {
+			pNext = pNext->pNext;
+		}
+		if (pNext == NULL) {
+			if (bOutputContainsText(pStart)) {
+				vAlign2Window(pDiag, pStart,
+					lChar2MilliPoints(DEFAULT_SCREEN_WIDTH),
+					ALIGNMENT_LEFT);
+			} else {
+				vMove2NextLinePS(pDiag, pStart->usFontSize);
+			}
+			break;
+		}
+		fail(pNext->tNextFree != 1);
+		fail(pNext->szStorage[0] != PAR_END &&
+			pNext->szStorage[0] != HARD_RETURN);
+
+		if (pStart != pNext) {
+			/* There is something to print */
+			pPrev = pNext->pPrev;
+			fail(pPrev->pNext != pNext);
+			/* Cut the chain */
+			pPrev->pNext = NULL;
+			if (bOutputContainsText(pStart)) {
+				/* Print it */
+				vAlign2Window(pDiag, pStart,
+					lChar2MilliPoints(DEFAULT_SCREEN_WIDTH),
+					ALIGNMENT_LEFT);
+			} else {
+				/* Just an empty line */
+				vMove2NextLinePS(pDiag, pStart->usFontSize);
+			}
+			/* Repair the chain */
+			pPrev->pNext = pNext;
+		}
+		if (pNext->szStorage[0] == PAR_END) {
+			vEndOfParagraphPS(pDiag, pNext->usFontSize,
+					(long)pNext->usFontSize * 200);
+		}
+		pStart = pNext->pNext;
+	}
+} /* end of vAddHdrFtr */
+
+/*
+ * vAddHeader - add a page header
+ */
+static void
+vAddHeader(diagram_type *pDiag)
+{
+	const hdrftr_block_type	*pHdrInfo;
+	const hdrftr_block_type	*pFtrInfo;
+
+	fail(pDiag == NULL);
+
+	NO_DBG_MSG("vAddHeader");
+
+	pHdrInfo = pGetHdrFtrInfo(iSectionIndex, TRUE,
+					odd(iPageCount), bFirstInSection);
+	pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE,
+					odd(iPageCount), bFirstInSection);
+	/* Set the height of the footer of this page */
+	lFooterHeight = pFtrInfo == NULL ? 0 : pFtrInfo->lHeight;
+	fail(lFooterHeight < 0);
+
+	if (pHdrInfo == NULL ||
+	    pHdrInfo->pText == NULL ||
+	    pHdrInfo->lHeight <= 0) {
+		fail(pHdrInfo != NULL && pHdrInfo->lHeight < 0);
+		fail(pHdrInfo != NULL &&
+			pHdrInfo->pText != NULL &&
+			pHdrInfo->lHeight == 0);
+		return;
+	}
+
+	vAddHdrFtr(pDiag, pHdrInfo);
+
+	DBG_DEC_C(pHdrInfo->lHeight !=
+		lPageHeight - PS_TOP_MARGIN - pDiag->lYtop,
+		pHdrInfo->lHeight);
+	DBG_DEC_C(pHdrInfo->lHeight !=
+		lPageHeight - PS_TOP_MARGIN - pDiag->lYtop,
+		lPageHeight - PS_TOP_MARGIN - pDiag->lYtop);
+
+#if 0 /* defined(DEBUG) */
+	fprintf(pDiag->pOutFile,
+	"(HEADER: FileOffset 0x%04lx-0x%04lx; Height %ld-%ld) show\n",
+		ulCharPos2FileOffset(pHdrInfo->ulCharPosStart),
+		ulCharPos2FileOffset(pHdrInfo->ulCharPosNext),
+		pHdrInfo->lHeight,
+		lPageHeight - PS_TOP_MARGIN - pDiag->lYtop);
+#endif
+} /* end of vAddHeader */
+
+/*
+ * vAddFooter - add a page footer
+ */
+static void
+vAddFooter(diagram_type *pDiag)
+{
+	const hdrftr_block_type	*pFtrInfo;
+
+	fail(pDiag == NULL);
+
+	NO_DBG_MSG("vAddFooter");
+	pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE,
+					odd(iPageCount), bFirstInSection);
+	bFirstInSection = FALSE;
+	if (pFtrInfo == NULL ||
+	    pFtrInfo->pText == NULL ||
+	    pFtrInfo->lHeight <= 0) {
+		fail(pFtrInfo != NULL && pFtrInfo->lHeight < 0);
+		fail(pFtrInfo != NULL &&
+			pFtrInfo->pText != NULL &&
+			pFtrInfo->lHeight == 0);
+		return;
+	}
+
+	bInFtrSpace = TRUE;
+
+	DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, pFtrInfo->lHeight);
+	DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, lFooterHeight);
+	DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN,
+			pDiag->lYtop);
+	DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN,
+			lFooterHeight + PS_BOTTOM_MARGIN);
+
+	if (pDiag->lYtop > lFooterHeight + PS_BOTTOM_MARGIN) {
+		/* Move down to the start of the footer */
+		pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN;
+		vMoveTo(pDiag, 0);
+	} else if (pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN / 2) {
+		DBG_FIXME();
+		/*
+		 * Move up to the start of the footer, to prevent moving
+		 * of the bottom edge of the paper
+		 */
+		pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN;
+		vMoveTo(pDiag, 0);
+	}
+
+	DBG_FLT_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN,
+	dDrawUnits2Points(lFooterHeight + PS_BOTTOM_MARGIN - pDiag->lYtop));
+
+#if 0 /* defined(DEBUG) */
+	fprintf(pDiag->pOutFile,
+	"(FOOTER: FileOffset 0x%04lx-0x%04lx; Bottom %ld-%ld) show\n",
+		ulCharPos2FileOffset(pFtrInfo->ulCharPosStart),
+		ulCharPos2FileOffset(pFtrInfo->ulCharPosNext),
+		pDiag->lYtop,
+		pFtrInfo->lHeight + PS_BOTTOM_MARGIN);
+#endif
+	vAddHdrFtr(pDiag, pFtrInfo);
+	bInFtrSpace = FALSE;
+} /* end of vAddFooter */
+
 /*
  * vMove2NextPage - move to the start of the next page
  */
 static void
-vMove2NextPage(diagram_type *pDiag)
+vMove2NextPage(diagram_type *pDiag, BOOL bNewSection)
 {
 	fail(pDiag == NULL);
 
+	vAddFooter(pDiag);
 	fprintf(pDiag->pOutFile, "showpage\n");
 	iPageCount++;
 	fprintf(pDiag->pOutFile, "%%%%Page: %d %d\n", iPageCount, iPageCount);
+	if (bNewSection) {
+		iSectionIndex++;
+		bFirstInSection = TRUE;
+	}
 	vAddPageSetup(pDiag->pOutFile);
 	pDiag->lYtop = lPageHeight - PS_TOP_MARGIN;
 	lYtopCurr = -1;
+	vAddHeader(pDiag);
 } /* end of vMove2NextPage */
 
 /*
- * vMoveToPS - move to the specified X,Y coordinates
+ * vMoveTo - move to the specified X,Y coordinates
  *
  * Move the current position of the specified diagram to its X,Y coordinates,
  * start on a new page if needed
  */
 static void
-vMoveToPS(diagram_type *pDiag, long lLastVerticalMovement)
+vMoveTo(diagram_type *pDiag, long lLastVerticalMovement)
 {
 	fail(pDiag == NULL);
 	fail(pDiag->pOutFile == NULL);
 
-	if (pDiag->lYtop < PS_BOTTOM_MARGIN) {
-		vMove2NextPage(pDiag);
+	if (pDiag->lYtop <= lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace) {
+		vMove2NextPage(pDiag, FALSE);
 		/* Repeat the last vertical movement on the new page */
 		pDiag->lYtop -= lLastVerticalMovement;
 	}
-	fail(pDiag->lYtop < PS_BOTTOM_MARGIN);
+
+	fail(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace);
+	DBG_DEC_C(pDiag->lYtop < PS_BOTTOM_MARGIN, pDiag->lYtop);
+	fail(pDiag->lYtop < PS_BOTTOM_MARGIN / 3);
 
 	if (pDiag->lYtop != lYtopCurr) {
 		fprintf(pDiag->pOutFile, "%.2f %.2f moveto\n",
@@ -231,7 +452,7 @@ vMoveToPS(diagram_type *pDiag, long lLastVerticalMovement)
 			dDrawUnits2Points(pDiag->lYtop));
 		lYtopCurr = pDiag->lYtop;
 	}
-} /* end of vMoveToPS */
+} /* end of vMoveTo */
 
 /*
  * vProloguePS - set options and perform the PostScript initialization
@@ -268,12 +489,17 @@ vProloguePS(diagram_type *pDiag,
 		lPageWidth = lPoints2DrawUnits(pOptions->iPageWidth);
 	}
 	DBG_DEC(lPageWidth);
-	tFontRefCurr = (draw_fontref)-1;
+	lFooterHeight = 0;
+	bInFtrSpace = FALSE;
+
+	tFontRefCurr = (drawfile_fontref)-1;
 	usFontSizeCurr = 0;
 	iFontColorCurr = -1;
 	lYtopCurr = -1;
-	iImageCount = 0;
 	iPageCount = 0;
+	iImageCount = 0;
+	iSectionIndex = 0;
+	bFirstInSection = TRUE;
 	pDiag->lXleft = 0;
 	pDiag->lYtop = lPageHeight - PS_TOP_MARGIN;
 
@@ -324,6 +550,7 @@ vEpiloguePS(diagram_type *pDiag)
 	fail(pDiag->pOutFile == NULL);
 
 	if (pDiag->lYtop < lPageHeight - PS_TOP_MARGIN) {
+		vAddFooter(pDiag);
 		fprintf(pDiag->pOutFile, "showpage\n");
 	}
 	fprintf(pDiag->pOutFile, "%%%%Trailer\n");
@@ -393,7 +620,7 @@ vImageProloguePS(diagram_type *pDiag, const imagedata_type *pImg)
 	DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);
 
 	pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled);
-	vMoveToPS(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled));
+	vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled));
 
 	pOutFile = pDiag->pOutFile;
 
@@ -454,7 +681,7 @@ vImageProloguePS(diagram_type *pDiag, const imagedata_type *pImg)
 			fprintf(pOutFile,
 			"/Data Data1 << >> /FlateDecode filter def\n");
 		}
-		if (pImg->iComponents == 3) {
+		if (pImg->iComponents == 3 || pImg->iComponents == 4) {
 			fprintf(pOutFile, "/DeviceRGB setcolorspace\n");
 		} else if (pImg->iColorsUsed > 0) {
 			vPrintPalette(pOutFile, pImg);
@@ -613,7 +840,7 @@ bAddDummyImagePS(diagram_type *pDiag, const imagedata_type *pImg)
 	DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);
 
 	pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled);
-	vMoveToPS(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled));
+	vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled));
 
 	pOutFile = pDiag->pOutFile;
 
@@ -645,7 +872,7 @@ vAddFontsPS(diagram_type *pDiag)
 	FILE	*pOutFile;
 	const font_table_type *pTmp, *pTmp2;
 	size_t	tIndex;
-	int	iLineLen;
+	int	iLineLen, iOurFontnameLen;
 	BOOL	bFound;
 
 	fail(pDiag == NULL);
@@ -670,10 +897,11 @@ vAddFontsPS(diagram_type *pDiag)
 					break;
 				}
 			}
-			if (bFound) {
+			iOurFontnameLen = (int)strlen(pTmp->szOurFontname);
+			if (bFound || iOurFontnameLen <= 0) {
 				continue;
 			}
-			if (iLineLen + (int)strlen(pTmp->szOurFontname) > 78) {
+			if (iLineLen + iOurFontnameLen > 76) {
 				fprintf(pOutFile, "\n%%%%+");
 				iLineLen = 3;
 			}
@@ -687,7 +915,7 @@ vAddFontsPS(diagram_type *pDiag)
 	fprintf(pOutFile, "%%%%BeginProlog\n");
 
 	switch (eEncoding) {
-	case encoding_iso_8859_1:
+	case encoding_latin_1:
 		for (tIndex = 0;
 		     tIndex < elementsof(iso_8859_1_data);
 		     tIndex++) {
@@ -700,7 +928,7 @@ vAddFontsPS(diagram_type *pDiag)
 			fprintf(pOutFile, "%s\n", iso_8859_x_func[tIndex]);
 		}
 		break;
-	case encoding_iso_8859_2:
+	case encoding_latin_2:
 		for (tIndex = 0;
 		     tIndex < elementsof(iso_8859_2_data);
 		     tIndex++) {
@@ -713,7 +941,20 @@ vAddFontsPS(diagram_type *pDiag)
 			fprintf(pOutFile, "%s\n", iso_8859_x_func[tIndex]);
 		}
 		break;
-	case encoding_utf8:
+	case encoding_cyrillic:
+		for (tIndex = 0;
+		     tIndex < elementsof(iso_8859_5_data);
+		     tIndex++) {
+			fprintf(pOutFile, "%s\n", iso_8859_5_data[tIndex]);
+		}
+		fprintf(pOutFile, "\n");
+		for (tIndex = 0;
+		     tIndex < elementsof(iso_8859_x_func);
+		     tIndex++) {
+			fprintf(pOutFile, "%s\n", iso_8859_x_func[tIndex]);
+		}
+		break;
+	case encoding_utf_8:
 		werr(1,
 		"The combination PostScript and UTF-8 is not supported");
 		break;
@@ -730,6 +971,7 @@ vAddFontsPS(diagram_type *pDiag)
 	iPageCount = 1;
 	fprintf(pDiag->pOutFile, "%%%%Page: %d %d\n", iPageCount, iPageCount);
 	vAddPageSetup(pDiag->pOutFile);
+	vAddHeader(pDiag);
 } /* end of vAddFontsPS */
 
 /*
@@ -849,7 +1091,7 @@ vMove2NextLinePS(diagram_type *pDiag, USHORT usFontSize)
 void
 vSubstringPS(diagram_type *pDiag,
 	char *szString, size_t tStringLength, long lStringWidth,
-	UCHAR ucFontColor, USHORT usFontstyle, draw_fontref tFontRef,
+	UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef,
 	USHORT usFontSize, USHORT usMaxFontSize)
 {
 	const char	*szOurFontname;
@@ -880,7 +1122,7 @@ vSubstringPS(diagram_type *pDiag,
 		vSetColor(pDiag->pOutFile, ucFontColor);
 		iFontColorCurr = (int)ucFontColor;
 	}
-	vMoveToPS(pDiag, lComputeLeading(usMaxFontSize));
+	vMoveTo(pDiag, lComputeLeading(usMaxFontSize));
 	vPrintPS(pDiag->pOutFile, szString, tStringLength, usFontstyle);
 	pDiag->lXleft += lStringWidth;
 } /* end of vSubstringPS */
@@ -903,7 +1145,7 @@ vStartOfParagraphPS(diagram_type *pDiag, long lBeforeIndentation)
  */
 void
 vEndOfParagraphPS(diagram_type *pDiag,
-	draw_fontref tFontRef, USHORT usFontSize, long lAfterIndentation)
+	USHORT usFontSize, long lAfterIndentation)
 {
 	fail(pDiag == NULL);
 	fail(pDiag->pOutFile == NULL);
@@ -912,7 +1154,7 @@ vEndOfParagraphPS(diagram_type *pDiag,
 
 	if (pDiag->lXleft > 0) {
 		/* To the start of the line */
-		vMove2NextLine(pDiag, tFontRef, usFontSize);
+		vMove2NextLinePS(pDiag, usFontSize);
 	}
 
 	pDiag->lXleft = 0;
@@ -923,7 +1165,7 @@ vEndOfParagraphPS(diagram_type *pDiag,
  * Create an end of page
  */
 void
-vEndOfPagePS(diagram_type *pDiag)
+vEndOfPagePS(diagram_type *pDiag, BOOL bNewSection)
 {
-	vMove2NextPage(pDiag);
+	vMove2NextPage(pDiag, bNewSection);
 } /* end of vEndOfPagePS */

+ 136 - 15
sys/src/cmd/aux/antiword/prop0.c

@@ -1,15 +1,134 @@
 /*
  * prop0.c
- * Copyright (C) 2002,2003 A.J. van Os; Released under GPL
+ * Copyright (C) 2002-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Read the property information from a Word for DOS file
  */
 
 #include <string.h>
+#include <time.h>
 #include "antiword.h"
 
 
+/*
+ * tConvertDosDate - convert DOS date format
+ *
+ * returns Unix time_t or -1
+ */
+static time_t
+tConvertDosDate(const char *szDosDate)
+{
+	struct tm	tTime;
+	const char	*pcTmp;
+	time_t		tResult;
+
+	memset(&tTime, 0, sizeof(tTime));
+	pcTmp = szDosDate;
+	/* Get the month */
+	if (!isdigit(*pcTmp)) {
+		return (time_t)-1;
+	}
+	tTime.tm_mon = (int)(*pcTmp - '0');
+	pcTmp++;
+	if (isdigit(*pcTmp)) {
+		tTime.tm_mon *= 10;
+		tTime.tm_mon += (int)(*pcTmp - '0');
+		pcTmp++;
+	}
+	/* Get the first separater */
+	if (isalnum(*pcTmp)) {
+		return (time_t)-1;
+	}
+	pcTmp++;
+	/* Get the day */
+	if (!isdigit(*pcTmp)) {
+		return (time_t)-1;
+	}
+	tTime.tm_mday = (int)(*pcTmp - '0');
+	pcTmp++;
+	if (isdigit(*pcTmp)) {
+		tTime.tm_mday *= 10;
+		tTime.tm_mday += (int)(*pcTmp - '0');
+		pcTmp++;
+	}
+	/* Get the second separater */
+	if (isalnum(*pcTmp)) {
+		return (time_t)-1;
+	}
+	pcTmp++;
+	/* Get the year */
+	if (!isdigit(*pcTmp)) {
+		return (time_t)-1;
+	}
+	tTime.tm_year = (int)(*pcTmp - '0');
+	pcTmp++;
+	if (isdigit(*pcTmp)) {
+		tTime.tm_year *= 10;
+		tTime.tm_year += (int)(*pcTmp - '0');
+		pcTmp++;
+	}
+	/* Check the values */
+	if (tTime.tm_mon == 0 || tTime.tm_mday == 0 || tTime.tm_mday > 31) {
+		return (time_t)-1;
+	}
+	/* Correct the values */
+	tTime.tm_mon--;		/* From 01-12 to 00-11 */
+	if (tTime.tm_year < 80) {
+		tTime.tm_year += 100;	/* 00 means 2000 is 100 */
+	}
+	tTime.tm_isdst = -1;
+	tResult = mktime(&tTime);
+	NO_DBG_MSG(ctime(&tResult));
+	return tResult;
+} /* end of tConvertDosDate */
+
+/*
+ * Build the lists with Document Property Information for Word for DOS files
+ */
+void
+vGet0DopInfo(FILE *pFile, const UCHAR *aucHeader)
+{
+	document_block_type	tDocument;
+	UCHAR	*aucBuffer;
+	ULONG	ulBeginSumdInfo, ulBeginNextBlock;
+	size_t	tLen;
+	USHORT	usOffset;
+
+        tDocument.ucHdrFtrSpecification = 0;
+        tDocument.usDefaultTabWidth = usGetWord(0x70, aucHeader); /* dxaTab */
+        tDocument.tCreateDate = (time_t)-1;
+        tDocument.tRevisedDate = (time_t)-1;
+
+	ulBeginSumdInfo = 128 * (ULONG)usGetWord(0x1c, aucHeader);
+	DBG_HEX(ulBeginSumdInfo);
+	ulBeginNextBlock = 128 * (ULONG)usGetWord(0x6a, aucHeader);
+	DBG_HEX(ulBeginNextBlock);
+
+	if (ulBeginSumdInfo < ulBeginNextBlock && ulBeginNextBlock != 0) {
+		/* There is a summary information block */
+		tLen = (size_t)(ulBeginNextBlock - ulBeginSumdInfo);
+		aucBuffer = xmalloc(tLen);
+		/* Read the summary information block */
+		if (bReadBytes(aucBuffer, tLen, ulBeginSumdInfo, pFile)) {
+       			usOffset = usGetWord(12, aucBuffer);
+			if (aucBuffer[usOffset] != 0) {
+				NO_DBG_STRN(aucBuffer + usOffset, 8);
+				tDocument.tRevisedDate =
+				tConvertDosDate((char *)aucBuffer + usOffset);
+			}
+			usOffset = usGetWord(14, aucBuffer);
+			if (aucBuffer[usOffset] != 0) {
+				NO_DBG_STRN(aucBuffer + usOffset, 8);
+				tDocument.tCreateDate =
+				tConvertDosDate((char *)aucBuffer + usOffset);
+			}
+		}
+		aucBuffer = xfree(aucBuffer);
+	}
+        vCreateDocumentInfoList(&tDocument);
+} /* end of vGet0DopInfo */
+
 /*
  * Fill the section information block with information
  * from a Word for DOS file.
@@ -48,14 +167,15 @@ vGet0SepInfo(FILE *pFile, const UCHAR *aucHeader)
 {
 	section_block_type	tSection;
 	UCHAR	*aucBuffer;
-	ULONG	ulBeginSectInfo, ulBeginNextBlock;
-	ULONG	ulSectPage, ulTextOffset;
-	size_t	tSectInfoLen, tBytes;
-	int	iIndex, iSections;
+	ULONG	ulBeginOfText, ulTextOffset, ulBeginSectInfo;
+	ULONG	ulCharPos, ulSectPage, ulBeginNextBlock;
+	size_t	tSectInfoLen, tIndex, tSections, tBytes;
 	UCHAR	aucTmp[2], aucFpage[35];
 
 	fail(pFile == NULL || aucHeader == NULL);
 
+	ulBeginOfText = 128;
+	NO_DBG_HEX(ulBeginOfText);
 	ulBeginSectInfo = 128 * (ULONG)usGetWord(0x18, aucHeader);
 	DBG_HEX(ulBeginSectInfo);
 	ulBeginNextBlock = 128 * (ULONG)usGetWord(0x1a, aucHeader);
@@ -69,11 +189,11 @@ vGet0SepInfo(FILE *pFile, const UCHAR *aucHeader)
 	if (!bReadBytes(aucTmp, 2, ulBeginSectInfo, pFile)) {
 		return;
 	}
-	iSections = (int)usGetWord(0, aucTmp);
-	NO_DBG_DEC(iSections);
+	tSections = (size_t)usGetWord(0, aucTmp);
+	NO_DBG_DEC(tSections);
 
 	/* Read the Section Descriptors */
-	tSectInfoLen = 10 * (size_t)iSections;
+	tSectInfoLen = 10 * tSections;
 	NO_DBG_DEC(tSectInfoLen);
 	aucBuffer = xmalloc(tSectInfoLen);
 	if (!bReadBytes(aucBuffer, tSectInfoLen, ulBeginSectInfo + 4, pFile)) {
@@ -83,16 +203,18 @@ vGet0SepInfo(FILE *pFile, const UCHAR *aucHeader)
 	NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen);
 
 	/* Read the Section Properties */
-	for (iIndex = 0; iIndex < iSections; iIndex++) {
-		ulTextOffset = ulGetLong(10 * iIndex, aucBuffer);
+	for (tIndex = 0; tIndex < tSections; tIndex++) {
+		ulTextOffset = ulGetLong(10 * tIndex, aucBuffer);
+		NO_DBG_HEX(ulTextOffset);
+		ulCharPos = ulBeginOfText + ulTextOffset;
 		NO_DBG_HEX(ulTextOffset);
-		ulSectPage = ulGetLong(10 * iIndex + 6, aucBuffer);
+		ulSectPage = ulGetLong(10 * tIndex + 6, aucBuffer);
 		NO_DBG_HEX(ulSectPage);
 		if (ulSectPage == FC_INVALID ||		/* Must use defaults */
 		    ulSectPage < 128 ||			/* Should not happen */
 		    ulSectPage >= ulBeginSectInfo) {	/* Should not happen */
 			DBG_HEX_C(ulSectPage != FC_INVALID, ulSectPage);
-			vDefault2SectionInfoList(ulTextOffset);
+			vDefault2SectionInfoList(ulCharPos);
 			continue;
 		}
 		/* Get the number of bytes to read */
@@ -101,7 +223,6 @@ vGet0SepInfo(FILE *pFile, const UCHAR *aucHeader)
 		}
 		tBytes = 1 + (size_t)ucGetByte(0, aucTmp);
 		NO_DBG_DEC(tBytes);
-		fail(tBytes > sizeof(aucFpage));
 		if (tBytes > sizeof(aucFpage)) {
 			DBG_DEC(tBytes);
 			tBytes = sizeof(aucFpage);
@@ -114,7 +235,7 @@ vGet0SepInfo(FILE *pFile, const UCHAR *aucHeader)
 		/* Process the bytes */
 		vGetDefaultSection(&tSection);
 		vGet0SectionInfo(aucFpage + 1, tBytes - 1, &tSection);
-		vAdd2SectionInfoList(&tSection, ulTextOffset);
+		vAdd2SectionInfoList(&tSection, ulCharPos);
 	}
 	/* Clean up before you leave */
 	aucBuffer = xfree(aucBuffer);
@@ -268,7 +389,7 @@ vGet0FontInfo(int iFodo, const UCHAR *aucGrpprl, font_block_type *pFont)
 		return;
 	}
 	/* cHps */
-	pFont->usFontSize = ucGetByte(iFodo + 3, aucGrpprl);
+	pFont->usFontSize = (USHORT)ucGetByte(iFodo + 3, aucGrpprl);
 	NO_DBG_DEC(pFont->usFontSize);
 	if (iBytes < 4) {
 		return;

+ 122 - 29
sys/src/cmd/aux/antiword/prop2.c

@@ -1,6 +1,6 @@
 /*
  * prop2.c
- * Copyright (C) 2002,2003 A.J. van Os; Released under GPL
+ * Copyright (C) 2002-2005 A.J. van Os; Released under GPL
  *
  * Description:
  * Read the property information from a WinWord 1 or 2 file
@@ -10,6 +10,8 @@
 #include "antiword.h"
 
 
+#define MAX_FILESIZE		0x2000000UL	/* 32 Mb */
+
 /*
  * iGet2InfoLength - the length of the information for WinWord 1/2 files
  */
@@ -53,6 +55,45 @@ iGet2InfoLength(int iByteNbr, const UCHAR *aucGrpprl)
 	}
 } /* end of iGet2InfoLength */
 
+/*
+ * Build the lists with Document Property Information for WinWord 1/2 files
+ */
+void
+vGet2DopInfo(FILE *pFile, const UCHAR *aucHeader)
+{
+	document_block_type	tDocument;
+	UCHAR	*aucBuffer;
+	ULONG	ulBeginDocpInfo, ulTmp;
+	size_t	tDocpInfoLen;
+	USHORT	usTmp;
+
+	ulBeginDocpInfo = ulGetLong(0x112, aucHeader); /* fcDop */
+	DBG_HEX(ulBeginDocpInfo);
+	tDocpInfoLen = (size_t)usGetWord(0x116, aucHeader); /* cbDop */
+	DBG_DEC(tDocpInfoLen);
+	if (tDocpInfoLen < 28) {
+		DBG_MSG("No Document information");
+		return;
+	}
+
+	aucBuffer = xmalloc(tDocpInfoLen);
+	if (!bReadBytes(aucBuffer, tDocpInfoLen, ulBeginDocpInfo, pFile)) {
+		aucBuffer = xfree(aucBuffer);
+		return;
+	}
+
+	usTmp = usGetWord(0x00, aucBuffer);
+	tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */
+	tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */
+	ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */
+	tDocument.tCreateDate = tConvertDTTM(ulTmp);
+	ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */
+	tDocument.tRevisedDate = tConvertDTTM(ulTmp);
+	vCreateDocumentInfoList(&tDocument);
+
+	aucBuffer = xfree(aucBuffer);
+} /* end of vGet2DopInfo */
+
 /*
  * Fill the section information block with information
  * from a WinWord 1/2 file.
@@ -79,6 +120,10 @@ vGet2SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,
 			usCcol = 1 + usGetWord(iFodoOff + 1, aucGrpprl);
 			DBG_DEC(usCcol);
 			break;
+		case 128:	/* grpfIhdt */
+			pSection->ucHdrFtrSpecification =
+					ucGetByte(iFodoOff + 1, aucGrpprl);
+			break;
 		default:
 			break;
 		}
@@ -95,15 +140,16 @@ void
 vGet2SepInfo(FILE *pFile, const UCHAR *aucHeader)
 {
 	section_block_type	tSection;
-	ULONG	*aulSectPage, *aulTextOffset;
+	ULONG	*aulSectPage, *aulCharPos;
 	UCHAR	*aucBuffer, *aucFpage;
-	ULONG	ulBeginSectInfo;
-	size_t	tSectInfoLen, tOffset, tLen, tBytes;
-	int	iIndex;
+	ULONG	ulBeginOfText, ulTextOffset, ulBeginSectInfo;
+	size_t	tSectInfoLen, tIndex, tOffset, tLen, tBytes;
 	UCHAR	aucTmp[1];
 
 	fail(pFile == NULL || aucHeader == NULL);
 
+	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
+	NO_DBG_HEX(ulBeginOfText);
 	ulBeginSectInfo = ulGetLong(0x7c, aucHeader); /* fcPlcfsed */
 	DBG_HEX(ulBeginSectInfo);
 	tSectInfoLen = (size_t)usGetWord(0x80, aucHeader); /* cbPlcfsed */
@@ -123,37 +169,40 @@ vGet2SepInfo(FILE *pFile, const UCHAR *aucHeader)
 	/* Read the Section Descriptors */
 	tLen = (tSectInfoLen - 4) / 10;
 	/* Save the section offsets */
-	aulTextOffset = xcalloc(tLen, sizeof(ULONG));
-	for (iIndex = 0, tOffset = 0;
-	     iIndex < (int)tLen;
-	     iIndex++, tOffset += 4) {
-		aulTextOffset[iIndex] = ulGetLong(tOffset, aucBuffer);
+	aulCharPos = xcalloc(tLen, sizeof(ULONG));
+	for (tIndex = 0, tOffset = 0;
+	     tIndex < tLen;
+	     tIndex++, tOffset += 4) {
+		ulTextOffset = ulGetLong(tOffset, aucBuffer);
+		NO_DBG_HEX(ulTextOffset);
+		aulCharPos[tIndex] = ulBeginOfText + ulTextOffset;
+		NO_DBG_HEX(aulCharPos[tIndex]);
 	}
 	/* Save the Sepx offsets */
 	aulSectPage = xcalloc(tLen, sizeof(ULONG));
-	for (iIndex = 0, tOffset = (tLen + 1) * 4;
-	     iIndex < (int)tLen;
-	     iIndex++, tOffset += 6) {
-		aulSectPage[iIndex] = ulGetLong(tOffset + 2, aucBuffer);
-		NO_DBG_HEX(aulSectPage[iIndex]); /* fcSepx */
+	for (tIndex = 0, tOffset = (tLen + 1) * 4;
+	     tIndex < tLen;
+	     tIndex++, tOffset += 6) {
+		aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer);
+		NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */
 	}
 	aucBuffer = xfree(aucBuffer);
 
 	/* Read the Section Properties */
-	for (iIndex = 0; iIndex < (int)tLen; iIndex++) {
-		if (aulSectPage[iIndex] == FC_INVALID) {
-			vDefault2SectionInfoList(aulTextOffset[iIndex]);
+	for (tIndex = 0; tIndex < tLen; tIndex++) {
+		if (aulSectPage[tIndex] == FC_INVALID) {
+			vDefault2SectionInfoList(aulCharPos[tIndex]);
 			continue;
 		}
 		/* Get the number of bytes to read */
-		if (!bReadBytes(aucTmp, 1, aulSectPage[iIndex], pFile)) {
+		if (!bReadBytes(aucTmp, 1, aulSectPage[tIndex], pFile)) {
 			continue;
 		}
 		tBytes = 1 + (size_t)ucGetByte(0, aucTmp);
 		NO_DBG_DEC(tBytes);
 		/* Read the bytes */
 		aucFpage = xmalloc(tBytes);
-		if (!bReadBytes(aucFpage, tBytes, aulSectPage[iIndex], pFile)) {
+		if (!bReadBytes(aucFpage, tBytes, aulSectPage[tIndex], pFile)) {
 			aucFpage = xfree(aucFpage);
 			continue;
 		}
@@ -161,13 +210,58 @@ vGet2SepInfo(FILE *pFile, const UCHAR *aucHeader)
 		/* Process the bytes */
 		vGetDefaultSection(&tSection);
 		vGet2SectionInfo(aucFpage + 1, tBytes - 1, &tSection);
-		vAdd2SectionInfoList(&tSection, aulTextOffset[iIndex]);
+		vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]);
 		aucFpage = xfree(aucFpage);
 	}
-	aulTextOffset = xfree(aulTextOffset);
+	aulCharPos = xfree(aulCharPos);
 	aulSectPage = xfree(aulSectPage);
 } /* end of vGet2SepInfo */
 
+/*
+ * Build the list with Header/Footer Information for WinWord 1/2 files
+ */
+void
+vGet2HdrFtrInfo(FILE *pFile, const UCHAR *aucHeader)
+{
+	ULONG	*aulCharPos;
+	UCHAR	*aucBuffer;
+	ULONG	ulHdrFtrOffset, ulBeginHdrFtrInfo;
+	size_t	tHdrFtrInfoLen, tIndex, tOffset, tLen;
+
+	fail(pFile == NULL || aucHeader == NULL);
+
+	ulBeginHdrFtrInfo = ulGetLong(0x9a, aucHeader); /* fcPlcfhdd */
+	NO_DBG_HEX(ulBeginHdrFtrInfo);
+	tHdrFtrInfoLen = (size_t)usGetWord(0x9e, aucHeader); /* cbPlcfhdd */
+	NO_DBG_DEC(tHdrFtrInfoLen);
+	if (tHdrFtrInfoLen < 8) {
+		DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen);
+		return;
+	}
+
+	aucBuffer = xmalloc(tHdrFtrInfoLen);
+	if (!bReadBytes(aucBuffer, tHdrFtrInfoLen, ulBeginHdrFtrInfo, pFile)) {
+		aucBuffer = xfree(aucBuffer);
+		return;
+	}
+	NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen);
+
+	tLen = tHdrFtrInfoLen / 4 - 1;
+	/* Save the header/footer offsets */
+	aulCharPos = xcalloc(tLen, sizeof(ULONG));
+	for (tIndex = 0, tOffset = 0;
+	     tIndex < tLen;
+	     tIndex++, tOffset += 4) {
+		ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer);
+		NO_DBG_HEX(ulHdrFtrOffset);
+		aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset);
+		NO_DBG_HEX(aulCharPos[tIndex]);
+	}
+	vCreat2HdrFtrInfoList(aulCharPos, tLen);
+	aulCharPos = xfree(aulCharPos);
+	aucBuffer = xfree(aucBuffer);
+} /* end of vGet2HdrFtrInfo */
+
 /*
  * Translate the rowinfo to a member of the row_info enumeration
  */
@@ -311,7 +405,6 @@ eGet2RowInfo(int iFodo,
 				werr(1, "The number of columns is corrupt");
 			}
 			pRow->ucNumberOfColumns = (UCHAR)iCol;
-			pRow->iColumnWidthSum = 0;
 			iPosPrev = (int)(short)usGetWord(
 					iFodo + iFodoOff + 4,
 					aucGrpprl);
@@ -321,8 +414,6 @@ eGet2RowInfo(int iFodo,
 					aucGrpprl);
 				pRow->asColumnWidth[iIndex] =
 						(short)(iPosCurr - iPosPrev);
-				pRow->iColumnWidthSum +=
-					pRow->asColumnWidth[iIndex];
 				iPosPrev = iPosCurr;
 			}
 			bFound154 = TRUE;
@@ -393,6 +484,7 @@ vGet2StyleInfo(int iFodo,
 				eGetNumType(ucTmp) == level_type_pause;
 			break;
 		case  15:	/* ChgTabsPapx */
+		case  23:	/* ChgTabs */
 			iTmp = (int)ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
 			if (iTmp < 2) {
 				iInfoLen = 1;
@@ -804,7 +896,7 @@ bGet1PicInfo(int iFodo,
 
 	if (tBytes > sizeof(aucChpx)) {
 		NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes);
-		return FALSE;
+		tBytes = sizeof(aucChpx);
 	}
 
 	/* Build the CHPX structure */
@@ -812,7 +904,7 @@ bGet1PicInfo(int iFodo,
 	(void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx)));
 
 	ulTmp = ulGetLong(8, aucChpx);
-	if (ulTmp != 0) {
+	if (ulTmp != 0 && ulTmp < MAX_FILESIZE) {
 		pPicture->ulPictureOffset = ulTmp;
 		DBG_HEX(pPicture->ulPictureOffset);
 		return TRUE;
@@ -835,7 +927,7 @@ bGet2PicInfo(int iFodo,
 
 	if (tBytes > sizeof(aucChpx)) {
 		NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes);
-		return FALSE;
+		tBytes = sizeof(aucChpx);
 	}
 
 	/* Build the CHPX structure */
@@ -843,7 +935,7 @@ bGet2PicInfo(int iFodo,
 	(void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx)));
 
 	ulTmp = ulGetLong(14, aucChpx);
-	if (ulTmp != 0) {
+	if (ulTmp != 0 && ulTmp < MAX_FILESIZE) {
 		pPicture->ulPictureOffset = ulTmp;
 		DBG_HEX(pPicture->ulPictureOffset);
 		DBG_DEC(tBytes);
@@ -879,6 +971,7 @@ vGet2ChrInfo(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 	DBG_DEC(tCharInfoLen);
 	if (tCharInfoLen < 4) {
 		DBG_DEC(tCharInfoLen);
+		return;
 	}
 
 	aucBuffer = xmalloc(tCharInfoLen);

+ 203 - 72
sys/src/cmd/aux/antiword/prop6.c

@@ -1,6 +1,6 @@
 /*
  * prop6.c
- * Copyright (C) 1998-2003 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2005 A.J. van Os; Released under GPL
  *
  * Description:
  * Read the property information from a MS Word 6 or 7 file
@@ -50,15 +50,56 @@ iGet6InfoLength(int iByteNbr, const UCHAR *aucGrpprl)
 		return 1 + 5;
 	case  73: case  95: case 136: case 137:
 		return 1 + 3;
-	case 120:
-		return 1 + 13;
-	case 187:
+	case 120: case 187:
 		return 1 + 12;
 	default:
 		return 1 + 1;
 	}
 } /* end of iGet6InfoLength */
 
+/*
+ * Build the lists with Document Property Information for Word 6/7 files
+ */
+void
+vGet6DopInfo(FILE *pFile, ULONG ulStartBlock,
+	const ULONG *aulBBD, size_t tBBDLen,
+	const UCHAR *aucHeader)
+{
+	document_block_type	tDocument;
+	UCHAR	*aucBuffer;
+	ULONG	ulBeginDocpInfo, ulTmp;
+	size_t	tDocpInfoLen;
+	USHORT	usTmp;
+
+	ulBeginDocpInfo = ulGetLong(0x150, aucHeader); /* fcDop */
+	DBG_HEX(ulBeginDocpInfo);
+	tDocpInfoLen = (size_t)ulGetLong(0x154, aucHeader); /* lcbDop */
+	DBG_DEC(tDocpInfoLen);
+	if (tDocpInfoLen < 28) {
+		DBG_MSG("No Document information");
+		return;
+	}
+
+	aucBuffer = xmalloc(tDocpInfoLen);
+	if (!bReadBuffer(pFile, ulStartBlock,
+			aulBBD, tBBDLen, BIG_BLOCK_SIZE,
+			aucBuffer, ulBeginDocpInfo, tDocpInfoLen)) {
+		aucBuffer = xfree(aucBuffer);
+		return;
+	}
+
+	usTmp = usGetWord(0x00, aucBuffer);
+	tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */
+	tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */
+	ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */
+	tDocument.tCreateDate = tConvertDTTM(ulTmp);
+	ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */
+	tDocument.tRevisedDate = tConvertDTTM(ulTmp);
+	vCreateDocumentInfoList(&tDocument);
+
+	aucBuffer = xfree(aucBuffer);
+} /* end of vGet6DopInfo */
+
 /*
  * Fill the section information block with information
  * from a Word 6/7 file.
@@ -110,6 +151,10 @@ vGet6SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,
 			usCcol = 1 + usGetWord(iFodoOff + 1, aucGrpprl);
 			DBG_DEC(usCcol);
 			break;
+		case 153:	/* grpfIhdt */
+			pSection->ucHdrFtrSpecification =
+					ucGetByte(iFodoOff + 1, aucGrpprl);
+			break;
 		default:
 			break;
 		}
@@ -130,17 +175,18 @@ vGet6SepInfo(FILE *pFile, ULONG ulStartBlock,
 	const UCHAR *aucHeader)
 {
 	section_block_type	tSection;
-	ULONG		*aulSectPage, *aulTextOffset;
+	ULONG		*aulSectPage, *aulCharPos;
 	UCHAR	*aucBuffer, *aucFpage;
-	ULONG	ulBeginSectInfo;
-	size_t	tSectInfoLen, tOffset, tLen, tBytes;
-	int	iIndex;
+	ULONG	ulBeginOfText, ulTextOffset, ulBeginSectInfo;
+	size_t	tSectInfoLen, tIndex, tOffset, tLen, tBytes;
 	UCHAR	aucTmp[2];
 
 	fail(pFile == NULL || aucHeader == NULL);
 	fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
 	fail(aulBBD == NULL);
 
+        ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
+        NO_DBG_HEX(ulBeginOfText);
 	ulBeginSectInfo = ulGetLong(0x88, aucHeader); /* fcPlcfsed */
 	DBG_HEX(ulBeginSectInfo);
 	tSectInfoLen = (size_t)ulGetLong(0x8c, aucHeader); /* lcbPlcfsed */
@@ -162,32 +208,33 @@ vGet6SepInfo(FILE *pFile, ULONG ulStartBlock,
 	/* Read the Section Descriptors */
 	tLen = (tSectInfoLen - 4) / 16;
 	/* Save the section offsets */
-	aulTextOffset = xcalloc(tLen, sizeof(ULONG));
-	for (iIndex = 0, tOffset = 0;
-	     iIndex < (int)tLen;
-	     iIndex++, tOffset += 4) {
-		aulTextOffset[iIndex] = ulGetLong(tOffset, aucBuffer);
+	aulCharPos = xcalloc(tLen, sizeof(ULONG));
+	for (tIndex = 0, tOffset = 0; tIndex < tLen; tIndex++, tOffset += 4) {
+		ulTextOffset = ulGetLong(tOffset, aucBuffer);
+		NO_DBG_HEX(ulTextOffset);
+		aulCharPos[tIndex] = ulBeginOfText + ulTextOffset;
+		NO_DBG_HEX(aulCharPos[tIndex]);
 	}
 	/* Save the Sepx offsets */
 	aulSectPage = xcalloc(tLen, sizeof(ULONG));
-	for (iIndex = 0, tOffset = (tLen + 1) * 4;
-	     iIndex < (int)tLen;
-	     iIndex++, tOffset += 12) {
-		aulSectPage[iIndex] = ulGetLong(tOffset + 2, aucBuffer);
-		NO_DBG_HEX(aulSectPage[iIndex]); /* fcSepx */
+	for (tIndex = 0, tOffset = (tLen + 1) * 4;
+	     tIndex < tLen;
+	     tIndex++, tOffset += 12) {
+		aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer);
+		NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */
 	}
 	aucBuffer = xfree(aucBuffer);
 
 	/* Read the Section Properties */
-	for (iIndex = 0; iIndex < (int)tLen; iIndex++) {
-		if (aulSectPage[iIndex] == FC_INVALID) {
-			vDefault2SectionInfoList(aulTextOffset[iIndex]);
+	for (tIndex = 0; tIndex < tLen; tIndex++) {
+		if (aulSectPage[tIndex] == FC_INVALID) {
+			vDefault2SectionInfoList(aulCharPos[tIndex]);
 			continue;
 		}
 		/* Get the number of bytes to read */
 		if (!bReadBuffer(pFile, ulStartBlock,
 				aulBBD, tBBDLen, BIG_BLOCK_SIZE,
-				aucTmp, aulSectPage[iIndex], 2)) {
+				aucTmp, aulSectPage[tIndex], 2)) {
 			continue;
 		}
 		tBytes = 2 + (size_t)usGetWord(0, aucTmp);
@@ -196,7 +243,7 @@ vGet6SepInfo(FILE *pFile, ULONG ulStartBlock,
 		aucFpage = xmalloc(tBytes);
 		if (!bReadBuffer(pFile, ulStartBlock,
 				aulBBD, tBBDLen, BIG_BLOCK_SIZE,
-				aucFpage, aulSectPage[iIndex], tBytes)) {
+				aucFpage, aulSectPage[tIndex], tBytes)) {
 			aucFpage = xfree(aucFpage);
 			continue;
 		}
@@ -204,13 +251,64 @@ vGet6SepInfo(FILE *pFile, ULONG ulStartBlock,
 		/* Process the bytes */
 		vGetDefaultSection(&tSection);
 		vGet6SectionInfo(aucFpage + 2, tBytes - 2, &tSection);
-		vAdd2SectionInfoList(&tSection, aulTextOffset[iIndex]);
+		vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]);
 		aucFpage = xfree(aucFpage);
 	}
-	aulTextOffset = xfree(aulTextOffset);
+	aulCharPos = xfree(aulCharPos);
 	aulSectPage = xfree(aulSectPage);
 } /* end of vGet6SepInfo */
 
+/*
+ * Build the list with Header/Footer Information for Word 6/7 files
+ */
+void
+vGet6HdrFtrInfo(FILE *pFile, ULONG ulStartBlock,
+	const ULONG *aulBBD, size_t tBBDLen,
+	const UCHAR *aucHeader)
+{
+	ULONG	*aulCharPos;
+	UCHAR	*aucBuffer;
+	ULONG	ulHdrFtrOffset, ulBeginHdrFtrInfo;
+	size_t	tHdrFtrInfoLen, tIndex, tOffset, tLen;
+
+	fail(pFile == NULL || aucHeader == NULL);
+	fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
+	fail(aulBBD == NULL);
+
+	ulBeginHdrFtrInfo = ulGetLong(0xb0, aucHeader); /* fcPlcfhdd */
+	NO_DBG_HEX(ulBeginHdrFtrInfo);
+	tHdrFtrInfoLen = (size_t)ulGetLong(0xb4, aucHeader); /* lcbPlcfhdd */
+	NO_DBG_DEC(tHdrFtrInfoLen);
+	if (tHdrFtrInfoLen < 8) {
+		DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen);
+		return;
+	}
+
+	aucBuffer = xmalloc(tHdrFtrInfoLen);
+	if (!bReadBuffer(pFile, ulStartBlock,
+			aulBBD, tBBDLen, BIG_BLOCK_SIZE,
+			aucBuffer, ulBeginHdrFtrInfo, tHdrFtrInfoLen)) {
+		aucBuffer = xfree(aucBuffer);
+		return;
+	}
+	NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen);
+
+	tLen = tHdrFtrInfoLen / 4 - 1;
+	/* Save the header/footer offsets */
+	aulCharPos = xcalloc(tLen, sizeof(ULONG));
+	for (tIndex = 0, tOffset = 0;
+	     tIndex < tLen;
+	     tIndex++, tOffset += 4) {
+		ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer);
+		NO_DBG_HEX(ulHdrFtrOffset);
+		aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset);
+		NO_DBG_HEX(aulCharPos[tIndex]);
+	}
+	vCreat6HdrFtrInfoList(aulCharPos, tLen);
+	aulCharPos = xfree(aulCharPos);
+	aucBuffer = xfree(aucBuffer);
+} /* end of vGet6HdrFtrInfo */
+
 /*
  * Translate the rowinfo to a member of the row_info enumeration
  */
@@ -235,7 +333,7 @@ eGet6RowInfo(int iFodo,
 	while (iBytes >= iFodoOff + 1) {
 		iInfoLen = 0;
 		switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) {
-		case  24:	/* fIntable */
+		case  24:	/* fInTable */
 			if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) {
 				bFound24_1 = TRUE;
 			} else {
@@ -289,6 +387,11 @@ eGet6RowInfo(int iFodo,
 				pRow->ucBorderInfo |= TABLE_BORDER_RIGHT;
 			}
 			break;
+		case 188:	/* cDefTable10 */
+			DBG_MSG("188: sprmTDefTable10");
+			iSize = (int)usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
+			DBG_DEC(iSize);
+			break;
 		case 190:	/* cDefTable */
 			iSize = (int)usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
 			if (iSize < 6 || iBytes < iFodoOff + 7) {
@@ -310,7 +413,6 @@ eGet6RowInfo(int iFodo,
 				werr(1, "The number of columns is corrupt");
 			}
 			pRow->ucNumberOfColumns = (UCHAR)iCol;
-			pRow->iColumnWidthSum = 0;
 			iPosPrev = (int)(short)usGetWord(
 					iFodo + iFodoOff + 4,
 					aucGrpprl);
@@ -320,8 +422,6 @@ eGet6RowInfo(int iFodo,
 					aucGrpprl);
 				pRow->asColumnWidth[iIndex] =
 						(short)(iPosCurr - iPosPrev);
-				pRow->iColumnWidthSum +=
-					pRow->asColumnWidth[iIndex];
 				iPosPrev = iPosCurr;
 			}
 			bFound190 = TRUE;
@@ -336,10 +436,11 @@ eGet6RowInfo(int iFodo,
 		}
 		iFodoOff += iInfoLen;
 	}
-	if (bFound24_1 && bFound25_1 && bFound190) {
+
+	if (bFound25_1 && bFound190) {
 		return found_end_of_row;
 	}
-	if (bFound24_0 && bFound25_0 && !bFound190) {
+	if (bFound25_0 && !bFound190) {
 		return found_not_end_of_row;
 	}
 	if (bFound24_1) {
@@ -413,6 +514,7 @@ vGet6StyleInfo(int iFodo,
 				eGetNumType(ucTmp) == level_type_pause;
 			break;
 		case  15:	/* ChgTabsPapx */
+		case  23:	/* ChgTabs */
 			iTmp = (int)ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
 			if (iTmp < 2) {
 				iInfoLen = 1;
@@ -495,7 +597,8 @@ vGet6PapInfo(FILE *pFile, ULONG ulStartBlock,
 	ULONG	ulCharPos, ulCharPosFirst, ulCharPosLast;
 	ULONG	ulBeginParfInfo;
 	size_t	tParfInfoLen, tParfPageNum, tOffset, tSize, tLenOld, tLen;
-	int	iIndex, iIndex2, iRun, iFodo, iLen;
+	size_t	tIndex, tIndex2, tRun;
+	int	iFodo, iLen;
 	row_info_enum	eRowInfo;
 	USHORT	usParfFirstPage, usCount, usIstd;
 	UCHAR	aucFpage[BIG_BLOCK_SIZE];
@@ -524,11 +627,11 @@ vGet6PapInfo(FILE *pFile, ULONG ulStartBlock,
 
 	tLen = (tParfInfoLen - 4) / 6;
 	ausParfPage = xcalloc(tLen, sizeof(USHORT));
-	for (iIndex = 0, tOffset = (tLen + 1) * 4;
-	     iIndex < (int)tLen;
-	     iIndex++, tOffset += 2) {
-		 ausParfPage[iIndex] = usGetWord(tOffset, aucBuffer);
-		 NO_DBG_DEC(ausParfPage[iIndex]);
+	for (tIndex = 0, tOffset = (tLen + 1) * 4;
+	     tIndex < tLen;
+	     tIndex++, tOffset += 2) {
+		 ausParfPage[tIndex] = usGetWord(tOffset, aucBuffer);
+		 NO_DBG_DEC(ausParfPage[tIndex]);
 	}
 	DBG_HEX(ulGetLong(0, aucBuffer));
 	aucBuffer = xfree(aucBuffer);
@@ -544,29 +647,29 @@ vGet6PapInfo(FILE *pFile, ULONG ulStartBlock,
 		ausParfPage = xrealloc(ausParfPage, tSize);
 		/* Add new values */
 		usCount = usParfFirstPage + 1;
-		for (iIndex = (int)tLenOld; iIndex < (int)tLen; iIndex++) {
-			ausParfPage[iIndex] = usCount;
-			NO_DBG_DEC(ausParfPage[iIndex]);
+		for (tIndex = tLenOld; tIndex < tLen; tIndex++) {
+			ausParfPage[tIndex] = usCount;
+			NO_DBG_DEC(ausParfPage[tIndex]);
 			usCount++;
 		}
 	}
 
 	(void)memset(&tRow, 0, sizeof(tRow));
 	ulCharPosFirst = CP_INVALID;
-	for (iIndex = 0; iIndex < (int)tLen; iIndex++) {
+	for (tIndex = 0; tIndex < tLen; tIndex++) {
 		if (!bReadBuffer(pFile, ulStartBlock,
 				aulBBD, tBBDLen, BIG_BLOCK_SIZE,
 				aucFpage,
-				(ULONG)ausParfPage[iIndex] * BIG_BLOCK_SIZE,
+				(ULONG)ausParfPage[tIndex] * BIG_BLOCK_SIZE,
 				BIG_BLOCK_SIZE)) {
 			break;
 		}
-		iRun = (int)ucGetByte(0x1ff, aucFpage);
-		NO_DBG_DEC(iRun);
-		for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) {
-			NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage));
+		tRun = (size_t)ucGetByte(0x1ff, aucFpage);
+		NO_DBG_DEC(tRun);
+		for (tIndex2 = 0; tIndex2 < tRun; tIndex2++) {
+			NO_DBG_HEX(ulGetLong(tIndex2 * 4, aucFpage));
 			iFodo = 2 * (int)ucGetByte(
-				(iRun + 1) * 4 + iIndex2 * 7, aucFpage);
+				(tRun + 1) * 4 + tIndex2 * 7, aucFpage);
 			if (iFodo <= 0) {
 				continue;
 			}
@@ -576,9 +679,10 @@ vGet6PapInfo(FILE *pFile, ULONG ulStartBlock,
 			usIstd = (USHORT)ucGetByte(iFodo + 1, aucFpage);
 			vFillStyleFromStylesheet(usIstd, &tStyle);
 			vGet6StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle);
-			ulCharPos = ulGetLong(iIndex2 * 4, aucFpage);
+			ulCharPos = ulGetLong(tIndex2 * 4, aucFpage);
 			NO_DBG_HEX(ulCharPos);
-			tStyle.ulFileOffset = ulCharPos2FileOffset(ulCharPos);
+			tStyle.ulFileOffset = ulCharPos2FileOffsetX(
+				ulCharPos, &tStyle.eListID);
 			vAdd2StyleInfoList(&tStyle);
 
 			eRowInfo = eGet6RowInfo(iFodo,
@@ -589,7 +693,7 @@ vGet6PapInfo(FILE *pFile, ULONG ulStartBlock,
 					break;
 				}
 				ulCharPosFirst = ulGetLong(
-						iIndex2 * 4, aucFpage);
+						tIndex2 * 4, aucFpage);
 				NO_DBG_HEX(ulCharPosFirst);
 				tRow.ulCharPosStart = ulCharPosFirst;
 				tRow.ulFileOffsetStart =
@@ -599,11 +703,11 @@ vGet6PapInfo(FILE *pFile, ULONG ulStartBlock,
 				break;
 			case found_end_of_row:
 				ulCharPosLast = ulGetLong(
-						iIndex2 * 4, aucFpage);
+						tIndex2 * 4, aucFpage);
 				NO_DBG_HEX(ulCharPosLast);
 				tRow.ulCharPosEnd = ulCharPosLast;
-				tRow.ulFileOffsetEnd = ulCharPos2FileOffset(
-							ulCharPosLast);
+				tRow.ulFileOffsetEnd =
+					ulCharPos2FileOffset(ulCharPosLast);
 				DBG_HEX_C(tRow.ulFileOffsetEnd == FC_INVALID,
 							ulCharPosLast);
 				vAdd2RowInfoList(&tRow);
@@ -635,6 +739,8 @@ vGet6FontInfo(int iFodo, USHORT usIstd,
 	USHORT	usTmp;
 	UCHAR	ucTmp;
 
+	TRACE_MSG("vGet6FontInfo");
+
 	fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL);
 
 	iFodoOff = 0;
@@ -651,7 +757,7 @@ vGet6FontInfo(int iFodo, USHORT usIstd,
 		case  80:	/* cIstd */
 			usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
 			NO_DBG_DEC(usTmp);
-                        break;
+			break;
 		case  82:	/* cDefault */
 			pFont->usFontStyle &= FONT_HIDDEN;
 			pFont->ucFontColor = FONT_COLOR_DEFAULT;
@@ -785,6 +891,8 @@ vGet6FontInfo(int iFodo, USHORT usIstd,
 			if (usTmp <= (USHORT)UCHAR_MAX) {
 				pFont->ucFontNumber = (UCHAR)usTmp;
 			} else {
+				DBG_DEC(usTmp);
+				DBG_FIXME();
 				pFont->ucFontNumber = 0;
 			}
 			break;
@@ -803,9 +911,11 @@ vGet6FontInfo(int iFodo, USHORT usIstd,
 			break;
 		case  95:	/* cHps, cHpsPos */
 			ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
+			DBG_DEC(ucTmp);
 			if (ucTmp != 0) {
 				pFont->usFontSize = (USHORT)ucTmp;
 			}
+			ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
 			DBG_DEC(ucTmp);
 			break;
 		case  98:	/* cIco */
@@ -816,6 +926,14 @@ vGet6FontInfo(int iFodo, USHORT usIstd,
 			pFont->usFontSize =
 				usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
 			break;
+		case 100:	/* cHpsInc */
+			DBG_MSG("100: sprmCHpsInc");
+			ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
+			DBG_DEC(ucTmp);
+			break;
+		case 103:	/* cMajority */
+			DBG_MSG("103: sprmCMajority");
+			break;
 		case 104:	/* cIss */
 			ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
 			ucTmp &= 0x07;
@@ -827,7 +945,7 @@ vGet6FontInfo(int iFodo, USHORT usIstd,
 				NO_DBG_MSG("Subscript");
 			}
 			break;
-		case 106:	/* cHps */
+		case 106:	/* cHpsInc1 */
 			usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
 			lTmp = (long)pFont->usFontSize + (long)usTmp;
 			if (lTmp < 8) {
@@ -838,6 +956,14 @@ vGet6FontInfo(int iFodo, USHORT usIstd,
 				pFont->usFontSize = (USHORT)lTmp;
 			}
 			break;
+		case 108:	/* cMajority50 */
+			DBG_MSG("108: sprmCMajority50");
+			break;
+		case 109:	/* cHpsMul */
+			DBG_MSG("109: sprmCHpsMul");
+			usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
+			DBG_DEC(usTmp);
+			break;
 		default:
 			break;
 		}
@@ -860,6 +986,8 @@ bGet6PicInfo(int iFodo,
 	BOOL	bFound;
 	UCHAR	ucTmp;
 
+	TRACE_MSG("vGet6PicInfo");
+
 	fail(iFodo < 0 || aucGrpprl == NULL || pPicture == NULL);
 
 	iFodoOff = 0;
@@ -871,7 +999,8 @@ bGet6PicInfo(int iFodo,
 					iFodo + iFodoOff + 2, aucGrpprl);
 			bFound = TRUE;
 			break;
-		case  71:	/* dttm */
+#if 0
+		case  71:	/* fData */
 			ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
 			if (ucTmp == 0x01) {
 				/* Not a picture, but a form field */
@@ -879,6 +1008,7 @@ bGet6PicInfo(int iFodo,
 			}
 			DBG_DEC_C(ucTmp != 0, ucTmp);
 			break;
+#endif
 		case  75:	/* fOle2 */
 			ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
 			if (ucTmp == 0x01) {
@@ -910,7 +1040,8 @@ vGet6ChrInfo(FILE *pFile, ULONG ulStartBlock,
 	UCHAR	*aucBuffer;
 	ULONG	ulFileOffset, ulCharPos, ulBeginCharInfo;
 	size_t	tCharInfoLen, tOffset, tSize, tLenOld, tLen, tCharPageNum;
-	int	iIndex, iIndex2, iRun, iFodo, iLen;
+	size_t	tIndex, tIndex2, tRun;
+	int	iFodo, iLen;
 	USHORT	usCharFirstPage, usCount, usIstd;
 	UCHAR	aucFpage[BIG_BLOCK_SIZE];
 
@@ -937,11 +1068,11 @@ vGet6ChrInfo(FILE *pFile, ULONG ulStartBlock,
 
 	tLen = (tCharInfoLen - 4) / 6;
 	ausCharPage = xcalloc(tLen, sizeof(USHORT));
-	for (iIndex = 0, tOffset = (tLen + 1) * 4;
-	     iIndex < (int)tLen;
-	     iIndex++, tOffset += 2) {
-		 ausCharPage[iIndex] = usGetWord(tOffset, aucBuffer);
-		 NO_DBG_DEC(ausCharPage[iIndex]);
+	for (tIndex = 0, tOffset = (tLen + 1) * 4;
+	     tIndex < tLen;
+	     tIndex++, tOffset += 2) {
+		 ausCharPage[tIndex] = usGetWord(tOffset, aucBuffer);
+		 NO_DBG_DEC(ausCharPage[tIndex]);
 	}
 	DBG_HEX(ulGetLong(0, aucBuffer));
 	aucBuffer = xfree(aucBuffer);
@@ -957,28 +1088,28 @@ vGet6ChrInfo(FILE *pFile, ULONG ulStartBlock,
 		ausCharPage = xrealloc(ausCharPage, tSize);
 		/* Add new values */
 		usCount = usCharFirstPage + 1;
-		for (iIndex = (int)tLenOld; iIndex < (int)tLen; iIndex++) {
-			ausCharPage[iIndex] = usCount;
-			NO_DBG_DEC(ausCharPage[iIndex]);
+		for (tIndex = tLenOld; tIndex < tLen; tIndex++) {
+			ausCharPage[tIndex] = usCount;
+			NO_DBG_DEC(ausCharPage[tIndex]);
 			usCount++;
 		}
 	}
 
-	for (iIndex = 0; iIndex < (int)tLen; iIndex++) {
+	for (tIndex = 0; tIndex < tLen; tIndex++) {
 		if (!bReadBuffer(pFile, ulStartBlock,
 				aulBBD, tBBDLen, BIG_BLOCK_SIZE,
 				aucFpage,
-				(ULONG)ausCharPage[iIndex] * BIG_BLOCK_SIZE,
+				(ULONG)ausCharPage[tIndex] * BIG_BLOCK_SIZE,
 				BIG_BLOCK_SIZE)) {
 			break;
 		}
-		iRun = (int)ucGetByte(0x1ff, aucFpage);
-		NO_DBG_DEC(iRun);
-		for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) {
-		  	ulCharPos = ulGetLong(iIndex2 * 4, aucFpage);
+		tRun = (size_t)ucGetByte(0x1ff, aucFpage);
+		NO_DBG_DEC(tRun);
+		for (tIndex2 = 0; tIndex2 < tRun; tIndex2++) {
+		  	ulCharPos = ulGetLong(tIndex2 * 4, aucFpage);
 			ulFileOffset = ulCharPos2FileOffset(ulCharPos);
 			iFodo = 2 * (int)ucGetByte(
-				(iRun + 1) * 4 + iIndex2, aucFpage);
+				(tRun + 1) * 4 + tIndex2, aucFpage);
 
 			iLen = (int)ucGetByte(iFodo, aucFpage);
 

+ 322 - 182
sys/src/cmd/aux/antiword/prop8.c

@@ -1,13 +1,14 @@
 /*
  * prop8.c
- * Copyright (C) 1998-2003 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
  *
  * Description:
- * Read the property information from a MS Word 8, 9 or 10 file
+ * Read the property information from a MS Word 8, 9,10 or 11 file
  *
  * Word  8 is better known as Word 97 or as Word 98 for Mac
  * Word  9 is better known as Word 2000 or as Word 2001 for Mac
  * Word 10 is better known as Word 2002 or as Word XP
+ * Word 11 is better known as Word 2003
  */
 
 #include <stdlib.h>
@@ -18,7 +19,7 @@
 
 
 /*
- * iGet8InfoLength - the length of the information for Word 8/9/10 files
+ * iGet8InfoLength - the length of the information for Word 8/9/10/11 files
  */
 static int
 iGet8InfoLength(int iByteNbr, const UCHAR *aucGrpprl)
@@ -53,9 +54,102 @@ iGet8InfoLength(int iByteNbr, const UCHAR *aucGrpprl)
 	}
 } /* end of iGet8InfoLength */
 
+/*
+ * aucFillInfoBuffer - fill the information buffer
+ *
+ * Returns the information buffer when successful, otherwise NULL
+ */
+static UCHAR *
+aucFillInfoBuffer(FILE *pFile, const pps_type *pTable,
+	const ULONG *aulBBD, size_t tBBDLen,
+	const ULONG *aulSBD, size_t tSBDLen,
+	ULONG ulBeginInfo, size_t tInfoLen)
+{
+	const ULONG	*aulBlockDepot;
+	UCHAR	*aucBuffer;
+	size_t	tBlockDepotLen, tBlockSize;
+
+	fail(pFile == NULL || pTable == NULL);
+	fail(aulBBD == NULL || aulSBD == NULL);
+	fail(tInfoLen == 0);
+
+	NO_DBG_DEC(pTable->ulSB);
+	NO_DBG_HEX(pTable->ulSize);
+	if (pTable->ulSize == 0) {
+		DBG_MSG("No information");
+		return NULL;
+	}
+
+	if (pTable->ulSize < MIN_SIZE_FOR_BBD_USE) {
+		/* Use the Small Block Depot */
+		aulBlockDepot = aulSBD;
+		tBlockDepotLen = tSBDLen;
+		tBlockSize = SMALL_BLOCK_SIZE;
+	} else {
+		/* Use the Big Block Depot */
+		aulBlockDepot = aulBBD;
+		tBlockDepotLen = tBBDLen;
+		tBlockSize = BIG_BLOCK_SIZE;
+	}
+	aucBuffer = xmalloc(tInfoLen);
+	if (!bReadBuffer(pFile, pTable->ulSB,
+			aulBlockDepot, tBlockDepotLen, tBlockSize,
+			aucBuffer, ulBeginInfo, tInfoLen)) {
+		aucBuffer = xfree(aucBuffer);
+		return NULL;
+	}
+	return aucBuffer;
+} /* end of aucFillInfoBuffer */
+
+/*
+ * Build the lists with Document Property Information for Word 8/9/10/11 files
+ */
+void
+vGet8DopInfo(FILE *pFile, const pps_type *pTable,
+	const ULONG *aulBBD, size_t tBBDLen,
+	const ULONG *aulSBD, size_t tSBDLen,
+	const UCHAR *aucHeader)
+{
+	document_block_type	tDocument;
+	UCHAR	*aucBuffer;
+	ULONG	ulBeginDocpInfo, ulTmp;
+	size_t	tDocpInfoLen;
+	USHORT	usTmp;
+
+	fail(pFile == NULL || pTable == NULL || aucHeader == NULL);
+	fail(aulBBD == NULL || aulSBD == NULL);
+
+	ulBeginDocpInfo = ulGetLong(0x192, aucHeader); /* fcDop */
+	NO_DBG_HEX(ulBeginSectInfo);
+	tDocpInfoLen = (size_t)ulGetLong(0x196, aucHeader); /* lcbDop */
+	NO_DBG_DEC(tSectInfoLen);
+	if (tDocpInfoLen < 28) {
+		DBG_MSG("No Document information");
+		return;
+	}
+
+	aucBuffer = aucFillInfoBuffer(pFile, pTable,
+			aulBBD, tBBDLen, aulSBD, tSBDLen,
+			ulBeginDocpInfo, tDocpInfoLen);
+	if (aucBuffer == NULL) {
+		return;
+	}
+
+	usTmp = usGetWord(0x00, aucBuffer);
+	tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */
+	tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */
+	ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */
+	tDocument.tCreateDate = tConvertDTTM(ulTmp);
+	ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */
+	tDocument.tRevisedDate = tConvertDTTM(ulTmp);
+	vCreateDocumentInfoList(&tDocument);
+
+	aucBuffer = xfree(aucBuffer);
+} /* end of vGet8DopInfo */
+
 /*
  * Fill the section information block with information
- * from a Word 8/9/10 file.
+ * from a Word 8/9/10/11 file.
  */
 static void
 vGet8SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,
@@ -77,6 +171,10 @@ vGet8SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,
 			DBG_DEC(ucTmp);
 			pSection->bNewPage = ucTmp != 0 && ucTmp != 1;
 			break;
+		case 0x3014:	/* grpfIhdt */
+			pSection->ucHdrFtrSpecification =
+					ucGetByte(iFodoOff + 2, aucGrpprl);
+			break;
 		case 0x500b:	/* ccolM1 */
 			usCcol = 1 + usGetWord(iFodoOff + 2, aucGrpprl);
 			DBG_DEC(usCcol);
@@ -116,7 +214,7 @@ vGet8SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,
 } /* end of vGet8SectionInfo */
 
 /*
- * Build the lists with Section Property Information for Word 8/9/10 files
+ * Build the lists with Section Property Information for Word 8/9/10/11 files
  */
 void
 vGet8SepInfo(FILE *pFile, const pps_info_type *pPPS,
@@ -125,20 +223,17 @@ vGet8SepInfo(FILE *pFile, const pps_info_type *pPPS,
 	const UCHAR *aucHeader)
 {
 	section_block_type	tSection;
-	ULONG		*aulSectPage, *aulTextOffset;
-	const ULONG	*aulBlockDepot;
+	ULONG	*aulSectPage, *aulCharPos;
 	UCHAR	*aucBuffer, *aucFpage;
-	ULONG	ulBeginSectInfo;
-	ULONG	ulTableSize, ulTableStartBlock;
-	size_t	tSectInfoLen, tBlockDepotLen;
-	size_t	tBlockSize, tOffset, tLen, tBytes;
-	int	iIndex;
-	USHORT	usDocStatus;
+	ULONG	ulBeginOfText, ulTextOffset, ulBeginSectInfo;
+	size_t	tSectInfoLen, tIndex, tOffset, tLen, tBytes;
 	UCHAR	aucTmp[2];
 
 	fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
 	fail(aulBBD == NULL || aulSBD == NULL);
 
+	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
+	NO_DBG_HEX(ulBeginOfText);
 	ulBeginSectInfo = ulGetLong(0xca, aucHeader); /* fcPlcfsed */
 	NO_DBG_HEX(ulBeginSectInfo);
 	tSectInfoLen = (size_t)ulGetLong(0xce, aucHeader); /* lcbPlcfsed */
@@ -148,37 +243,10 @@ vGet8SepInfo(FILE *pFile, const pps_info_type *pPPS,
 		return;
 	}
 
-	/* Use 0Table or 1Table? */
-	usDocStatus = usGetWord(0x0a, aucHeader);
-	if (usDocStatus & BIT(9)) {
-		ulTableStartBlock = pPPS->t1Table.ulSB;
-		ulTableSize = pPPS->t1Table.ulSize;
-	} else {
-		ulTableStartBlock = pPPS->t0Table.ulSB;
-		ulTableSize = pPPS->t0Table.ulSize;
-	}
-	DBG_DEC(ulTableStartBlock);
-	if (ulTableStartBlock == 0) {
-		DBG_MSG("No section information");
-		return;
-	}
-	DBG_HEX(ulTableSize);
-	if (ulTableSize < MIN_SIZE_FOR_BBD_USE) {
-		/* Use the Small Block Depot */
-		aulBlockDepot = aulSBD;
-		tBlockDepotLen = tSBDLen;
-		tBlockSize = SMALL_BLOCK_SIZE;
-	} else {
-		/* Use the Big Block Depot */
-		aulBlockDepot = aulBBD;
-		tBlockDepotLen = tBBDLen;
-		tBlockSize = BIG_BLOCK_SIZE;
-	}
-	aucBuffer = xmalloc(tSectInfoLen);
-	if (!bReadBuffer(pFile, ulTableStartBlock,
-			aulBlockDepot, tBlockDepotLen, tBlockSize,
-			aucBuffer, ulBeginSectInfo, tSectInfoLen)) {
-		aucBuffer = xfree(aucBuffer);
+	aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable,
+			aulBBD, tBBDLen, aulSBD, tSBDLen,
+			ulBeginSectInfo, tSectInfoLen);
+	if (aucBuffer == NULL) {
 		return;
 	}
 	NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen);
@@ -186,32 +254,35 @@ vGet8SepInfo(FILE *pFile, const pps_info_type *pPPS,
 	/* Read the Section Descriptors */
 	tLen = (tSectInfoLen - 4) / 16;
 	/* Save the section offsets */
-	aulTextOffset = xcalloc(tLen, sizeof(ULONG));
-	for (iIndex = 0, tOffset = 0;
-	     iIndex < (int)tLen;
-	     iIndex++, tOffset += 4) {
-		aulTextOffset[iIndex] = ulGetLong(tOffset, aucBuffer);
+	aulCharPos = xcalloc(tLen, sizeof(ULONG));
+	for (tIndex = 0, tOffset = 0;
+	     tIndex < tLen;
+	     tIndex++, tOffset += 4) {
+		ulTextOffset = ulGetLong(tOffset, aucBuffer);
+		NO_DBG_HEX(ulTextOffset);
+		aulCharPos[tIndex] = ulBeginOfText + ulTextOffset;
+		NO_DBG_HEX(aulCharPos[tIndex]);
 	}
 	/* Save the Sepx offsets */
 	aulSectPage = xcalloc(tLen, sizeof(ULONG));
-	for (iIndex = 0, tOffset = (tLen + 1) * 4;
-	     iIndex < (int)tLen;
-	     iIndex++, tOffset += 12) {
-		 aulSectPage[iIndex] = ulGetLong(tOffset + 2, aucBuffer);
-		 NO_DBG_HEX(aulSectPage[iIndex]); /* fcSepx */
+	for (tIndex = 0, tOffset = (tLen + 1) * 4;
+	     tIndex < tLen;
+	     tIndex++, tOffset += 12) {
+		 aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer);
+		 NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */
 	}
 	aucBuffer = xfree(aucBuffer);
 
 	/* Read the Section Properties */
-	for (iIndex = 0; iIndex < (int)tLen; iIndex++) {
-		if (aulSectPage[iIndex] == FC_INVALID) {
-			vDefault2SectionInfoList(aulTextOffset[iIndex]);
+	for (tIndex = 0; tIndex < tLen; tIndex++) {
+		if (aulSectPage[tIndex] == FC_INVALID) {
+			vDefault2SectionInfoList(aulCharPos[tIndex]);
 			continue;
 		}
 		/* Get the number of bytes to read */
 		if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB,
 				aulBBD, tBBDLen, BIG_BLOCK_SIZE,
-				aucTmp, aulSectPage[iIndex], 2)) {
+				aucTmp, aulSectPage[tIndex], 2)) {
 			continue;
 		}
 		tBytes = 2 + (size_t)usGetWord(0, aucTmp);
@@ -220,7 +291,7 @@ vGet8SepInfo(FILE *pFile, const pps_info_type *pPPS,
 		aucFpage = xmalloc(tBytes);
 		if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB,
 				aulBBD, tBBDLen, BIG_BLOCK_SIZE,
-				aucFpage, aulSectPage[iIndex], tBytes)) {
+				aucFpage, aulSectPage[tIndex], tBytes)) {
 			aucFpage = xfree(aucFpage);
 			continue;
 		}
@@ -228,13 +299,65 @@ vGet8SepInfo(FILE *pFile, const pps_info_type *pPPS,
 		/* Process the bytes */
 		vGetDefaultSection(&tSection);
 		vGet8SectionInfo(aucFpage + 2, tBytes - 2, &tSection);
-		vAdd2SectionInfoList(&tSection, aulTextOffset[iIndex]);
+		vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]);
 		aucFpage = xfree(aucFpage);
 	}
-	aulTextOffset = xfree(aulTextOffset);
+	aulCharPos = xfree(aulCharPos);
 	aulSectPage = xfree(aulSectPage);
 } /* end of vGet8SepInfo */
 
+/*
+ * Build the list with Header/Footer Information for Word 8/9/10/11 files
+ */
+void
+vGet8HdrFtrInfo(FILE *pFile, const pps_type *pTable,
+	const ULONG *aulBBD, size_t tBBDLen,
+	const ULONG *aulSBD, size_t tSBDLen,
+	const UCHAR *aucHeader)
+{
+	ULONG	*aulCharPos;
+	UCHAR	*aucBuffer;
+	ULONG	ulHdrFtrOffset, ulBeginHdrFtrInfo;
+	size_t	tHdrFtrInfoLen, tIndex, tOffset, tLen;
+
+	fail(pFile == NULL || pTable == NULL || aucHeader == NULL);
+	fail(aulBBD == NULL || aulSBD == NULL);
+
+	ulBeginHdrFtrInfo = ulGetLong(0xf2, aucHeader); /* fcPlcfhdd */
+	NO_DBG_HEX(ulBeginHdrFtrInfo);
+	tHdrFtrInfoLen = (size_t)ulGetLong(0xf6, aucHeader); /* lcbPlcfhdd */
+	NO_DBG_DEC(tHdrFtrInfoLen);
+	if (tHdrFtrInfoLen < 8) {
+		DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen);
+		return;
+	}
+
+	aucBuffer = aucFillInfoBuffer(pFile, pTable,
+			aulBBD, tBBDLen, aulSBD, tSBDLen,
+			ulBeginHdrFtrInfo, tHdrFtrInfoLen);
+	if (aucBuffer == NULL) {
+		return;
+	}
+	NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen);
+
+	tLen = tHdrFtrInfoLen / 4 - 1;
+	DBG_DEC_C(tLen % 12 != 1 && tLen % 12 != 7, tLen);
+	/* Save the header/footer offsets */
+	aulCharPos = xcalloc(tLen, sizeof(ULONG));
+	for (tIndex = 0, tOffset = 0;
+	     tIndex < tLen;
+	     tIndex++, tOffset += 4) {
+		ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer);
+		NO_DBG_HEX(ulHdrFtrOffset);
+		aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset);
+		NO_DBG_HEX(aulCharPos[tIndex]);
+	}
+	vCreat8HdrFtrInfoList(aulCharPos, tLen);
+	/* Clean up and leave */
+	aulCharPos = xfree(aulCharPos);
+	aucBuffer = xfree(aucBuffer);
+} /* end of vGet8HdrFtrInfo */
+
 /*
  * Translate the rowinfo to a member of the row_info enumeration
  */
@@ -247,6 +370,7 @@ eGet8RowInfo(int iFodo,
 	int	iPosCurr, iPosPrev;
 	USHORT	usTmp;
 	BOOL	bFound2416_0, bFound2416_1, bFound2417_0, bFound2417_1;
+	BOOL	bFound244b_0, bFound244b_1, bFound244c_0, bFound244c_1;
 	BOOL	bFoundd608;
 
 	fail(iFodo < 0 || aucGrpprl == NULL || pRow == NULL);
@@ -256,11 +380,15 @@ eGet8RowInfo(int iFodo,
 	bFound2416_1 = FALSE;
 	bFound2417_0 = FALSE;
 	bFound2417_1 = FALSE;
+	bFound244b_0 = FALSE;
+	bFound244b_1 = FALSE;
+	bFound244c_0 = FALSE;
+	bFound244c_1 = FALSE;
 	bFoundd608 = FALSE;
 	while (iBytes >= iFodoOff + 2) {
 		iInfoLen = 0;
 		switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) {
-		case 0x2416:	/* fIntable */
+		case 0x2416:	/* fInTable */
 			if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) {
 				bFound2416_1 = TRUE;
 			} else {
@@ -274,6 +402,20 @@ eGet8RowInfo(int iFodo,
 				bFound2417_0 = TRUE;
 			}
 			break;
+		case 0x244b:	/* sub-table fInTable */
+			if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) {
+				bFound244b_1 = TRUE;
+			} else {
+				bFound244b_0 = TRUE;
+			}
+			break;
+		case 0x244c:	/* sub-table fTtp */
+			if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) {
+				bFound244c_1 = TRUE;
+			} else {
+				bFound244c_0 = TRUE;
+			}
+			break;
 		case 0x6424:	/* brcTop */
 			usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
 			usTmp &= 0xff00;
@@ -314,6 +456,11 @@ eGet8RowInfo(int iFodo,
 				pRow->ucBorderInfo |= TABLE_BORDER_RIGHT;
 			}
 			break;
+		case 0xd606:	/* cDefTable10 */
+			DBG_MSG("0xd606: sprmTDefTable10");
+			iSize = (int)usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
+			DBG_DEC(iSize);
+			break;
 		case 0xd608:	/* cDefTable */
 			iSize = (int)usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
 			if (iSize < 6 || iBytes < iFodoOff + 8) {
@@ -335,7 +482,6 @@ eGet8RowInfo(int iFodo,
 				werr(1, "The number of columns is corrupt");
 			}
 			pRow->ucNumberOfColumns = (UCHAR)iCol;
-			pRow->iColumnWidthSum = 0;
 			iPosPrev = (int)(short)usGetWord(
 					iFodo + iFodoOff + 5,
 					aucGrpprl);
@@ -345,8 +491,6 @@ eGet8RowInfo(int iFodo,
 					aucGrpprl);
 				pRow->asColumnWidth[iIndex] =
 						(short)(iPosCurr - iPosPrev);
-				pRow->iColumnWidthSum +=
-					pRow->asColumnWidth[iIndex];
 				iPosPrev = iPosCurr;
 			}
 			bFoundd608 = TRUE;
@@ -361,16 +505,17 @@ eGet8RowInfo(int iFodo,
 		}
 		iFodoOff += iInfoLen;
 	}
-	if (bFound2416_1 && bFound2417_1 && bFoundd608) {
+
+	if (bFound2417_1 && bFoundd608) {
 		return found_end_of_row;
 	}
-	if (bFound2416_0 && bFound2417_0 && !bFoundd608) {
+	if (bFound2417_0 && !bFoundd608) {
 		return found_not_end_of_row;
 	}
-	if (bFound2416_1) {
+	if (bFound2416_1 || bFound244b_1) {
 		return found_a_cell;
 	}
-	if (bFound2416_0) {
+	if (bFound2416_0 || bFound244b_0) {
 		return found_not_a_cell;
 	}
 	return found_nothing;
@@ -378,7 +523,7 @@ eGet8RowInfo(int iFodo,
 
 /*
  * Fill the style information block with information
- * from a Word 8/9/10 file.
+ * from a Word 8/9/10/11 file.
  */
 void
 vGet8StyleInfo(int iFodo,
@@ -432,26 +577,27 @@ vGet8StyleInfo(int iFodo,
 			DBG_DEC(sTmp);
 			DBG_DEC(pStyle->sLeftIndent);
 			break;
-		case 0x6c0d:	/* ChgTabsPapx */
+		case 0xc60d:	/* ChgTabsPapx */
+		case 0xc615:	/* ChgTabs */
 			iTmp = (int)ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
 			if (iTmp < 2) {
 				iInfoLen = 1;
 				break;
 			}
-			DBG_DEC(iTmp);
+			NO_DBG_DEC(iTmp);
 			iDel = (int)ucGetByte(iFodo + iFodoOff + 3, aucGrpprl);
 			if (iTmp < 2 + 2 * iDel) {
 				iInfoLen = 1;
 				break;
 			}
-			DBG_DEC(iDel);
+			NO_DBG_DEC(iDel);
 			iAdd = (int)ucGetByte(
 				iFodo + iFodoOff + 4 + 2 * iDel, aucGrpprl);
 			if (iTmp < 2 + 2 * iDel + 2 * iAdd) {
 				iInfoLen = 1;
 				break;
 			}
-			DBG_DEC(iAdd);
+			NO_DBG_DEC(iAdd);
 			break;
 		case 0x840e:	/* dxaRight */
 			pStyle->sRightIndent = (short)usGetWord(
@@ -567,7 +713,7 @@ sGetLeftIndent(const UCHAR *aucGrpprl, size_t tBytes)
 } /* end of sGetLeftIndent */
 
 /*
- * Build the list with List Information for Word 8/9/10 files
+ * Build the list with List Information for Word 8/9/10/11 files
  */
 void
 vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS,
@@ -578,36 +724,27 @@ vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS,
 	list_block_type	tList;
 	const ULONG	*aulBlockDepot;
 	UCHAR	*aucLfoInfo, *aucLstfInfo, *aucPapx, *aucXString;
-	ULONG	ulTableStartBlock, ulTableSize;
 	ULONG	ulBeginLfoInfo, ulBeginLstfInfo, ulBeginLvlfInfo;
 	ULONG	ulListID, ulStart;
 	size_t	tBlockDepotLen, tBlockSize;
 	size_t	tLfoInfoLen, tLstfInfoLen, tPapxLen, tXstLen, tOff;
 	size_t	tLstfRecords, tStart, tIndex;
 	int	iNums;
-	USHORT	usDocStatus, usIstd;
+	USHORT	usIstd;
 	UCHAR	ucTmp, ucListLevel, ucMaxLevel, ucChpxLen;
 	UCHAR	aucLvlfInfo[28], aucXst[2];
 
 	fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
 	fail(aulBBD == NULL || aulSBD == NULL);
 
-	/* Use 0Table or 1Table? */
-	usDocStatus = usGetWord(0x0a, aucHeader);
-	if (usDocStatus & BIT(9)) {
-		ulTableStartBlock = pPPS->t1Table.ulSB;
-		ulTableSize = pPPS->t1Table.ulSize;
-	} else {
-		ulTableStartBlock = pPPS->t0Table.ulSB;
-		ulTableSize = pPPS->t0Table.ulSize;
-	}
-	DBG_DEC(ulTableStartBlock);
-	if (ulTableStartBlock == 0) {
+	NO_DBG_DEC(pPPS->tTable.ulSB);
+	NO_DBG_HEX(pPPS->tTable.ulSize);
+	if (pPPS->tTable.ulSize == 0) {
 		DBG_MSG("No list information");
 		return;
 	}
-	DBG_HEX(ulTableSize);
-	if (ulTableSize < MIN_SIZE_FOR_BBD_USE) {
+
+	if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
 		/* Use the Small Block Depot */
 		aulBlockDepot = aulSBD;
 		tBlockDepotLen = tSBDLen;
@@ -630,7 +767,7 @@ vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS,
 	}
 
 	aucLfoInfo = xmalloc(tLfoInfoLen);
-	if (!bReadBuffer(pFile, ulTableStartBlock,
+	if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
 			aulBlockDepot, tBlockDepotLen, tBlockSize,
 			aucLfoInfo, ulBeginLfoInfo, tLfoInfoLen)) {
 		aucLfoInfo = xfree(aucLfoInfo);
@@ -651,7 +788,7 @@ vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS,
 	}
 
 	aucLstfInfo = xmalloc(tLstfInfoLen);
-	if (!bReadBuffer(pFile, ulTableStartBlock,
+	if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
 			aulBlockDepot, tBlockDepotLen, tBlockSize,
 			aucLstfInfo, ulBeginLstfInfo, tLstfInfoLen)) {
 		aucLstfInfo = xfree(aucLstfInfo);
@@ -690,7 +827,7 @@ vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS,
 			NO_DBG_HEX(ulStart);
 			(void)memset(&tList, 0, sizeof(tList));
 			/* Read the lvlf (List leVeL on File) */
-			if (!bReadBuffer(pFile, ulTableStartBlock,
+			if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
 					aulBlockDepot, tBlockDepotLen,
 					tBlockSize, aucLvlfInfo,
 					ulStart, sizeof(aucLvlfInfo))) {
@@ -707,13 +844,15 @@ vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS,
 				tList.ucNFC = ucGetByte(4, aucLvlfInfo);
 				ucTmp = ucGetByte(5, aucLvlfInfo);
 				tList.bNoRestart = (ucTmp & BIT(3)) != 0;
+				DBG_MSG_C((ucTmp & BIT(4)) != 0 &&
+					(ucTmp & BIT(6)) != 0, "Found one");
 			}
 			ulStart += sizeof(aucLvlfInfo);
 			tPapxLen = (size_t)ucGetByte(25, aucLvlfInfo);
 			if (tPapxLen != 0) {
 				aucPapx = xmalloc(tPapxLen);
 				/* Read the Papx */
-				if (!bReadBuffer(pFile, ulTableStartBlock,
+				if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
 						aulBlockDepot, tBlockDepotLen,
 						tBlockSize, aucPapx,
 						ulStart, tPapxLen)) {
@@ -730,7 +869,7 @@ vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS,
 			ucChpxLen = ucGetByte(24, aucLvlfInfo);
 			ulStart += (ULONG)ucChpxLen;
 			/* Read the length of the XString */
-			if (!bReadBuffer(pFile, ulTableStartBlock,
+			if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
 					aulBlockDepot, tBlockDepotLen,
 					tBlockSize, aucXst,
 					ulStart, sizeof(aucXst))) {
@@ -751,7 +890,7 @@ vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS,
 			tXstLen *= 2;	/* Length in chars to length in bytes */
 			aucXString = xmalloc(tXstLen);
 			/* Read the XString */
-			if (!bReadBuffer(pFile, ulTableStartBlock,
+			if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
 					aulBlockDepot, tBlockDepotLen,
 					tBlockSize, aucXString,
 					ulStart, tXstLen)) {
@@ -771,6 +910,7 @@ vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS,
 			tOff *= 2;	/* Offset in chars to offset in bytes */
 			NO_DBG_DEC(tOff);
 			if (tList.ucNFC == LIST_SPECIAL ||
+			    tList.ucNFC == LIST_SPECIAL2 ||
 			    tList.ucNFC == LIST_BULLETS) {
 				tList.usListChar = usGetWord(0, aucXString);
 			} else if (tOff != 0 && tOff < tXstLen) {
@@ -790,7 +930,7 @@ vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS,
 } /* end of vGet8LstInfo */
 
 /*
- * Build the lists with Paragraph Information for Word 8/9/10 files
+ * Build the lists with Paragraph Information for Word 8/9/10/11 files
  */
 void
 vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS,
@@ -801,16 +941,13 @@ vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS,
 	row_block_type		tRow;
 	style_block_type	tStyle;
 	ULONG		*aulParfPage;
-	const ULONG	*aulBlockDepot;
 	UCHAR	*aucBuffer;
 	ULONG	ulCharPos, ulCharPosFirst, ulCharPosLast;
 	ULONG	ulBeginParfInfo;
-	ULONG	ulTableSize, ulTableStartBlock;
-	size_t	tParfInfoLen, tBlockDepotLen;
-	size_t	tBlockSize, tOffset, tLen;
+	size_t	tParfInfoLen, tOffset, tLen;
 	int	iIndex, iIndex2, iRun, iFodo, iLen;
 	row_info_enum	eRowInfo;
-	USHORT	usDocStatus, usIstd;
+	USHORT	usIstd;
 	UCHAR	aucFpage[BIG_BLOCK_SIZE];
 
 	fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
@@ -825,38 +962,10 @@ vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS,
 		return;
 	}
 
-	/* Use 0Table or 1Table? */
-	usDocStatus = usGetWord(0x0a, aucHeader);
-	if (usDocStatus & BIT(9)) {
-		ulTableStartBlock = pPPS->t1Table.ulSB;
-		ulTableSize = pPPS->t1Table.ulSize;
-	} else {
-		ulTableStartBlock = pPPS->t0Table.ulSB;
-		ulTableSize = pPPS->t0Table.ulSize;
-	}
-	DBG_DEC(ulTableStartBlock);
-	if (ulTableStartBlock == 0) {
-		DBG_MSG("No paragraph information");
-		return;
-	}
-	DBG_HEX(ulTableSize);
-	if (ulTableSize < MIN_SIZE_FOR_BBD_USE) {
-		/* Use the Small Block Depot */
-		aulBlockDepot = aulSBD;
-		tBlockDepotLen = tSBDLen;
-		tBlockSize = SMALL_BLOCK_SIZE;
-	} else {
-		/* Use the Big Block Depot */
-		aulBlockDepot = aulBBD;
-		tBlockDepotLen = tBBDLen;
-		tBlockSize = BIG_BLOCK_SIZE;
-	}
-
-	aucBuffer = xmalloc(tParfInfoLen);
-	if (!bReadBuffer(pFile, ulTableStartBlock,
-			aulBlockDepot, tBlockDepotLen, tBlockSize,
-			aucBuffer, ulBeginParfInfo, tParfInfoLen)) {
-		aucBuffer = xfree(aucBuffer);
+	aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable,
+			aulBBD, tBBDLen, aulSBD, tSBDLen,
+			ulBeginParfInfo, tParfInfoLen);
+	if (aucBuffer == NULL) {
 		return;
 	}
 	NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen);
@@ -906,7 +1015,8 @@ vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS,
 			vGet8StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle);
 			ulCharPos = ulGetLong(iIndex2 * 4, aucFpage);
 			NO_DBG_HEX(ulCharPos);
-			tStyle.ulFileOffset = ulCharPos2FileOffset(ulCharPos);
+			tStyle.ulFileOffset = ulCharPos2FileOffsetX(
+						ulCharPos, &tStyle.eListID);
 			vAdd2StyleInfoList(&tStyle);
 
 			eRowInfo = eGet8RowInfo(iFodo,
@@ -952,7 +1062,7 @@ vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS,
 
 /*
  * Fill the font information block with information
- * from a Word 8/9/10 file.
+ * from a Word 8/9/10/11 file.
  */
 void
 vGet8FontInfo(int iFodo, USHORT usIstd,
@@ -960,11 +1070,15 @@ vGet8FontInfo(int iFodo, USHORT usIstd,
 {
 	long	lTmp;
 	int	iFodoOff, iInfoLen;
-	USHORT	usTmp;
+	USHORT	usFtc0, usFtc1, usFtc2, usTmp;
 	UCHAR	ucTmp;
 
 	fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL);
 
+	usFtc0 = USHRT_MAX;
+	usFtc1 = USHRT_MAX;
+	usFtc2 = USHRT_MAX;
+
 	iFodoOff = 0;
 	while (iBytes >= iFodoOff + 2) {
 		switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) {
@@ -1122,6 +1236,11 @@ vGet8FontInfo(int iFodo, USHORT usIstd,
 				ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
 			NO_DBG_DEC(pFont->ucFontColor);
 			break;
+		case 0x2a44:	/* cHpsInc */
+			DBG_MSG("0x2a44: sprmCHpsInc");
+			ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
+			DBG_DEC(ucTmp);
+			break;
 		case 0x2a48:	/* cIss */
 			ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
 			ucTmp &= 0x07;
@@ -1142,15 +1261,24 @@ vGet8FontInfo(int iFodo, USHORT usIstd,
 				usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
 			NO_DBG_DEC(pFont->usFontSize);
 			break;
-		case 0x4a51:	/* cFtc */
+		case 0x4a4d:	/* cHpsMul */
+			DBG_MSG("0x4a4d: sprmCHpsMul");
 			usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
-			if (usTmp <= (USHORT)UCHAR_MAX) {
-				pFont->ucFontNumber = (UCHAR)usTmp;
-			} else {
-				pFont->ucFontNumber = 0;
-			}
+			DBG_DEC(usTmp);
+			break;
+		case 0x4a4f:	/* cFtc0 */
+			usFtc0 = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
+			break;
+		case 0x4a50:	/* cFtc1 */
+			usFtc1 = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
+			break;
+		case 0x4a51:	/* cFtc2 */
+			usFtc2 = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
+			break;
+		case 0xca47:	/* cMajority */
+			DBG_MSG("0xca47: sprmCMajority");
 			break;
-		case 0xca4a:	/* cHps */
+		case 0xca4a:	/* cHpsInc1 */
 			usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
 			lTmp = (long)pFont->usFontSize + (long)usTmp;
 			if (lTmp < 8) {
@@ -1161,11 +1289,16 @@ vGet8FontInfo(int iFodo, USHORT usIstd,
 				pFont->usFontSize = (USHORT)lTmp;
 			}
 			break;
+		case 0xca4c:	/* cMajority50 */
+			DBG_MSG("0xca4c: sprmCMajority50");
+			break;
 		case 0xea3f:	/* cHps, cHpsPos */
 			ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
+			DBG_DEC(ucTmp);
 			if (ucTmp != 0) {
 				pFont->usFontSize = (USHORT)ucTmp;
 			}
+			ucTmp = ucGetByte(iFodo + iFodoOff + 3, aucGrpprl);
 			DBG_DEC(ucTmp);
 			break;
 		default:
@@ -1175,17 +1308,48 @@ vGet8FontInfo(int iFodo, USHORT usIstd,
 		fail(iInfoLen <= 0);
 		iFodoOff += iInfoLen;
 	}
+
+	/* Combine the Ftc's to a FontNumber */
+	NO_DBG_DEC_C(usFtc0 != USHRT_MAX, usFtc0);
+	NO_DBG_DEC_C(usFtc2 != USHRT_MAX, usFtc2);
+	NO_DBG_DEC_C(usFtc1 != USHRT_MAX, usFtc1);
+	if (usFtc0 <= 0x7fff) {
+		if (usFtc0 <= (USHORT)UCHAR_MAX) {
+			pFont->ucFontNumber = (UCHAR)usFtc0;
+		} else {
+			DBG_DEC(usFtc0);
+			DBG_FIXME();
+			pFont->ucFontNumber = 0;
+		}
+	} else if (usFtc2 <= 0x7fff) {
+		if (usFtc2 <= (USHORT)UCHAR_MAX) {
+			pFont->ucFontNumber = (UCHAR)usFtc2;
+		} else {
+			DBG_DEC(usFtc2);
+			DBG_FIXME();
+			pFont->ucFontNumber = 0;
+		}
+	} else if (usFtc1 <= 0x7fff) {
+		if (usFtc1 <= (USHORT)UCHAR_MAX) {
+			pFont->ucFontNumber = (UCHAR)usFtc1;
+		} else {
+			DBG_DEC(usFtc1);
+			DBG_FIXME();
+			pFont->ucFontNumber = 0;
+		}
+	}
 } /* end of vGet8FontInfo */
 
 /*
  * Fill the picture information block with information
- * from a Word 8/9/10 file.
+ * from a Word 8/9/10/11 file.
  * Returns TRUE when successful, otherwise FALSE
  */
 static BOOL
 bGet8PicInfo(int iFodo,
 	const UCHAR *aucGrpprl, int iBytes, picture_block_type *pPicture)
 {
+	ULONG	ulTmp;
 	int	iFodoOff, iInfoLen;
 	BOOL	bFound;
 	UCHAR	ucTmp;
@@ -1196,6 +1360,7 @@ bGet8PicInfo(int iFodo,
 	bFound = FALSE;
 	while (iBytes >= iFodoOff + 2) {
 		switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) {
+#if 0
 		case 0x0806:	/* fData */
 			ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
 			if (ucTmp == 0x01) {
@@ -1204,6 +1369,7 @@ bGet8PicInfo(int iFodo,
 			}
 			DBG_DEC_C(ucTmp != 0, ucTmp);
 			break;
+#endif
 		case 0x080a:	/* fOle2 */
 			ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
 			if (ucTmp == 0x01) {
@@ -1212,6 +1378,10 @@ bGet8PicInfo(int iFodo,
 			}
 			DBG_DEC_C(ucTmp != 0, ucTmp);
 			break;
+		case 0x680e:	/* fcObj */
+			ulTmp = ulGetLong(iFodo + iFodoOff + 2, aucGrpprl);
+			DBG_HEX(ulTmp);
+			break;
 		case 0x6a03:	/* fcPic */
 			pPicture->ulPictureOffset = ulGetLong(
 					iFodo + iFodoOff + 2, aucGrpprl);
@@ -1228,7 +1398,7 @@ bGet8PicInfo(int iFodo,
 } /* end of bGet8PicInfo */
 
 /*
- * Build the lists with Character Information for Word 8/9/10 files
+ * Build the lists with Character Information for Word 8/9/10/11 files
  */
 void
 vGet8ChrInfo(FILE *pFile, const pps_info_type *pPPS,
@@ -1239,14 +1409,11 @@ vGet8ChrInfo(FILE *pFile, const pps_info_type *pPPS,
 	font_block_type		tFont;
 	picture_block_type	tPicture;
 	ULONG		*aulCharPage;
-	const ULONG	*aulBlockDepot;
 	UCHAR	*aucBuffer;
 	ULONG	ulFileOffset, ulCharPos, ulBeginCharInfo;
-	ULONG	ulTableSize, ulTableStartBlock;
-	size_t	tCharInfoLen, tBlockDepotLen;
-	size_t	tOffset, tBlockSize, tLen;
+	size_t	tCharInfoLen, tOffset, tLen;
 	int	iIndex, iIndex2, iRun, iFodo, iLen;
-	USHORT	usDocStatus, usIstd;
+	USHORT	usIstd;
 	UCHAR	aucFpage[BIG_BLOCK_SIZE];
 
 	fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
@@ -1261,37 +1428,10 @@ vGet8ChrInfo(FILE *pFile, const pps_info_type *pPPS,
 		return;
 	}
 
-	/* Use 0Table or 1Table? */
-	usDocStatus = usGetWord(0x0a, aucHeader);
-	if (usDocStatus & BIT(9)) {
-		ulTableStartBlock = pPPS->t1Table.ulSB;
-		ulTableSize = pPPS->t1Table.ulSize;
-	} else {
-		ulTableStartBlock = pPPS->t0Table.ulSB;
-		ulTableSize = pPPS->t0Table.ulSize;
-	}
-	DBG_DEC(ulTableStartBlock);
-	if (ulTableStartBlock == 0) {
-		DBG_MSG("No character information");
-		return;
-	}
-	DBG_HEX(ulTableSize);
-	if (ulTableSize < MIN_SIZE_FOR_BBD_USE) {
-		/* Use the Small Block Depot */
-		aulBlockDepot = aulSBD;
-		tBlockDepotLen = tSBDLen;
-		tBlockSize = SMALL_BLOCK_SIZE;
-	} else {
-		/* Use the Big Block Depot */
-		aulBlockDepot = aulBBD;
-		tBlockDepotLen = tBBDLen;
-		tBlockSize = BIG_BLOCK_SIZE;
-	}
-	aucBuffer = xmalloc(tCharInfoLen);
-	if (!bReadBuffer(pFile, ulTableStartBlock,
-			aulBlockDepot, tBlockDepotLen, tBlockSize,
-			aucBuffer, ulBeginCharInfo, tCharInfoLen)) {
-		aucBuffer = xfree(aucBuffer);
+	aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable,
+			aulBBD, tBBDLen, aulSBD, tSBDLen,
+			ulBeginCharInfo, tCharInfoLen);
+	if (aucBuffer == NULL) {
 		return;
 	}
 	NO_DBG_PRINT_BLOCK(aucBuffer, tCharInfoLen);

+ 59 - 6
sys/src/cmd/aux/antiword/properties.c

@@ -1,6 +1,6 @@
 /*
  * properties.c
- * Copyright (C) 1998-2003 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Read the properties information from a MS Word file
@@ -22,22 +22,33 @@ vGetPropertyInfo(FILE *pFile, const pps_info_type *pPPS,
 {
 	options_type	tOptions;
 
+	TRACE_MSG("vGetPropertyInfo");
+
 	fail(pFile == NULL);
 	fail(pPPS == NULL && iWordVersion >= 6);
 	fail(aulBBD == NULL && tBBDLen != 0);
 	fail(aulSBD == NULL && tSBDLen != 0);
 	fail(aucHeader == NULL);
 
+	/* Get the options */
 	vGetOptions(&tOptions);
 
+	/* Get the property information per Word version */
 	switch (iWordVersion) {
 	case 0:
+		vGet0DopInfo(pFile, aucHeader);
 		vGet0SepInfo(pFile, aucHeader);
 		vGet0PapInfo(pFile, aucHeader);
 		if (tOptions.eConversionType == conversion_draw ||
 		    tOptions.eConversionType == conversion_ps ||
-		    tOptions.eConversionType == conversion_xml) {
+		    tOptions.eConversionType == conversion_xml ||
+		    tOptions.eConversionType == conversion_fmt_text ||
+		    tOptions.eConversionType == conversion_pdf) {
 			vGet0ChrInfo(pFile, aucHeader);
+		}
+		if (tOptions.eConversionType == conversion_draw ||
+		    tOptions.eConversionType == conversion_ps ||
+		    tOptions.eConversionType == conversion_pdf) {
 			vCreate0FontTable();
 		}
 		vSet0SummaryInfo(pFile, aucHeader);
@@ -45,13 +56,24 @@ vGetPropertyInfo(FILE *pFile, const pps_info_type *pPPS,
 	case 1:
 	case 2:
 		vGet2Stylesheet(pFile, iWordVersion, aucHeader);
+		vGet2DopInfo(pFile, aucHeader);
 		vGet2SepInfo(pFile, aucHeader);
 		vGet2PapInfo(pFile, aucHeader);
+		if (tOptions.eConversionType == conversion_ps ||
+		    tOptions.eConversionType == conversion_pdf) {
+			vGet2HdrFtrInfo(pFile, aucHeader);
+		}
 		if (tOptions.eConversionType == conversion_draw ||
 		    tOptions.eConversionType == conversion_ps ||
-		    tOptions.eConversionType == conversion_xml) {
+		    tOptions.eConversionType == conversion_xml ||
+		    tOptions.eConversionType == conversion_fmt_text ||
+		    tOptions.eConversionType == conversion_pdf) {
 			vGet2ChrInfo(pFile, iWordVersion, aucHeader);
-			vCreate2FontTable(pFile, aucHeader);
+		}
+		if (tOptions.eConversionType == conversion_draw ||
+		    tOptions.eConversionType == conversion_ps ||
+		    tOptions.eConversionType == conversion_pdf) {
+			vCreate2FontTable(pFile, iWordVersion, aucHeader);
 		}
 		vSet2SummaryInfo(pFile, iWordVersion, aucHeader);
 		break;
@@ -62,15 +84,28 @@ vGetPropertyInfo(FILE *pFile, const pps_info_type *pPPS,
 	case 7:
 		vGet6Stylesheet(pFile, pPPS->tWordDocument.ulSB,
 			aulBBD, tBBDLen, aucHeader);
+		vGet6DopInfo(pFile, pPPS->tWordDocument.ulSB,
+			aulBBD, tBBDLen, aucHeader);
 		vGet6SepInfo(pFile, pPPS->tWordDocument.ulSB,
 			aulBBD, tBBDLen, aucHeader);
 		vGet6PapInfo(pFile, pPPS->tWordDocument.ulSB,
 			aulBBD, tBBDLen, aucHeader);
+		if (tOptions.eConversionType == conversion_ps ||
+		    tOptions.eConversionType == conversion_pdf) {
+			vGet6HdrFtrInfo(pFile, pPPS->tWordDocument.ulSB,
+				aulBBD, tBBDLen, aucHeader);
+		}
 		if (tOptions.eConversionType == conversion_draw ||
 		    tOptions.eConversionType == conversion_ps ||
-		    tOptions.eConversionType == conversion_xml) {
+		    tOptions.eConversionType == conversion_xml ||
+		    tOptions.eConversionType == conversion_fmt_text ||
+		    tOptions.eConversionType == conversion_pdf) {
 			vGet6ChrInfo(pFile, pPPS->tWordDocument.ulSB,
 				aulBBD, tBBDLen, aucHeader);
+		}
+		if (tOptions.eConversionType == conversion_draw ||
+		    tOptions.eConversionType == conversion_ps ||
+		    tOptions.eConversionType == conversion_pdf) {
 			vCreate6FontTable(pFile, pPPS->tWordDocument.ulSB,
 				aulBBD, tBBDLen, aucHeader);
 		}
@@ -82,15 +117,28 @@ vGetPropertyInfo(FILE *pFile, const pps_info_type *pPPS,
 			aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
 		vGet8Stylesheet(pFile, pPPS,
 			aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
+		vGet8DopInfo(pFile, &pPPS->tTable,
+			aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
 		vGet8SepInfo(pFile, pPPS,
 			aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
 		vGet8PapInfo(pFile, pPPS,
 			aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
+		if (tOptions.eConversionType == conversion_ps ||
+		    tOptions.eConversionType == conversion_pdf) {
+			vGet8HdrFtrInfo(pFile, &pPPS->tTable,
+				aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
+		}
 		if (tOptions.eConversionType == conversion_draw ||
 		    tOptions.eConversionType == conversion_ps ||
-		    tOptions.eConversionType == conversion_xml) {
+		    tOptions.eConversionType == conversion_xml ||
+		    tOptions.eConversionType == conversion_fmt_text ||
+		    tOptions.eConversionType == conversion_pdf) {
 			vGet8ChrInfo(pFile, pPPS,
 				aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
+		}
+		if (tOptions.eConversionType == conversion_draw ||
+		    tOptions.eConversionType == conversion_ps ||
+		    tOptions.eConversionType == conversion_pdf) {
 			vCreate8FontTable(pFile, pPPS,
 				aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
 		}
@@ -103,6 +151,9 @@ vGetPropertyInfo(FILE *pFile, const pps_info_type *pPPS,
 		werr(0, "Sorry, no property information");
 		break;
 	}
+
+	/* Temporarily: Correct the font table */
+	vCorrectFontTable(tOptions.eConversionType, tOptions.eEncoding);
 } /* end of vGetPropertyInfo */
 
 /*
@@ -117,6 +168,8 @@ ePropMod2RowInfo(USHORT usPropMod, int iWordVersion)
 	const UCHAR	*aucPropMod;
 	int	iLen;
 
+	TRACE_MSG("ePropMod2RowInfo");
+
 	aucPropMod = aucReadPropModListItem(usPropMod);
 	if (aucPropMod == NULL) {
 		return found_nothing;

+ 64 - 103
sys/src/cmd/aux/antiword/riscos.c

@@ -7,8 +7,10 @@
  */
 
 #include <string.h>
-#include "kernel.h"
-#include "swis.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include "DeskLib:Error.h"
+#include "DeskLib:SWI.h"
 #include "antiword.h"
 
 #if !defined(DrawFile_Render)
@@ -18,6 +20,26 @@
 #define JPEG_Info		0x049980
 #endif /* !JPEG_Info */
 
+/*
+ * werr - write an error message and exit if needed
+ */
+void
+werr(int iFatal, const char *szFormat, ...)
+{
+	va_list tArg;
+
+	va_start(tArg, szFormat);
+	Error_Report(iFatal, (char *)szFormat, tArg);
+	va_end(tArg);
+	switch (iFatal) {
+	case 0:		/* The message is just a warning, so no exit */
+		return;
+	case 1:		/* Fatal error with a standard exit */
+		exit(EXIT_FAILURE);
+	default:	/* Fatal error with a non-standard exit */
+		exit(iFatal);
+	}
+} /* end of werr */
 
 /*
  * iGetFiletype
@@ -27,17 +49,16 @@
 int
 iGetFiletype(const char *szFilename)
 {
-	_kernel_swi_regs	regs;
-	_kernel_oserror		*e;
+	os_error	*e;
+	int		iType;
 
 	fail(szFilename == NULL || szFilename[0] == '\0');
 
-	(void)memset((void *)&regs, 0, sizeof(regs));
-	regs.r[0] = 23;
-	regs.r[1] = (int)szFilename;
-	e = _kernel_swi(OS_File, &regs, &regs);
+	e = SWI(2, 7, SWI_OS_File | XOS_Bit,
+		23, szFilename,
+		NULL, NULL, NULL, NULL, NULL, NULL, &iType);
 	if (e == NULL) {
-		return regs.r[6];
+		return iType;
 	}
 	werr(0, "Get Filetype error %d: %s", e->errnum, e->errmess);
 	return -1;
@@ -51,19 +72,15 @@ iGetFiletype(const char *szFilename)
 void
 vSetFiletype(const char *szFilename, int iFiletype)
 {
-	_kernel_swi_regs	regs;
-	_kernel_oserror		*e;
+	os_error	*e;
 
 	fail(szFilename == NULL || szFilename[0] == '\0');
 
 	if (iFiletype < 0x000 || iFiletype > 0xfff) {
 		return;
 	}
-	(void)memset((void *)&regs, 0, sizeof(regs));
-	regs.r[0] = 18;
-	regs.r[1] = (int)szFilename;
-	regs.r[2] = iFiletype;
-	e = _kernel_swi(OS_File, &regs, &regs);
+	e = SWI(3, 0, SWI_OS_File | XOS_Bit,
+		18, szFilename, iFiletype);
 	if (e != NULL) {
 		switch (e->errnum) {
 		case 0x000113:	/* ROM */
@@ -88,9 +105,9 @@ vSetFiletype(const char *szFilename, int iFiletype)
 BOOL
 bMakeDirectory(const char *szFilename)
 {
-	_kernel_swi_regs	regs;
-	_kernel_oserror		*e;
+	os_error	*e;
 	char	*pcLastDot;
+	int	iObjectType;
 	char	szDirectory[PATH_MAX+1];
 
 	DBG_MSG("bMakeDirectory");
@@ -111,30 +128,26 @@ bMakeDirectory(const char *szFilename)
 	*pcLastDot = '\0';
 	DBG_MSG(szDirectory);
 	/* Check if the name exists */
-	(void)memset((void *)&regs, 0, sizeof(regs));
-	regs.r[0] = 17;
-	regs.r[1] = (int)szDirectory;
-	e = _kernel_swi(OS_File, &regs, &regs);
+	e = SWI(2, 1, SWI_OS_File | XOS_Bit,
+		17, szDirectory,
+		&iObjectType);
 	if (e != NULL) {
 		werr(0, "Directory check %d: %s", e->errnum, e->errmess);
 		return FALSE;
 	}
-	if (regs.r[0] == 2) {
+	if (iObjectType == 2) {
 		/* The name exists and it is a directory */
 		DBG_MSG("The directory already exists");
 		return TRUE;
 	}
-	if (regs.r[0] != 0) {
+	if (iObjectType != 0) {
 		/* The name exists and it is not a directory */
-		DBG_DEC(regs.r[0]);
+		DBG_DEC(iObjectType);
 		return FALSE;
 	}
 	/* The name does not exist, make the directory */
-	(void)memset((void *)&regs, 0, sizeof(regs));
-	regs.r[0] = 8;
-	regs.r[1] = (int)szDirectory;
-	regs.r[4] = 0;
-	e = _kernel_swi(OS_File, &regs, &regs);
+	e = SWI(5, 0, SWI_OS_File | XOS_Bit,
+		8, szDirectory, 0, 0, 0);
 	if (e != NULL) {
 		werr(0, "I can't make a directory %d: %s",
 			e->errnum, e->errmess);
@@ -151,15 +164,14 @@ bMakeDirectory(const char *szFilename)
 int
 iReadCurrentAlphabetNumber(void)
 {
-	_kernel_swi_regs	regs;
-	_kernel_oserror		*e;
+	os_error	*e;
+	int		iAlphabetNumber;
 
-	(void)memset((void *)&regs, 0, sizeof(regs));
-	regs.r[0] = 71;
-	regs.r[1] = 127;
-	e = _kernel_swi(OS_Byte, &regs, &regs);
+	e = SWI(2, 2, SWI_OS_Byte | XOS_Bit,
+		71, 127,
+		NULL, &iAlphabetNumber);
 	if (e == NULL) {
-		return regs.r[1];
+		return iAlphabetNumber;
 	}
 	werr(0, "Read alphabet error %d: %s", e->errnum, e->errmess);
 	return -1;
@@ -173,20 +185,18 @@ iReadCurrentAlphabetNumber(void)
 int
 iGetRiscOsVersion(void)
 {
-	_kernel_swi_regs	regs;
-	_kernel_oserror		*e;
+	os_error	*e;
+	int		iVersion;
 
-	(void)memset((void *)&regs, 0, sizeof(regs));
-	regs.r[0] = 129;
-	regs.r[1] = 0;
-	regs.r[2] = 0xff;
-	e = _kernel_swi(OS_Byte, &regs, &regs);
+	e = SWI(3, 2, SWI_OS_Byte | XOS_Bit,
+		129, 0, 0xff,
+		NULL, &iVersion);
 	if (e != NULL) {
 		werr(0, "Read RISC OS version error %d: %s",
 			e->errnum, e->errmess);
 		return 0;
 	}
-	switch (regs.r[1]) {
+	switch (iVersion) {
 	case 0xa0:	/* Arthur 1.20 */
 		return 120;
 	case 0xa1:	/* RISC OS 2.00 */
@@ -206,7 +216,7 @@ iGetRiscOsVersion(void)
 	case 0xa8:	/* RISC OS 4.0x */
 		return 400;
 	default:
-		if (regs.r[1] >= 0xa9 && regs.r[1] <= 0xaf) {
+		if (iVersion >= 0xa9 && iVersion <= 0xaf) {
 			/* RISC OS 4.10 and up */
 			return 410;
 		}
@@ -215,73 +225,24 @@ iGetRiscOsVersion(void)
 	}
 } /* end of iGetRiscOsVersion */
 
-/*
- * Replaces the draw_render_diag function from RISC_OSLib when using
- * RISC OS version 3.60 or higher
- * This function calls a SWI that does not exist in earlier versions
- */
-BOOL
-bDrawRenderDiag360(draw_diag *pInfo,
-	draw_redrawstr *pRedraw, double dScale, draw_error *pError)
-{
-	_kernel_swi_regs	regs;
-	_kernel_oserror		*e;
-	int	aiTransform[6];
-
-	fail(pInfo == NULL);
-	fail(pRedraw == NULL);
-	fail(dScale < 0.01);
-	fail(pError == NULL);
-	fail(iGetRiscOsVersion() < 360);
-
-	aiTransform[0] = (int)(dScale * 0x10000);
-	aiTransform[1] = 0;
-	aiTransform[2] = 0;
-	aiTransform[3] = (int)(dScale * 0x10000);
-	aiTransform[4] = (pRedraw->box.x0 - pRedraw->scx) * 256;
-	aiTransform[5] = (pRedraw->box.y1 - pRedraw->scy) * 256;
-
-	(void)memset((void *)&regs, 0, sizeof(regs));
-	regs.r[0] = 0;
-	regs.r[1] = (int)pInfo->data;
-	regs.r[2] = pInfo->length;
-	regs.r[3] = (int)aiTransform;
-	regs.r[4] = (int)&pRedraw->box;
-	regs.r[5] = 0;
-	e = _kernel_swi(DrawFile_Render, &regs, &regs);
-	if (e == NULL) {
-		return TRUE;
-	}
-	werr(0, "DrawFile render error %d: %s", e->errnum, e->errmess);
-	pError->type = DrawOSError;
-	pError->err.os.errnum = e->errnum;
-	strncpy(pError->err.os.errmess,
-		e->errmess,
-		sizeof(pError->err.os.errmess) - 1);
-	pError->err.os.errmess[sizeof(pError->err.os.errmess) - 1] = '\0';
-	return FALSE;
-} /* end of bDrawRenderDiag360 */
-
 #if defined(DEBUG)
 BOOL
 bGetJpegInfo(UCHAR *pucJpeg, size_t tJpegSize)
 {
-	_kernel_swi_regs	regs;
-	_kernel_oserror		*e;
+	os_error	*e;
+	int	iReg0, iReg4, iReg5;
 
-	(void)memset((void *)&regs, 0, sizeof(regs));
-	regs.r[0] = 0x00;
-	regs.r[1] = (int)pucJpeg;
-	regs.r[2] = (int)tJpegSize;
-	e = _kernel_swi(JPEG_Info, &regs, &regs);
+	e = SWI(3, 6, JPEG_Info | XOS_Bit,
+		0x00, pucJpeg, tJpegSize,
+		&iReg0, NULL, NULL, NULL, &iReg4, &iReg5);
 	if (e == NULL) {
-		if (regs.r[0] & BIT(2)) {
+		if (iReg0 & BIT(2)) {
 			DBG_MSG("Pixel density is a simple ratio");
 		} else {
 			DBG_MSG("Pixel density is in dpi");
 		}
-		DBG_DEC(regs.r[4]);
-		DBG_DEC(regs.r[5]);
+		DBG_DEC(iReg4);
+		DBG_DEC(iReg5);
 		return TRUE;
 	}
 	werr(0, "JPEG Info error %d: %s", e->errnum, e->errmess);

+ 1 - 2
sys/src/cmd/aux/antiword/rowlist.c

@@ -1,6 +1,6 @@
 /*
  * rowlist.c
- * Copyright (C) 1998-2001 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2004 A.J. van Os; Released under GPL
  *
  * Description:
  * Build, read and destroy a list of Word table-row information
@@ -74,7 +74,6 @@ vAdd2RowInfoList(const row_block_type *pRowBlock)
 	NO_DBG_HEX(pRowBlock->ulFileOffsetStart);
 	NO_DBG_HEX(pRowBlock->ulFileOffsetEnd);
 	NO_DBG_DEC(pRowBlock->ucNumberOfColumns);
-	NO_DBG_DEC(pRowBlock->iColumnWidthSum);
 
 	/* Create the new list member */
 	pListMember = xmalloc(sizeof(row_desc_type));

+ 201 - 144
sys/src/cmd/aux/antiword/saveas.c

@@ -8,10 +8,42 @@
 
 #include <stdio.h>
 #include <string.h>
-#include "saveas.h"
-#include "event.h"
+#include "DeskLib:Menu.h"
+#include "DeskLib:Save.h"
+#include "DeskLib:Template.h"
+#include "DeskLib:Window.h"
+#include "drawfile.h"
 #include "antiword.h"
 
+/* The window handle of the save window */
+static window_handle	tSaveWindow = 0;
+
+/* Xfer_send box fields */
+#define DRAG_SPRITE	3
+#define OK_BUTTON	0
+#define CANCEL_BUTTON	(-1)
+#define FILENAME_ICON	2
+
+
+/*
+ * saveas - a wrapper around Save_InitSaveWindowhandler
+ */
+static void
+saveas(int iFileType, char *szOutfile, size_t tEstSize,
+	save_filesaver save_function, void *pvReference)
+{
+	TRACE_MSG("saveas");
+
+	if (tSaveWindow == 0) {
+		tSaveWindow = Window_Create("xfer_send", template_TITLEMIN);
+	}
+	Icon_SetText(tSaveWindow, FILENAME_ICON, szOutfile);
+	Window_Show(tSaveWindow, open_UNDERPOINTER);
+	(void)Save_InitSaveWindowHandler(tSaveWindow, FALSE, TRUE, TRUE,
+		DRAG_SPRITE, OK_BUTTON, CANCEL_BUTTON, FILENAME_ICON,
+		save_function, NULL, NULL, tEstSize, iFileType, pvReference);
+} /* end of saveas */
+
 static BOOL
 bWrite2File(void *pvBytes, size_t tSize, FILE *pFile, const char *szFilename)
 {
@@ -30,15 +62,17 @@ bText2File(char *szFilename, void *pvHandle)
 {
 	FILE	*pFile;
 	diagram_type	*pDiag;
-	draw_textstrhdr	tText;
-	char	*pcTmp;
-	int	iToGo, iSize, iX, iYtopPrev, iHeight, iLines;
+	drawfile_object	*pObj;
+	drawfile_text	*pText;
+	const char	*pcTmp;
+	int	iToGo, iX, iYtopPrev, iHeight, iLines;
 	BOOL	bFirst, bIndent, bSuccess;
 
+	TRACE_MSG("bText2File");
+
 	fail(szFilename == NULL || szFilename[0] == '\0');
 	fail(pvHandle == NULL);
 
-	DBG_MSG("bText2File");
 	DBG_MSG(szFilename);
 
 	pDiag = (diagram_type *)pvHandle;
@@ -51,22 +85,21 @@ bText2File(char *szFilename, void *pvHandle)
 	iYtopPrev = 0;
 	iHeight = (int)lWord2DrawUnits20(DEFAULT_FONT_SIZE);
 	bSuccess = TRUE;
-	iToGo = pDiag->tInfo.length - sizeof(draw_fileheader);
+	fail(pDiag->tInfo.length < offsetof(drawfile_diagram, objects));
+	iToGo = pDiag->tInfo.length - offsetof(drawfile_diagram, objects);
 	DBG_DEC(iToGo);
-	pcTmp = pDiag->tInfo.data + sizeof(draw_fileheader);
+	pcTmp = (const char *)pDiag->tInfo.data +
+				offsetof(drawfile_diagram, objects);
 	while (iToGo > 0 && bSuccess) {
-		tText = *(draw_textstrhdr *)pcTmp;
-		switch (tText.tag) {
-		case draw_OBJFONTLIST:
-			/* These are not relevant in a textfile */
-			iSize = ((draw_fontliststrhdr *)pcTmp)->size;
-			pcTmp += iSize;
-			iToGo -= iSize;
-			break;
-		case draw_OBJTEXT:
+		pObj = (drawfile_object *)pcTmp;
+		switch (pObj->type) {
+		case drawfile_TYPE_TEXT:
+			pText = &pObj->data.text;
 			/* Compute the number of lines */
-			iLines =
-			(iYtopPrev - tText.bbox.y1 + iHeight / 2) / iHeight;
+			iLines = (iYtopPrev - pText->bbox.max.y +
+					iHeight / 2) / iHeight;
+			DBG_DEC_C(iLines < 0, iYtopPrev);
+			DBG_DEC_C(iLines < 0, pText->bbox.max.y);
 			fail(iLines < 0);
 			bIndent = iLines > 0 || bFirst;
 			bFirst = FALSE;
@@ -78,9 +111,9 @@ bText2File(char *szFilename, void *pvHandle)
 			}
 			/* Print the indentation */
 			if (bIndent && bSuccess) {
-				for (iX = draw_screenToDraw(8);
-				     iX <= tText.bbox.x0 && bSuccess;
-				     iX += draw_screenToDraw(16)) {
+				for (iX = Drawfile_ScreenToDraw(8);
+				     iX <= pText->bbox.min.x && bSuccess;
+				     iX += Drawfile_ScreenToDraw(16)) {
 					bSuccess = bWrite2File(" ",
 						1, pFile, szFilename);
 				}
@@ -89,33 +122,25 @@ bText2File(char *szFilename, void *pvHandle)
 				break;
 			}
 			/* Print the text object */
-			pcTmp += sizeof(tText);
-			bSuccess = bWrite2File(pcTmp,
-				strlen(pcTmp), pFile, szFilename);
-			pcTmp += tText.size - sizeof(tText);
-			/* Setup for the next text object */
-			iToGo -= tText.size;
-			iYtopPrev = tText.bbox.y1;
-			iHeight = tText.bbox.y1 - tText.bbox.y0;
+			bSuccess = bWrite2File(pText->text,
+				strlen(pText->text), pFile, szFilename);
+			/* Setup for the next object */
+			iYtopPrev = pText->bbox.max.y;
+			iHeight = pText->bbox.max.y - pText->bbox.min.y;
 			break;
-		case draw_OBJPATH:
+		case drawfile_TYPE_FONT_TABLE:
+		case drawfile_TYPE_PATH:
+		case drawfile_TYPE_SPRITE:
+		case drawfile_TYPE_JPEG:
 			/* These are not relevant in a textfile */
-			iSize = ((draw_pathstrhdr *)pcTmp)->size;
-			pcTmp += iSize;
-			iToGo -= iSize;
-			break;
-		case draw_OBJSPRITE:
-		case draw_OBJJPEG:
-			/* These are not relevant in a textfile */
-			iSize = ((draw_spristrhdr *)pcTmp)->size;
-			pcTmp += iSize;
-			iToGo -= iSize;
 			break;
 		default:
-			DBG_DEC(tText.tag);
+			DBG_DEC(pObj->type);
 			bSuccess = FALSE;
 			break;
 		}
+		pcTmp += pObj->size;
+		iToGo -= pObj->size;
 	}
 	DBG_DEC_C(iToGo != 0, iToGo);
 	if (bSuccess) {
@@ -132,29 +157,48 @@ bText2File(char *szFilename, void *pvHandle)
 } /* end of bText2File */
 
 /*
- * vSaveTextfile
+ * bSaveTextfile - save the diagram as a text file
  */
-void
-vSaveTextfile(diagram_type *pDiagram)
+BOOL
+bSaveTextfile(event_pollblock *pEvent, void *pvReference)
 {
-	wimp_emask	tMask;
-	int		iRecLen, iNbrRecs, iEstSize;
+	diagram_type	*pDiag;
+	size_t	tRecLen, tNbrRecs, tEstSize;
+
+	TRACE_MSG("bSaveTextfile");
 
-	fail(pDiagram == NULL);
+	fail(pEvent == NULL);
+	fail(pvReference == NULL);
 
-	DBG_MSG("vSaveTextfile");
-	iRecLen = sizeof(draw_textstrhdr) + DEFAULT_SCREEN_WIDTH * 2 / 3;
-	iNbrRecs = pDiagram->tInfo.length / iRecLen + 1;
-	iEstSize = iNbrRecs * DEFAULT_SCREEN_WIDTH * 2 / 3;
-	DBG_DEC(iEstSize);
+	pDiag = (diagram_type *)pvReference;
+
+	switch (pEvent->type) {
+	case event_SEND:	/* From a menu */
+		fail(pEvent->data.message.header.action != message_MENUWARN);
+		if (menu_currentopen != pDiag->pSaveMenu ||
+		    pEvent->data.message.data.menuwarn.selection[0] !=
+							SAVEMENU_SAVETEXT) {
+			return FALSE;
+		}
+		break;
+	case event_KEY:		/* From a key short cut */
+		if (pEvent->data.key.caret.window != pDiag->tMainWindow) {
+			return FALSE;
+		}
+		break;
+	default:
+		DBG_DEC(pEvent->type);
+		return FALSE;
+	}
 
-	tMask = event_getmask();
-	event_setmask(0);
-	saveas(FILETYPE_TEXT, "WordText",
-		iEstSize, bText2File,
-		NULL, NULL, pDiagram);
-	event_setmask(tMask);
-} /* end of vSaveTextfile */
+	tRecLen = sizeof(drawfile_text) + DEFAULT_SCREEN_WIDTH * 2 / 3;
+	tNbrRecs = pDiag->tInfo.length / tRecLen + 1;
+	tEstSize = tNbrRecs * DEFAULT_SCREEN_WIDTH * 2 / 3;
+	DBG_DEC(tEstSize);
+
+	saveas(FILETYPE_TEXT, "WordText", tEstSize, bText2File, pDiag);
+	return TRUE;
+} /* end of bSaveTextfile */
 
 /*
  * bDraw2File - Save the generated draw file to a Draw file
@@ -168,20 +212,22 @@ bDraw2File(char *szFilename, void *pvHandle)
 {
 	FILE		*pFile;
 	diagram_type	*pDiagram;
-	draw_fileheader tHdr;
-	draw_textstrhdr	tText;
-	draw_pathstrhdr	tPath;
-	draw_spristrhdr	tSprite;
-	draw_jpegstrhdr tJpeg;
+	wimp_box	*pBbox;
+	drawfile_object	*pObj;
+	drawfile_text	*pText;
+	drawfile_path	*pPath;
+	drawfile_sprite	*pSprite;
+	drawfile_jpeg	*pJpeg;
 	int	*piPath;
 	char	*pcTmp;
 	int	iYadd, iToGo, iSize;
 	BOOL	bSuccess;
 
+	TRACE_MSG("bDraw2File");
+
 	fail(szFilename == NULL || szFilename[0] == '\0');
 	fail(pvHandle == NULL);
 
-	DBG_MSG("bDraw2File");
 	NO_DBG_MSG(szFilename);
 
 	pDiagram = (diagram_type *)pvHandle;
@@ -193,51 +239,55 @@ bDraw2File(char *szFilename, void *pvHandle)
 	iToGo = pDiagram->tInfo.length;
 	DBG_DEC(iToGo);
 	pcTmp = pDiagram->tInfo.data;
-	tHdr = *(draw_fileheader *)pcTmp;
-	iYadd = -tHdr.bbox.y0;
-	tHdr.bbox.y0 += iYadd;
-	tHdr.bbox.y1 += iYadd;
-	bSuccess = bWrite2File(&tHdr, sizeof(tHdr), pFile, szFilename);
-	iToGo -= sizeof(tHdr);
-	DBG_DEC(iToGo);
-	pcTmp += sizeof(tHdr);
+	bSuccess = bWrite2File(pcTmp,
+			offsetof(drawfile_diagram, bbox), pFile, szFilename);
+	if (bSuccess) {
+	  	pcTmp += offsetof(drawfile_diagram, bbox);
+		iToGo -= offsetof(drawfile_diagram, bbox);
+		pBbox = (wimp_box *)pcTmp;
+		iYadd = -pBbox->min.y;
+		pBbox->min.y += iYadd;
+		pBbox->max.y += iYadd;
+		bSuccess = bWrite2File(pcTmp,
+				sizeof(*pBbox), pFile, szFilename);
+		iToGo -= sizeof(*pBbox);
+		DBG_DEC(iToGo);
+		pcTmp += sizeof(*pBbox);
+	} else {
+		iYadd = 0;
+	}
 	while (iToGo > 0 && bSuccess) {
-		tText = *(draw_textstrhdr *)pcTmp;
-		switch (tText.tag) {
-		case draw_OBJFONTLIST:
-			iSize = ((draw_fontliststrhdr *)pcTmp)->size;
+		pObj = (drawfile_object *)pcTmp;
+		iSize = pObj->size;
+		switch (pObj->type) {
+		case drawfile_TYPE_FONT_TABLE:
 			bSuccess = bWrite2File(pcTmp,
 					iSize, pFile, szFilename);
 			pcTmp += iSize;
 			iToGo -= iSize;
 			break;
-		case draw_OBJTEXT:
+		case drawfile_TYPE_TEXT:
+			pText = &pObj->data.text;
 			/* First correct the coordinates */
-			tText.bbox.y0 += iYadd;
-			tText.bbox.y1 += iYadd;
-			tText.coord.y += iYadd;
+			pText->bbox.min.y += iYadd;
+			pText->bbox.max.y += iYadd;
+			pText->base.y += iYadd;
 			/* Now write the information to file */
-			bSuccess = bWrite2File(&tText,
-				sizeof(tText), pFile, szFilename);
-			pcTmp += sizeof(tText);
-			iSize = tText.size - sizeof(tText);
-			if (bSuccess) {
-				bSuccess = bWrite2File(pcTmp,
+			bSuccess = bWrite2File(pcTmp,
 					iSize, pFile, szFilename);
-				pcTmp += iSize;
-			}
-			iToGo -= tText.size;
+			pcTmp += pObj->size;
+			iToGo -= pObj->size;
 			break;
-		case draw_OBJPATH:
-			tPath = *(draw_pathstrhdr *)pcTmp;
+		case drawfile_TYPE_PATH:
+			pPath = &pObj->data.path;
 			/* First correct the coordinates */
-			tPath.bbox.y0 += iYadd;
-			tPath.bbox.y1 += iYadd;
+			pPath->bbox.min.y += iYadd;
+			pPath->bbox.max.y += iYadd;
 			/* Now write the information to file */
-			bSuccess = bWrite2File(&tPath,
-				sizeof(tPath), pFile, szFilename);
-			pcTmp += sizeof(tPath);
-			iSize = tPath.size - sizeof(tPath);
+			bSuccess = bWrite2File(pPath,
+				sizeof(*pPath), pFile, szFilename);
+			pcTmp += sizeof(*pPath);
+			iSize = pObj->size - sizeof(*pPath);
 			fail(iSize < 14 * sizeof(int));
 			/* Second correct the path coordinates */
 			piPath = xmalloc(iSize);
@@ -252,45 +302,33 @@ bDraw2File(char *szFilename, void *pvHandle)
 				pcTmp += iSize;
 			}
 			piPath = xfree(piPath);
-			iToGo -= tPath.size;
+			iToGo -= pObj->size;
 			break;
-		case draw_OBJSPRITE:
-			tSprite = *(draw_spristrhdr *)pcTmp;
+		case drawfile_TYPE_SPRITE:
+			pSprite = &pObj->data.sprite;
 			/* First correct the coordinates */
-			tSprite.bbox.y0 += iYadd;
-			tSprite.bbox.y1 += iYadd;
+			pSprite->bbox.min.y += iYadd;
+			pSprite->bbox.max.y += iYadd;
 			/* Now write the information to file */
-			bSuccess = bWrite2File(&tSprite,
-				sizeof(tSprite), pFile, szFilename);
-			pcTmp += sizeof(tSprite);
-			iSize = tSprite.size - sizeof(tSprite);
-			if (bSuccess) {
-				bSuccess = bWrite2File(pcTmp,
+			bSuccess = bWrite2File(pcTmp,
 					iSize, pFile, szFilename);
-				pcTmp += iSize;
-			}
-			iToGo -= tSprite.size;
+			pcTmp += pObj->size;
+			iToGo -= pObj->size;
 			break;
-		case draw_OBJJPEG:
-			tJpeg = *(draw_jpegstrhdr *)pcTmp;
+		case drawfile_TYPE_JPEG:
+			pJpeg = &pObj->data.jpeg;
 			/* First correct the coordinates */
-			tJpeg.bbox.y0 += iYadd;
-			tJpeg.bbox.y1 += iYadd;
-			tJpeg.trfm[5] += iYadd;
+			pJpeg->bbox.min.y += iYadd;
+			pJpeg->bbox.max.y += iYadd;
+			pJpeg->trfm.entries[2][1] += iYadd;
 			/* Now write the information to file */
-			bSuccess = bWrite2File(&tJpeg,
-				sizeof(tJpeg), pFile, szFilename);
-			pcTmp += sizeof(tJpeg);
-			iSize = tJpeg.size - sizeof(tJpeg);
-			if (bSuccess) {
-				bSuccess = bWrite2File(pcTmp,
+			bSuccess = bWrite2File(pcTmp,
 					iSize, pFile, szFilename);
-				pcTmp += iSize;
-			}
-			iToGo -= tJpeg.size;
+			pcTmp += pObj->size;
+			iToGo -= pObj->size;
 			break;
 		default:
-			DBG_DEC(tText.tag);
+			DBG_DEC(pObj->type);
 			bSuccess = FALSE;
 			break;
 		}
@@ -307,24 +345,43 @@ bDraw2File(char *szFilename, void *pvHandle)
 } /* end of bDraw2File */
 
 /*
- * vSaveDrawfile
+ * bSaveDrawfile - save the diagram as a draw file
  */
-void
-vSaveDrawfile(diagram_type *pDiagram)
+BOOL
+bSaveDrawfile(event_pollblock *pEvent, void *pvReference)
 {
-	wimp_emask	tMask;
-	int		iEstSize;
+	diagram_type	*pDiag;
+	size_t		tEstSize;
+
+	TRACE_MSG("bSaveDrawfile");
 
-	fail(pDiagram == NULL);
+	fail(pEvent == NULL);
+	fail(pvReference == NULL);
 
-	DBG_MSG("vSaveDrawfile");
-	iEstSize = pDiagram->tInfo.length;
-	DBG_DEC(iEstSize);
+	pDiag = (diagram_type *)pvReference;
 
-	tMask = event_getmask();
-	event_setmask(0);
-	saveas(FILETYPE_DRAW, "WordDraw",
-		iEstSize, bDraw2File,
-		NULL, NULL, pDiagram);
-	event_setmask(tMask);
-} /* end of vSaveDrawfile */
+	switch (pEvent->type) {
+	case event_SEND:	/* From a menu */
+		fail(pEvent->data.message.header.action != message_MENUWARN);
+		if (menu_currentopen != pDiag->pSaveMenu ||
+		    pEvent->data.message.data.menuwarn.selection[0] !=
+							SAVEMENU_SAVEDRAW) {
+			return FALSE;
+		}
+		break;
+	case event_KEY:		/* From a key short cut */
+		if (pEvent->data.key.caret.window != pDiag->tMainWindow) {
+			return FALSE;
+		}
+		break;
+	default:
+		DBG_DEC(pEvent->type);
+		return FALSE;
+	}
+
+	tEstSize = pDiag->tInfo.length;
+	DBG_DEC(tEstSize);
+
+	saveas(FILETYPE_DRAW, "WordDraw", tEstSize, bDraw2File, pDiag);
+	return TRUE;
+} /* end of bSaveDrawfile */

+ 51 - 11
sys/src/cmd/aux/antiword/sectlist.c

@@ -1,6 +1,6 @@
 /*
  * sectlist.c
- * Copyright (C) 2001,2002 A.J. van Os; Released under GPL
+ * Copyright (C) 2001-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Build, read and destroy list(s) of Word section information
@@ -17,7 +17,7 @@
  */
 typedef struct section_mem_tag {
 	section_block_type	tInfo;
-	ULONG			ulTextOffset;
+	ULONG			ulCharPos;
 	struct section_mem_tag	*pNext;
 } section_mem_type;
 
@@ -52,7 +52,7 @@ vDestroySectionInfoList(void)
  * vAdd2SectionInfoList - Add an element to the Section Information List
  */
 void
-vAdd2SectionInfoList(const section_block_type *pSection, ULONG ulTextOffset)
+vAdd2SectionInfoList(const section_block_type *pSection, ULONG ulCharPos)
 {
 	section_mem_type	*pListMember;
 
@@ -62,7 +62,7 @@ vAdd2SectionInfoList(const section_block_type *pSection, ULONG ulTextOffset)
 	pListMember = xmalloc(sizeof(section_mem_type));
 	/* Fill the list member */
 	pListMember->tInfo = *pSection;
-	pListMember->ulTextOffset = ulTextOffset;
+	pListMember->ulCharPos = ulCharPos;
 	pListMember->pNext = NULL;
 	/* Add the new member to the list */
 	if (pAnchor == NULL) {
@@ -88,23 +88,23 @@ vGetDefaultSection(section_block_type *pSection)
  * vDefault2SectionInfoList - Add a default to the Section Information List
  */
 void
-vDefault2SectionInfoList(ULONG ulTextOffset)
+vDefault2SectionInfoList(ULONG ulCharPos)
 {
 	section_block_type	tSection;
 
 	vGetDefaultSection(&tSection);
-	vAdd2SectionInfoList(&tSection, ulTextOffset);
+	vAdd2SectionInfoList(&tSection, ulCharPos);
 } /* end of vDefault2SectionInfoList */
 
 /*
  * pGetSectionInfo - get the section information
  */
 const section_block_type *
-pGetSectionInfo(const section_block_type *pOld, ULONG ulTextOffset)
+pGetSectionInfo(const section_block_type *pOld, ULONG ulCharPos)
 {
 	const section_mem_type	*pCurr;
 
-	if (pOld == NULL || ulTextOffset == 0) {
+	if (pOld == NULL || ulCharPos == 0) {
 		if (pAnchor == NULL) {
 			/* There are no records, make one */
 			vDefault2SectionInfoList(0);
@@ -114,12 +114,52 @@ pGetSectionInfo(const section_block_type *pOld, ULONG ulTextOffset)
 		NO_DBG_MSG("First record");
 		return &pAnchor->tInfo;
 	}
+
+	NO_DBG_HEX(ulCharPos);
 	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
-		if (ulTextOffset == pCurr->ulTextOffset ||
-		    ulTextOffset + 1 == pCurr->ulTextOffset) {
-			NO_DBG_HEX(pCurr->ulTextOffset);
+		NO_DBG_HEX(pCurr->ulCharPos);
+		if (ulCharPos == pCurr->ulCharPos ||
+		    ulCharPos + 1 == pCurr->ulCharPos) {
+			NO_DBG_HEX(pCurr->ulCharPos);
 			return &pCurr->tInfo;
 		}
 	}
 	return pOld;
 } /* end of pGetSectionInfo */
+
+/*
+ * tGetNumberOfSections - get the number of sections
+ */
+size_t
+tGetNumberOfSections(void)
+{
+	const section_mem_type	*pCurr;
+	size_t	tCounter;
+
+	for (tCounter = 0, pCurr = pAnchor;
+	     pCurr != NULL;
+	     tCounter++, pCurr = pCurr->pNext)
+		;	/* Empty */
+	return tCounter;
+} /* end of tGetNumberOfSections */
+
+/*
+ * ucGetSepHdrFtrSpecification - get the Heder/footer specification
+ */
+UCHAR
+ucGetSepHdrFtrSpecification(size_t tSectionNumber)
+{
+	const section_mem_type	*pCurr;
+	size_t	tIndex;
+
+	for (tIndex = 0, pCurr = pAnchor;
+	     tIndex < tSectionNumber && pCurr != NULL;
+	     tIndex++, pCurr = pCurr->pNext)
+		;	/* Empty */
+	if (pCurr == NULL) {
+		DBG_DEC(tSectionNumber);
+		DBG_FIXME();
+		return 0x00;
+	}
+	return pCurr->tInfo.ucHdrFtrSpecification;
+} /* end of ucGetSepHdrFtrSpecification */

+ 32 - 46
sys/src/cmd/aux/antiword/startup.c

@@ -9,10 +9,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include "kernel.h"
-#include "swis.h"
-#include "wimp.h"
-#include "wimpt.h"
+#include "DeskLib:Error.h"
+#include "DeskLib:Event.h"
+#include "DeskLib:SWI.h"
 #include "antiword.h"
 
 
@@ -45,37 +44,19 @@ bIsMatch(const char *szStr1, const char *szStr2)
  *
  * returns the task handle when found, otherwise 0
  */
-static wimp_t
-tGetTaskHandle(const char *szTaskname, int iOSVersion)
+static task_handle
+tGetTaskHandle(const char *szTaskname)
 {
-	_kernel_swi_regs	regs;
-	_kernel_oserror		*e;
 	const char	*pcTmp;
-	int	iIndex;
+	int	iReg0, iIndex;
 	int	aiBuffer[4];
 	char	szTmp[21];
 
-	if (iOSVersion < 310) {
-		/*
-		 * SWI TaskManager_EnumerateTasks does not
-		 * exist in earlier versions of RISC OS
-		 */
-		return 0;
-	}
-
-	(void)memset((void *)&regs, 0, sizeof(regs));
-	regs.r[0] = 0;
-
+	iReg0 = 0;
 	do {
 		/* Get info on the next task */
-		regs.r[1] = (int)aiBuffer;
-		regs.r[2] = sizeof(aiBuffer);
-		e = _kernel_swi(TaskManager_EnumerateTasks, &regs, &regs);
-		if (e != NULL) {
-			werr(1, "TaskManager_EnumerateTasks error %d: %s",
-				e->errnum, e->errmess);
-			exit(EXIT_FAILURE);
-		}
+		Error_CheckFatal(SWI(3, 1, TaskManager_EnumerateTasks | XOS_Bit,
+			iReg0, aiBuffer, sizeof(aiBuffer), &iReg0));
 		/* Copy the (control character terminated) task name */
 		for (iIndex = 0, pcTmp = (const char *)aiBuffer[1];
 		     iIndex < elementsof(szTmp);
@@ -89,9 +70,9 @@ tGetTaskHandle(const char *szTaskname, int iOSVersion)
 		szTmp[elementsof(szTmp) - 1] = '\0';
 		if (bIsMatch(szTmp, szTaskname)) {
 			/* Task found */
-			return (wimp_t)aiBuffer[0];
+			return (task_handle)aiBuffer[0];
 		}
-	} while (regs.r[0] >= 0);
+	} while (iReg0 >= 0);
 
 	/* Task not found */
 	return 0;
@@ -100,25 +81,25 @@ tGetTaskHandle(const char *szTaskname, int iOSVersion)
 int
 main(int argc, char **argv)
 {
-	wimp_msgstr	tMsg;
-	wimp_t	tTaskHandle;
+	message_block	tMsg;
+	task_handle	tTaskHandle;
 	size_t	tArgLen;
-	int	iVersion;
+	int	aiMessages[] = {0};
 	char	szCommand[512];
 
-	iVersion = wimpt_init("StartUp");
+	Event_Initialise3("StartUp", 310, aiMessages);
 
 	if (argc > 1) {
 		tArgLen = strlen(argv[1]);
 	} else {
 		tArgLen = 0;
 	}
-	if (tArgLen >= sizeof(tMsg.data.dataload.name)) {
+	if (tArgLen >= sizeof(tMsg.data.dataload.filename)) {
 		werr(1, "Input filename too long");
 		return EXIT_FAILURE;
 	}
 
-	tTaskHandle = tGetTaskHandle("antiword", iVersion);
+	tTaskHandle = tGetTaskHandle("antiword");
 
 	if (tTaskHandle == 0) {
 		/* Antiword is not active */
@@ -138,18 +119,23 @@ main(int argc, char **argv)
 
 	/* Antiword is active */
 	if (argc > 1) {
-		/* Send the argument to Antiword */
-		tMsg.hdr.size = ROUND4(sizeof(tMsg) -
-					sizeof(tMsg.data.dataload.name) +
+		/*
+		 * Send the argument to Antiword by imitating a
+		 * drag-and-drop to Antiword's iconbar icon
+		 */
+		memset(&tMsg, 0, sizeof(tMsg));
+		tMsg.header.size = ROUND4(offsetof(message_block, data) +
+					offsetof(message_dataload, filename) +
 					1 + tArgLen);
-		tMsg.hdr.your_ref = 0;
-		tMsg.hdr.action = wimp_MDATALOAD;
-		tMsg.data.dataload.w = -1;
+		tMsg.header.yourref = 0;
+		tMsg.header.action = message_DATALOAD;
+		tMsg.data.dataload.window = window_ICONBAR;
+		tMsg.data.dataload.icon = -1;
 		tMsg.data.dataload.size = 0;
-		tMsg.data.dataload.type = FILETYPE_MSWORD;
-		strcpy(tMsg.data.dataload.name, argv[1]);
-		wimpt_noerr(wimp_sendmessage(wimp_ESEND,
-						&tMsg, tTaskHandle));
+		tMsg.data.dataload.filetype = FILETYPE_MSWORD;
+		strcpy(tMsg.data.dataload.filename, argv[1]);
+		Error_CheckFatal(Wimp_SendMessage(event_SEND,
+						&tMsg, tTaskHandle, 0));
 		return EXIT_SUCCESS;
 	} else {
 		/* Give an error message and return */

+ 33 - 8
sys/src/cmd/aux/antiword/stylelist.c

@@ -1,6 +1,6 @@
 /*
  * stylelist.c
- * Copyright (C) 1998-2003 A.J. van Os; Released under GNU GPL
+ * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Build, read and destroy a list of Word style information
@@ -79,7 +79,9 @@ vConvertListCharacter(UCHAR ucNFC, USHORT usListChar, char *szListChar)
 		return;
 	}
 
-	if (ucNFC != LIST_SPECIAL && ucNFC != LIST_BULLETS) {
+	if (ucNFC != LIST_SPECIAL &&
+	    ucNFC != LIST_SPECIAL2 &&
+	    ucNFC != LIST_BULLETS) {
 		szListChar[0] = '.';
 		szListChar[1] = '\0';
 		return;
@@ -94,7 +96,7 @@ vConvertListCharacter(UCHAR ucNFC, USHORT usListChar, char *szListChar)
 
 	switch (usListChar) {
 	case 0x0000: case 0x00b7: case 0x00fe: case  0xf021: case 0xf043:
-	case 0xf093: case 0xf0b7:
+	case 0xf06c: case 0xf093: case 0xf0b7:
 		usListChar = 0x2022;	/* BULLET */
 		break;
 	case 0x0096: case 0xf02d:
@@ -130,7 +132,7 @@ vConvertListCharacter(UCHAR ucNFC, USHORT usListChar, char *szListChar)
 	case 0xf071:
 		usListChar = 0x2751;	/* LOWER RIGHT SHADOWED WHITE SQUARE */
 		break;
-	case 0xf075:
+	case 0xf075: case 0xf077:
 		usListChar = 0x25c6;	/* BLACK DIAMOND */
 		break;
 	case 0xf076:
@@ -156,16 +158,21 @@ vConvertListCharacter(UCHAR ucNFC, USHORT usListChar, char *szListChar)
 		    (usListChar < 0x80 && !isprint((int)usListChar))) {
 			/*
 			 * All remaining private area characters and all
-			 * remaining non-printable ASCII characters to bullet
+			 * remaining non-printable ASCII characters to their
+			 * default bullet character
 			 */
 			DBG_HEX(usListChar);
 			DBG_FIXME();
-			usListChar = 0x2022;	/* BULLET */
+			if (ucNFC == LIST_SPECIAL || ucNFC == LIST_SPECIAL2) {
+				usListChar = 0x2190;	/* LEFTWARDS ARROW */
+			} else {
+				usListChar = 0x2022;	/* BULLET */
+			}
 		}
 		break;
 	}
 
-	if (eEncoding == encoding_utf8) {
+	if (eEncoding == encoding_utf_8) {
 		tLen = tUcs2Utf8(usListChar, szListChar, 4);
 		szListChar[tLen] = '\0';
 	} else {
@@ -177,7 +184,7 @@ vConvertListCharacter(UCHAR ucNFC, USHORT usListChar, char *szListChar)
 		case 0x2013: case 0x2500:
 			szListChar[0] = '-';
 			break;
-		case 0x2199: case 0x2329:
+		case 0x2190: case 0x2199: case 0x2329:
 			szListChar[0] = '<';
 			break;
 		case 0x21d2:
@@ -387,6 +394,24 @@ pGetNextStyleInfoListItem(const style_block_type *pCurr)
 	return &pRecord->pNext->tInfo;
 } /* end of pGetNextStyleInfoListItem */
 
+/*
+ * Get the next text style
+ */
+const style_block_type *
+pGetNextTextStyle(const style_block_type *pCurr)
+{
+	const style_block_type	*pRecord;
+
+	pRecord = pCurr;
+	do {
+		pRecord = pGetNextStyleInfoListItem(pRecord);
+	} while (pRecord != NULL &&
+		 (pRecord->eListID == hdrftr_list ||
+		  pRecord->eListID == macro_list ||
+		  pRecord->eListID == annotation_list));
+	return pRecord;
+} /* end of pGetNextTextStyle */
+
 /*
  * usGetIstd - get the istd that belongs to the given file offset
  */

+ 85 - 64
sys/src/cmd/aux/antiword/stylesheet.c

@@ -1,6 +1,6 @@
 /*
  * stylesheet.c
- * Copyright (C) 2001,2002 A.J. van Os; Released under GPL
+ * Copyright (C) 2001-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Build, read and destroy a list of stylesheet information
@@ -52,10 +52,17 @@ vGetDefaultStyle(style_block_type *pStyle)
  * vGetDefaultFont - fill the font struct with default values
  */
 static void
-vGetDefaultFont(font_block_type *pFont)
+vGetDefaultFont(font_block_type *pFont, USHORT usDefaultFontNumber)
 {
 	(void)memset(pFont, 0, sizeof(*pFont));
 	pFont->usFontSize = DEFAULT_FONT_SIZE;
+	if (usDefaultFontNumber <= (USHORT)UCHAR_MAX) {
+		pFont->ucFontNumber = (UCHAR)usDefaultFontNumber;
+	} else {
+		DBG_DEC(usDefaultFontNumber);
+		DBG_FIXME();
+		pFont->ucFontNumber = 0;
+	}
 } /* end of vGetDefaultFont */
 
 /*
@@ -83,26 +90,6 @@ iGetStyleIndex(USHORT usIstd)
 	return -1;
 } /* end of iGetStyleIndex */
 
-/*
- * Convert a stylecode (stc) as used by WinWord 2 into a styleindex (istd)
- * as used by Word 6 and up
- */
-USHORT
-usStc2istd(UCHAR ucStc)
-{
-	/* Old nil style to new nil style */
-	if (ucStc == 222) {
-		return STI_NIL;
-	}
-	/* Heading 1 through 9 must become istd 1 through 9 */
-	/* so 254 through 246 must become 1 through 9 and vice versa */
-	if ((ucStc >= 1 && ucStc <= 9) ||
-	    (ucStc >= 246 && ucStc <= 254)) {
-		return 255 - (USHORT)ucStc;
-	}
-	return (USHORT)ucStc;
-} /* end of usStd2istd */
-
 /*
  * Get a build-in style for Winword 1/2
  */
@@ -114,7 +101,7 @@ vGetBuildinStyle(UCHAR ucStc, style_block_type *pStyle)
 	/* Start with de defaults */
 	vGetDefaultStyle(pStyle);
 
-	/* Add the build-in style */
+	/* Add the build-in style info */
 	switch (ucStc) {
 	case 246:
 	case 247:
@@ -155,9 +142,9 @@ vGetBuildinFont(UCHAR ucStc, font_block_type *pFont)
 	fail(pFont == NULL);
 
 	/* Start with de defaults */
-	vGetDefaultFont(pFont);
+	vGetDefaultFont(pFont, 0);
 
-	/* Add the build-in fontstyle */
+	/* Add the build-in fontstyle info */
 	switch (ucStc) {
 	case 223:
 	case 244:
@@ -197,6 +184,27 @@ vGetBuildinFont(UCHAR ucStc, font_block_type *pFont)
 	}
 } /* end of vGetBuildinFont */
 
+/*
+ * Convert a stylecode (stc) as used by WinWord 1/2 into a styleindex (istd)
+ * as used by Word 6 and up
+ */
+USHORT
+usStc2istd(UCHAR ucStc)
+{
+	/* Old nil style to new nil style */
+	if (ucStc == 222) {
+		return STI_NIL;
+	}
+
+	/* Heading 1 through 9 must become istd 1 through 9 */
+	/* so 254 through 246 must become 1 through 9 and vice versa */
+	if ((ucStc >= 1 && ucStc <= 9) ||
+	    (ucStc >= 246 && ucStc <= 254)) {
+		return 255 - (USHORT)ucStc;
+	}
+	return (USHORT)ucStc;
+} /* end of usStd2istd */
+
 /*
  * Build the lists with Stylesheet Information for WinWord 1/2 files
  */
@@ -207,8 +215,8 @@ vGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 	font_block_type		*pFont;
 	UCHAR	*aucBuffer;
 	ULONG	ulBeginStshInfo;
-	size_t	tStshInfoLen, tName, tChpx, tPapx;
-	int	iStIndex, iChpxIndex, iPapxIndex, iMaxIndex, iSt, iChpx, iPapx;
+	size_t	tStshInfoLen, tName, tChpx, tPapx, tMaxIndex;
+	int	iStIndex, iChpxIndex, iPapxIndex, iSt, iChpx, iPapx;
 	int	iStd, iIndex, iBaseStyleIndex, iCounter;
 	USHORT	usBaseStyle;
 	UCHAR	ucStc, ucStcNext, ucStcBase;
@@ -228,14 +236,22 @@ vGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 	}
 	NO_DBG_PRINT_BLOCK(aucBuffer, tStshInfoLen);
 
+	fail(2 > tStshInfoLen);
 	iStd = (int)usGetWord(0, aucBuffer);
+
+	fail(2 + 2 > tStshInfoLen);
 	tName = (size_t)usGetWord(2, aucBuffer);
+
+	fail(2 + tName + 2 > tStshInfoLen);
 	tChpx = (size_t)usGetWord(2 + tName, aucBuffer);
+
+	fail(2 + tName + tChpx + 2 > tStshInfoLen);
 	tPapx = (size_t)usGetWord(2 + tName + tChpx, aucBuffer);
+
+	fail(2 + tName + tChpx + tPapx + 2 > tStshInfoLen);
 	tStdCount = (size_t)usGetWord(2 + tName + tChpx + tPapx, aucBuffer);
 
 	NO_DBG_HEX(tStdCount);
-	fail(2 + tName + tChpx + tPapx + 2 + 2 * tStdCount > tStshInfoLen);
 
 	atStyleInfo = xcalloc(tStdCount, sizeof(style_block_type));
 	atFontInfo = xcalloc(tStdCount, sizeof(font_block_type));
@@ -246,7 +262,7 @@ vGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 		iStIndex = 2 + 2;
 		iChpxIndex = 2 + (int)tName + 2;
 		iPapxIndex = 2 + (int)tName + (int)tChpx + 2;
-		iMaxIndex = 2 + (int)tName + (int)tChpx + (int)tPapx + 2;
+		tMaxIndex = 2 + tName + tChpx + tPapx + 2;
 		/* Read the styles one-by-one */
 		for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) {
 			pStyle = &atStyleInfo[iIndex];
@@ -257,17 +273,17 @@ vGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 			NO_DBG_HEX(iSt);
 			NO_DBG_HEX(iChpx);
 			NO_DBG_HEX(iPapx);
-			if (iSt == 0xff) {
-				/* Undefined style */
+			if (iSt == 0xff || tMaxIndex + 1 >= tStshInfoLen) {
+				/* Undefined style or no information */
 				iStIndex++;
 				iChpxIndex++;
 				iPapxIndex++;
-				iMaxIndex += 2;
+				tMaxIndex += 2;
 				if (!abFilled[iIndex]) {
 					DBG_HEX_C(iChpx != 0xff, iChpx);
 					DBG_HEX_C(iPapx != 0xff, iPapx);
 					vGetDefaultStyle(pStyle);
-					vGetDefaultFont(pFont);
+					vGetDefaultFont(pFont, 0);
 					abFilled[iIndex] = TRUE;
 				}
 				continue;
@@ -276,8 +292,8 @@ vGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 			NO_DBG_STRN(aucBuffer + iStIndex + 1, iSt);
 			iStIndex += iSt + 1;
 
-			ucStcNext = ucGetByte(iMaxIndex, aucBuffer);
-			ucStcBase = ucGetByte(iMaxIndex + 1, aucBuffer);
+			ucStcNext = ucGetByte(tMaxIndex, aucBuffer);
+			ucStcBase = ucGetByte(tMaxIndex + 1, aucBuffer);
 			ucStc = (UCHAR)((iIndex - iStd) & 0xff);
 			NO_DBG_DEC(ucStc);
 
@@ -285,7 +301,7 @@ vGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 				/* Use a build-in style */
 				iChpxIndex++;
 				iPapxIndex++;
-				iMaxIndex += 2;
+				tMaxIndex += 2;
 				if (!abFilled[iIndex]) {
 					DBG_HEX_C(iChpx != 0xff, iChpx);
 					DBG_HEX_C(iPapx != 0xff, iPapx);
@@ -303,7 +319,7 @@ vGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 				/* This record has already been filled */
 				iChpxIndex += iChpx + 1;
 				iPapxIndex += iPapx + 1;
-				iMaxIndex += 2;
+				tMaxIndex += 2;
 				continue;
 			}
 
@@ -312,7 +328,7 @@ vGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 			if (usBaseStyle == STI_NIL) {
 				/* Based on the Nil style */
 				vGetDefaultStyle(pStyle);
-				vGetDefaultFont(pFont);
+				vGetDefaultFont(pFont, 0);
 			} else {
 				iBaseStyleIndex = iGetStyleIndex(usBaseStyle);
 				NO_DBG_DEC(iBaseStyleIndex);
@@ -320,7 +336,7 @@ vGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 					/* This style is not known yet */
 					iChpxIndex += iChpx + 1;
 					iPapxIndex += iPapx + 1;
-					iMaxIndex += 2;
+					tMaxIndex += 2;
 					continue;
 				}
 				fail(iBaseStyleIndex >= (int)tStdCount);
@@ -370,20 +386,22 @@ vGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 				iPapxIndex += iPapx + 1;
 				break;
 			}
-			iMaxIndex += 2;
+			tMaxIndex += 2;
 
 		}
 		NO_DBG_DEC(iCounter);
 	} while (iCounter > 0);
 
+	/* Fill records that are still empty */
 	for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) {
 		if (!abFilled[iIndex]) {
 			NO_DBG_DEC(iIndex);
 			vGetDefaultStyle(&atStyleInfo[iIndex]);
-			vGetDefaultFont(&atFontInfo[iIndex]);
+			vGetDefaultFont(&atFontInfo[iIndex], 0);
 		}
 	}
 
+	/* Clean up before you leave */
 	abFilled = xfree(abFilled);
 	aucBuffer = xfree(aucBuffer);
 } /* end of vGet2Stylesheet */
@@ -403,6 +421,7 @@ vGet6Stylesheet(FILE *pFile, ULONG ulStartBlock,
 	size_t	tPos, tNameLen, tUpxLen;
 	int	iIndex, iBaseStyleIndex, iCounter;
 	USHORT	usTmp, usUpxCount, usStyleType, usBaseStyle;
+	USHORT	usFtcStandardChpStsh;
 
 	fail(pFile == NULL || aucHeader == NULL);
 	fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
@@ -425,6 +444,8 @@ vGet6Stylesheet(FILE *pFile, ULONG ulStartBlock,
 	tStdCount = (size_t)usGetWord(2, aucBuffer);
 	NO_DBG_DEC(tStdCount);
 	tStdBaseInFile = (size_t)usGetWord(4, aucBuffer);
+	usFtcStandardChpStsh = usGetWord(14, aucBuffer);
+	NO_DBG_DEC(usFtcStandardChpStsh);
 
 	atStyleInfo = xcalloc(tStdCount, sizeof(style_block_type));
 	atFontInfo = xcalloc(tStdCount, sizeof(font_block_type));
@@ -448,7 +469,7 @@ vGet6Stylesheet(FILE *pFile, ULONG ulStartBlock,
 			if (tStdLen == 0) {
 				/* Empty record */
 				vGetDefaultStyle(pStyle);
-				vGetDefaultFont(pFont);
+				vGetDefaultFont(pFont, usFtcStandardChpStsh);
 				abFilled[iIndex] = TRUE;
 				continue;
 			}
@@ -460,7 +481,7 @@ vGet6Stylesheet(FILE *pFile, ULONG ulStartBlock,
 			if (usBaseStyle == STI_NIL || usBaseStyle == STI_USER) {
 				/* Based on the Nil style */
 				vGetDefaultStyle(pStyle);
-				vGetDefaultFont(pFont);
+				vGetDefaultFont(pFont, usFtcStandardChpStsh);
 			} else {
 				iBaseStyleIndex = iGetStyleIndex(usBaseStyle);
 				NO_DBG_DEC(iBaseStyleIndex);
@@ -551,14 +572,17 @@ vGet6Stylesheet(FILE *pFile, ULONG ulStartBlock,
 		NO_DBG_DEC(iCounter);
 	} while (iCounter > 0);
 
+	/* Fill records that are still empty */
 	for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) {
 		if (!abFilled[iIndex]) {
 			NO_DBG_DEC(iIndex);
 			vGetDefaultStyle(&atStyleInfo[iIndex]);
-			vGetDefaultFont(&atFontInfo[iIndex]);
+			vGetDefaultFont(&atFontInfo[iIndex],
+					usFtcStandardChpStsh);
 		}
 	}
 
+	/* Clean up before you leave */
 	abFilled = xfree(abFilled);
 	aucBuffer = xfree(aucBuffer);
 } /* end of vGet6Stylesheet */
@@ -577,11 +601,11 @@ vGet8Stylesheet(FILE *pFile, const pps_info_type *pPPS,
 	const ULONG	*aulBlockDepot;
 	UCHAR	*aucBuffer;
 	ULONG	ulBeginStshInfo;
-	ULONG	ulTableSize, ulTableStartBlock;
 	size_t	tStshInfoLen, tBlockDepotLen, tOffset, tStdLen, tStdBaseInFile;
 	size_t	tBlockSize, tPos, tNameLen, tUpxLen;
 	int	iIndex, iBaseStyleIndex, iCounter;
-	USHORT	usDocStatus, usTmp, usUpxCount, usStyleType, usBaseStyle;
+	USHORT	usTmp, usUpxCount, usStyleType, usBaseStyle;
+	USHORT	usFtcStandardChpStsh;
 
 	fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
 	fail(aulBBD == NULL || aulSBD == NULL);
@@ -591,22 +615,14 @@ vGet8Stylesheet(FILE *pFile, const pps_info_type *pPPS,
 	tStshInfoLen = (size_t)ulGetLong(0xa6, aucHeader); /* lcbStshf */
 	NO_DBG_DEC(tStshInfoLen);
 
-	/* Use 0Table or 1Table? */
-	usDocStatus = usGetWord(0x0a, aucHeader);
-	if (usDocStatus & BIT(9)) {
-		ulTableStartBlock = pPPS->t1Table.ulSB;
-		ulTableSize = pPPS->t1Table.ulSize;
-	} else {
-		ulTableStartBlock = pPPS->t0Table.ulSB;
-		ulTableSize = pPPS->t0Table.ulSize;
-	}
-	NO_DBG_DEC(ulTableStartBlock);
-	if (ulTableStartBlock == 0) {
+	NO_DBG_DEC(pPPS->tTable.ulSB);
+	NO_DBG_HEX(pPPS->tTable.ulSize);
+	if (pPPS->tTable.ulSize == 0) {
 		DBG_MSG("No stylesheet information");
 		return;
 	}
-	NO_DBG_HEX(ulTableSize);
-	if (ulTableSize < MIN_SIZE_FOR_BBD_USE) {
+
+	if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
 		/* Use the Small Block Depot */
 		aulBlockDepot = aulSBD;
 		tBlockDepotLen = tSBDLen;
@@ -618,7 +634,7 @@ vGet8Stylesheet(FILE *pFile, const pps_info_type *pPPS,
 		tBlockSize = BIG_BLOCK_SIZE;
 	}
 	aucBuffer = xmalloc(tStshInfoLen);
-	if (!bReadBuffer(pFile, ulTableStartBlock,
+	if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
 			aulBlockDepot, tBlockDepotLen, tBlockSize,
 			aucBuffer, ulBeginStshInfo, tStshInfoLen)) {
 		aucBuffer = xfree(aucBuffer);
@@ -629,6 +645,8 @@ vGet8Stylesheet(FILE *pFile, const pps_info_type *pPPS,
 	tStdCount = (size_t)usGetWord(2, aucBuffer);
 	NO_DBG_DEC(tStdCount);
 	tStdBaseInFile = (size_t)usGetWord(4, aucBuffer);
+	usFtcStandardChpStsh = usGetWord(14, aucBuffer);
+	NO_DBG_DEC(usFtcStandardChpStsh);
 
 	atStyleInfo = xcalloc(tStdCount, sizeof(style_block_type));
 	atFontInfo = xcalloc(tStdCount, sizeof(font_block_type));
@@ -652,7 +670,7 @@ vGet8Stylesheet(FILE *pFile, const pps_info_type *pPPS,
 			if (tStdLen == 0) {
 				/* Empty record */
 				vGetDefaultStyle(pStyle);
-				vGetDefaultFont(pFont);
+				vGetDefaultFont(pFont, usFtcStandardChpStsh);
 				abFilled[iIndex] = TRUE;
 				continue;
 			}
@@ -664,7 +682,7 @@ vGet8Stylesheet(FILE *pFile, const pps_info_type *pPPS,
 			if (usBaseStyle == STI_NIL || usBaseStyle == STI_USER) {
 				/* Based on the Nil style */
 				vGetDefaultStyle(pStyle);
-				vGetDefaultFont(pFont);
+				vGetDefaultFont(pFont, usFtcStandardChpStsh);
 			} else {
 				iBaseStyleIndex = iGetStyleIndex(usBaseStyle);
 				NO_DBG_DEC(iBaseStyleIndex);
@@ -757,14 +775,17 @@ vGet8Stylesheet(FILE *pFile, const pps_info_type *pPPS,
 		NO_DBG_DEC(iCounter);
 	} while (iCounter > 0);
 
+	/* Fill records that are still empty */
 	for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) {
 		if (!abFilled[iIndex]) {
 			NO_DBG_DEC(iIndex);
 			vGetDefaultStyle(&atStyleInfo[iIndex]);
-			vGetDefaultFont(&atFontInfo[iIndex]);
+			vGetDefaultFont(&atFontInfo[iIndex],
+					usFtcStandardChpStsh);
 		}
 	}
 
+	/* Clean up before you leave */
 	abFilled = xfree(abFilled);
 	aucBuffer = xfree(aucBuffer);
 } /* end of vGet8Stylesheet */
@@ -813,5 +834,5 @@ vFillFontFromStylesheet(USHORT usIstd, font_block_type *pFont)
 		}
 	}
 
-	vGetDefaultFont(pFont);
+	vGetDefaultFont(pFont, 0);
 } /* end of vFillFontFromStylesheet */

+ 85 - 44
sys/src/cmd/aux/antiword/summary.c

@@ -1,6 +1,6 @@
 /*
  * summary.c
- * Copyright (C) 2002,2003 A.J. van Os; Released under GNU GPL
+ * Copyright (C) 2002-2005 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Read the summary information of a Word document
@@ -49,7 +49,7 @@ static USHORT	usLid = (USHORT)-1;
 void
 vDestroySummaryInfo(void)
 {
-	DBG_MSG("vDestroySummaryInfo");
+	TRACE_MSG("vDestroySummaryInfo");
 
 	szTitle = xfree(szTitle);
 	szSubject = xfree(szSubject);
@@ -134,33 +134,6 @@ tConvertDosDate(const char *szDosDate)
 	return tResult;
 } /* end of tConvertDosDate */
 
-/*
- * tConvertDTTM - convert Windows Date and Time format
- *
- * returns Unix time_t or -1
- */
-static time_t
-tConvertDTTM(ULONG ulDTTM)
-{
-	struct tm	tTime;
-	time_t		tResult;
-
-	if (ulDTTM == 0) {
-		return (time_t)-1;
-	}
-	memset(&tTime, 0, sizeof(tTime));
-	tTime.tm_min = (int)(ulDTTM & 0x0000003f);
-	tTime.tm_hour = (int)((ulDTTM & 0x000007c0) >> 6);
-	tTime.tm_mday = (int)((ulDTTM & 0x0000f800) >> 11);
-	tTime.tm_mon = (int)((ulDTTM & 0x000f0000) >> 16);
-	tTime.tm_year = (int)((ulDTTM & 0x1ff00000) >> 20);
-	tTime.tm_isdst = -1;
-	tTime.tm_mon--;		/* From 01-12 to 00-11 */
-	tResult = mktime(&tTime);
-	NO_DBG_MSG(ctime(&tResult));
-	return tResult;
-} /* end of tConvertDTTM */
-
 /*
  * szLpstr - get a zero terminate string property
  */
@@ -168,14 +141,17 @@ static char *
 szLpstr(ULONG ulOffset, const UCHAR *aucBuffer)
 {
 	char	*szStart, *szResult, *szTmp;
-	size_t	tTmp;
+	size_t	tSize;
 
-	tTmp = (size_t)ulGetLong(ulOffset + 4, aucBuffer);
-	NO_DBG_DEC(tTmp);
-	NO_DBG_MSG(aucBuffer + ulOffset + 8);
+	tSize = (size_t)ulGetLong(ulOffset + 4, aucBuffer);
+	NO_DBG_DEC(tSize);
+	if (tSize == 0) {
+		return NULL;
+	}
 	/* Remove white space from the start of the string */
 	szStart = (char *)aucBuffer + ulOffset + 8;
-	fail(strlen(szStart) >= tTmp);
+	NO_DBG_MSG(szStart);
+	fail(strlen(szStart) >= tSize);
 	while (isspace(*szStart)) {
 		szStart++;
 	}
@@ -229,7 +205,7 @@ tFiletime(ULONG ulOffset, const UCHAR *aucBuffer)
 } /* end of tFiletime */
 
 /*
- * vAnalyseSummaryInfo -
+ * vAnalyseSummaryInfo - analyse the summary information
  */
 static void
 vAnalyseSummaryInfo(const UCHAR *aucBuffer)
@@ -286,7 +262,7 @@ vAnalyseSummaryInfo(const UCHAR *aucBuffer)
 } /* end of vAnalyseSummaryInfo */
 
 /*
- * vAnalyseDocumentSummaryInfo -
+ * vAnalyseDocumentSummaryInfo - analyse the document summary information
  */
 static void
 vAnalyseDocumentSummaryInfo(const UCHAR *aucBuffer)
@@ -451,6 +427,8 @@ vSet0SummaryInfo(FILE *pFile, const UCHAR *aucHeader)
 	size_t	tLen;
 	USHORT	usCodepage, usOffset;
 
+	TRACE_MSG("vSet0SummaryInfo");
+
 	fail(pFile == NULL || aucHeader == NULL);
 
 	/* First check the header */
@@ -514,6 +492,8 @@ vSet2SummaryInfo(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 	ULONG	ulBeginSumdInfo, ulBeginDocpInfo, ulTmp;
 	size_t	tSumdInfoLen, tDocpInfoLen, tLen, tCounter, tStart;
 
+	TRACE_MSG("vSet2SummaryInfo");
+
 	fail(pFile == NULL || aucHeader == NULL);
 	fail(iWordVersion != 1 && iWordVersion != 2);
 
@@ -522,13 +502,21 @@ vSet2SummaryInfo(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 	DBG_HEX(usLid);
 	if (usLid < 999 && iWordVersion == 1) {
 		switch (usLid) {
-		case  1: usLid = 0x0409; break;	/* American English */
-		case  2: usLid = 0x0c0c; break;	/* Canadian French */
-		case 31: usLid = 0x0413; break;	/* Dutch */
-		case 33: usLid = 0x040c; break;	/* French */
-		case 34: usLid = 0x040a; break;	/* Spanish */
-		case 44: usLid = 0x0809; break;	/* British English */
-		case 49: usLid = 0x0407; break;	/* German */
+		case   1: usLid = 0x0409; break;	/* American English */
+		case   2: usLid = 0x0c0c; break;	/* Canadian French */
+		case  31: usLid = 0x0413; break;	/* Dutch */
+		case  33: usLid = 0x040c; break;	/* French */
+		case  34: usLid = 0x040a; break;	/* Spanish */
+		case  36: usLid = 0x040e; break;	/* Hungarian */
+		case  39: usLid = 0x0410; break;	/* Italian */
+		case  44: usLid = 0x0809; break;	/* British English */
+		case  45: usLid = 0x0406; break;	/* Danish */
+		case  46: usLid = 0x041f; break;	/* Swedish */
+		case  47: usLid = 0x0414; break;	/* Norwegian */
+		case  48: usLid = 0x0415; break;	/* Polish */
+		case  49: usLid = 0x0407; break;	/* German */
+		case 351: usLid = 0x0816; break;	/* Portuguese */
+		case 358: usLid = 0x040b; break;	/* Finnish */
 		default:
 			DBG_DEC(usLid);
 			DBG_FIXME();
@@ -537,6 +525,11 @@ vSet2SummaryInfo(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 		}
 	}
 
+	if (iWordVersion != 2) {
+		/* Unknown where to find the associated strings */
+		return;
+	}
+
 	/* Second check the associated strings */
 	ulBeginSumdInfo = ulGetLong(0x118, aucHeader); /* fcSttbfAssoc */
 	DBG_HEX(ulBeginSumdInfo);
@@ -558,7 +551,7 @@ vSet2SummaryInfo(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
 	DBG_DEC_C(tSumdInfoLen != tLen, tSumdInfoLen);
 	DBG_DEC_C(tSumdInfoLen != tLen, tLen);
 	tStart = 1;
-	for (tCounter = 0; tCounter < 18; tCounter++) {
+	for (tCounter = 0; tCounter < 17; tCounter++) {
 		if (tStart >= tSumdInfoLen) {
 			break;
 		}
@@ -655,6 +648,8 @@ vSet6SummaryInfo(FILE *pFile, const pps_info_type *pPPS,
 	const ULONG *aulSBD, size_t tSBDLen,
 	const UCHAR *aucHeader)
 {
+	TRACE_MSG("vSet6SummaryInfo");
+
 	/* Header Information */
 	usLid = usGetWord(0x06, aucHeader); /* Language IDentification */
 	DBG_HEX(usLid);
@@ -674,6 +669,8 @@ vSet8SummaryInfo(FILE *pFile, const pps_info_type *pPPS,
 {
 	USHORT	usTmp;
 
+	TRACE_MSG("vSet8SummaryInfo");
+
 	/* Header Information */
 	usTmp = usGetWord(0x0a, aucHeader);
 	if (usTmp & BIT(14)) {
@@ -737,6 +734,50 @@ szGetLastSaveDtm(void)
 	return szTime;
 } /* end of szGetLastSaveDtm */
 
+/*
+ * szGetModDate - get the last save date field
+ */
+const char *
+szGetModDate(void)
+{
+	static char	szTime[20];
+	struct tm	*pTime;
+
+	if (tLastSaveDtm == (time_t)-1) {
+		return NULL;
+	}
+	pTime = localtime(&tLastSaveDtm);
+	if (pTime == NULL) {
+		return NULL;
+	}
+	sprintf(szTime, "D:%04d%02d%02d%02d%02d",
+		pTime->tm_year + 1900, pTime->tm_mon + 1, pTime->tm_mday,
+		pTime->tm_hour, pTime->tm_min);
+	return szTime;
+} /* end of szGetModDate */
+
+/*
+ * szGetCreationDate - get the last save date field
+ */
+const char *
+szGetCreationDate(void)
+{
+	static char	szTime[20];
+	struct tm	*pTime;
+
+	if (tCreateDtm == (time_t)-1) {
+		return NULL;
+	}
+	pTime = localtime(&tCreateDtm);
+	if (pTime == NULL) {
+		return NULL;
+	}
+	sprintf(szTime, "D:%04d%02d%02d%02d%02d",
+		pTime->tm_year + 1900, pTime->tm_mon + 1, pTime->tm_mday,
+		pTime->tm_hour, pTime->tm_min);
+	return szTime;
+} /* end of szGetCreationDate */
+
 /*
  * szGetCompany - get the company field
  */

+ 10 - 18
sys/src/cmd/aux/antiword/tabstop.c

@@ -1,6 +1,6 @@
 /*
  * tabstops.c
- * Copyright (C) 1999-2002 A.J. van Os; Released under GPL
+ * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Read the tab stop information from a MS Word file
@@ -109,9 +109,8 @@ vSet8DefaultTabWidth(FILE *pFile, const pps_info_type *pPPS,
         const ULONG	*aulBlockDepot;
 	UCHAR	*aucBuffer;
 	ULONG	ulBeginDocpInfo;
-	ULONG	ulTableSize, ulTableStartBlock;
 	size_t	tDocpInfoLen, tBlockDepotLen, tBlockSize;
-	USHORT	usDocStatus, usTmp;
+	USHORT	usTmp;
 
 	ulBeginDocpInfo = ulGetLong(0x192, aucHeader); /* fcDop */
 	DBG_HEX(ulBeginDocpInfo);
@@ -122,23 +121,14 @@ vSet8DefaultTabWidth(FILE *pFile, const pps_info_type *pPPS,
 		return;
 	}
 
-	/* Use 0Table or 1Table? */
-	usDocStatus = usGetWord(0x0a, aucHeader);
-	if (usDocStatus & BIT(9)) {
-		ulTableStartBlock = pPPS->t1Table.ulSB;
-		ulTableSize = pPPS->t1Table.ulSize;
-	} else {
-		ulTableStartBlock = pPPS->t0Table.ulSB;
-		ulTableSize = pPPS->t0Table.ulSize;
-	}
-	DBG_DEC(ulTableStartBlock);
-	if (ulTableStartBlock == 0) {
-		DBG_DEC(ulTableStartBlock);
+	DBG_DEC(pPPS->tTable.ulSB);
+	DBG_HEX(pPPS->tTable.ulSize);
+	if (pPPS->tTable.ulSize == 0) {
 		DBG_MSG("No TAB information");
 		return;
 	}
-	DBG_HEX(ulTableSize);
-	if (ulTableSize < MIN_SIZE_FOR_BBD_USE) {
+
+	if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
 		/* Use the Small Block Depot */
 		aulBlockDepot = aulSBD;
 		tBlockDepotLen = tSBDLen;
@@ -150,7 +140,7 @@ vSet8DefaultTabWidth(FILE *pFile, const pps_info_type *pPPS,
 		tBlockSize = BIG_BLOCK_SIZE;
 	}
 	aucBuffer = xmalloc(tDocpInfoLen);
-	if (!bReadBuffer(pFile, ulTableStartBlock,
+	if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
 			aulBlockDepot, tBlockDepotLen, tBlockSize,
 			aucBuffer, ulBeginDocpInfo, tDocpInfoLen)) {
 		aucBuffer = xfree(aucBuffer);
@@ -206,6 +196,7 @@ vSetDefaultTabWidth(FILE *pFile, const pps_info_type *pPPS,
 	}
 } /* end of vSetDefaultTabWidth */
 
+#if 0
 /*
  * lGetDefaultTabWidth - Get the default tabwidth in millipoints
  */
@@ -218,3 +209,4 @@ lGetDefaultTabWidth(void)
 	}
 	return lDefaultTabWidth;
 } /* end of lGetDefaultTabWidth */
+#endif

BIN
sys/src/cmd/aux/antiword/testdoc.doc


+ 7 - 7
sys/src/cmd/aux/antiword/text.c

@@ -1,6 +1,6 @@
 /*
  * text.c
- * Copyright (C) 1999-2003 A.J. van Os; Released under GNU GPL
+ * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Functions to deal with the Text format
@@ -59,13 +59,13 @@ vPrintTXT(FILE *pFile, const char *szString, size_t tStringLength)
 		return;
 	}
 
-	if (eEncoding == encoding_utf8) {
+	if (eEncoding == encoding_utf_8) {
 		fprintf(pFile, "%.*s", (int)tStringLength, szString);
 		return;
 	}
 
 	if (ucNbsp == 0) {
-		ucNbsp = ucGetNbspValue();
+		ucNbsp = ucGetNbspCharacter();
 		DBG_HEX_C(ucNbsp != 0xa0, ucNbsp);
 	}
 
@@ -80,13 +80,13 @@ vPrintTXT(FILE *pFile, const char *szString, size_t tStringLength)
 } /* end of vPrintTXT */
 
 /*
- * vMoveToTXT - move to the given X,Y coordinates (Text)
+ * vMoveTo - move to the given X,Y coordinates
  *
  * Move the current position of the given diagram to its X,Y coordinates,
  * start on a new page if needed
  */
 static void
-vMoveToTXT(diagram_type *pDiag)
+vMoveTo(diagram_type *pDiag)
 {
 	int	iCount, iNbr;
 
@@ -100,7 +100,7 @@ vMoveToTXT(diagram_type *pDiag)
 		}
 		lYtopCurr = pDiag->lYtop;
 	}
-} /* end of vMoveToTXT */
+} /* end of vMoveTo */
 
 /*
  * vMove2NextLineTXT - move to the next line
@@ -131,7 +131,7 @@ vSubstringTXT(diagram_type *pDiag,
 		return;
 	}
 
-	vMoveToTXT(pDiag);
+	vMoveTo(pDiag);
 	vPrintTXT(pDiag->pOutFile, szString, tStringLength);
 	pDiag->lXleft += lStringWidth;
 } /* end of vSubstringTXT */

+ 4 - 4
sys/src/cmd/aux/antiword/unix.c

@@ -35,11 +35,11 @@ werr(int iFatal, const char *szFormat, ...)
 } /* end of werr */
 
 void
-visdelay_begin(void)
+Hourglass_On(void)
 {
-} /* end of visdelay_begin */
+} /* end of Hourglass_On */
 
 void
-visdelay_end(void)
+Hourglass_Off(void)
 {
-} /* end of visdelay_end */
+} /* end of Hourglass_Off */

+ 58 - 96
sys/src/cmd/aux/antiword/utf8.c

@@ -1,6 +1,6 @@
 /*
  * utf8.c
- * Copyright (C) 2001-2003 A.J. van Os; Released under GPL
+ * Copyright (C) 2001-2004 A.J. van Os; Released under GPL
  *
  *====================================================================
  * This part of the software is based on:
@@ -154,42 +154,45 @@ iWcWidth(ULONG ucs)
  * Fills in the number of bytes in the UTF-8 character
  */
 static ULONG
-utf8_to_ucs(const char *p, int *utflen)
+utf8_to_ucs(const char *p, int iStrLen, int *piUtfLen)
 {
-	ULONG	wc;
-	int	j, charlen;
+	ULONG	ulUcs;
+	int	iIndex, iCharLen;
 
-	fail(p == NULL || utflen == NULL);
+	fail(p == NULL || piUtfLen == NULL);
+	fail(iStrLen < 1);
 
-	wc = (ULONG)(UCHAR)p[0];
+	ulUcs = (ULONG)(UCHAR)p[0];
 
-	if (wc < 0x80) {
-		*utflen = 1;
-		return wc;
+	if (ulUcs < 0x80) {
+		*piUtfLen = 1;
+		return ulUcs;
 	}
 
-	if (wc < 0xe0){
-		charlen = 2;
-		wc &= 0x1f;
-	} else if (wc < 0xf0){
-		charlen = 3;
-		wc &= 0x0f;
-	} else if (wc < 0xf8){
-		charlen = 4;
-		wc &= 0x07;
-	} else if (wc < 0xfc){
-		charlen = 5;
-		wc &= 0x03;
+	if (ulUcs < 0xe0){
+		iCharLen = 2;
+		ulUcs &= 0x1f;
+	} else if (ulUcs < 0xf0){
+		iCharLen = 3;
+		ulUcs &= 0x0f;
+	} else if (ulUcs < 0xf8){
+		iCharLen = 4;
+		ulUcs &= 0x07;
+	} else if (ulUcs < 0xfc){
+		iCharLen = 5;
+		ulUcs &= 0x03;
 	} else {
-		charlen = 6;
-		wc &= 0x01;
+		iCharLen = 6;
+		ulUcs &= 0x01;
 	}
-	for (j = 1; j < charlen; j++) {
-		wc <<= 6;
-		wc |= (UCHAR)p[j] & 0x3f;
+	for (iIndex = 1; iIndex < iCharLen; iIndex++) {
+		ulUcs <<= 6;
+		if (iIndex < iStrLen) {
+			ulUcs |= (ULONG)(UCHAR)p[iIndex] & 0x3f;
+		}
 	}
-	*utflen = charlen;
-	return wc;
+	*piUtfLen = iCharLen;
+	return ulUcs;
 } /* end of utf8_to_ucs */
 
 /*
@@ -198,28 +201,28 @@ utf8_to_ucs(const char *p, int *utflen)
  * Returns the string width in columns
  */
 long
-utf8_strwidth(const char *p, size_t numchars)
+utf8_strwidth(const char *pcString, size_t tNumchars)
 {
-	const char	*maxp;
-	ULONG	ucs;
-	long	width, totwidth;
-	int	utflen;
+	ULONG	ulUcs;
+	long	lTotal;
+	int	iToGo, iWidth, iUtflen;
 
-	fail(p == NULL);
+	fail(pcString == NULL || tNumchars > (size_t)INT_MAX);
 
-	totwidth = 0;
-	maxp = p + numchars;
+	lTotal = 0;
+	iToGo = (int)tNumchars;
 
-	while (*p != '\0' && p < maxp) {
-		ucs = utf8_to_ucs(p, &utflen);
-		width = iWcWidth(ucs);
-		if (width > 0) {
-			totwidth += width;
+	while (iToGo > 0 && *pcString != '\0') {
+		ulUcs = utf8_to_ucs(pcString, iToGo, &iUtflen);
+		iWidth = iWcWidth(ulUcs);
+		if (iWidth > 0) {
+			lTotal += iWidth;
 		}
-		p += utflen;
+		pcString += iUtflen;
+		iToGo -= iUtflen;
 	}
-	NO_DBG_DEC(totwidth);
-	return totwidth;
+	NO_DBG_DEC(lTotal);
+	return lTotal;
 } /* end of utf8_strwidth */
 
 /*
@@ -230,69 +233,28 @@ utf8_strwidth(const char *p, size_t numchars)
 int
 utf8_chrlength(const char *p)
 {
-	int	utflen;
+	int	iUtflen;
 
 	fail(p == NULL);
 
-	utflen = -1;		/* Just to make sure */
-	(void)utf8_to_ucs(p, &utflen);
-	NO_DBG_DEC(utflen);
-	return utflen;
+	iUtflen = -1;		/* Just to make sure */
+	(void)utf8_to_ucs(p, INT_MAX, &iUtflen);
+	NO_DBG_DEC(iUtflen);
+	return iUtflen;
 } /* end of utf8_chrlength */
 
 /*
- * Original version:
- * Copyright (C) 1999  Bruno Haible
+ * is_locale_utf8 - return TRUE if the locale is UTF-8
  */
 BOOL
 is_locale_utf8(void)
 {
-	const char	*locale, *cp, *encoding;
-
-	/*
-	 * Determine the current locale the same way as setlocale() does,
-	 * according to POSIX.
-	 */
-	locale = getenv("LC_ALL");
-	if (locale == NULL || locale[0] == '\0') {
-		locale = getenv("LC_CTYPE");
-		if (locale == NULL || locale[0] == '\0') {
-			locale = getenv("LANG");
-		}
-	}
-
-	if (locale == NULL || locale[0] == '\0') {
-		return FALSE;
-	}
+	char	szCodeset[20];
 
-	/* The most general syntax of a locale (not all optional parts
-	 * recognized by all systems) is
-	 * language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]]
-	 * To retrieve the codeset, search the first dot. Stop searching when
-	 * a '@' or '+' or ',' is encountered.
-	 */
-	for (cp = locale;
-	     *cp != '\0' && *cp != '@' && *cp != '+' && *cp != ',';
-	     cp++) {
-		if (*cp != '.') {
-			continue;
-		}
-		encoding = cp + 1;
-		for (cp = encoding;
-		     *cp != '\0' && *cp != '@' && *cp != '+' && *cp != ',';
-		     cp++)
-			;	/* EMPTY */
-		/*
-		 * The encoding is now contained in the part from encoding to
-		 * cp. Check it for "UTF-8", which is the only official IANA
-		 * name of UTF-8. Also check for the lowercase-no-dashes
-		 * version, which is what some SystemV systems use.
-		 */
-		if ((cp - encoding == 5 && STRNEQ(encoding, "UTF-8", 5)) ||
-		    (cp - encoding == 4 && STRNEQ(encoding, "utf8", 4))) {
-			return TRUE;
-		}
+	szCodeset[0] = '\0';
+	if (!bGetNormalizedCodeset(szCodeset, sizeof(szCodeset), NULL)) {
 		return FALSE;
 	}
-	return FALSE;
+	DBG_MSG(szCodeset);
+	return STREQ(szCodeset, "utf8");
 } /* end of is_locale_utf8 */

+ 12 - 4
sys/src/cmd/aux/antiword/version.h

@@ -1,6 +1,6 @@
 /*
  * version.h
- * Copyright (C) 1998-2003 A.J. van Os; Released under GNU GPL
+ * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Version and release information
@@ -13,12 +13,20 @@
 #define PURPOSESTRING	"Display MS-Word files"
 
 #if defined(__riscos)
-#define AUTHORSTRING	"© 1998-2003 Adri van Os"
+#define AUTHORSTRING	"© 1998-2005 Adri van Os"
 #else
-#define AUTHORSTRING	"(C) 1998-2003 Adri van Os"
+#define AUTHORSTRING	"(C) 1998-2005 Adri van Os"
 #endif /* __riscos */
 
-#define VERSIONSTRING	"0.34  (25 Aug 2003)"
+#define VERSIONSTRING	"0.37  (21 Oct 2005)"
+
+#if defined(__dos)
+#if defined(__DJGPP__)
+#define VERSIONSTRING2	" # 32-bit Protected Mode"
+#else
+#define VERSIONSTRING2	" # 16-bit Real Mode"
+#endif /* __DJGPP__ */
+#endif /* __dos */
 
 #if defined(DEBUG)
 #define STATUSSTRING	"DEBUG version"

+ 394 - 61
sys/src/cmd/aux/antiword/word2text.c

@@ -1,9 +1,9 @@
 /*
  * word2text.c
- * Copyright (C) 1998-2003 A.J. van Os; Released under GNU GPL
+ * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
  *
  * Description:
- * MS Word to text functions
+ * MS Word to "text" functions
  */
 
 #include <stdio.h>
@@ -11,7 +11,8 @@
 #include <string.h>
 #include <ctype.h>
 #if defined(__riscos)
-#include "visdelay.h"
+#include "DeskLib:Hourglass.h"
+#include "drawfile.h"
 #endif /* __riscos */
 #include "antiword.h"
 
@@ -24,6 +25,7 @@
 #define OUTPUT_LINE()		\
 	do {\
 		vAlign2Window(pDiag, pAnchor, lWidthMax, ucAlignment);\
+		TRACE_MSG("after vAlign2Window");\
 		pAnchor = pStartNewOutput(pAnchor, NULL);\
 		pOutput = pAnchor;\
 	} while(0)
@@ -43,7 +45,7 @@ static int	iCurrPct, iPrevPct;
 #endif /* __riscos */
 /* The document is in the format belonging to this version of Word */
 static int	iWordVersion = -1;
-/* Special treatment for files from Word 6 on an Apple Macintosh */
+/* Special treatment for files from Word 4/5/6 on an Apple Macintosh */
 static BOOL	bOldMacFile = FALSE;
 /* Section Information */
 static const section_block_type	*pSection = NULL;
@@ -82,7 +84,7 @@ vUpdateCounters(void)
 	ulCharCounter++;
 	iCurrPct = (int)((ulCharCounter * 100) / ulDocumentLength);
 	if (iCurrPct != iPrevPct) {
-		visdelay_percent(iCurrPct);
+		Hourglass_Percentage(iCurrPct);
 		iPrevPct = iCurrPct;
 	}
 #endif /* __riscos */
@@ -91,10 +93,10 @@ vUpdateCounters(void)
 /*
  * bOutputContainsText - see if the output contains more than white space
  */
-static BOOL
-bOutputContainsText(output_type *pAnchor)
+BOOL
+bOutputContainsText(const output_type *pAnchor)
 {
-	output_type	*pCurr;
+	const output_type	*pCurr;
 	size_t	tIndex;
 
 	fail(pAnchor == NULL);
@@ -120,9 +122,9 @@ bOutputContainsText(output_type *pAnchor)
  * lTotalStringWidth - compute the total width of the output string
  */
 static long
-lTotalStringWidth(output_type *pAnchor)
+lTotalStringWidth(const output_type *pAnchor)
 {
-	output_type	*pCurr;
+	const output_type	*pCurr;
 	long		lTotal;
 
 	lTotal = 0;
@@ -168,7 +170,7 @@ vStoreChar(ULONG ulChar, BOOL bChangeAllowed, output_type *pOutput)
 
 	fail(pOutput == NULL);
 
-	if (tOptions.eEncoding == encoding_utf8 && bChangeAllowed) {
+	if (tOptions.eEncoding == encoding_utf_8 && bChangeAllowed) {
 		DBG_HEX_C(ulChar > 0xffff, ulChar);
 		fail(ulChar > 0xffff);
 		tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult));
@@ -208,7 +210,7 @@ vStoreString(const char *szString, size_t tStringLength, output_type *pOutput)
 	fail(szString == NULL || pOutput == NULL);
 
 	for (tIndex = 0; tIndex < tStringLength; tIndex++) {
-		vStoreCharacter((UCHAR)szString[tIndex], pOutput);
+		vStoreCharacter((ULONG)(UCHAR)szString[tIndex], pOutput);
 	}
 } /* end of vStoreString */
 
@@ -261,7 +263,8 @@ vStoreStyle(diagram_type *pDiag, output_type *pOutput,
 	if (tOptions.eConversionType == conversion_xml) {
 		vSetHeaders(pDiag, pStyle->usIstd);
 	} else {
-		tLen = tStyle2Window(szString, pStyle, pSection);
+		tLen = tStyle2Window(szString, sizeof(szString),
+					pStyle, pSection);
 		vStoreString(szString, tLen, pOutput);
 	}
 } /* end of vStoreStyle */
@@ -306,7 +309,7 @@ vPutIndentation(diagram_type *pDiag, output_type *pOutput,
 	}
 
 #if defined(DEBUG)
-	if (tOptions.eEncoding == encoding_utf8) {
+	if (tOptions.eEncoding == encoding_utf_8) {
 		fail(strlen(szListChar) > 3);
 	} else {
 		DBG_HEX_C(iscntrl((int)szListChar[0]), szListChar[0]);
@@ -317,6 +320,7 @@ vPutIndentation(diagram_type *pDiag, output_type *pOutput,
 
 	switch (ucNFC) {
 	case LIST_ARABIC_NUM:
+	case LIST_NUMBER_TXT:
 		tNextFree = (size_t)sprintf(szLine, "%u", uiListNumber);
 		break;
 	case LIST_UPPER_ROMAN:
@@ -330,6 +334,7 @@ vPutIndentation(diagram_type *pDiag, output_type *pOutput,
 				ucNFC == LIST_UPPER_ALPHA, szLine);
 		break;
 	case LIST_ORDINAL_NUM:
+	case LIST_ORDINAL_TXT:
 		if (uiListNumber % 10 == 1 && uiListNumber != 11) {
 			tNextFree =
 				(size_t)sprintf(szLine, "%ust", uiListNumber);
@@ -344,12 +349,16 @@ vPutIndentation(diagram_type *pDiag, output_type *pOutput,
 				(size_t)sprintf(szLine, "%uth", uiListNumber);
 		}
 		break;
+	case LIST_OUTLINE_NUM:
+		tNextFree = (size_t)sprintf(szLine, "%02u", uiListNumber);
+		break;
 	case LIST_SPECIAL:
+	case LIST_SPECIAL2:
 	case LIST_BULLETS:
 		tNextFree = 0;
 		break;
 	default:
-		DBG_DEC(ucNFC);
+		DBG_HEX(ucNFC);
 		DBG_FIXME();
 		tNextFree = (size_t)sprintf(szLine, "%u", uiListNumber);
 		break;
@@ -365,7 +374,7 @@ vPutIndentation(diagram_type *pDiag, output_type *pOutput,
 	}
 	vSetLeftIndentation(pDiag, lLeftIndentation);
 	for (tIndex = 0; tIndex < tNextFree; tIndex++) {
-		vStoreChar((UCHAR)szLine[tIndex], FALSE, pOutput);
+		vStoreChar((ULONG)(UCHAR)szLine[tIndex], FALSE, pOutput);
 	}
 } /* end of vPutIndentation */
 
@@ -406,6 +415,8 @@ pStartNextOutput(output_type *pCurrent)
 {
 	output_type	*pNew;
 
+	TRACE_MSG("pStartNextOutput");
+
 	if (pCurrent->tNextFree == 0) {
 		/* The current record is empty, re-use */
 		fail(pCurrent->szStorage[0] != '\0');
@@ -422,7 +433,7 @@ pStartNextOutput(output_type *pCurrent)
 	pNew->lStringWidth = 0;
 	pNew->ucFontColor = FONT_COLOR_DEFAULT;
 	pNew->usFontStyle = FONT_REGULAR;
-	pNew->tFontRef = (draw_fontref)0;
+	pNew->tFontRef = (drawfile_fontref)0;
 	pNew->usFontSize = DEFAULT_FONT_SIZE;
 	pNew->pPrev = pCurrent;
 	pNew->pNext = NULL;
@@ -437,16 +448,19 @@ pStartNewOutput(output_type *pAnchor, output_type *pLeftOver)
 {
 	output_type	*pCurr, *pNext;
 	USHORT		usFontStyle, usFontSize;
-	draw_fontref	tFontRef;
+	drawfile_fontref	tFontRef;
 	UCHAR		ucFontColor;
 
+	TRACE_MSG("pStartNewOutput");
+
 	ucFontColor = FONT_COLOR_DEFAULT;
 	usFontStyle = FONT_REGULAR;
-	tFontRef = (draw_fontref)0;
+	tFontRef = (drawfile_fontref)0;
 	usFontSize = DEFAULT_FONT_SIZE;
 	/* Free the old output space */
 	pCurr = pAnchor;
 	while (pCurr != NULL) {
+		TRACE_MSG("Free the old output space");
 		pNext = pCurr->pNext;
 		pCurr->szStorage = xfree(pCurr->szStorage);
 		if (pCurr->pNext == NULL) {
@@ -460,9 +474,13 @@ pStartNewOutput(output_type *pAnchor, output_type *pLeftOver)
 	}
 	if (pLeftOver == NULL) {
 		/* Create new output space */
+		TRACE_MSG("Create new output space");
 		pLeftOver = xmalloc(sizeof(*pLeftOver));
 		pLeftOver->tStorageSize = INITIAL_SIZE;
+		NO_DBG_DEC(pLeftOver->tStorageSize);
+		TRACE_MSG("before 2nd xmalloc");
 		pLeftOver->szStorage = xmalloc(pLeftOver->tStorageSize);
+		TRACE_MSG("after 2nd xmalloc");
 		pLeftOver->szStorage[0] = '\0';
 		pLeftOver->tNextFree = 0;
 		pLeftOver->lStringWidth = 0;
@@ -486,7 +504,7 @@ static ULONG
 ulGetChar(FILE *pFile, list_id_enum eListID)
 {
 	const font_block_type	*pCurr;
-	ULONG		ulChar, ulFileOffset, ulTextOffset;
+	ULONG		ulChar, ulFileOffset, ulCharPos;
 	row_info_enum	eRowInfo;
 	USHORT		usChar, usPropMod;
 	BOOL		bSkip;
@@ -497,7 +515,7 @@ ulGetChar(FILE *pFile, list_id_enum eListID)
 	bSkip = FALSE;
 	for (;;) {
 		usChar = usNextChar(pFile, eListID,
-				&ulFileOffset, &ulTextOffset, &usPropMod);
+				&ulFileOffset, &ulCharPos, &usPropMod);
 		if (usChar == (USHORT)EOF) {
 			return (ULONG)EOF;
 		}
@@ -583,14 +601,36 @@ ulGetChar(FILE *pFile, list_id_enum eListID)
 		}
 		if (ulChar == PAGE_BREAK) {
 			/* Might be the start of a new section */
-			pSectionNext = pGetSectionInfo(pSection, ulTextOffset);
+			pSectionNext = pGetSectionInfo(pSection, ulCharPos);
 		}
 		return ulChar;
 	}
 } /* end of ulGetChar */
 
 /*
- * bWordDecryptor - translate Word to text or PostScript
+ * lGetWidthMax - get the maximum line width from the paragraph break value
+ *
+ * Returns the maximum line width in millipoints
+ */
+static long
+lGetWidthMax(int iParagraphBreak)
+{
+	fail(iParagraphBreak < 0);
+
+	if (iParagraphBreak == 0) {
+		return LONG_MAX;
+	}
+	if (iParagraphBreak < MIN_SCREEN_WIDTH) {
+		return lChar2MilliPoints(MIN_SCREEN_WIDTH);
+	}
+	if (iParagraphBreak > MAX_SCREEN_WIDTH) {
+		return lChar2MilliPoints(MAX_SCREEN_WIDTH);
+	}
+	return lChar2MilliPoints(iParagraphBreak);
+} /* end of lGetWidthMax */
+
+/*
+ * bWordDecryptor - turn Word to something more useful
  *
  * returns TRUE when succesful, otherwise FALSE
  */
@@ -605,7 +645,7 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 	ULONG	ulChar;
 	long	lBeforeIndentation, lAfterIndentation;
 	long	lLeftIndentation, lLeftIndentation1, lRightIndentation;
-	long	lWidthCurr, lWidthMax, lDefaultTabWidth, lTmp;
+	long	lWidthCurr, lWidthMax, lDefaultTabWidth, lHalfSpaceWidth, lTmp;
 	list_id_enum 	eListID;
 	image_info_enum	eRes;
 	UINT	uiFootnoteNumber, uiEndnoteNumber, uiTmp;
@@ -620,13 +660,19 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 
 	fail(pFile == NULL || lFilesize <= 0 || pDiag == NULL);
 
-	DBG_MSG("bWordDecryptor");
+	TRACE_MSG("bWordDecryptor");
 
 	iWordVersion = iInitDocument(pFile, lFilesize);
 	if (iWordVersion < 0) {
 		DBG_DEC(iWordVersion);
 		return FALSE;
 	}
+
+	vGetOptions(&tOptions);
+	bOldMacFile = bIsOldMacFile();
+	vPrepareHdrFtrText(pFile);
+	vPrepareFootnoteText(pFile);
+
 	vPrologue2(pDiag, iWordVersion);
 
 	/* Initialisation */
@@ -636,7 +682,6 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 	iPrevPct = -1;
 	ulDocumentLength = ulGetDocumentLength();
 #endif /* __riscos */
-	bOldMacFile = bIsOldMacFile();
 	pSection = pGetSectionInfo(NULL, 0);
 	pSectionNext = pSection;
 	lDefaultTabWidth = lGetDefaultTabWidth();
@@ -651,7 +696,7 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 	bIsTableRow = FALSE;
 	bWasTableRow = FALSE;
 	vResetStyles();
-	pStyleInfo = pGetNextStyleInfoListItem(NULL);
+	pStyleInfo = pGetNextTextStyle(NULL);
 	bStartStyle = FALSE;
 	bInList = FALSE;
 	bWasInList = FALSE;
@@ -683,7 +728,6 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 	bNoMarks = TRUE;
 	bFirstLine = TRUE;
 	ucNFC = LIST_BULLETS;
-	vGetOptions(&tOptions);
 	if (pStyleInfo != NULL) {
 		szListChar = pStyleInfo->szListChar;
 		pStyleTmp = pStyleInfo;
@@ -700,19 +744,10 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 	bAllCapitals = FALSE;
 	bHiddenText = FALSE;
 	bMarkDelText = FALSE;
-	fail(tOptions.iParagraphBreak < 0);
-	if (tOptions.iParagraphBreak == 0) {
-		lWidthMax = LONG_MAX;
-	} else if (tOptions.iParagraphBreak < MIN_SCREEN_WIDTH) {
-		lWidthMax = lChar2MilliPoints(MIN_SCREEN_WIDTH);
-	} else if (tOptions.iParagraphBreak > MAX_SCREEN_WIDTH) {
-		lWidthMax = lChar2MilliPoints(MAX_SCREEN_WIDTH);
-	} else {
-		lWidthMax = lChar2MilliPoints(tOptions.iParagraphBreak);
-	}
+	lWidthMax = lGetWidthMax(tOptions.iParagraphBreak);
 	NO_DBG_DEC(lWidthMax);
 
-	visdelay_begin();
+	Hourglass_On();
 
 	uiFootnoteNumber = 0;
 	uiEndnoteNumber = 0;
@@ -727,13 +762,17 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 			}
 			switch (eListID) {
 			case text_list:
-				eListID = footnote_list;
-				if (uiFootnoteNumber != 0) {
-					vPutSeparatorLine(pAnchor);
-					OUTPUT_LINE();
-					uiFootnoteNumber = 0;
+				if (tOptions.eConversionType !=
+							conversion_xml) {
+					eListID = footnote_list;
+					if (uiFootnoteNumber != 0) {
+						vPutSeparatorLine(pAnchor);
+						OUTPUT_LINE();
+						uiFootnoteNumber = 0;
+					}
+					break;
 				}
-				break;
+				/* No break or return */
 			case footnote_list:
 				eListID = endnote_list;
 				if (uiEndnoteNumber != 0) {
@@ -834,7 +873,7 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 		case PAGE_BREAK:
 		case COLUMN_FEED:
 			if (bIsTableRow) {
-				vStoreCharacter((ULONG)'\n', pOutput);
+				/* Ignore when in a table */
 				break;
 			}
 			if (bOutputContainsText(pAnchor)) {
@@ -843,8 +882,8 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 				RESET_LINE();
 			}
 			if (ulChar == PAGE_BREAK) {
-				vEndOfPage(pDiag,
-					lAfterIndentation);
+				vEndOfPage(pDiag, lAfterIndentation,
+						pSection != pSectionNext);
 			} else {
 				vEndOfParagraph(pDiag,
 					pOutput->tFontRef,
@@ -945,8 +984,7 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 			}
 			bWasInList = bInList;
 			if (bStartStyle) {
-				pStyleInfo =
-					pGetNextStyleInfoListItem(pStyleInfo);
+				pStyleInfo = pGetNextTextStyle(pStyleInfo);
 				NO_DBG_HEX_C(pStyleInfo != NULL,
 						pStyleInfo->ulFileOffset);
 				DBG_MSG_C(pStyleInfo == NULL,
@@ -1015,6 +1053,11 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 			break;
 		case FOOTNOTE_CHAR:
 			uiFootnoteNumber++;
+			if (tOptions.eConversionType == conversion_xml) {
+				vStoreCharacter((ULONG)FOOTNOTE_OR_ENDNOTE,
+								pOutput);
+				break;
+			}
 			vStoreCharacter((ULONG)'[', pOutput);
 			vStoreNumberAsDecimal(uiFootnoteNumber, pOutput);
 			vStoreCharacter((ULONG)']', pOutput);
@@ -1033,7 +1076,13 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 				vStoreCharacter((ULONG)'\n', pOutput);
 				break;
 			}
-			OUTPUT_LINE();
+			if (bOutputContainsText(pAnchor)) {
+				OUTPUT_LINE();
+			} else {
+				vMove2NextLine(pDiag,
+					pOutput->tFontRef, pOutput->usFontSize);
+				RESET_LINE();
+			}
 			vEndOfParagraph(pDiag,
 					pOutput->tFontRef,
 					pOutput->usFontSize,
@@ -1047,9 +1096,11 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 			}
 			if (bOutputContainsText(pAnchor)) {
 				OUTPUT_LINE();
-			}
-			vMove2NextLine(pDiag,
+			} else {
+				vMove2NextLine(pDiag,
 					pOutput->tFontRef, pOutput->usFontSize);
+				RESET_LINE();
+			}
 			break;
 		case PAGE_BREAK:
 		case COLUMN_FEED:
@@ -1070,11 +1121,15 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 				break;
 			}
 			if (tOptions.iParagraphBreak == 0 &&
-			    tOptions.eConversionType == conversion_text) {
+			    (tOptions.eConversionType == conversion_text ||
+			     tOptions.eConversionType == conversion_fmt_text)) {
 				/* No logical lines, so no tab expansion */
 				vStoreCharacter(TAB, pOutput);
 				break;
 			}
+			lHalfSpaceWidth = (lComputeSpaceWidth(
+					pOutput->tFontRef,
+					pOutput->usFontSize) + 1) / 2;
 			lTmp = lTotalStringWidth(pAnchor);
 			lTmp += lDrawUnits2MilliPoints(pDiag->lXleft);
 			lTmp /= lDefaultTabWidth;
@@ -1090,14 +1145,18 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 			if (bHiddenText && tOptions.bHideHiddenText) {
 				continue;
 			}
-			if (bMarkDelText &&
-			    tOptions.eConversionType != conversion_ps) {
+			if (bMarkDelText && tOptions.bRemoveRemovedText) {
 				continue;
 			}
-			if (bAllCapitals) {
-				ulChar = ulToUpper(ulChar);
+			if (ulChar == UNICODE_ELLIPSIS &&
+			    tOptions.eEncoding != encoding_utf_8) {
+				vStoreString("...", 3, pOutput);
+			} else {
+				if (bAllCapitals) {
+					ulChar = ulToUpper(ulChar);
+				}
+				vStoreCharacter(ulChar, pOutput);
 			}
-			vStoreCharacter(ulChar, pOutput);
 			break;
 		}
 
@@ -1124,7 +1183,9 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 			/* End of a table row */
 			if (bEndRowNorm) {
 				fail(pRowInfo == NULL);
-				vTableRow2Window(pDiag, pAnchor, pRowInfo);
+				vTableRow2Window(pDiag, pAnchor, pRowInfo,
+						tOptions.eConversionType,
+						tOptions.iParagraphBreak);
 			} else {
 				fail(!bEndRowFast);
 			}
@@ -1167,6 +1228,278 @@ bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
 	pAnchor = xfree(pAnchor);
 	vCloseFont();
 	vFreeDocument();
-	visdelay_end();
+	Hourglass_Off();
 	return TRUE;
 } /* end of bWordDecryptor */
+
+/*
+ * lLastStringWidth - compute the width of the last part of the output string
+ */
+static long
+lLastStringWidth(const output_type *pAnchor)
+{
+	const output_type	*pCurr, *pStart;
+
+	pStart = NULL;
+	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
+		if (pCurr->tNextFree == 1 &&
+		    (pCurr->szStorage[0] == PAR_END ||
+		     pCurr->szStorage[0] == HARD_RETURN)) {
+			/* Found a separator. Start after the separator */
+			pStart = pCurr->pNext;
+		}
+	}
+	if (pStart == NULL) {
+		/* No separators. Use the whole output string */
+		pStart = pAnchor;
+	}
+	return lTotalStringWidth(pStart);
+} /* end of lLastStringWidth */
+
+/*
+ * pHdrFtrDecryptor - turn a header/footer list element to something useful
+ */
+output_type *
+pHdrFtrDecryptor(FILE *pFile, ULONG ulCharPosStart, ULONG ulCharPosNext)
+{
+	output_type	*pAnchor, *pOutput, *pLeftOver;
+	ULONG	ulChar, ulFileOffset, ulCharPos;
+	long	lWidthCurr, lWidthMax;
+	long	lRightIndentation;
+	USHORT	usChar;
+	UCHAR	ucAlignment;
+	BOOL	bSkip;
+
+	fail(iWordVersion < 0);
+	fail(tOptions.eConversionType == conversion_unknown);
+	fail(tOptions.eEncoding == 0);
+
+	if (ulCharPosStart == ulCharPosNext) {
+		/* There are no bytes to decrypt */
+		return NULL;
+	}
+
+	lRightIndentation = 0;
+	ucAlignment = ALIGNMENT_LEFT;
+	bSkip = FALSE;
+	lWidthMax = lGetWidthMax(tOptions.iParagraphBreak);
+	pAnchor = pStartNewOutput(NULL, NULL);
+	pOutput = pAnchor;
+	pOutput->tFontRef = tOpenFont(0, FONT_REGULAR, DEFAULT_FONT_SIZE);
+	usChar = usToHdrFtrPosition(pFile, ulCharPosStart);
+	ulCharPos = ulCharPosStart;
+	ulFileOffset = ulCharPos2FileOffset(ulCharPos);
+	while (usChar != (USHORT)EOF && ulCharPos != ulCharPosNext) {
+		/* Skip embedded characters */
+		if (usChar == START_EMBEDDED) {
+			bSkip = TRUE;
+		} else if (usChar == END_IGNORE || usChar == END_EMBEDDED) {
+			bSkip = FALSE;
+		}
+		/* Translate character */
+		if (bSkip || usChar == END_IGNORE || usChar == END_EMBEDDED) {
+			ulChar = IGNORE_CHARACTER;
+		} else {
+			ulChar = ulTranslateCharacters(usChar,
+					ulFileOffset,
+					iWordVersion,
+					tOptions.eConversionType,
+					tOptions.eEncoding,
+					bOldMacFile);
+		}
+		/* Process character */
+		if (ulChar != IGNORE_CHARACTER) {
+			switch (ulChar) {
+			case PICTURE:
+				vStoreString("[pic]", 5, pOutput);
+				break;
+			case PAR_END:
+			case HARD_RETURN:
+			case PAGE_BREAK:
+			case COLUMN_FEED:
+				/* To the next substring */
+				pOutput = pStartNextOutput(pOutput);
+				vCloseFont();
+				pOutput->tFontRef = tOpenFont(0,
+					FONT_REGULAR, DEFAULT_FONT_SIZE);
+				/* A substring with just one character */
+				if (ulChar == HARD_RETURN) {
+					vStoreCharacter(HARD_RETURN, pOutput);
+				} else {
+					vStoreCharacter(PAR_END, pOutput);
+				}
+				/* To the next substring */
+				pOutput = pStartNextOutput(pOutput);
+				vCloseFont();
+				pOutput->tFontRef = tOpenFont(0,
+					FONT_REGULAR, DEFAULT_FONT_SIZE);
+				fail(!bCheckDoubleLinkedList(pAnchor));
+				break;
+			case TABLE_SEPARATOR:
+				vStoreCharacter((ULONG)' ', pOutput);
+				vStoreCharacter((ULONG)TABLE_SEPARATOR_CHAR,
+							pOutput);
+				break;
+			case TAB:
+				vStoreCharacter((ULONG)FILLER_CHAR, pOutput);
+				break;
+			default:
+				vStoreCharacter(ulChar, pOutput);
+				break;
+			}
+		}
+		lWidthCurr = lLastStringWidth(pAnchor);
+		if (lWidthCurr >= lWidthMax + lRightIndentation) {
+			pLeftOver = pSplitList(pAnchor);
+			for (pOutput = pAnchor;
+			     pOutput->pNext != NULL;
+			     pOutput = pOutput->pNext)
+				;	/* EMPTY */
+			fail(pOutput == NULL);
+			/* To the next substring */
+			pOutput = pStartNextOutput(pOutput);
+			/* A substring with just one HARD_RETURN */
+			vStoreCharacter(HARD_RETURN, pOutput);
+			/* Put the leftover piece(s) at the end */
+			pOutput->pNext = pLeftOver;
+			if (pLeftOver != NULL) {
+				pLeftOver->pPrev = pOutput;
+			}
+			fail(!bCheckDoubleLinkedList(pAnchor));
+			for (pOutput = pAnchor;
+			     pOutput->pNext != NULL;
+			     pOutput = pOutput->pNext)
+				;	/* EMPTY */
+			fail(pOutput == NULL);
+		}
+		usChar = usNextChar(pFile, hdrftr_list,
+					&ulFileOffset, &ulCharPos, NULL);
+	}
+	vCloseFont();
+	if (bOutputContainsText(pAnchor)) {
+		return pAnchor;
+	}
+	pAnchor = pStartNewOutput(pAnchor, NULL);
+	pAnchor->szStorage = xfree(pAnchor->szStorage);
+	pAnchor = xfree(pAnchor);
+	return NULL;
+} /* end of pHdrFtrDecryptor */
+
+/*
+ * pFootnoteDecryptor - turn a footnote text list element into text
+ */
+char *
+szFootnoteDecryptor(FILE *pFile, ULONG ulCharPosStart, ULONG ulCharPosNext)
+{
+	char	*szText;
+	ULONG	ulChar, ulFileOffset, ulCharPos;
+	USHORT	usChar;
+	size_t	tLen, tIndex, tNextFree, tStorageSize;
+	char	szResult[6];
+	BOOL	bSkip;
+
+	fail(iWordVersion < 0);
+	fail(tOptions.eConversionType == conversion_unknown);
+	fail(tOptions.eEncoding == 0);
+
+	if (ulCharPosStart == ulCharPosNext) {
+		/* There are no bytes to decrypt */
+		return NULL;
+	}
+
+	if (tOptions.eConversionType != conversion_xml) {
+		/* Only implemented for XML output */
+		return NULL;
+	}
+
+	bSkip = FALSE;
+
+	/* Initialise the text buffer */
+	tStorageSize = INITIAL_SIZE;
+	szText = xmalloc(tStorageSize);
+	tNextFree = 0;
+	szText[tNextFree] = '\0';
+
+	/* Goto the start */
+	usChar = usToFootnotePosition(pFile, ulCharPosStart);
+	ulCharPos = ulCharPosStart;
+	ulFileOffset = ulCharPos2FileOffset(ulCharPos);
+	/* Skip the unwanted starting characters */
+	while (usChar != (USHORT)EOF && ulCharPos != ulCharPosNext &&
+	       (usChar == FOOTNOTE_OR_ENDNOTE ||
+		usChar == PAR_END ||
+		usChar == TAB ||
+		usChar == (USHORT)' ')) {
+		usChar = usNextChar(pFile, footnote_list,
+					&ulFileOffset, &ulCharPos, NULL);
+	}
+	/* Process the footnote text */
+	while (usChar != (USHORT)EOF && ulCharPos != ulCharPosNext) {
+		/* Skip embedded characters */
+		if (usChar == START_EMBEDDED) {
+			bSkip = TRUE;
+		} else if (usChar == END_IGNORE || usChar == END_EMBEDDED) {
+			bSkip = FALSE;
+		}
+		/* Translate character */
+		if (bSkip ||
+		    usChar == END_IGNORE ||
+		    usChar == END_EMBEDDED ||
+		    usChar == FOOTNOTE_OR_ENDNOTE) {
+			ulChar = IGNORE_CHARACTER;
+		} else {
+			ulChar = ulTranslateCharacters(usChar,
+					ulFileOffset,
+					iWordVersion,
+					tOptions.eConversionType,
+					tOptions.eEncoding,
+					bOldMacFile);
+		}
+		/* Process character */
+		if (ulChar == PICTURE) {
+			tLen = 5;
+			strcpy(szResult, "[pic]");
+		} else if (ulChar == IGNORE_CHARACTER) {
+			tLen = 0;
+			szResult[0] = '\0';
+		} else {
+			switch (ulChar) {
+			case PAR_END:
+			case HARD_RETURN:
+			case PAGE_BREAK:
+			case COLUMN_FEED:
+				ulChar = (ULONG)PAR_END;
+				break;
+			case TAB:
+				ulChar = (ULONG)' ';
+				break;
+			default:
+				break;
+			}
+			tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult));
+		}
+		/* Add the results to the text */
+		if (tNextFree + tLen + 1 > tStorageSize) {
+			tStorageSize += EXTENTION_SIZE;
+			szText = xrealloc(szText, tStorageSize);
+		}
+		for (tIndex = 0; tIndex < tLen; tIndex++) {
+			szText[tNextFree++] = szResult[tIndex];
+		}
+		szText[tNextFree] = '\0';
+		/* Next character */
+		usChar = usNextChar(pFile, footnote_list,
+					&ulFileOffset, &ulCharPos, NULL);
+	}
+	/* Remove redundant spaces */
+	while (tNextFree != 0 && szText[tNextFree - 1] == ' ') {
+		szText[tNextFree - 1] = '\0';
+		tNextFree--;
+	}
+	if (tNextFree == 0) {
+		/* No text */
+		szText = xfree(szText);
+		return NULL;
+	}
+	return szText;
+} /* end of szFootnoteDecryptor */

+ 18 - 7
sys/src/cmd/aux/antiword/wordconst.h

@@ -1,6 +1,6 @@
 /*
  * wordconst.h
- * Copyright (C) 1998-2003 A.J. van Os; Released under GNU GPL
+ * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Constants and macros for the interpretation of MS Word files
@@ -79,7 +79,11 @@
 #define LIST_UPPER_ALPHA		0x03
 #define LIST_LOWER_ALPHA		0x04
 #define LIST_ORDINAL_NUM		0x05
+#define LIST_NUMBER_TXT			0x06
+#define LIST_ORDINAL_TXT		0x07
+#define LIST_OUTLINE_NUM		0x16
 #define LIST_SPECIAL			0x17
+#define LIST_SPECIAL2			0x19
 #define LIST_BULLETS			0xff
 /* Types of paragraph alignment */
 #define ALIGNMENT_LEFT			0x00
@@ -188,7 +192,11 @@
 #define WORD_SOFT_HYPHEN		0x1f
 
 /* Unicode characters */
-#define UNICODE_COPYRIGHT_SIGN		0x00a9
+#define UNICODE_DOUBLE_LEFT_ANGLE_QMARK	0x00ab
+#define UNICODE_MIDDLE_DOT		0x00b7
+#define UNICODE_DOUBLE_RIGHT_ANGLE_QMARK	0x00bb
+#define UNICODE_CAPITAL_D_WITH_STROKE	0x0110
+#define UNICODE_SMALL_D_WITH_STROKE	0x0111
 #define UNICODE_CAPITAL_LIGATURE_OE	0x0152
 #define UNICODE_SMALL_LIGATURE_OE	0x0153
 #define UNICODE_SMALL_F_HOOK		0x0192
@@ -234,13 +242,17 @@
 #define UNICODE_BULLET			0x2022
 #define UNICODE_TRIANGULAR_BULLET	0x2023
 #define UNICODE_ONE_DOT_LEADER		0x2024
+#define UNICODE_TWO_DOT_LEADER		0x2025
 #define UNICODE_ELLIPSIS		0x2026
 #define UNICODE_HYPHENATION_POINT	0x2027
 #define UNICODE_LEFT_TO_RIGHT_EMBEDDING	0x202a
 #define UNICODE_RIGHT_TO_LEFT_EMBEDDING	0x202b
+#define UNICODE_POP_DIRECTIONAL_FORMATTING	0x202c
+#define UNICODE_LEFT_TO_RIGHT_OVERRIDE	0x202d
+#define UNICODE_RIGHT_TO_LEFT_OVERRIDE	0x202e
+#define UNICODE_NARROW_NO_BREAK_SPACE	0x202f
 #define UNICODE_PER_MILLE_SIGN		0x2030
 #define UNICODE_PRIME			0x2032
-#define UNICODE_PRIME			0x2032
 #define UNICODE_DOUBLE_PRIME		0x2033
 #define UNICODE_SINGLE_LEFT_ANGLE_QMARK	0x2039
 #define UNICODE_SINGLE_RIGHT_ANGLE_QMARK	0x203a
@@ -250,6 +262,7 @@
 #define UNICODE_CIRCLE			0x20dd
 #define UNICODE_SQUARE			0x20de
 #define UNICODE_DIAMOND			0x20df
+#define UNICODE_NUMERO_SIGN		0x2116
 #define UNICODE_TRADEMARK_SIGN		0x2122
 #define UNICODE_KELVIN_SIGN		0x212a
 #define UNICODE_LEFTWARDS_ARROW		0x2190
@@ -260,6 +273,7 @@
 #define UNICODE_MINUS_SIGN		0x2212
 #define UNICODE_DIVISION_SLASH		0x2215
 #define UNICODE_ASTERISK_OPERATOR	0x2217
+#define UNICODE_BULLET_OPERATOR		0x2219
 #define UNICODE_RATIO			0x2236
 #define UNICODE_TILDE_OPERATOR		0x223c
 #define UNICODE_BD_LIGHT_HORIZONTAL	0x2500
@@ -291,17 +305,14 @@
 #define UNICODE_BLACK_CLUB_SUIT		0x2663
 #define UNICODE_SMALL_LIGATURE_FI	0xfb01
 #define UNICODE_SMALL_LIGATURE_FL	0xfb02
+#define UNICODE_ZERO_WIDTH_NO_BREAK_SPACE	0xfeff
 
 #if defined(__riscos)
 #define OUR_ELLIPSIS			0x8c
-#define OUR_BULLET_TEXT			0x8f
-#define OUR_BULLET_PS			0x8f
 #define OUR_EM_DASH			0x98
 #define OUR_UNBREAKABLE_JOIN		0x99
 #else
 #define OUR_ELLIPSIS			'.'
-#define OUR_BULLET_TEXT			'.'
-#define OUR_BULLET_PS			'\217'
 #define OUR_EM_DASH			'-'
 #define OUR_UNBREAKABLE_JOIN		'-'
 #endif /* __riscos */

+ 5 - 2
sys/src/cmd/aux/antiword/worddos.c

@@ -1,6 +1,6 @@
 /*
  * worddos.c
- * Copyright (C) 2002 A.J. van Os; Released under GPL
+ * Copyright (C) 2002-2005 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Deal with the DOS internals of a MS Word file
@@ -96,10 +96,13 @@ iInitDocumentDOS(FILE *pFile, long lFilesize)
 	}
 	bSuccess = bGetDocumentText(pFile, lFilesize, aucHeader);
 	if (bSuccess) {
+		vGetPropertyInfo(pFile, NULL,
+				NULL, 0, NULL, 0,
+				aucHeader, iWordVersion);
 		vSetDefaultTabWidth(pFile, NULL,
 				NULL, 0, NULL, 0,
 				aucHeader, iWordVersion);
-		vGetPropertyInfo(pFile, NULL,
+		vGetNotesInfo(pFile, NULL,
 				NULL, 0, NULL, 0,
 				aucHeader, iWordVersion);
 	}

+ 3 - 1
sys/src/cmd/aux/antiword/wordlib.c

@@ -1,6 +1,6 @@
 /*
  * wordlib.c
- * Copyright (C) 1998-2003 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Deal with the internals of a MS Word file
@@ -349,7 +349,9 @@ vFreeDocument(void)
 	vDestroyFontInfoList();
 	vDestroyStylesheetList();
 	vDestroyPictInfoList();
+	vDestroyDocumentInfoList();
 	vDestroySectionInfoList();
+	vDestroyHdrFtrInfoList();
 	vDestroyPropModList();
 	vDestroyNotesInfoLists();
 	vDestroyFontTable();

+ 17 - 3
sys/src/cmd/aux/antiword/wordmac.c

@@ -1,6 +1,6 @@
 /*
  * wordmac.c
- * Copyright (C) 2002 A.J. van Os; Released under GPL
+ * Copyright (C) 2002-2004 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Deal with the MAC internals of a MS Word file
@@ -20,12 +20,26 @@ bGetDocumentText(FILE *pFile, const UCHAR *aucHeader)
 	text_block_type	tTextBlock;
 	ULONG	ulBeginOfText, ulEndOfText;
 	ULONG	ulTextLen;
+	UCHAR	ucDocStatus;
+	BOOL    bFastSaved;
 
 	fail(pFile == NULL);
 	fail(aucHeader == NULL);
 
 	DBG_MSG("bGetDocumentText");
 
+	NO_DBG_PRINT_BLOCK(aucHeader, 0x20);
+
+	/* Get the status flags from the header */
+	ucDocStatus = ucGetByte(0x0a, aucHeader);
+	DBG_HEX(ucDocStatus);
+	bFastSaved = (ucDocStatus & BIT(5)) != 0;
+	DBG_MSG_C(bFastSaved, "This document is Fast Saved");
+	if (bFastSaved) {
+		werr(0, "MacWord: fast saved documents are not supported yet");
+		return FALSE;
+	}
+
 	/* Get length information */
 	ulBeginOfText = ulGetLongBE(0x14, aucHeader);
 	DBG_HEX(ulBeginOfText);
@@ -83,10 +97,10 @@ iInitDocumentMAC(FILE *pFile, long lFilesize)
 	}
 	bSuccess = bGetDocumentText(pFile, aucHeader);
 	if (bSuccess) {
-		vSetDefaultTabWidth(pFile, NULL,
+		vGetPropertyInfo(pFile, NULL,
 				NULL, 0, NULL, 0,
 				aucHeader, iWordVersion);
-		vGetPropertyInfo(pFile, NULL,
+		vSetDefaultTabWidth(pFile, NULL,
 				NULL, 0, NULL, 0,
 				aucHeader, iWordVersion);
 	}

+ 16 - 4
sys/src/cmd/aux/antiword/wordole.c

@@ -1,6 +1,6 @@
 /*
  * wordole.c
- * Copyright (C) 1998-2003 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2004 A.J. van Os; Released under GPL
  *
  * Description:
  * Deal with the OLE internals of a MS Word file
@@ -557,6 +557,7 @@ vGetDocumentData(FILE *pFile, const pps_info_type *pPPS,
 
 	if (!bHasImages ||
 	    tOptions.eConversionType == conversion_text ||
+	    tOptions.eConversionType == conversion_fmt_text ||
 	    tOptions.eConversionType == conversion_xml ||
 	    tOptions.eImageLevel == level_no_images) {
 		/*
@@ -629,7 +630,7 @@ iInitDocumentOLE(FILE *pFile, long lFilesize)
 	size_t	tBBDLen, tSBDLen, tNumBbdBlocks, tRootListLen;
 	int	iWordVersion, iIndex, iToGo;
 	BOOL	bSuccess;
-	USHORT	usIdent;
+	USHORT	usIdent, usDocStatus;
 	UCHAR	aucHeader[HEADER_SIZE];
 
 	fail(pFile == NULL);
@@ -771,16 +772,27 @@ iInitDocumentOLE(FILE *pFile, long lFilesize)
 		return -1;
 	}
 
+	/* Get the status flags from the header */
+	usDocStatus = usGetWord(0x0a, aucHeader);
+        if (usDocStatus & BIT(9)) {
+		PPS_info.tTable = PPS_info.t1Table;
+	} else {
+		PPS_info.tTable = PPS_info.t0Table;
+	}
+	/* Clean the entries that should not be used */
+	memset(&PPS_info.t0Table, 0, sizeof(PPS_info.t0Table));
+	memset(&PPS_info.t1Table, 0, sizeof(PPS_info.t1Table));
+
 	bSuccess = bGetDocumentText(pFile, &PPS_info,
 			aulBBD, tBBDLen, aulSBD, tSBDLen,
 			aucHeader, iWordVersion);
 	if (bSuccess) {
 		vGetDocumentData(pFile, &PPS_info,
 			aulBBD, tBBDLen, aucHeader, iWordVersion);
-		vSetDefaultTabWidth(pFile, &PPS_info,
+		vGetPropertyInfo(pFile, &PPS_info,
 			aulBBD, tBBDLen, aulSBD, tSBDLen,
 			aucHeader, iWordVersion);
-		vGetPropertyInfo(pFile, &PPS_info,
+		vSetDefaultTabWidth(pFile, &PPS_info,
 			aulBBD, tBBDLen, aulSBD, tSBDLen,
 			aucHeader, iWordVersion);
 		vGetNotesInfo(pFile, &PPS_info,

+ 65 - 35
sys/src/cmd/aux/antiword/wordtypes.h

@@ -1,6 +1,6 @@
 /*
  * wordtypes.h
- * Copyright (C) 1998-2003 A.J. van Os; Released under GPL
+ * Copyright (C) 1998-2004 A.J. van Os; Released under GPL
  *
  * Description:
  * Typedefs for the interpretation of MS Word files
@@ -9,6 +9,12 @@
 #if !defined(__wordtypes_h)
 #define __wordtypes_h 1
 
+#include <time.h>
+#if defined(__riscos)
+#include "DeskLib:Font.h"
+#include "DeskLib:Wimp.h"
+#endif /* __riscos */
+
 typedef unsigned char	UCHAR;
 typedef unsigned short	USHORT;
 typedef unsigned int	UINT;
@@ -16,9 +22,10 @@ typedef unsigned long	ULONG;
 
 #if defined(__riscos)
 typedef struct diagram_tag {
-	draw_diag	tInfo;
-	wimp_w		tMainWindow;
-	wimp_w		tScaleWindow;
+	drawfile_info	tInfo;
+	window_handle	tMainWindow;
+	window_handle	tScaleWindow;
+	menu_ptr	pSaveMenu;
 	long		lXleft;			/* In DrawUnits */
 	long		lYtop;			/* In DrawUnits */
 	size_t		tMemorySize;
@@ -32,18 +39,18 @@ typedef struct diagram_tag {
 	long		lXleft;			/* In DrawUnits */
 	long		lYtop;			/* In DrawUnits */
 } diagram_type;
-typedef UCHAR	draw_fontref;
+typedef UCHAR		drawfile_fontref;
 #endif /* __riscos */
 
 typedef struct output_tag {
- 	char	*szStorage;
+	char	*szStorage;
 	long	lStringWidth;		/* In millipoints */
 	size_t	tStorageSize;
 	size_t	tNextFree;
 	USHORT	usFontStyle;
 	USHORT	usFontSize;
 	UCHAR	ucFontColor;
-	draw_fontref		tFontRef;
+	drawfile_fontref	tFontRef;
 	struct output_tag	*pPrev;
 	struct output_tag	*pNext;
 } output_type;
@@ -54,21 +61,26 @@ typedef enum conversion_tag {
 	conversion_text,
 	conversion_draw,
 	conversion_ps,
-	conversion_xml
+	conversion_xml,
+	conversion_pdf,
+	conversion_fmt_text
 } conversion_type;
 
 /* Types of encoding */
 typedef enum encoding_tag {
 	encoding_neutral = 100,
-	encoding_iso_8859_1 = 801,
-	encoding_iso_8859_2 = 802,
-	encoding_utf8 = 1601
+	encoding_latin_1 = 801,
+	encoding_latin_2 = 802,
+	encoding_cyrillic = 805,
+	encoding_utf_8 = 1601
 } encoding_type;
 
 /* Font translation table entry */
 typedef struct font_table_tag {
 	USHORT	usFontStyle;
 	UCHAR	ucWordFontNumber;
+	UCHAR	ucFFN;
+	UCHAR	ucEmphasis;
 	UCHAR	ucInUse;
 	char	szWordFontname[65];
 	char	szOurFontname[33];
@@ -87,6 +99,7 @@ typedef struct options_tag {
 	int		iParagraphBreak;
 	conversion_type	eConversionType;
 	BOOL		bHideHiddenText;
+	BOOL		bRemoveRemovedText;
 	BOOL		bUseLandscape;
 	encoding_type	eEncoding;
 	int		iPageHeight;		/* In points */
@@ -106,10 +119,11 @@ typedef struct pps_tag {
 typedef struct pps_info_tag {
 	pps_type	tWordDocument;	/* Text stream */
 	pps_type	tData;		/* Data stream */
-	pps_type	t0Table;	/* Table 0 stream */
-	pps_type	t1Table;	/* Table 1 stream */
+	pps_type	tTable;		/* Table stream */
 	pps_type	tSummaryInfo;	/* Summary Information */
 	pps_type	tDocSummaryInfo;/* Document Summary Information */
+	pps_type	t0Table;	/* Table 0 stream */
+	pps_type	t1Table;	/* Table 1 stream */
 } pps_info_type;
 
 /* Record of data block information */
@@ -128,13 +142,20 @@ typedef struct text_block_tag {
 	USHORT	usPropMod;
 } text_block_type;
 
+/* Record of the document block information */
+typedef struct document_block_tag {
+	time_t	tCreateDate;		/* Unix timestamp */
+	time_t	tRevisedDate;		/* Unix timestamp */
+	USHORT	usDefaultTabWidth;	/* In twips */
+	UCHAR	ucHdrFtrSpecification;
+} document_block_type;
+
 /* Record of table-row block information */
 typedef struct row_block_tag {
 	ULONG	ulFileOffsetStart;
 	ULONG	ulFileOffsetEnd;
 	ULONG	ulCharPosStart;
 	ULONG	ulCharPosEnd;
-	int	iColumnWidthSum;			/* In twips */
 	short	asColumnWidth[TABLE_COLUMN_MAX+1];	/* In twips */
 	UCHAR	ucNumberOfColumns;
 	UCHAR	ucBorderInfo;
@@ -149,9 +170,23 @@ typedef enum level_type_tag {
 	level_type_pause
 } level_type_enum;
 
+typedef enum list_id_tag {
+	no_list = 0,
+	text_list,
+	footnote_list,
+	hdrftr_list,
+	macro_list,
+	annotation_list,
+	endnote_list,
+	textbox_list,
+	hdrtextbox_list,
+	end_of_lists
+} list_id_enum;
+
 /* Linked list of style description information */
 typedef struct style_block_tag {
-	ULONG	ulFileOffset;
+	ULONG	ulFileOffset;   /* The style start with this character */
+	list_id_enum	eListID;/* The fileoffset is in this list */
 	BOOL	bNumPause;
 	BOOL	bNoRestart;	/* Don't restart by more significant levels */
 	USHORT	usIstd;		/* Current style */
@@ -171,7 +206,7 @@ typedef struct style_block_tag {
 	char	szListChar[4];	/* Character for an itemized list */
 } style_block_type;
 
-/* Linked list of font description information */
+/* Font description information */
 typedef struct font_block_tag {
 	ULONG	ulFileOffset;
 	USHORT	usFontStyle;
@@ -179,30 +214,34 @@ typedef struct font_block_tag {
 	UCHAR	ucFontNumber;
 	UCHAR	ucFontColor;
 } font_block_type;
-typedef struct font_desc_tag {
-	font_block_type	tInfo;
-	struct font_desc_tag	*pNext;
-} font_desc_type;
 
-/* Linked list of picture description information */
+/* Picture description information */
 typedef struct picture_block_tag {
 	ULONG	ulFileOffset;
 	ULONG	ulFileOffsetPicture;
 	ULONG	ulPictureOffset;
 } picture_block_type;
-typedef struct picture_desc_tag {
-	picture_block_type	tInfo;
-	struct picture_desc_tag	*pNext;
-} picture_desc_type;
 
 /* Section description information */
 typedef struct section_block_tag {
 	BOOL	bNewPage;
-	UCHAR	aucNFC[9];		/* Number format code */
 	USHORT	usNeedPrevLvl;		/* Print previous level numbers */
 	USHORT	usHangingIndent;
+	UCHAR	aucNFC[9];		/* Number format code */
+	UCHAR	ucHdrFtrSpecification;	/* Which headers/footers Word < 8 */
 } section_block_type;
 
+/* Header/footer description information */
+typedef struct hdrftr_block_tag {
+	output_type	*pText;
+	long		lHeight;	/* In DrawUnits */
+} hdrftr_block_type;
+
+/* Footnote description information */
+typedef struct footnote_block_tag {
+	char		*szText;
+} footnote_block_type;
+
 /* List description information */
 typedef struct list_block_tag {
 	ULONG	ulStartAt;	/* Number at the start of a list */
@@ -263,15 +302,6 @@ typedef enum row_info_tag {
 	found_not_end_of_row
 } row_info_enum;
 
-typedef enum list_id_tag {
-	text_list,
-	footnote_list,
-	endnote_list,
-	textbox_list,
-	hdrtextbox_list,
-	end_of_lists
-} list_id_enum;
-
 typedef enum notetype_tag {
 	notetype_is_footnote,
 	notetype_is_endnote,

+ 6 - 2
sys/src/cmd/aux/antiword/wordwin.c

@@ -1,6 +1,6 @@
 /*
  * wordwin.c
- * Copyright (C) 2002,2003 A.J. van Os; Released under GPL
+ * Copyright (C) 2002-2005 A.J. van Os; Released under GPL
  *
  * Description:
  * Deal with the WIN internals of a MS Word file
@@ -121,6 +121,7 @@ vGetDocumentData(FILE *pFile, const UCHAR *aucHeader)
 
 	if (!bHasImages ||
 	    tOptions.eConversionType == conversion_text ||
+	    tOptions.eConversionType == conversion_fmt_text ||
 	    tOptions.eConversionType == conversion_xml ||
 	    tOptions.eImageLevel == level_no_images) {
 		/*
@@ -194,10 +195,13 @@ iInitDocumentWIN(FILE *pFile, long lFilesize)
 	bSuccess = bGetDocumentText(pFile, aucHeader);
 	if (bSuccess) {
 		vGetDocumentData(pFile, aucHeader);
+		vGetPropertyInfo(pFile, NULL,
+				NULL, 0, NULL, 0,
+				aucHeader, iWordVersion);
 		vSetDefaultTabWidth(pFile, NULL,
 				NULL, 0, NULL, 0,
 				aucHeader, iWordVersion);
-		vGetPropertyInfo(pFile, NULL,
+		vGetNotesInfo(pFile, NULL,
 				NULL, 0, NULL, 0,
 				aucHeader, iWordVersion);
 	}

+ 26 - 13
sys/src/cmd/aux/antiword/xmalloc.c

@@ -1,6 +1,6 @@
 /*
  * xmalloc.c
- * Copyright (C) 1998-2003 A.J. van Os
+ * Copyright (C) 1998-2005 A.J. van Os
  *
  * Description:
  * Extended malloc and friends
@@ -10,13 +10,12 @@
 #include <string.h>
 #include "antiword.h"
 
-#if !defined(DMALLOC)
-static char *szWarning =
+static char *szMessage =
 	"Memory allocation failed, unable to continue";
-#if defined(__dos)
-static char *szDosWarning =
+#if defined(__dos) && !defined(__DJGPP__)
+static char *szDosMessage =
 	"DOS can't allocate this kind of memory, unable to continue";
-#endif /* __dos */
+#endif /* __dos && !__DJGPP__ */
 
 
 /*
@@ -30,12 +29,16 @@ xmalloc(size_t tSize)
 {
 	void	*pvTmp;
 
+	TRACE_MSG("xmalloc");
+
 	if (tSize == 0) {
 		tSize = 1;
 	}
 	pvTmp = malloc(tSize);
 	if (pvTmp == NULL) {
-		werr(1, szWarning);
+		DBG_MSG("xmalloc returned NULL");
+		DBG_DEC(tSize);
+		werr(1, szMessage);
 	}
 	return pvTmp;
 } /* end of xmalloc */
@@ -50,11 +53,14 @@ xcalloc(size_t tNmemb, size_t tSize)
 {
 	void	*pvTmp;
 
-#if defined(__dos)
+	TRACE_MSG("xcalloc");
+
+#if defined(__dos) && !defined(__DJGPP__)
 	if ((ULONG)tNmemb * (ULONG)tSize > 0xffffUL) {
-		werr(1, szDosWarning);
+		DBG_DEC((ULONG)tNmemb * (ULONG)tSize);
+		werr(1, szDosMessage);
 	}
-#endif /* __dos */
+#endif /* __dos && !__DJGPP__ */
 
 	if (tNmemb == 0 || tSize == 0) {
 		tNmemb = 1;
@@ -62,7 +68,8 @@ xcalloc(size_t tNmemb, size_t tSize)
 	}
 	pvTmp = calloc(tNmemb, tSize);
 	if (pvTmp == NULL) {
-		werr(1, szWarning);
+		DBG_MSG("xcalloc returned NULL");
+		werr(1, szMessage);
 	}
 	return pvTmp;
 } /* end of xcalloc */
@@ -78,9 +85,12 @@ xrealloc(void *pvArg, size_t tSize)
 {
 	void	*pvTmp;
 
+	TRACE_MSG("xrealloc");
+
 	pvTmp = realloc(pvArg, tSize);
 	if (pvTmp == NULL) {
-		werr(1, szWarning);
+		DBG_MSG("realloc returned NULL");
+		werr(1, szMessage);
 	}
 	return pvTmp;
 } /* end of xrealloc */
@@ -99,11 +109,12 @@ xstrdup(const char *szArg)
 {
 	char	*szTmp;
 
+	TRACE_MSG("xstrdup");
+
 	szTmp = xmalloc(strlen(szArg) + 1);
 	strcpy(szTmp, szArg);
 	return szTmp;
 } /* end of xstrdup */
-#endif /* !DMALLOC */
 
 /*
  * xfree - Deallocates dynamic memory
@@ -116,6 +127,8 @@ xstrdup(const char *szArg)
 void *
 xfree(void *pvArg)
 {
+	TRACE_MSG("xfree");
+
 	if (pvArg != NULL) {
 		free(pvArg);
 	}

+ 237 - 117
sys/src/cmd/aux/antiword/xml.c

@@ -1,6 +1,6 @@
 /*
  * xml.c
- * Copyright (C) 2002,2003 A.J. van Os; Released under GNU GPL
+ * Copyright (C) 2002-2005 A.J. van Os; Released under GNU GPL
  *
  * Description:
  * Functions to deal with the XML/DocBook format
@@ -19,6 +19,12 @@
 #define vStackTrace()	/* EMPTY */
 #endif /* DEBUG */
 
+/* The character set */
+static encoding_type	eEncoding = encoding_neutral;
+/* Word version */
+static int	iWordVersion = -1;
+/* Special treatment for files from Word 4/5/6 on an Apple Macintosh */
+static BOOL	bOldMacFile = FALSE;
 /* Text is emphasised */
 static BOOL	bEmphasisOpen = FALSE;
 /* Text is superscript */
@@ -29,6 +35,8 @@ static BOOL	bSubscriptOpen = FALSE;
 static BOOL	bTitleOpen = FALSE;
 /* Table is open */
 static BOOL	bTableOpen = FALSE;
+/* Footnote is open */
+static BOOL	bFootnoteOpen = FALSE;
 /* Current paragraph level */
 static UINT	uiParagraphLevel = 0;
 /* Current list level */
@@ -41,6 +49,8 @@ static USHORT	usHeaderLevelCurrent = 0;
 static BOOL	bEmptyHeaderLevel = TRUE;
 /* Number of columns in the current table */
 static int	iTableColumnsCurrent = 0;
+/* Footnote number */
+static UINT	uiFootnoteNumber = 0;
 
 /* Constants for the stack */
 #define INITIAL_STACK_SIZE	10
@@ -68,64 +78,72 @@ static size_t	tStackNextFree = 0;
 #define TAG_EMPHASIS		(UCHAR)9
 #define TAG_ENTRY		(UCHAR)10
 #define TAG_FILENAME		(UCHAR)11
-#define TAG_INFORMALTABLE	(UCHAR)12
-#define TAG_ITEMIZEDLIST	(UCHAR)13
-#define TAG_LISTITEM		(UCHAR)14
-#define TAG_ORDEREDLIST		(UCHAR)15
-#define TAG_PARA		(UCHAR)16
-#define TAG_ROW			(UCHAR)17
-#define TAG_SECT1		(UCHAR)18
-#define TAG_SECT2		(UCHAR)19
-#define TAG_SECT3		(UCHAR)20
-#define TAG_SECT4		(UCHAR)21
-#define TAG_SECT5		(UCHAR)22
-#define TAG_SUBSCRIPT		(UCHAR)23
-#define TAG_SUBTITLE		(UCHAR)24
-#define TAG_SUPERSCRIPT		(UCHAR)25
-#define TAG_SURNAME		(UCHAR)26
-#define TAG_TBODY		(UCHAR)27
-#define TAG_TGROUP		(UCHAR)28
-#define TAG_TITLE		(UCHAR)29
+#define TAG_FOOTNOTE		(UCHAR)12
+#define TAG_INFORMALTABLE	(UCHAR)13
+#define TAG_ITEMIZEDLIST	(UCHAR)14
+#define TAG_LISTITEM		(UCHAR)15
+#define TAG_ORDEREDLIST		(UCHAR)16
+#define TAG_PARA		(UCHAR)17
+#define TAG_ROW			(UCHAR)18
+#define TAG_SECT1		(UCHAR)19
+#define TAG_SECT2		(UCHAR)20
+#define TAG_SECT3		(UCHAR)21
+#define TAG_SECT4		(UCHAR)22
+#define TAG_SECT5		(UCHAR)23
+#define TAG_SUBSCRIPT		(UCHAR)24
+#define TAG_SUBTITLE		(UCHAR)25
+#define TAG_SUPERSCRIPT		(UCHAR)26
+#define TAG_SURNAME		(UCHAR)27
+#define TAG_TBODY		(UCHAR)28
+#define TAG_TGROUP		(UCHAR)29
+#define TAG_TITLE		(UCHAR)30
 
 typedef struct docbooktags_tag {
 	UCHAR	ucTagnumber;
 	char	szTagname[15];
-	BOOL	bAddNewline;
+	BOOL	bAddNewlineStart;
+	BOOL	bAddNewlineEnd;
 } docbooktags_type;
 
 static const docbooktags_type atDocBookTags[] = {
-	{	TAG_NOTAG, 		"!ERROR!",	TRUE	},
-	{	TAG_AUTHOR,		"author",	TRUE	},
-	{	TAG_BEGINPAGE,		"beginpage",	TRUE	},
-	{	TAG_BOOK, 		"book",		TRUE	},
-	{	TAG_BOOKINFO, 		"bookinfo",	TRUE	},
-	{	TAG_CHAPTER, 		"chapter",	TRUE	},
-	{	TAG_COLSPEC,		"colspec",	TRUE	},
-	{	TAG_CORPNAME,		"corpname",	FALSE	},
-	{	TAG_DATE,		"date",		FALSE	},
-	{	TAG_EMPHASIS,		"emphasis",	FALSE	},
-	{	TAG_ENTRY,		"entry",	TRUE	},
-	{	TAG_FILENAME,		"filename",	FALSE	},
-	{	TAG_INFORMALTABLE,	"informaltable",TRUE	},
-	{	TAG_ITEMIZEDLIST,	"itemizedlist",	TRUE	},
-	{	TAG_LISTITEM,		"listitem",	TRUE	},
-	{	TAG_ORDEREDLIST,	"orderedlist",	TRUE	},
-	{	TAG_PARA, 		"para",		TRUE	},
-	{	TAG_ROW,		"row",		TRUE	},
-	{	TAG_SECT1, 		"sect1",	TRUE	},
-	{	TAG_SECT2, 		"sect2",	TRUE	},
-	{	TAG_SECT3, 		"sect3",	TRUE	},
-	{	TAG_SECT4, 		"sect4",	TRUE	},
-	{	TAG_SECT5, 		"sect5",	TRUE	},
-	{	TAG_SUBSCRIPT,		"subscript",	FALSE	},
-	{	TAG_SUBTITLE,		"subtitle",	FALSE	},
-	{	TAG_SUPERSCRIPT,	"superscript",	FALSE	},
-	{	TAG_SURNAME,		"surname",	FALSE	},
-	{	TAG_TBODY,		"tbody",	TRUE	},
-	{	TAG_TGROUP,		"tgroup",	TRUE	},
-	{	TAG_TITLE, 		"title",	FALSE	},
+	{	TAG_NOTAG, 		"!ERROR!",	TRUE,	TRUE	},
+	{	TAG_AUTHOR,		"author",	TRUE,	TRUE	},
+	{	TAG_BEGINPAGE,		"beginpage",	TRUE,	TRUE	},
+	{	TAG_BOOK, 		"book",		TRUE,	TRUE	},
+	{	TAG_BOOKINFO, 		"bookinfo",	TRUE,	TRUE	},
+	{	TAG_CHAPTER, 		"chapter",	TRUE,	TRUE	},
+	{	TAG_COLSPEC,		"colspec",	TRUE,	TRUE	},
+	{	TAG_CORPNAME,		"corpname",	FALSE,	FALSE	},
+	{	TAG_DATE,		"date",		FALSE,	FALSE	},
+	{	TAG_EMPHASIS,		"emphasis",	FALSE,	FALSE	},
+	{	TAG_ENTRY,		"entry",	TRUE,	TRUE	},
+	{	TAG_FILENAME,		"filename",	FALSE,	FALSE	},
+	{	TAG_FOOTNOTE,		"footnote",	FALSE,	FALSE	},
+	{	TAG_INFORMALTABLE,	"informaltable",TRUE,	TRUE	},
+	{	TAG_ITEMIZEDLIST,	"itemizedlist",	TRUE,	TRUE	},
+	{	TAG_LISTITEM,		"listitem",	TRUE,	TRUE	},
+	{	TAG_ORDEREDLIST,	"orderedlist",	TRUE,	TRUE	},
+	{	TAG_PARA, 		"para",		TRUE,	TRUE	},
+	{	TAG_ROW,		"row",		TRUE,	TRUE	},
+	{	TAG_SECT1, 		"sect1",	TRUE,	TRUE	},
+	{	TAG_SECT2, 		"sect2",	TRUE,	TRUE	},
+	{	TAG_SECT3, 		"sect3",	TRUE,	TRUE	},
+	{	TAG_SECT4, 		"sect4",	TRUE,	TRUE	},
+	{	TAG_SECT5, 		"sect5",	TRUE,	TRUE	},
+	{	TAG_SUBSCRIPT,		"subscript",	FALSE,	FALSE	},
+	{	TAG_SUBTITLE,		"subtitle",	FALSE,	FALSE	},
+	{	TAG_SUPERSCRIPT,	"superscript",	FALSE,	FALSE	},
+	{	TAG_SURNAME,		"surname",	FALSE,	FALSE	},
+	{	TAG_TBODY,		"tbody",	TRUE,	TRUE	},
+	{	TAG_TGROUP,		"tgroup",	TRUE,	TRUE	},
+	{	TAG_TITLE, 		"title",	FALSE,	FALSE	},
 };
 
+static void	vAddStartTag(diagram_type *, UCHAR, const char *);
+static void	vAddEndTag(diagram_type *, UCHAR);
+static void	vAddCombinedTag(diagram_type *, UCHAR, const char *);
+static void	vPrintChar(diagram_type *, char);
+
 
 #if defined(DEBUG)
 /*
@@ -237,61 +255,132 @@ vPrintLevel(FILE *pOutFile)
 	}
 } /* end of vPrintLevel */
 
+/*
+ * vPrintFootnote - print a footnote
+ */
+static void
+vPrintFootnote(diagram_type *pDiag, UINT uiFootnoteIndex)
+{
+	const char	*szText, *pcTmp;
+	BOOL	bSuScript;
+	UCHAR	ucTopTag;
+
+	TRACE_MSG("vPrintFootnote");
+
+	szText = szGetFootnootText(uiFootnoteIndex);
+
+	if (szText == NULL) {
+		szText = "";
+	}
+
+	/* Remove the subscript/superscript (if any) */
+	ucTopTag = ucReadStack();
+	bSuScript = ucTopTag == TAG_SUBSCRIPT || ucTopTag == TAG_SUPERSCRIPT;
+	if (bSuScript) {
+		vAddEndTag(pDiag, ucTopTag);
+	}
+
+	/* Start a footnote */
+	vAddStartTag(pDiag, TAG_FOOTNOTE, NULL);
+	vAddStartTag(pDiag, TAG_PARA, NULL);
+
+	/* Print a footnote */
+	for (pcTmp = szText; *pcTmp != '\0'; pcTmp++) {
+		if (*pcTmp == PAR_END) {
+			if (*(pcTmp + 1) != PAR_END && *(pcTmp + 1) != '\0') {
+				/* PAR_END is not empty and not last */
+				vAddEndTag(pDiag, TAG_PARA);
+				vAddStartTag(pDiag, TAG_PARA, NULL);
+			}
+		} else {
+			vPrintChar(pDiag, *pcTmp);
+		}
+	}
+
+	/* End a footnote */
+	vAddEndTag(pDiag, TAG_PARA);
+	vAddEndTag(pDiag, TAG_FOOTNOTE);
+
+	/* Repair the subscript/superscript (if any) */
+	if (bSuScript) {
+		vAddStartTag(pDiag, ucTopTag, NULL);
+	}
+} /* end of vPrintFootnote */
+
 /*
  * vPrintChar - print a character with XML encoding
  */
 static void
-vPrintChar(FILE *pOutFile, char cChar)
+vPrintChar(diagram_type *pDiag, char cChar)
 {
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+
 	switch (cChar) {
+	case FOOTNOTE_OR_ENDNOTE:
+		uiFootnoteNumber++;
+		vPrintFootnote(pDiag, uiFootnoteNumber - 1);
+		break;
 	case '<':
-		fprintf(pOutFile, "%s", "&lt;");
+		fprintf(pDiag->pOutFile, "%s", "&lt;");
 		break;
 	case '>':
-		fprintf(pOutFile, "%s", "&gt;");
+		fprintf(pDiag->pOutFile, "%s", "&gt;");
 		break;
 	case '&':
-		fprintf(pOutFile, "%s", "&amp;");
+		fprintf(pDiag->pOutFile, "%s", "&amp;");
 		break;
 	default:
-		(void)putc(cChar, pOutFile);
+		(void)putc(cChar, pDiag->pOutFile);
 		break;
 	}
 } /* end of vPrintChar */
 
 /*
- * vPrintSpecial
+ * vPrintSpecialChar - convert and print a character
+ */
+static void
+vPrintSpecialChar(diagram_type *pDiag, USHORT usChar)
+{
+	ULONG   ulChar;
+	size_t  tLen, tIndex;
+	char    szResult[4];
+
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
+	fail(iWordVersion < 0);
+	fail(eEncoding == encoding_neutral);
+
+	ulChar = ulTranslateCharacters(usChar, 0, iWordVersion,
+				conversion_xml, eEncoding, bOldMacFile);
+	tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult));
+	if (tLen == 1) {
+		vPrintChar(pDiag, szResult[0]);
+	} else {
+		for (tIndex = 0; tIndex < tLen; tIndex++) {
+			(void)putc(szResult[tIndex], pDiag->pOutFile);
+		}
+	}
+} /* end of vPrintSpecialChar */
+
+/*
+ * vPrintSpecialString - convert and print a string
  */
 static void
-vPrintSpecial(FILE *pOutFile, const char *szString,
-	int iWordVersion, encoding_type eEncoding)
+vPrintSpecialString(diagram_type *pDiag, const char *szString)
 {
-	ULONG	ulChar;
-	size_t	tLen, tIndex;
 	int	iIndex;
-	BOOL	bOldMacFile;
 	USHORT	usChar;
-	char	szResult[4];
 
-	fail(pOutFile == NULL);
+	fail(pDiag == NULL);
+	fail(pDiag->pOutFile == NULL);
 	fail(szString == NULL);
 
-	bOldMacFile = bIsOldMacFile();
-
 	for (iIndex = 0; szString[iIndex] != '\0'; iIndex++) {
 		usChar = (USHORT)(UCHAR)szString[iIndex];
-		ulChar = ulTranslateCharacters(usChar, 0, iWordVersion,
-				conversion_xml, eEncoding, bOldMacFile);
-		tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult));
-		if (tLen == 1) {
-			vPrintChar(pOutFile, szResult[0]);
-		} else {
-			for (tIndex = 0; tIndex < tLen; tIndex++) {
-				(void)putc(szResult[tIndex], pOutFile);
-			}
-		}
+		vPrintSpecialChar(pDiag, usChar);
 	}
-} /* end of vPrintSpecial */
+} /* end of vPrintSpecialString */
 
 /*
  * vAddStartTag - add the specified start tag to the file
@@ -303,7 +392,7 @@ vAddStartTag(diagram_type *pDiag, UCHAR ucTag, const char *szAttribute)
 	fail(pDiag->pOutFile == NULL);
 	fail((size_t)ucTag >= elementsof(atDocBookTags));
 
-	if (atDocBookTags[(UINT)ucTag].bAddNewline) {
+	if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) {
 		fprintf(pDiag->pOutFile, "\n");
 		vPrintLevel(pDiag->pOutFile);
 	}
@@ -316,7 +405,7 @@ vAddStartTag(diagram_type *pDiag, UCHAR ucTag, const char *szAttribute)
 			atDocBookTags[(UINT)ucTag].szTagname, szAttribute);
 	}
 
-	if (atDocBookTags[(UINT)ucTag].bAddNewline) {
+	if (atDocBookTags[(UINT)ucTag].bAddNewlineEnd) {
 		fprintf(pDiag->pOutFile, "\n");
 		pDiag->lXleft = 0;
 	}
@@ -353,8 +442,11 @@ vAddStartTag(diagram_type *pDiag, UCHAR ucTag, const char *szAttribute)
 		fail(uiParagraphLevel != 0);
 		bTitleOpen = TRUE;
 		break;
+	case TAG_FOOTNOTE:
+		bFootnoteOpen = TRUE;
+		break;
 	case TAG_PARA:
-		fail(bTitleOpen);
+		fail(bTitleOpen && !bFootnoteOpen);
 		uiParagraphLevel++;
 		bEmptyHeaderLevel = FALSE;
 		break;
@@ -415,14 +507,14 @@ vAddEndTag(diagram_type *pDiag, UCHAR ucTag)
 		werr(1, "Impossible tag sequence, unable to continue");
 	}
 
-	if (atDocBookTags[(UINT)ucTag].bAddNewline) {
+	if (atDocBookTags[(UINT)ucTag].bAddNewlineEnd) {
 		fprintf(pDiag->pOutFile, "\n");
 		vPrintLevel(pDiag->pOutFile);
 	}
 
 	fprintf(pDiag->pOutFile, "</%s>", atDocBookTags[(UINT)ucTag].szTagname);
 
-	if (atDocBookTags[(UINT)ucTag].bAddNewline) {
+	if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) {
 		fprintf(pDiag->pOutFile, "\n");
 		pDiag->lXleft = 0;
 	}
@@ -450,6 +542,9 @@ vAddEndTag(diagram_type *pDiag, UCHAR ucTag)
 	case TAG_TITLE:
 		bTitleOpen = FALSE;
 		break;
+	case TAG_FOOTNOTE:
+		bFootnoteOpen = FALSE;
+		break;
 	case TAG_PARA:
 		uiParagraphLevel--;
 		break;
@@ -499,7 +594,7 @@ vAddCombinedTag(diagram_type *pDiag, UCHAR ucTag, const char *szAttribute)
 	fail(pDiag->pOutFile == NULL);
 	fail((size_t)ucTag >= elementsof(atDocBookTags));
 
-	if (atDocBookTags[(UINT)ucTag].bAddNewline) {
+	if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) {
 		fprintf(pDiag->pOutFile, "\n");
 		vPrintLevel(pDiag->pOutFile);
 	}
@@ -512,7 +607,7 @@ vAddCombinedTag(diagram_type *pDiag, UCHAR ucTag, const char *szAttribute)
 			atDocBookTags[(UINT)ucTag].szTagname, szAttribute);
 	}
 
-	if (atDocBookTags[(UINT)ucTag].bAddNewline) {
+	if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) {
 		fprintf(pDiag->pOutFile, "\n");
 		pDiag->lXleft = 0;
 	}
@@ -568,7 +663,7 @@ vAddEndTagsUntil2(diagram_type *pDiag, UCHAR ucTag1, UCHAR ucTag2)
  * vCreateBookIntro - create title and bookinfo
  */
 void
-vCreateBookIntro(diagram_type *pDiag, int iWordVersion, encoding_type eEncoding)
+vCreateBookIntro(diagram_type *pDiag, int iVersion)
 {
 	const char	*szTitle, *szSubject, *szAuthor;
 	const char	*szLastSaveDtm, *szCompany;
@@ -577,9 +672,11 @@ vCreateBookIntro(diagram_type *pDiag, int iWordVersion, encoding_type eEncoding)
 
 	fail(pDiag == NULL);
 	fail(pDiag->pOutFile == NULL);
-	fail(iWordVersion < 0);
+	fail(iVersion < 0);
 	fail(eEncoding == encoding_neutral);
 
+	iWordVersion = iVersion;
+	bOldMacFile = bIsOldMacFile();
 	szTitle = szGetTitle();
 	szSubject = szGetSubject();
 	szAuthor = szGetAuthor();
@@ -598,8 +695,7 @@ vCreateBookIntro(diagram_type *pDiag, int iWordVersion, encoding_type eEncoding)
 	/* Book title */
 	if (szTitle != NULL && szTitle[0] != '\0') {
 		vAddStartTag(pDiag, TAG_TITLE, NULL);
-		vPrintSpecial(pDiag->pOutFile,
-				szTitle, iWordVersion, eEncoding);
+		vPrintSpecialString(pDiag, szTitle);
 		vAddEndTag(pDiag, TAG_TITLE);
 	}
 	/* Bookinfo */
@@ -611,34 +707,29 @@ vCreateBookIntro(diagram_type *pDiag, int iWordVersion, encoding_type eEncoding)
 		vAddStartTag(pDiag, TAG_BOOKINFO, NULL);
 		if (szTitle != NULL && szTitle[0] != '\0') {
 			vAddStartTag(pDiag, TAG_TITLE, NULL);
-			vPrintSpecial(pDiag->pOutFile,
-					szTitle, iWordVersion, eEncoding);
+			vPrintSpecialString(pDiag, szTitle);
 			vAddEndTag(pDiag, TAG_TITLE);
 		}
 		if (szSubject != NULL && szSubject[0] != '\0') {
 			vAddStartTag(pDiag, TAG_SUBTITLE, NULL);
-			vPrintSpecial(pDiag->pOutFile,
-					szSubject, iWordVersion, eEncoding);
+			vPrintSpecialString(pDiag, szSubject);
 			vAddEndTag(pDiag, TAG_SUBTITLE);
 		}
 		if (szAuthor != NULL && szAuthor[0] != '\0') {
 			vAddStartTag(pDiag, TAG_AUTHOR, NULL);
 			vAddStartTag(pDiag, TAG_SURNAME, NULL);
-			vPrintSpecial(pDiag->pOutFile,
-					szAuthor, iWordVersion, eEncoding);
+			vPrintSpecialString(pDiag, szAuthor);
 			vAddEndTag(pDiag, TAG_SURNAME);
 			vAddEndTag(pDiag, TAG_AUTHOR);
 		}
 		if (szLastSaveDtm != NULL && szLastSaveDtm[0] != '\0') {
 			vAddStartTag(pDiag, TAG_DATE, NULL);
-			vPrintSpecial(pDiag->pOutFile,
-					szLastSaveDtm, iWordVersion, eEncoding);
+			vPrintSpecialString(pDiag, szLastSaveDtm);
 			vAddEndTag(pDiag, TAG_DATE);
 		}
 		if (szCompany != NULL && szCompany[0] != '\0') {
 			vAddStartTag(pDiag, TAG_CORPNAME, NULL);
-			vPrintSpecial(pDiag->pOutFile,
-					szCompany, iWordVersion, eEncoding);
+			vPrintSpecialString(pDiag, szCompany);
 			vAddEndTag(pDiag, TAG_CORPNAME);
 		}
 		vAddEndTag(pDiag, TAG_BOOKINFO);
@@ -649,28 +740,32 @@ vCreateBookIntro(diagram_type *pDiag, int iWordVersion, encoding_type eEncoding)
  * vPrologueXML - perform the XML initialization
  */
 void
-vPrologueXML(diagram_type *pDiag)
+vPrologueXML(diagram_type *pDiag, const options_type *pOptions)
 {
 
 	fail(pDiag == NULL);
 	fail(pDiag->pOutFile == NULL);
+	fail(pOptions == NULL);
 
 #if defined(DEBUG)
 	vCheckTagTable();
 #endif /* DEBUG */
 
 	/* Set global variables to their start values */
+	eEncoding = pOptions->eEncoding;
 	bEmphasisOpen = FALSE;
 	bSuperscriptOpen = FALSE;
 	bSubscriptOpen = FALSE;
 	bTitleOpen = FALSE;
 	bTableOpen = FALSE;
+	bFootnoteOpen = FALSE;
 	uiParagraphLevel = 0;
 	uiListLevel = 0;
 	bEmptyListLevel = TRUE;
 	usHeaderLevelCurrent = 0;
 	bEmptyHeaderLevel = TRUE;
 	iTableColumnsCurrent = 0;
+	uiFootnoteNumber = 0;
 
 	pDiag->lXleft = 0;
 	pDiag->lYtop = 0;
@@ -707,6 +802,7 @@ static void
 vPrintXML(diagram_type *pDiag, const char *szString, size_t tStringLength,
 		USHORT usFontstyle)
 {
+	const char	*szAttr;
 	int	iCount;
 	size_t	tNextFree;
 	BOOL	bNotReady, bEmphasisNew, bSuperscriptNew, bSubscriptNew;
@@ -718,12 +814,20 @@ vPrintXML(diagram_type *pDiag, const char *szString, size_t tStringLength,
 		return;
 	}
 
-	bEmphasisNew = bIsBold(usFontstyle) ||
-			bIsItalic(usFontstyle) ||
-			bIsUnderline(usFontstyle) ||
-			bIsStrike(usFontstyle);
-	bSuperscriptNew = bIsSuperscript(usFontstyle);
-	bSubscriptNew = bIsSubscript(usFontstyle);
+	if (tStringLength == 1 && szString[0] == FOOTNOTE_OR_ENDNOTE) {
+		/* Don't do anything special for just a single footnote */
+		bEmphasisNew = FALSE;
+		bSuperscriptNew = FALSE;
+		bSubscriptNew = FALSE;
+	} else {
+		/* Situation normal */
+		bEmphasisNew = bIsBold(usFontstyle) ||
+				bIsItalic(usFontstyle) ||
+				bIsUnderline(usFontstyle) ||
+				bIsStrike(usFontstyle);
+		bSuperscriptNew = bIsSuperscript(usFontstyle);
+		bSubscriptNew = bIsSubscript(usFontstyle);
+	}
 
 	/* End what has to be ended (or more to keep the stack happy) */
 	tNextFree = 0;
@@ -770,7 +874,18 @@ vPrintXML(diagram_type *pDiag, const char *szString, size_t tStringLength,
 
 	/* Start what has to be started */
 	if (bEmphasisNew && !bEmphasisOpen) {
-		vAddStartTag(pDiag, TAG_EMPHASIS, NULL);
+		if (bIsBold(usFontstyle)) {
+			szAttr = "role='bold'";
+		} else if (bIsItalic(usFontstyle)) {
+			szAttr = NULL;
+		} else if (bIsUnderline(usFontstyle)) {
+			szAttr = "role='underline'";
+		} else if (bIsStrike(usFontstyle)) {
+			szAttr = "role='strikethrough'";
+		} else {
+			szAttr = NULL;
+		}
+		vAddStartTag(pDiag, TAG_EMPHASIS, szAttr);
 	}
 	if (bSuperscriptNew && !bSuperscriptOpen) {
 		vAddStartTag(pDiag, TAG_SUPERSCRIPT, NULL);
@@ -781,7 +896,7 @@ vPrintXML(diagram_type *pDiag, const char *szString, size_t tStringLength,
 
 	/* The print the string */
 	for (iCount = 0; iCount < (int)tStringLength; iCount++) {
-		vPrintChar(pDiag->pOutFile, szString[iCount]);
+		vPrintChar(pDiag, szString[iCount]);
 	}
 } /* end of vPrintXML */
 
@@ -793,10 +908,11 @@ vMove2NextLineXML(diagram_type *pDiag)
 {
 	fail(pDiag == NULL);
 
+	/*
 	if (uiParagraphLevel != 0) {
-		vEndOfParagraphXML(pDiag, INT_MAX);
-		vStartOfParagraphXML(pDiag, INT_MAX);
+		We need something like HTML's <BR> tag
 	}
+	*/
 } /* end of vMove2NextLineXML */
 
 /*
@@ -826,12 +942,12 @@ vSubstringXML(diagram_type *pDiag,
  * in paragraphs. Other paragraph levels result from DocBooks special needs.
  */
 void
-vStartOfParagraphXML(diagram_type *pDiag, int iMaxLevel)
+vStartOfParagraphXML(diagram_type *pDiag, UINT uiMaxLevel)
 {
 	fail(pDiag == NULL);
 
-	if (uiParagraphLevel >= (UINT)iMaxLevel || bTitleOpen) {
-		/* To Word titles are just paragraphs */
+	if (uiParagraphLevel >= uiMaxLevel || bTitleOpen) {
+		/* In Word a title is just a paragraph */
 		return;
 	}
 	if (uiListLevel != 0 && bEmptyListLevel) {
@@ -852,13 +968,13 @@ vStartOfParagraphXML(diagram_type *pDiag, int iMaxLevel)
  * Only for paragraph level one and for titles
  */
 void
-vEndOfParagraphXML(diagram_type *pDiag, int iMaxLevel)
+vEndOfParagraphXML(diagram_type *pDiag, UINT uiMaxLevel)
 {
 	UCHAR	ucTopTag;
 
 	fail(pDiag == NULL);
 
-	if (uiParagraphLevel > (UINT)iMaxLevel) {
+	if (uiParagraphLevel > uiMaxLevel) {
 		DBG_DEC(uiParagraphLevel);
 		return;
 	}
@@ -918,8 +1034,8 @@ vEndOfPageXML(diagram_type *pDiag)
 	if (bTitleOpen) {
 		/* A beginpage is not allowed when in a title */
 		/* So start a new paragraph */
-		vEndOfParagraphXML(pDiag, INT_MAX);
-		vStartOfParagraphXML(pDiag, INT_MAX);
+		vEndOfParagraphXML(pDiag, UINT_MAX);
+		vStartOfParagraphXML(pDiag, UINT_MAX);
 		return;
 	}
 	vAddCombinedTag(pDiag, TAG_BEGINPAGE, NULL);
@@ -1060,6 +1176,9 @@ vStartOfListXML(diagram_type *pDiag, UCHAR ucNFC, BOOL bIsEndOfTable)
 	switch (ucNFC) {
 	case LIST_ARABIC_NUM:
 	case LIST_ORDINAL_NUM:
+	case LIST_NUMBER_TXT:
+	case LIST_ORDINAL_TXT:
+	case LIST_OUTLINE_NUM:
 		ucTag = TAG_ORDEREDLIST;
 		szAttr = "numeration='arabic'";
 		break;
@@ -1080,6 +1199,7 @@ vStartOfListXML(diagram_type *pDiag, UCHAR ucNFC, BOOL bIsEndOfTable)
 		szAttr = "numeration='loweralpha'";
 		break;
 	case LIST_SPECIAL:
+	case LIST_SPECIAL2:
 	case LIST_BULLETS:
 		ucTag = TAG_ITEMIZEDLIST;
 		szAttr = "mark='bullet'";
@@ -1087,7 +1207,7 @@ vStartOfListXML(diagram_type *pDiag, UCHAR ucNFC, BOOL bIsEndOfTable)
 	default:
 		ucTag = TAG_ORDEREDLIST;
 		szAttr = "numeration='arabic'";
-		DBG_DEC(ucNFC);
+		DBG_HEX(ucNFC);
 		DBG_FIXME();
 		break;
 	}
@@ -1310,7 +1430,7 @@ vAddTableRowXML(diagram_type *pDiag, char **aszColTxt,
 		vAddStartTag(pDiag, TAG_ENTRY, NULL);
 		tStringLength = strlen(aszColTxt[iIndex]);
 		for (tCount = 0; tCount < tStringLength; tCount++) {
-			vPrintChar(pDiag->pOutFile, aszColTxt[iIndex][tCount]);
+			vPrintChar(pDiag, aszColTxt[iIndex][tCount]);
 		}
 		vAddEndTag(pDiag, TAG_ENTRY);
 	}

Some files were not shown because too many files changed in this diff