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.

478 lines
10 KiB

  1. /*
  2. * @doc INTERNAL
  3. *
  4. * @module OLSOLE.CPP -- OlsOle LineServices object class
  5. *
  6. * Author:
  7. * Murray Sargent (with lots of help from RickSa's ols code)
  8. *
  9. * Copyright (c) 1997-2000 Microsoft Corporation. All rights reserved.
  10. */
  11. #include "_common.h"
  12. #ifndef NOLINESERVICES
  13. #include "_font.h"
  14. #include "_edit.h"
  15. #include "_disp.h"
  16. #include "_ols.h"
  17. #include "_render.h"
  18. extern "C" {
  19. #include "objdim.h"
  20. #include "pobjdim.h"
  21. #include "plsdnode.h"
  22. #include "dispi.h"
  23. #include "pdispi.h"
  24. #include "fmti.h"
  25. #include "lsdnset.h"
  26. #include "lsdnfin.h"
  27. #include "brko.h"
  28. #include "pbrko.h"
  29. #include "locchnk.h"
  30. #include "lsqout.h"
  31. #include "lsqin.h"
  32. #include "lsimeth.h"
  33. }
  34. extern BOOL g_OLSBusy;
  35. /*
  36. * OlsOleCreateILSObj(pols, plsc, pclscbk, dword, ppilsobj)
  37. *
  38. * @func
  39. * Create LS Ole object handler. We don't have any need for
  40. * this, so just set it to 0.
  41. *
  42. * @rdesc
  43. * LSERR
  44. */
  45. LSERR WINAPI OlsOleCreateILSObj(
  46. POLS pols, //[IN]: COls *
  47. PLSC plsc, //[IN]: LineServices context
  48. PCLSCBK,
  49. DWORD,
  50. PILSOBJ *ppilsobj) //[OUT]: ptr to ilsobj
  51. {
  52. *ppilsobj = 0;
  53. return lserrNone;
  54. }
  55. /*
  56. * OlsOleDestroyILSObj(pilsobj)
  57. *
  58. * @func
  59. * Destroy LS Ole handler object. Nothing to do, since we don't
  60. * use the ILSObj.
  61. *
  62. * @rdesc
  63. * LSERR
  64. */
  65. LSERR WINAPI OlsOleDestroyILSObj(
  66. PILSOBJ pilsobj)
  67. {
  68. return lserrNone;
  69. }
  70. /*
  71. * OlsOleSetDoc(pilsobj, pclsdocinf)
  72. *
  73. * @func
  74. * Set doc info. Nothing to do for Ole objects
  75. *
  76. * @rdesc
  77. * LSERR
  78. */
  79. LSERR WINAPI OlsOleSetDoc(
  80. PILSOBJ,
  81. PCLSDOCINF)
  82. {
  83. // Ole objects don't care about this
  84. return lserrNone;
  85. }
  86. /*
  87. * OlsOleCreateLNObj(pilsobj, pplnobj)
  88. *
  89. * @func
  90. * Create the line object. Nothing needed in addition to the ped,
  91. * so just return the ped as the LN object.
  92. *
  93. * @rdesc
  94. * LSERR
  95. */
  96. LSERR WINAPI OlsOleCreateLNObj(
  97. PCILSOBJ pilsobj,
  98. PLNOBJ * pplnobj)
  99. {
  100. *pplnobj = (PLNOBJ)g_pols->_pme->GetPed(); // Just the ped
  101. return lserrNone;
  102. }
  103. /*
  104. * OlsOleDestroyLNObj(plnobj)
  105. *
  106. * @func
  107. * Destroy LN object. Nothing to do, since ped is destroyed
  108. * elsewhere
  109. *
  110. * @rdesc
  111. * LSERR
  112. */
  113. LSERR WINAPI OlsOleDestroyLNObj(
  114. PLNOBJ plnobj)
  115. {
  116. return lserrNone;
  117. }
  118. /*
  119. * OlsOleFmt(plnobj, pcfmtin, pfmres)
  120. *
  121. * @func
  122. * Compute dimensions of a particular Ole object
  123. *
  124. * @rdesc
  125. * LSERR
  126. */
  127. LSERR WINAPI OlsOleFmt(
  128. PLNOBJ plnobj,
  129. PCFMTIN pcfmtin,
  130. FMTRES *pfmres)
  131. {
  132. const LONG cp = pcfmtin->lsfrun.plsrun->_cp; //Cannot trust LS cps
  133. LONG dup = 0;
  134. LSERR lserr;
  135. OBJDIM objdim;
  136. CMeasurer * pme = g_pols->_pme;
  137. COleObject * pobj = pme->GetObjectFromCp(cp);
  138. Assert(pobj);
  139. ZeroMemory(&objdim, sizeof(objdim));
  140. pobj->MeasureObj(pme->_dvrInch, pme->_durInch, objdim.dur, objdim.heightsRef.dvAscent,
  141. objdim.heightsRef.dvDescent, pcfmtin->lstxmRef.dvDescent, pme->GetTflow());
  142. pobj->MeasureObj(pme->_dvpInch, pme->_dupInch, dup, objdim.heightsPres.dvAscent,
  143. objdim.heightsPres.dvDescent, pcfmtin->lstxmPres.dvDescent, pme->GetTflow());
  144. pobj->_plsdnTop = pcfmtin->plsdnTop;
  145. lserr = g_plsc->dnFinishRegular(1, pcfmtin->lsfrun.plsrun, pcfmtin->lsfrun.plschp, (PDOBJ)pobj, &objdim);
  146. if(lserrNone == lserr)
  147. {
  148. lserr = g_plsc->dnSetRigidDup(pcfmtin->plsdnTop, dup);
  149. if(lserrNone == lserr)
  150. {
  151. *pfmres = fmtrCompletedRun;
  152. if (pcfmtin->lsfgi.urPen + objdim.dur > pcfmtin->lsfgi.urColumnMax
  153. && !pcfmtin->lsfgi.fFirstOnLine)
  154. {
  155. *pfmres = fmtrExceededMargin;
  156. }
  157. }
  158. }
  159. return lserr;
  160. }
  161. /*
  162. * OlsOleTruncateChunk(plocchnk, posichnk)
  163. *
  164. * @func
  165. * Truncate chunk plocchnk at the point posichnk
  166. *
  167. * @rdesc
  168. * LSERR
  169. */
  170. LSERR WINAPI OlsOleTruncateChunk(
  171. PCLOCCHNK plocchnk, // (IN): locchnk to truncate
  172. PPOSICHNK posichnk) // (OUT): truncation point
  173. {
  174. LSERR lserr;
  175. OBJDIM objdim;
  176. PLSCHNK plschnk = plocchnk->plschnk;
  177. COleObject * pobj;
  178. long ur = plocchnk->lsfgi.urPen;
  179. long urColumnMax = plocchnk->lsfgi.urColumnMax;
  180. for(DWORD i = 0; ur <= urColumnMax; i++)
  181. {
  182. AssertSz(i < plocchnk->clschnk, "OlsOleTruncateChunk: exceeded group of chunks");
  183. pobj = (COleObject *)plschnk[i].pdobj;
  184. Assert(pobj);
  185. lserr = g_plsc->dnQueryObjDimRange(pobj->_plsdnTop, pobj->_plsdnTop, &objdim);
  186. if(lserr != lserrNone)
  187. return lserr;
  188. ur += objdim.dur;
  189. }
  190. posichnk->ichnk = i - 1;
  191. posichnk->dcp = 1;
  192. return lserrNone;
  193. }
  194. /*
  195. * OlsOleFindPrevBreakChunk(plocchnk, pposichnk, brkcond, pbrkout)
  196. *
  197. * @func
  198. * Find previous break in chunk
  199. *
  200. * @rdesc
  201. * LSERR
  202. */
  203. LSERR WINAPI OlsOleFindPrevBreakChunk(
  204. PCLOCCHNK plocchnk,
  205. PCPOSICHNK pposichnk,
  206. BRKCOND brkcond, //(IN): recommendation about break after chunk
  207. PBRKOUT pbrkout)
  208. {
  209. ZeroMemory(pbrkout, sizeof(*pbrkout));
  210. if (pposichnk->ichnk == ichnkOutside && (brkcond == brkcondPlease || brkcond == brkcondCan))
  211. {
  212. pbrkout->fSuccessful = fTrue;
  213. pbrkout->posichnk.ichnk = plocchnk->clschnk - 1;
  214. pbrkout->posichnk.dcp = plocchnk->plschnk[plocchnk->clschnk - 1].dcp;
  215. COleObject *pobj = (COleObject *)plocchnk->plschnk[plocchnk->clschnk - 1].pdobj;
  216. Assert(pobj);
  217. g_plsc->dnQueryObjDimRange(pobj->_plsdnTop, pobj->_plsdnTop, &pbrkout->objdim);
  218. }
  219. else
  220. pbrkout->brkcond = brkcondPlease;
  221. return lserrNone;
  222. }
  223. /*
  224. * OlsOleForceBreakChunk(plocchnk, pposichnk, pbrkout)
  225. *
  226. * @func
  227. * Called when forced to break a line.
  228. *
  229. * @rdesc
  230. * LSERR
  231. */
  232. LSERR WINAPI OlsOleForceBreakChunk(
  233. PCLOCCHNK plocchnk,
  234. PCPOSICHNK pposichnk,
  235. PBRKOUT pbrkout)
  236. {
  237. ZeroMemory(pbrkout, sizeof(*pbrkout));
  238. pbrkout->fSuccessful = fTrue;
  239. if (plocchnk->lsfgi.fFirstOnLine && pposichnk->ichnk == 0 || pposichnk->ichnk == ichnkOutside)
  240. {
  241. pbrkout->posichnk.dcp = 1;
  242. COleObject *pobj = (COleObject *)plocchnk->plschnk[0].pdobj;
  243. Assert(pobj);
  244. g_plsc->dnQueryObjDimRange(pobj->_plsdnTop, pobj->_plsdnTop, &pbrkout->objdim);
  245. }
  246. else
  247. {
  248. pbrkout->posichnk.ichnk = pposichnk->ichnk;
  249. pbrkout->posichnk.dcp = 0;
  250. }
  251. return lserrNone;
  252. }
  253. /*
  254. * OlsOleSetBreak(pdobj, brkkind, nBreakRecord, rgBreakRecord, nActualBreakRecord)
  255. *
  256. * @func
  257. * Set break
  258. *
  259. * @rdesc
  260. * LSERR
  261. */
  262. LSERR WINAPI OlsOleSetBreak(
  263. PDOBJ pdobj, // (IN): dobj which is broken
  264. BRKKIND brkkind, // (IN): Previous/Next/Force/Imposed was chosen
  265. DWORD nBreakRecord, // (IN): size of array
  266. BREAKREC* rgBreakRecord, // (OUT): array of break records
  267. DWORD* nActualBreakRecord) // (OUT): actual number of used elements in array
  268. {
  269. return lserrNone;
  270. }
  271. LSERR WINAPI OlsOleGetSpecialEffectsInside(
  272. PDOBJ pdobj, // (IN): dobj
  273. UINT *pEffectsFlags) // (OUT): Special effects for this object
  274. {
  275. *pEffectsFlags = 0;
  276. return lserrNone;
  277. }
  278. LSERR WINAPI OlsOleCalcPresentation(
  279. PDOBJ, // (IN): dobj
  280. long, // (IN): dup of dobj
  281. LSKJUST, // (IN): LSKJUST
  282. BOOL fLastVisibleOnLine)// (IN): this object is last visible object on line
  283. {
  284. return lserrNone;
  285. }
  286. /*
  287. * OlsOleQueryPointPcp(pdobj, ppointuvQuery, plsqin, plsqout)
  288. *
  289. * @func
  290. * Query Ole object PointFromCp.
  291. *
  292. * @rdesc
  293. * LSERR
  294. */
  295. LSERR WINAPI OlsOleQueryPointPcp(
  296. PDOBJ pdobj, //(IN): dobj to query
  297. PCPOINTUV ppointuvQuery, //(IN): query point (uQuery,vQuery)
  298. PCLSQIN plsqin, //(IN): query input
  299. PLSQOUT plsqout) //(OUT): query output
  300. {
  301. ZeroMemory(plsqout, sizeof(LSQOUT));
  302. plsqout->heightsPresObj = plsqin->heightsPresRun;
  303. plsqout->dupObj = plsqin->dupRun;
  304. return lserrNone;
  305. }
  306. /*
  307. * OlsOleQueryCpPpoint(pdobj, dcp, plsqin, plsqout)
  308. *
  309. * @func
  310. * Query Ole object CpFromPoint.
  311. *
  312. * @rdesc
  313. * LSERR
  314. */
  315. LSERR WINAPI OlsOleQueryCpPpoint(
  316. PDOBJ pdobj, //(IN): dobj to query
  317. LSDCP dcp, //(IN): dcp for query
  318. PCLSQIN plsqin, //(IN): query input
  319. PLSQOUT plsqout) //(OUT): query output
  320. {
  321. ZeroMemory(plsqout, sizeof(LSQOUT));
  322. plsqout->heightsPresObj = plsqin->heightsPresRun;
  323. plsqout->dupObj = plsqin->dupRun;
  324. return lserrNone;
  325. }
  326. /*
  327. * OlsOleDisplay(pdobj, pcdispin)
  328. *
  329. * @func
  330. * Display object
  331. *
  332. * @rdesc
  333. * LSERR
  334. */
  335. LSERR WINAPI OlsOleDisplay(
  336. PDOBJ pdobj, //(IN): dobj to query
  337. PCDISPIN pcdispin) //(IN): display info
  338. {
  339. COleObject *pobj = (COleObject *)pdobj;
  340. Assert(pobj);
  341. CRenderer *pre = g_pols->GetRenderer();
  342. const CDisplay *pdp = pre->GetPdp();
  343. POINTUV ptuv = {pcdispin->ptPen.x, pcdispin->ptPen.y - pre->GetLine().GetDescent()};
  344. if (pcdispin->lstflow == lstflowWS)
  345. ptuv.u -= pcdispin->dup - 1;
  346. pre->SetSelected(pcdispin->plsrun->IsSelected());
  347. pre->Check_pccs();
  348. pre->SetFontAndColor(pcdispin->plsrun->_pCF);
  349. if (pre->_fEraseOnFirstDraw)
  350. pre->EraseLine();
  351. pre->SetCurPoint(ptuv);
  352. pre->SetClipLeftRight(pcdispin->dup);
  353. if (!pobj->FWrapTextAround())
  354. {
  355. COls *polsOld = g_pols;
  356. CLineServices *plscOld = g_plsc;
  357. BOOL fOLSBusyOld = g_OLSBusy;
  358. BOOL fRestore = FALSE;
  359. if (g_plsc && g_pols)
  360. {
  361. // This is to fix a re-entrance problem.
  362. // We first NULL out the two globals. If the OleObject is using Richedit, it will
  363. // create a new LineService context. By the time it get back to here, we will free that
  364. // context and restore the current context. This is necessary since LineService will returns
  365. // error when we are using the same context in the Parent and then in the Ole Object using RE.
  366. g_plsc = NULL;
  367. g_pols = NULL;
  368. g_OLSBusy = FALSE;
  369. fRestore = TRUE;
  370. }
  371. pobj->DrawObj(pdp, pre->_dvpInch, pre->_dupInch, pre->GetDC(), &pre->GetClipRect(), pdp->IsMetafile(),
  372. &ptuv, pcdispin->ptPen.y - ptuv.v, pre->GetLine().GetDescent(), pre->GetTflow());
  373. if (fRestore)
  374. {
  375. // Time to delete the new context created within the DrawObject.
  376. if (g_pols)
  377. delete g_pols;
  378. // Restore old globals
  379. g_pols = polsOld;
  380. g_plsc = plscOld;
  381. g_OLSBusy = fOLSBusyOld;
  382. }
  383. }
  384. return lserrNone;
  385. }
  386. /*
  387. * OlsOleDistroyDObj(pdobj)
  388. *
  389. * @func
  390. * Destroy object: nothing to do since object is destroyed elsewhere
  391. *
  392. * @rdesc
  393. * LSERR
  394. */
  395. LSERR WINAPI OlsOleDestroyDObj(
  396. PDOBJ pdobj)
  397. {
  398. return lserrNone;
  399. }
  400. extern const LSIMETHODS vlsimethodsOle =
  401. {
  402. OlsOleCreateILSObj,
  403. OlsOleDestroyILSObj,
  404. OlsOleSetDoc,
  405. OlsOleCreateLNObj,
  406. OlsOleDestroyLNObj,
  407. OlsOleFmt,
  408. 0,//OlsOleFmtResume
  409. 0,//OlsOleGetModWidthPrecedingChar
  410. 0,//OlsOleGetModWidthFollowingChar
  411. OlsOleTruncateChunk,
  412. OlsOleFindPrevBreakChunk,
  413. 0,//OlsOleFindNextBreakChunk
  414. OlsOleForceBreakChunk,
  415. OlsOleSetBreak,
  416. OlsOleGetSpecialEffectsInside,
  417. 0,//OlsOleFExpandWithPrecedingChar
  418. 0,//OlsOleFExpandWithFollowingChar
  419. OlsOleCalcPresentation,
  420. OlsOleQueryPointPcp,
  421. OlsOleQueryCpPpoint,
  422. 0,//pfnEnum
  423. OlsOleDisplay,
  424. OlsOleDestroyDObj
  425. };
  426. #endif // NOLINESERVICES