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.

249 lines
6.5 KiB

  1. /*
  2. * sobjhelp.c
  3. *
  4. * This file contains implementations of methods that help
  5. * common simple objects handle breaking and queries. All objects
  6. * that use these routines must as the first entry in their dobj
  7. * structure define an SObjCommon entry which these routines
  8. * will cast dobj's to.
  9. *
  10. */
  11. #include "lsdefs.h"
  12. #include "lsidefs.h"
  13. #include "plocchnk.h"
  14. #include "pposichn.h"
  15. #include "posichnk.h"
  16. #include "locchnk.h"
  17. #include "brkcond.h"
  18. #include "pbrko.h"
  19. #include "brko.h"
  20. #include "lsqout.h"
  21. #include "lsqin.h"
  22. #include "objhelp.h"
  23. #include "sobjhelp.h"
  24. #include "memory.h"
  25. #include "lsmem.h"
  26. #include "brkkind.h"
  27. #define GET_DUR(pdobj) (((PSOBJHELP)pdobj)->objdimAll.dur)
  28. #define GET_OBJDIM(pdobj) (((PSOBJHELP)pdobj)->objdimAll)
  29. #define GET_DCP(pdobj) (((PSOBJHELP)pdobj)->dcp)
  30. #define GET_MODAFTER(pdobj) (((PSOBJHELP)pdobj)->durModAfter)
  31. /* F I L L B R E A K O U T */
  32. /*----------------------------------------------------------------------------
  33. %%Function: FillBreakOut
  34. %%Contact: ricksa
  35. Fill break output record.
  36. ----------------------------------------------------------------------------*/
  37. static void FillBreakOut(
  38. PDOBJ pdobj, /* (IN): DOBJ for object */
  39. DWORD ichnk, /* (IN): index in chunk */
  40. PBRKOUT pbrkout) /* (OUT): break output record */
  41. {
  42. pbrkout->posichnk.ichnk = ichnk;
  43. pbrkout->fSuccessful = fTrue;
  44. pbrkout->posichnk.dcp = GET_DCP(pdobj);
  45. pbrkout->objdim = GET_OBJDIM(pdobj);
  46. pbrkout->objdim.dur -= GET_MODAFTER(pdobj);
  47. }
  48. /* S O B J T R U N C A T E C H U N K */
  49. /*----------------------------------------------------------------------------
  50. %%Function: SobjTruncateChunk
  51. %%Contact: ricksa
  52. .
  53. ----------------------------------------------------------------------------*/
  54. LSERR WINAPI SobjTruncateChunk(
  55. PCLOCCHNK plocchnk, /* (IN): locchnk to truncate */
  56. PPOSICHNK posichnk) /* (OUT): truncation point */
  57. {
  58. long urColumnMax = plocchnk->lsfgi.urColumnMax;
  59. long ur = plocchnk->ppointUvLoc[0].u;
  60. PDOBJ pdobj = NULL;
  61. DWORD i = 0;
  62. AssertSz(plocchnk->ppointUvLoc[0].u <= urColumnMax,
  63. "SobjTruncateChunk - pen greater than column max");
  64. while (ur <= urColumnMax)
  65. {
  66. AssertSz((i < plocchnk->clschnk), "SobjTruncateChunk exceeded group of chunks");
  67. AssertSz(plocchnk->ppointUvLoc[i].u <= urColumnMax,
  68. "SobjTruncateChunk starting pen exceeds col max");
  69. pdobj = plocchnk->plschnk[i].pdobj;
  70. ur = plocchnk->ppointUvLoc[i].u + GET_DUR(pdobj);
  71. i++;
  72. }
  73. /* LS does not allow the truncation point to be at the beginning of the object */
  74. AssertSz(pdobj != NULL, "SobjTruncateChunk - pdobj NULL!");
  75. posichnk->ichnk = i - 1;
  76. posichnk->dcp = GET_DCP(pdobj);
  77. return lserrNone;
  78. }
  79. /* S O B J F I N D P R E V B R E A K C H U N K */
  80. /*----------------------------------------------------------------------------
  81. %%Function: SobjFindPrevBreakChunk
  82. %%Contact: ricksa
  83. .
  84. ----------------------------------------------------------------------------*/
  85. LSERR WINAPI SobjFindPrevBreakChunk(
  86. PCLOCCHNK pclocchnk, /* (IN): locchnk to break */
  87. PCPOSICHNK pcpoischnk, /* (IN): place to start looking for break */
  88. BRKCOND brkcond, /* (IN): recommmendation about the break after chunk */
  89. PBRKOUT pbrkout) /* (OUT): results of breaking */
  90. {
  91. PDOBJ pdobj;
  92. DWORD ichnk = pcpoischnk->ichnk;
  93. AssertSz((int) brkcondPlease == 0,
  94. "SobjFindPrevBreakChunk - brcondPlease != 0");
  95. ZeroMemory(pbrkout, sizeof(*pbrkout));
  96. if (ichnk == ichnkOutside)
  97. {
  98. ichnk = pclocchnk->clschnk - 1;
  99. pbrkout->posichnk.ichnk = ichnk;
  100. pdobj = pclocchnk->plschnk[ichnk].pdobj;
  101. if (GET_DUR(pdobj) - GET_MODAFTER(pdobj)
  102. + pclocchnk->ppointUvLoc[ichnk].u
  103. > pclocchnk->lsfgi.urColumnMax)
  104. {
  105. /* Are we at beginning of chunk? */
  106. if (ichnk > 0)
  107. {
  108. /* No - use the prior object in chunk */
  109. ichnk--;
  110. pdobj = pclocchnk->plschnk[ichnk].pdobj;
  111. }
  112. else
  113. {
  114. /* Yes. We need the break to happen before us. */
  115. pbrkout->posichnk.ichnk = ichnk;
  116. return lserrNone;
  117. }
  118. }
  119. if (brkcond != brkcondNever)
  120. {
  121. /* Break at end of chunk. */
  122. FillBreakOut(pdobj, ichnk, pbrkout);
  123. return lserrNone;
  124. }
  125. /* Else break at the beginning of last part of chunk */
  126. }
  127. if (ichnk >= 1)
  128. {
  129. /* Break before the current object */
  130. FillBreakOut(pclocchnk->plschnk[ichnk - 1].pdobj, ichnk - 1, pbrkout);
  131. }
  132. return lserrNone;
  133. }
  134. /* S O B J F I N D N E X T B R E A K C H U N K */
  135. /*----------------------------------------------------------------------------
  136. %%Function: SobjFindNextBreakChunk
  137. %%Contact: ricksa
  138. .
  139. ----------------------------------------------------------------------------*/
  140. LSERR WINAPI SobjFindNextBreakChunk(
  141. PCLOCCHNK pclocchnk, /* (IN): locchnk to break */
  142. PCPOSICHNK pcpoischnk, /* (IN): place to start looking for break */
  143. BRKCOND brkcond, /* (IN): recommmendation about the break before chunk */
  144. PBRKOUT pbrkout) /* (OUT): results of breaking */
  145. {
  146. DWORD ichnk = pcpoischnk->ichnk;
  147. AssertSz((int) brkcondPlease == 0,
  148. "SobjFindNextBreakChunk - brcondPlease != 0");
  149. ZeroMemory(pbrkout, sizeof(*pbrkout));
  150. if (ichnkOutside == ichnk)
  151. {
  152. if (brkcondNever != brkcond)
  153. {
  154. pbrkout->fSuccessful = fTrue;
  155. return lserrNone;
  156. }
  157. /* can't break before so break after first item in chunk */
  158. ichnk = 0;
  159. }
  160. /* If not outside, we break at end of current dobj */
  161. FillBreakOut(pclocchnk->plschnk[ichnk].pdobj, ichnk, pbrkout);
  162. if (pclocchnk->clschnk - 1 == ichnk)
  163. {
  164. /* At the end of chunk. We can't say success for sure */
  165. pbrkout->fSuccessful = fFalse;
  166. }
  167. return lserrNone;
  168. }
  169. /* S O B J F O R C E B R E A K C H U N K */
  170. /*----------------------------------------------------------------------------
  171. %%Function: SobjForceBreak
  172. %%Contact: ricksa
  173. Force Break
  174. .
  175. ----------------------------------------------------------------------------*/
  176. LSERR WINAPI SobjForceBreakChunk(
  177. PCLOCCHNK pclocchnk, /* (IN): locchnk to break */
  178. PCPOSICHNK pcposichnk, /* (IN): place to start looking for break */
  179. PBRKOUT pbrkout) /* (OUT): results of breaking */
  180. {
  181. DWORD ichnk = pcposichnk->ichnk;
  182. ZeroMemory(pbrkout, sizeof(*pbrkout));
  183. pbrkout->posichnk.ichnk = ichnk;
  184. if (pclocchnk->lsfgi.fFirstOnLine && (0 == ichnk))
  185. {
  186. FillBreakOut(pclocchnk->plschnk[ichnk].pdobj, ichnk, pbrkout);
  187. }
  188. else if (ichnk == ichnkOutside)
  189. {
  190. /* Breaking after first object */
  191. FillBreakOut(pclocchnk->plschnk[0].pdobj, 0, pbrkout);
  192. }
  193. else if (ichnk != 0)
  194. {
  195. FillBreakOut(pclocchnk->plschnk[ichnk-1].pdobj, ichnk-1, pbrkout);
  196. }
  197. else /* Nothing, breaking before object */;
  198. pbrkout->fSuccessful = fTrue; /* Force break is always successful! */
  199. return lserrNone;
  200. }