Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

409 lines
13 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. /* doc.c -- MW document processing routines (non-resident) */
  5. #define NOGDICAPMASKS
  6. #define NOVIRTUALKEYCODES
  7. #define NOWINMESSAGES
  8. #define NOWINSTYLES
  9. #define NOSYSMETRICS
  10. #define NOMENUS
  11. #define NOICON
  12. #define NOKEYSTATE
  13. #define NOSYSCOMMANDS
  14. #define NORASTEROPS
  15. #define NOSHOWWINDOW
  16. #define NOATOM
  17. #define NOBITMAP
  18. #define NOBRUSH
  19. #define NOCLIPBOARD
  20. #define NOCOLOR
  21. #define NOCREATESTRUCT
  22. #define NOCTLMGR
  23. #define NODRAWTEXT
  24. #define NOFONT
  25. #define NOGDI
  26. #define NOHDC
  27. #define NOMB
  28. #define NOMEMMGR
  29. #define NOMENUS
  30. #define NOMETAFILE
  31. #define NOMINMAX
  32. #define NOMSG
  33. #define NOOPENFILE
  34. #define NOPEN
  35. #define NOPOINT
  36. #define NOREGION
  37. #define NOSCROLL
  38. #define NOSOUND
  39. #define NOTEXTMETRIC
  40. #define NOWH
  41. #define NOWINOFFSETS
  42. #define NOWNDCLASS
  43. #define NOCOMM
  44. #include <windows.h>
  45. #include "mw.h"
  46. #include "editdefs.h"
  47. #include "docdefs.h"
  48. #include "fontdefs.h"
  49. #include "cmddefs.h"
  50. #include "filedefs.h"
  51. #include "str.h"
  52. #include "fmtdefs.h"
  53. #include "propdefs.h"
  54. #include "fkpdefs.h"
  55. #define NOKCCODES
  56. #include "ch.h"
  57. #include "stcdefs.h"
  58. #include "printdef.h" /* printdefs.h */
  59. #include "macro.h"
  60. extern struct DOD (**hpdocdod)[];
  61. extern int docMac;
  62. extern int docScrap;
  63. extern int docUndo;
  64. #ifdef STYLES
  65. #ifdef SAND
  66. extern CHAR szSshtEmpty[];
  67. #else
  68. extern CHAR szSshtEmpty[];
  69. #endif
  70. #endif
  71. /* E X T E R N A L S */
  72. extern int docRulerSprm;
  73. extern int vfSeeSel;
  74. extern struct SEP vsepNormal;
  75. extern struct CHP vchpNormal;
  76. extern int docCur;
  77. extern struct FLI vfli;
  78. extern int vdocParaCache;
  79. extern struct FCB (**hpfnfcb)[];
  80. extern struct UAB vuab;
  81. extern typeCP cpMacCur;
  82. extern struct SEL selCur;
  83. extern int vdocExpFetch;
  84. extern CHAR (**hszSearch)[];
  85. extern typeCP vcpFetch;
  86. extern int vccpFetch;
  87. extern CHAR *vpchFetch;
  88. extern struct CHP vchpFetch;
  89. #ifdef STYLES
  90. extern struct PAP vpapCache;
  91. extern CHAR mpusgstcBase[];
  92. #endif
  93. extern int vrefFile;
  94. struct PGTB **HpgtbCreate();
  95. #ifdef ENABLE /* This is never called */
  96. int DocFromSz(sz, dty)
  97. CHAR sz[];
  98. /* Return doc if one with that name exists already */
  99. {
  100. int doc;
  101. struct DOD *pdod = &(**hpdocdod)[0];
  102. struct DOD *pdodMac = pdod + docMac;
  103. if (sz[0] == 0)
  104. return docNil;
  105. for (doc = 0; pdod < pdodMac; ++pdod, ++doc)
  106. if (pdod->hpctb != 0 && pdod->dty == dty &&
  107. FSzSame(sz, **pdod->hszFile)
  108. #ifdef SAND
  109. && (pdod->vref == vrefFile)
  110. #endif
  111. )
  112. {
  113. ++pdod->cref;
  114. return doc;
  115. }
  116. return docNil;
  117. }
  118. #endif
  119. KillDoc(doc)
  120. int doc;
  121. { /* Wipe this doc, destroying any changes since last save */
  122. extern int vdocBitmapCache;
  123. if (doc == docScrap)
  124. return; /* Can't be killed no-how */
  125. if (--(**hpdocdod)[doc].cref == 0)
  126. {
  127. struct FNTB **hfntb;
  128. #ifdef CASHMERE
  129. struct SETB **hsetb;
  130. #else
  131. struct SEP **hsep;
  132. #endif
  133. struct FFNTB **hffntb;
  134. struct TBD (**hgtbd)[];
  135. CHAR (**hsz)[];
  136. int docSsht;
  137. SmashDocFce( doc );
  138. /* Kill style sheet doc if there is one. */
  139. if ((docSsht = (**hpdocdod)[doc].docSsht) != docNil)
  140. KillDoc(docSsht);
  141. /* Free piece table, filename, and footnote (or style) table */
  142. FreeH((**hpdocdod)[doc].hpctb);
  143. (**hpdocdod)[doc].hpctb = 0; /* To show doc free */
  144. if ((hsz = (**hpdocdod)[doc].hszFile) != 0)
  145. FreeH(hsz);
  146. if ((hfntb = (**hpdocdod)[doc].hfntb) != 0)
  147. FreeH(hfntb);
  148. #ifdef CASHMERE
  149. if ((hsetb = (**hpdocdod)[doc].hsetb) != 0)
  150. FreeH(hsetb);
  151. #else
  152. if ((hsep = (**hpdocdod)[doc].hsep) != 0)
  153. FreeH(hsep);
  154. #endif
  155. if ((hgtbd = (**hpdocdod)[doc].hgtbd) != 0)
  156. FreeH( hgtbd );
  157. if ((hffntb = (**hpdocdod)[doc].hffntb) != 0)
  158. FreeFfntb(hffntb);
  159. if (doc == vdocBitmapCache)
  160. FreeBitmapCache();
  161. InvalidateCaches(doc);
  162. if (docCur == doc)
  163. docCur = docNil;
  164. if (docRulerSprm == doc)
  165. docRulerSprm = docNil;
  166. if (vuab.doc == doc || vuab.doc2 == doc)
  167. NoUndo();
  168. }
  169. }
  170. #ifdef STYLES
  171. struct SYTB **HsytbCreate(doc)
  172. int doc;
  173. { /* Create a map from stc to cp for a style sheet */
  174. typeCP cp, *pcp;
  175. struct SYTB **hsytb;
  176. typeCP cpMac;
  177. int stc, usg, stcBase, stcMin;
  178. int ch, cch, cchT;
  179. int *pbchFprop, *mpstcbchFprop;
  180. CHAR *pchFprop, *grpchFprop;
  181. int iakd, iakdT, cakd, cakdBase;
  182. struct AKD *rgakd, *pakd;
  183. #ifdef DEBUG
  184. int cakdTotal;
  185. #endif
  186. CHAR rgch[3];
  187. CHAR mpchcakc[chMaxAscii];
  188. typeCP mpstccp[stcMax];
  189. /* First, clear out the stc-->cp map by filling with cpNil. */
  190. for (stc = 0, pcp = &mpstccp[0]; stc < stcMax; stc++, pcp++)
  191. *pcp = cpNil;
  192. bltbc(mpchcakc, 0, chMaxAscii);
  193. /* Now go through all entries in the style sheet. In this pass,
  194. check for duplicates (and return 0 if in gallery mode), fill
  195. mpstccp with appropriate entries for all defined stc's, and
  196. count the length of all the styles so we can allocate the heap
  197. block later. */
  198. cpMac = (**hpdocdod)[doc].cpMac;
  199. for (cp = 0, cch = 0, cakd = 1, cakdBase = 1; cp < cpMac; cp += ccpSshtEntry)
  200. {
  201. FetchRgch(&cchT, rgch, doc, cp, cpMac, 3);
  202. stc = rgch[0]; /* stc is first cp of entry */
  203. #ifdef DEBUG
  204. Assert(stc < stcMax);
  205. #endif
  206. if (mpstccp[stc] != cpNil && doc == docCur)
  207. { /* Repeated entry */
  208. Error(IDPMTStcRepeat);
  209. goto ErrRet;
  210. }
  211. mpstccp[stc] = cp;
  212. if (stc < stcSectMin)
  213. {
  214. FetchCp(doc, cp, 0, fcmProps);
  215. cch += CchDiffer(&vchpFetch, &vchpNormal, cchCHP) + 1;
  216. }
  217. if (stc >= stcParaMin)
  218. {
  219. CachePara(doc, cp);
  220. if (stc >= stcSectMin)
  221. cch += CchDiffer(&vpapCache, &vsepNormal, cchSEP) + 1;
  222. else
  223. cch += CchDiffer(&vpapCache, &vpapStd, cchPAP) + 1;
  224. }
  225. ch = rgch[1];
  226. if (ch != ' ')
  227. { /* Define an alt-key code for this style */
  228. ++cakd;
  229. if (rgch[2] == ' ')
  230. {
  231. if (mpchcakc[ch]-- != 0)
  232. {
  233. Error(IDPMTAkcRepeat);
  234. goto ErrRet;
  235. }
  236. ++cakdBase;
  237. }
  238. else
  239. {
  240. ++mpchcakc[ch]; /* increment before switch to avoid
  241. the increment being taken
  242. as for an int. */
  243. switch (mpchcakc[ch])
  244. {
  245. case 0:
  246. Error(IDPMTAkcRepeat);
  247. goto ErrRet;
  248. case 1:
  249. ++cakdBase;
  250. ++cakd;
  251. }
  252. }
  253. }
  254. }
  255. /* Now allocate the heap block, using the total we got above. */
  256. /* HEAP MOVEMENT */
  257. hsytb = (struct SYTB **) HAllocate(cwSYTBBase + cwAKD * cakd +
  258. CwFromCch(cch));
  259. if (FNoHeap(hsytb))
  260. return hOverflow;
  261. /* Now go through the stc-->cp map, filling in the stc-->fprop map
  262. in the sytb. For each stc that isn't defined, determine which
  263. stc to alias it to (either the first of the usage or, if that
  264. one isn't defined, the first one of the first usage). Copy the
  265. actual CHP's, PAP's, and SEP's into grpchFprop. */
  266. mpstcbchFprop = (**hsytb).mpstcbchFprop;
  267. rgakd = (struct AKD *) (grpchFprop = (**hsytb).grpchFprop);
  268. pchFprop = (CHAR *) &rgakd[cakd];
  269. pcp = &mpstccp[0];
  270. pbchFprop = &mpstcbchFprop[0];
  271. *pbchFprop = bNil;
  272. #ifdef DEBUG
  273. cakdTotal = cakd;
  274. #endif
  275. for (stc = 0, usg = 0, stcBase = 0, stcMin = 0, iakd = 0;
  276. stc < stcMax;
  277. stc++, pcp++, pbchFprop++)
  278. {
  279. if (stc >= mpusgstcBase[usg + 1])
  280. { /* Crossed a usage or class boundary */
  281. *pbchFprop = bNil;
  282. stcBase = mpusgstcBase[++usg];
  283. if (stcBase == stcParaMin || stcBase == stcSectMin)
  284. { /* Update the base; make std if none defined */
  285. stcMin = stcBase;
  286. }
  287. }
  288. if ((cp = *pcp) == cpNil)
  289. { /* No style defined; take first for usg or, failing
  290. that, first style of this class. */
  291. if ((*pbchFprop = mpstcbchFprop[stcBase]) == bNil)
  292. *pbchFprop = mpstcbchFprop[stcMin];
  293. }
  294. else
  295. { /* New style; copy the looks and bump the pointers */
  296. /* Char stc's have just FCHP; para has FPAP followed by
  297. FCHP; sect has FSEP. */
  298. *pbchFprop = pchFprop - grpchFprop;
  299. if (stc >= stcParaMin)
  300. { /* Para or sect */
  301. CachePara(doc, cp);
  302. if (stc >= stcSectMin)
  303. cchT = CchDiffer(&vpapCache, &vsepNormal, cchSEP);
  304. else
  305. cchT = CchDiffer(&vpapCache, &vpapStd, cchPAP);
  306. if ((*pchFprop++ = cchT) != 0)
  307. bltbyte(&vpapCache, pchFprop, cchT);
  308. pchFprop += cchT;
  309. }
  310. if (stc < stcSectMin)
  311. { /* Char or para */
  312. FetchCp(doc, cp, 0, fcmProps);
  313. cchT = CchDiffer(&vchpFetch, &vchpNormal, cchCHP);
  314. if ((*pchFprop++ = cchT) != 0)
  315. bltbyte(&vchpFetch, pchFprop, cchT);
  316. pchFprop += cchT;
  317. }
  318. /* Insert element in akd table */
  319. FetchRgch(&cchT, rgch, doc, cp, cpMac, 3);
  320. if ((ch = rgch[1]) == ' ')
  321. continue;
  322. if (rgch[2] == ' ')
  323. { /* Single-key akc */
  324. pakd = &rgakd[iakd++];
  325. pakd->ch = ch;
  326. pakd->fMore = false;
  327. pakd->ustciakd = stc;
  328. }
  329. else
  330. { /* Two-char akc */
  331. for (iakdT = 0; iakdT < iakd; iakdT++)
  332. if (rgakd[iakdT].ch == ch)
  333. {
  334. pakd = &rgakd[rgakd[iakdT].ustciakd +
  335. --mpchcakc[ch]];
  336. pakd->ch = rgch[2];
  337. pakd->fMore = true;
  338. pakd->ustciakd = stc;
  339. do
  340. if ((++pakd)->ch == rgch[2])
  341. {
  342. Error(IDPMTAkcRepeat);
  343. FreeH(hsytb);
  344. goto ErrRet;
  345. }
  346. while (pakd->fMore);
  347. goto NextStc;
  348. }
  349. pakd = &rgakd[iakd++];
  350. pakd->ch = ch;
  351. pakd->fMore = true;
  352. pakd->ustciakd = (cakd -= mpchcakc[ch]);
  353. pakd = &rgakd[cakd + --mpchcakc[ch]];
  354. pakd->ch = rgch[2];
  355. pakd->fMore = false;
  356. pakd->ustciakd = stc;
  357. }
  358. }
  359. NextStc: ;
  360. }
  361. pakd = &rgakd[iakd++];
  362. pakd->ch = ' ';
  363. pakd->fMore = false;
  364. pakd->ustciakd = stcNormal;
  365. #ifdef DEBUG
  366. Assert(grpchFprop + cchAKD * cakdTotal + cch == pchFprop && iakd == cakd);
  367. #endif
  368. return hsytb;
  369. ErrRet:
  370. Select(cp, cp + ccpSshtEntry);
  371. vfSeeSel = true;
  372. return 0;
  373. }
  374. #endif /* STYLES */
  375. 
  376.