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.

205 lines
5.0 KiB

  1. #include "lsdsply.h"
  2. #include "lsc.h"
  3. #include "lsline.h"
  4. #include "lssubl.h"
  5. #include "heights.h"
  6. #include "lstflow.h"
  7. #include "lssubset.h"
  8. #include "lstfset.h"
  9. #include "port.h"
  10. #include "prepdisp.h"
  11. #include "dispmain.h"
  12. static LSERR LSDrawBreaks(PLSC, PLSLINE, const POINT*, UINT, const RECT*);
  13. #define grpfQuickDisplayMask (fPortDisplayInvisible | \
  14. fPortDisplayUnderline | \
  15. fPortDisplayStrike | \
  16. fPortDisplayShade | \
  17. fPortDisplayBorder \
  18. )
  19. // %%Function: LsDisplayLine
  20. // %%Contact: victork
  21. //
  22. /*
  23. * Displays formatted line (main subline) from the given point.
  24. * Assumes background has been properly erased.
  25. */
  26. LSERR WINAPI LsDisplayLine(PLSLINE plsline, const POINT* pptOrg, UINT kdispmode, const RECT *prectClip)
  27. {
  28. PLSC plsc;
  29. LSERR lserr;
  30. PLSSUBL plssubl;
  31. LSCP cpLim;
  32. LSTFLOW lstflow;
  33. POINTUV pt;
  34. PLSDNODE pdn;
  35. PDOBJ pdobj;
  36. DISPIN dispin;
  37. if (!FIsLSLINE(plsline)) return lserrInvalidParameter;
  38. plsc = plsline->lssubl.plsc;
  39. Assert(FIsLSC(plsc));
  40. if (plsc->lsstate != LsStateFree) return lserrContextInUse;
  41. lserr = PrepareLineForDisplayProc(plsline);
  42. plsc->lsstate = LsStateFree;
  43. if (lserr != lserrNone) return lserr;
  44. plsc->lsstate = LsStateDisplaying;
  45. Assert(plsline->lslinfo.dvpDescent >= 0);
  46. Assert(plsline->lslinfo.dvpAscent >= 0);
  47. Assert(plsline->upStartAutonumberingText <= plsline->upLimAutonumberingText);
  48. Assert(plsline->upLimAutonumberingText <= plsline->upStartMainText);
  49. // Assert(plsline->upStartMainText <= plsline->upLimUnderline) wrong - negative advance pen
  50. Assert(plsline->upLimUnderline <= plsline->upLimLine);
  51. plssubl = &(plsline->lssubl);
  52. plsc->plslineDisplay = plsline; // set up display context
  53. if (plsline->lssubl.plsdnLastDisplay == NULL)
  54. {
  55. // do nothing - happens with only splat on the line
  56. }
  57. else // Do it quick way or call general procedure
  58. if (!plsline->fNonZeroDvpPosEncounted &&
  59. !plsline->fNonRealDnodeEncounted &&
  60. ((plsline->AggregatedDisplayFlags == 0) ||
  61. ((plsline->AggregatedDisplayFlags & grpfQuickDisplayMask) == 0)
  62. )
  63. )
  64. {
  65. cpLim = plssubl->cpLimDisplay;
  66. lstflow = plssubl->lstflow;
  67. dispin.dupLimUnderline = 0;
  68. dispin.fDrawUnderline = fFalse;
  69. dispin.fDrawStrikethrough = fFalse;
  70. dispin.kDispMode = kdispmode;
  71. dispin.lstflow = lstflow;
  72. dispin.prcClip = (RECT*) prectClip;
  73. pt.u = plsline->upStartAutonumberingText;
  74. pt.v = 0;
  75. pdn = plssubl->plsdnFirst;
  76. // can use the loop condition instead of FDnodeBeforeCpLim macro - no borders
  77. for (;;)
  78. {
  79. Assert(pdn->klsdn == klsdnReal);
  80. pdobj = pdn->u.real.pdobj;
  81. dispin.plschp = &(pdn->u.real.lschp);
  82. dispin.plsrun = pdn->u.real.plsrun;
  83. dispin.heightsPres = pdn->u.real.objdim.heightsPres;
  84. dispin.dup = pdn->u.real.dup;
  85. LsPointXYFromPointUV(pptOrg, lstflow, &pt, &(dispin.ptPen));
  86. lserr = (*plsc->lsiobjcontext.rgobj[pdn->u.real.lschp.idObj].lsim.pfnDisplay)
  87. (pdobj, &dispin);
  88. if (pdn == plsline->lssubl.plsdnLastDisplay || lserr != lserrNone)
  89. {
  90. break;
  91. }
  92. pt.u += pdn->u.real.dup;
  93. pdn = pdn->plsdnNext;
  94. }
  95. }
  96. else
  97. {
  98. lserr = DisplaySublineCore(plssubl, pptOrg, kdispmode, prectClip,
  99. plsline->upLimUnderline,
  100. plsline->upStartAutonumberingText);
  101. }
  102. if (lserr == lserrNone && plsline->kspl != ksplNone)
  103. {
  104. lserr = LSDrawBreaks(plsc, plsline, pptOrg, kdispmode, prectClip);
  105. }
  106. plsc->plslineDisplay = NULL; // invalidate display context
  107. plsc->lsstate = LsStateFree;
  108. return lserr;
  109. }
  110. // %%Function: LSDrawBreaks
  111. // %%Contact: victork
  112. //
  113. static LSERR LSDrawBreaks(PLSC plsc, PLSLINE plsline, const POINT* pptOrg, UINT kdispmode, const RECT* prectClip)
  114. {
  115. LSERR lserr;
  116. POINTUV ptUV;
  117. POINT pt;
  118. long dup;
  119. enum lsksplat lsks;
  120. LSTFLOW lstflow = plsline->lssubl.lstflow;
  121. HEIGHTS heightsLineFull;
  122. HEIGHTS heightsLineWithoutAddedSpace;
  123. OBJDIM objdimSubline;
  124. heightsLineFull.dvAscent = plsline->dvpAbove + plsline->lslinfo.dvpAscent;
  125. heightsLineFull.dvDescent = plsline->dvpBelow + plsline->lslinfo.dvpDescent;
  126. heightsLineFull.dvMultiLineHeight = dvHeightIgnore;
  127. heightsLineWithoutAddedSpace.dvAscent = plsline->lslinfo.dvpAscent;
  128. heightsLineWithoutAddedSpace.dvDescent = plsline->lslinfo.dvpDescent;
  129. heightsLineWithoutAddedSpace.dvMultiLineHeight = dvHeightIgnore;
  130. lserr = LssbGetObjDimSubline(&(plsline->lssubl), &lstflow, &objdimSubline);
  131. if (lserr == lserrNone)
  132. {
  133. ptUV.u = plsline->upLimLine;
  134. ptUV.v = 0;
  135. dup = plsline->upRightMarginJustify - plsline->upLimLine;
  136. if (plsline->kspl == ksplPageBreak)
  137. lsks = lsksplPageBreak;
  138. else if (plsline->kspl == ksplColumnBreak)
  139. lsks = lsksplColumnBreak;
  140. else
  141. lsks = lsksplSectionBreak;
  142. LsPointXYFromPointUV(pptOrg, lstflow, &ptUV, &pt);
  143. return (*plsc->lscbk.pfnDrawSplatLine) (plsc->pols, lsks, plsline->lslinfo.cpLim - 1, &pt,
  144. &(heightsLineFull), &(heightsLineWithoutAddedSpace),
  145. &(objdimSubline.heightsPres),
  146. dup, lstflow, kdispmode, prectClip);
  147. }
  148. return lserr;
  149. }