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.

741 lines
21 KiB

  1. /* ---------------------------- */
  2. /* */
  3. /* Vertical Ruby object handler */
  4. /* */
  5. /* Contact: antons */
  6. /* */
  7. /* ---------------------------- */
  8. #include "lsmem.h"
  9. #include "limits.h"
  10. #include "vruby.h"
  11. #include "objhelp.h"
  12. #include "lscbk.h"
  13. #include "lsdevres.h"
  14. #include "pdobj.h"
  15. #include "objdim.h"
  16. #include "plssubl.h"
  17. #include "plsdnode.h"
  18. #include "pilsobj.h"
  19. #include "lscrsubl.h"
  20. #include "lssubset.h"
  21. #include "lsdnset.h"
  22. #include "zqfromza.h"
  23. #include "lsdocinf.h"
  24. #include "fmti.h"
  25. #include "posichnk.h"
  26. #include "locchnk.h"
  27. #include "lsdnfin.h"
  28. #include "brko.h"
  29. #include "lspap.h"
  30. #include "plspap.h"
  31. #include "lsqsubl.h"
  32. #include "dispi.h"
  33. #include "lsdssubl.h"
  34. #include "lsems.h"
  35. #include "dispmisc.h"
  36. #include "lstfset.h"
  37. #include "lsqout.h"
  38. #include "lsqin.h"
  39. #include "sobjhelp.h"
  40. #include "brkkind.h"
  41. #define VRUBY_MAIN_ESC_CNT 1
  42. #define VRUBY_RUBY_ESC_CNT 1
  43. #define max(a,b) ((a)>(b) ? (a) : (b))
  44. struct ilsobj
  45. {
  46. POLS pols;
  47. LSCBK lscbk;
  48. PLSC plsc;
  49. LSDEVRES lsdevres;
  50. VRUBYSYNTAX vrubysyntax;
  51. LSESC lsescMain;
  52. LSESC lsescRuby;
  53. VRUBYCBK vrcbk; /* Callbacks to client application */
  54. };
  55. struct dobj
  56. {
  57. SOBJHELP sobjhelp; /* common area for simple objects */
  58. PILSOBJ pilsobj; /* ILS object */
  59. PLSDNODE plsdn; /* DNODE for this object */
  60. PLSRUN plsrun; /* PLSRUN of the object */
  61. LSCP cpStart; /* Starting LS cp for object */
  62. LSTFLOW lstflowParent; /* text flow of the parent subline */
  63. LSTFLOW lstflowRuby; /* text flow of the ruby subline (must be Rotate90CloclWise [lstflowParent]) */
  64. LSCP cpStartRuby; /* first cp of the ruby line */
  65. LSCP cpStartMain; /* first cp of the main line */
  66. PLSSUBL plssublMain; /* Handle to first subline */
  67. PLSSUBL plssublRuby; /* Handle to second line */
  68. HEIGHTS heightsRefRubyT; /* Ref and pres height of rotated Ruby line as given by client */
  69. HEIGHTS heightsPresRubyT;
  70. OBJDIM objdimMain; /* Dimensions of the main subline */
  71. OBJDIM objdimRuby; /* Dimensions of the ruby subline */
  72. /* Display information */
  73. long dupMain;
  74. long dupOffsetRuby; /* Offset of Ruby line's baseline from start of object */
  75. long dvpOffsetRuby; /* Offset of Ruby line's baseline from start of object */
  76. };
  77. /* V R U B Y F R E E D O B J */
  78. /*----------------------------------------------------------------------------
  79. %%Function: VRubyFreeDobj
  80. %%Contact: antons
  81. Free all resources associated with this VRuby dobj.
  82. ----------------------------------------------------------------------------*/
  83. static LSERR VRubyFreeDobj (PDOBJ pdobj)
  84. {
  85. LSERR lserr1 = lserrNone;
  86. LSERR lserr2 = lserrNone;
  87. PILSOBJ pilsobj = pdobj->pilsobj;
  88. if (pdobj->plssublMain != NULL)
  89. {
  90. lserr1 = LsDestroySubline(pdobj->plssublMain);
  91. }
  92. if (pdobj->plssublRuby != NULL)
  93. {
  94. lserr2 = LsDestroySubline(pdobj->plssublRuby);
  95. }
  96. pilsobj->lscbk.pfnDisposePtr(pilsobj->pols, pdobj);
  97. if (lserr1 != lserrNone) return lserr1;
  98. else return lserr2;
  99. }
  100. /* V R U B Y F M T F A I L E D */
  101. /*----------------------------------------------------------------------------
  102. %%Function: RubyFmtFailed
  103. %%Contact: antons
  104. Could not create VRuby DOBJ due to error.
  105. ----------------------------------------------------------------------------*/
  106. static LSERR VRubyFmtFailed (PDOBJ pdobj, LSERR lserr)
  107. {
  108. if (pdobj != NULL) VRubyFreeDobj (pdobj); /* Works with parially-filled DOBJ */
  109. return lserr;
  110. }
  111. /* V R U B I C R E A T E I L S O B J */
  112. /*----------------------------------------------------------------------------
  113. %%Function: VRubyCreateILSObj
  114. %%Contact: antons
  115. Create the ILS object for all VRuby objects.
  116. ----------------------------------------------------------------------------*/
  117. LSERR WINAPI VRubyCreateILSObj (
  118. POLS pols, /* (IN): client application context */
  119. PLSC plsc, /* (IN): LS context */
  120. PCLSCBK pclscbk, /* (IN): callbacks to client application */
  121. DWORD idObj, /* (IN): id of the object */
  122. PILSOBJ *ppilsobj) /* (OUT): object ilsobj */
  123. {
  124. PILSOBJ pilsobj;
  125. LSERR lserr;
  126. VRUBYINIT vrubyinit;
  127. vrubyinit.dwVersion = VRUBY_VERSION;
  128. /* Get initialization data */
  129. lserr = pclscbk->pfnGetObjectHandlerInfo(pols, idObj, &vrubyinit);
  130. if (lserr != lserrNone) return lserr;
  131. pilsobj = pclscbk->pfnNewPtr(pols, sizeof(*pilsobj));
  132. if (NULL == pilsobj) return lserrOutOfMemory;
  133. pilsobj->pols = pols;
  134. pilsobj->lscbk = *pclscbk;
  135. pilsobj->plsc = plsc;
  136. pilsobj->lsescMain.wchFirst = vrubyinit.wchEscMain;
  137. pilsobj->lsescMain.wchLast = vrubyinit.wchEscMain;
  138. pilsobj->lsescRuby.wchFirst = vrubyinit.wchEscRuby;
  139. pilsobj->lsescRuby.wchLast = vrubyinit.wchEscRuby;
  140. pilsobj->vrcbk = vrubyinit.vrcbk;
  141. pilsobj->vrubysyntax = vrubyinit.vrubysyntax;
  142. *ppilsobj = pilsobj;
  143. return lserrNone;
  144. }
  145. /* V R U B I D E S T R O Y I L S O B J */
  146. /*----------------------------------------------------------------------------
  147. %%Function: RubyDestroyILSObj
  148. %%Contact: antons
  149. Free all resources assocaiated with VRuby ILS object.
  150. ----------------------------------------------------------------------------*/
  151. LSERR WINAPI VRubyDestroyILSObj(
  152. PILSOBJ pilsobj) /* (IN): object ilsobj */
  153. {
  154. pilsobj->lscbk.pfnDisposePtr(pilsobj->pols, pilsobj);
  155. return lserrNone;
  156. }
  157. /* V R U B I S E T D O C */
  158. /*----------------------------------------------------------------------------
  159. %%Function: VRubySetDoc
  160. %%Contact: antons
  161. Keep track of device resolution.
  162. ----------------------------------------------------------------------------*/
  163. LSERR WINAPI VRubySetDoc(
  164. PILSOBJ pilsobj, /* (IN): object ilsobj */
  165. PCLSDOCINF pclsdocinf) /* (IN): initialization data of the document level */
  166. {
  167. pilsobj->lsdevres = pclsdocinf->lsdevres;
  168. return lserrNone;
  169. }
  170. /* V R U B I C R E A T E L N O B J */
  171. /*----------------------------------------------------------------------------
  172. %%Function: RubyCreateLNObj
  173. %%Contact: antons
  174. Create the Line Object for the Ruby. Since we only really need
  175. the global ILS object, just pass that object back as the line object.
  176. ----------------------------------------------------------------------------*/
  177. LSERR WINAPI VRubyCreateLNObj (PCILSOBJ pcilsobj, PLNOBJ *pplnobj)
  178. {
  179. *pplnobj = (PLNOBJ) pcilsobj;
  180. return lserrNone;
  181. }
  182. /* V R U B I D E S T R O Y L N O B J */
  183. /*----------------------------------------------------------------------------
  184. %%Function: RubyDestroyLNObj
  185. %%Contact: antons
  186. Frees resources associated with the Ruby line object. No-op because
  187. we don't really allocate one.
  188. ----------------------------------------------------------------------------*/
  189. LSERR WINAPI VRubyDestroyLNObj (PLNOBJ plnobj)
  190. {
  191. Unreferenced(plnobj);
  192. return lserrNone;
  193. }
  194. /* L S F T L O W V R U B Y F R O M L S T F L O W M A I N */
  195. /* ----------------------------------------------------------------------------
  196. %%Function: LstflowVRubyFromLstflowMain
  197. %%Contact: antons
  198. ----------------------------------------------------------------------------*/
  199. LSTFLOW LstflowVRubyFromLstflowMain (LSTFLOW lstflow)
  200. {
  201. static LSTFLOW lstflowRotateForRuby [] =
  202. {
  203. lstflowSW, /* [ lstflowES ] - english */
  204. lstflowNW, /* [ lstflowEN ] */
  205. lstflowEN, /* [ lstflowSE ] */
  206. lstflowWN, /* [ lstflowSW ] */
  207. lstflowSE, /* [ lstflowWS ] - bidi */
  208. lstflowNE, /* [ lstflowWN ] */
  209. lstflowES, /* [ lstflowNE ] */
  210. lstflowWS /* [ lstflowNW ] */
  211. };
  212. return lstflowRotateForRuby [lstflow];
  213. }
  214. /* C A L C A G R E G A T E D H E I G H T */
  215. /*----------------------------------------------------------------------------
  216. %%Function: CalcAgregatedHeight
  217. %%Contact: antons
  218. ----------------------------------------------------------------------------*/
  219. void CalcAgregatedHeights (PCHEIGHTS pcHeights1, PCHEIGHTS pcHeights2, PHEIGHTS pHeightOut)
  220. {
  221. pHeightOut->dvAscent = max (pcHeights1->dvAscent, pcHeights2->dvAscent);
  222. pHeightOut->dvDescent = max (pcHeights1->dvDescent, pcHeights2->dvDescent);
  223. pHeightOut->dvMultiLineHeight = max (pcHeights1->dvMultiLineHeight, pcHeights2->dvMultiLineHeight);
  224. }
  225. /* V R U B I F M T */
  226. /*----------------------------------------------------------------------------
  227. %%Function: VRubyFmt
  228. %%Contact: antons
  229. Format Vertical Ruby object
  230. ----------------------------------------------------------------------------*/
  231. LSERR WINAPI VRubyFmt(
  232. PLNOBJ plnobj, /* (IN): object lnobj */
  233. PCFMTIN pcfmtin, /* (IN): formatting input */
  234. FMTRES *pfmtres) /* (OUT): formatting result */
  235. {
  236. PDOBJ pdobj;
  237. LSERR lserr;
  238. PILSOBJ pilsobj = (PILSOBJ) plnobj;
  239. POLS pols = pilsobj->pols;
  240. LSCP cpStartMain;
  241. LSCP cpStartRuby = pcfmtin->lsfgi.cpFirst + 1;
  242. LSCP cpOut;
  243. LSTFLOW lstflow = pcfmtin->lsfgi.lstflow;
  244. FMTRES fmtres;
  245. FMTRES fmtr = fmtrCompletedRun;
  246. LONG durAdjust;
  247. /* Allocate the DOBJ */
  248. pdobj = pilsobj->lscbk.pfnNewPtr(pols, sizeof(*pdobj));
  249. if (pdobj == NULL) return VRubyFmtFailed (NULL, lserrOutOfMemory);
  250. ZeroMemory(pdobj, sizeof(*pdobj));
  251. pdobj->pilsobj = pilsobj;
  252. pdobj->plsrun = pcfmtin->lsfrun.plsrun;
  253. pdobj->plsdn = pcfmtin->plsdnTop;
  254. pdobj->cpStart = pcfmtin->lsfgi.cpFirst;
  255. pdobj->lstflowParent = lstflow;
  256. pdobj->lstflowRuby = LstflowVRubyFromLstflowMain (lstflow);
  257. if (VRubyPronunciationLineFirst == pilsobj->vrubysyntax)
  258. {
  259. /* Build pronunciation line of text */
  260. lserr = FormatLine ( pilsobj->plsc, cpStartRuby, LONG_MAX, pdobj->lstflowRuby,
  261. & pdobj->plssublRuby, 1, &pilsobj->lsescRuby,
  262. & pdobj->objdimRuby, &cpOut, NULL, NULL, &fmtres );
  263. /* +1 moves passed the ruby line escape character */
  264. cpStartMain = cpOut + 1;
  265. pdobj->cpStartRuby = cpStartRuby;
  266. pdobj->cpStartMain = cpStartMain;
  267. /* Build main line of text */
  268. if (lserrNone == lserr)
  269. {
  270. lserr = FormatLine ( pilsobj->plsc, cpStartMain, LONG_MAX, lstflow,
  271. & pdobj->plssublMain, 1, &pilsobj->lsescMain,
  272. & pdobj->objdimMain, &cpOut, NULL, NULL, &fmtres );
  273. }
  274. }
  275. else
  276. {
  277. /* Build main line of text */
  278. cpStartMain = cpStartRuby;
  279. lserr = FormatLine ( pilsobj->plsc, cpStartMain, LONG_MAX, lstflow,
  280. & pdobj->plssublMain, 1, &pilsobj->lsescMain,
  281. & pdobj->objdimMain, &cpOut, NULL, NULL, &fmtres );
  282. /* +1 moves passed the main line escape character */
  283. cpStartRuby = cpOut + 1;
  284. pdobj->cpStartRuby = cpStartRuby;
  285. pdobj->cpStartMain = cpStartMain;
  286. /* Build pronunciation line of text */
  287. if (lserrNone == lserr)
  288. {
  289. lserr = FormatLine ( pilsobj->plsc, cpStartRuby, LONG_MAX, pdobj->lstflowRuby,
  290. & pdobj->plssublRuby, 1, &pilsobj->lsescRuby,
  291. & pdobj->objdimRuby, &cpOut, NULL, NULL, &fmtres);
  292. }
  293. }
  294. if (lserr != lserrNone) return VRubyFmtFailed (pdobj, lserr);
  295. /* Calculate the object dimensions */
  296. lserr = pilsobj->vrcbk.pfnFetchVRubyPosition
  297. ( pols, pdobj->cpStart, pdobj->lstflowParent,
  298. pdobj->plsrun,
  299. &pdobj->objdimMain.heightsRef, &pdobj->objdimMain.heightsPres,
  300. pdobj->objdimRuby.dur,
  301. &pdobj->heightsPresRubyT,
  302. &pdobj->heightsRefRubyT,
  303. &durAdjust );
  304. if (lserr != lserrNone) return VRubyFmtFailed (pdobj, lserr);
  305. pdobj->sobjhelp.objdimAll.dur = pdobj->objdimMain.dur + pdobj->objdimRuby.heightsRef.dvDescent +
  306. pdobj->objdimRuby.heightsRef.dvAscent +
  307. durAdjust ;
  308. CalcAgregatedHeights (&pdobj->objdimMain.heightsPres, &pdobj->heightsPresRubyT, &pdobj->sobjhelp.objdimAll.heightsPres );
  309. CalcAgregatedHeights (&pdobj->objdimMain.heightsRef, &pdobj->heightsRefRubyT, &pdobj->sobjhelp.objdimAll.heightsRef );
  310. /* Need to add 1 to take into account escape character at end. */
  311. pdobj->sobjhelp.dcp = cpOut - pdobj->cpStart + 1;
  312. lserr = LsdnFinishRegular(pilsobj->plsc, pdobj->sobjhelp.dcp,
  313. pcfmtin->lsfrun.plsrun, pcfmtin->lsfrun.plschp, pdobj,
  314. &pdobj->sobjhelp.objdimAll);
  315. if (lserr != lserrNone) return VRubyFmtFailed (pdobj, lserr);
  316. if (pcfmtin->lsfgi.urPen + pdobj->sobjhelp.objdimAll.dur > pcfmtin->lsfgi.urColumnMax)
  317. {
  318. fmtr = fmtrExceededMargin;
  319. }
  320. *pfmtres = fmtr;
  321. return lserrNone;
  322. }
  323. /* V R U B Y S E T B R E A K */
  324. /*----------------------------------------------------------------------------
  325. %%Function: VRubySetBreak
  326. %%Contact: antons
  327. SetBreak
  328. ----------------------------------------------------------------------------*/
  329. LSERR WINAPI VRubySetBreak (
  330. PDOBJ pdobj, /* (IN): dobj which is broken */
  331. BRKKIND brkkind, /* (IN): prev | next | force | after */
  332. DWORD cBreakRecord, /* (IN): size of array */
  333. BREAKREC *rgBreakRecord, /* (IN): array of break records */
  334. DWORD *pcActualBreakRecord) /* (IN): actual number of used elements in array */
  335. {
  336. Unreferenced (rgBreakRecord);
  337. Unreferenced (cBreakRecord);
  338. Unreferenced (brkkind);
  339. Unreferenced (pdobj);
  340. *pcActualBreakRecord = 0;
  341. return lserrNone;
  342. }
  343. /* V R U B Y G E T S P E C I A L E F F E C T S I N S I D E */
  344. /*----------------------------------------------------------------------------
  345. %%Function: VRubyGetSpecialEffectsInside
  346. %%Contact: antons
  347. VRubyGetSpecialEffectsInside
  348. ----------------------------------------------------------------------------*/
  349. LSERR WINAPI VRubyGetSpecialEffectsInside(
  350. PDOBJ pdobj, /* (IN): dobj */
  351. UINT *pEffectsFlags) /* (OUT): Special effects for this object */
  352. {
  353. LSERR lserr = LsGetSpecialEffectsSubline(pdobj->plssublMain, pEffectsFlags);
  354. if (lserrNone == lserr)
  355. {
  356. UINT uiSpecialEffectsRuby;
  357. lserr = LsGetSpecialEffectsSubline(pdobj->plssublRuby, &uiSpecialEffectsRuby);
  358. *pEffectsFlags |= uiSpecialEffectsRuby;
  359. }
  360. return lserr;
  361. }
  362. /* V R U B Y C A L C P R E S E N T A T I O N */
  363. /*----------------------------------------------------------------------------
  364. %%Function: VRubyCalcPresentation
  365. %%Contact: antons
  366. CalcPresentation
  367. ----------------------------------------------------------------------------*/
  368. LSERR WINAPI VRubyCalcPresentation (
  369. PDOBJ pdobj, /* (IN): dobj */
  370. long dup, /* (IN): dup of dobj */
  371. LSKJUST lskjust, /* (IN): Justification type */
  372. BOOL fLastVisibleOnLine ) /* (IN): Is this object last visible on line? */
  373. {
  374. LSERR lserr = lserrNone;
  375. LSTFLOW lstflowUnused;
  376. Unreferenced (lskjust);
  377. Unreferenced(dup);
  378. Unreferenced (fLastVisibleOnLine);
  379. lserr = LsMatchPresSubline(pdobj->plssublMain);
  380. if (lserr != lserrNone) return lserr;
  381. lserr = LsMatchPresSubline(pdobj->plssublRuby);
  382. if (lserr != lserrNone) return lserr;
  383. LssbGetDupSubline (pdobj->plssublMain, &lstflowUnused, &pdobj->dupMain);
  384. pdobj->dupOffsetRuby = pdobj->dupMain + pdobj->objdimRuby.heightsPres.dvDescent;
  385. /* Review (antons): This will not work if horizintal res != vertical */
  386. pdobj->dvpOffsetRuby = pdobj->heightsPresRubyT.dvAscent;
  387. return lserr;
  388. }
  389. /* V R U B Y Q U E R Y P O I N T P C P */
  390. /*----------------------------------------------------------------------------
  391. %%Function: RubyQueryPointPcp
  392. %%Contact: antons
  393. ----------------------------------------------------------------------------*/
  394. LSERR WINAPI VRubyQueryPointPcp(
  395. PDOBJ pdobj, /*(IN): dobj to query */
  396. PCPOINTUV ppointuvQuery, /*(IN): query point (uQuery,vQuery) */
  397. PCLSQIN plsqin, /*(IN): query input */
  398. PLSQOUT plsqout) /*(OUT): query output */
  399. {
  400. PLSSUBL plssubl;
  401. long dupAdj;
  402. long dvpAdj;
  403. /*
  404. * Decide which line to to return based on the height of the point input
  405. */
  406. /* Assume main line */
  407. plssubl = pdobj->plssublMain;
  408. dupAdj = 0;
  409. dvpAdj = 0;
  410. if (ppointuvQuery->u > pdobj->dupMain)
  411. {
  412. /* hit second line */
  413. plssubl = pdobj->plssublRuby;
  414. dupAdj = pdobj->dupOffsetRuby;
  415. dvpAdj = pdobj->dvpOffsetRuby;
  416. }
  417. return CreateQueryResult(plssubl, dupAdj, dvpAdj, plsqin, plsqout);
  418. }
  419. /* V R U B Y Q U E R Y C P P P O I N T */
  420. /*----------------------------------------------------------------------------
  421. %%Function: RubyQueryCpPpoint
  422. %%Contact: antons
  423. ----------------------------------------------------------------------------*/
  424. LSERR WINAPI VRubyQueryCpPpoint(
  425. PDOBJ pdobj, /*(IN): dobj to query, */
  426. LSDCP dcp, /*(IN): dcp for the query */
  427. PCLSQIN plsqin, /*(IN): query input */
  428. PLSQOUT plsqout) /*(OUT): query output */
  429. {
  430. PLSSUBL plssubl;
  431. long dupAdj;
  432. long dvpAdj;
  433. BOOL fMain = fFalse;
  434. LSCP cpQuery = pdobj->cpStart + dcp;
  435. /* Assume ruby line */
  436. plssubl = pdobj->plssublRuby;
  437. dupAdj = pdobj->dupOffsetRuby;
  438. dvpAdj = pdobj->dvpOffsetRuby;
  439. /* + 1 means we include the cp of the object in the Ruby pronunciation line. */
  440. if (VRubyPronunciationLineFirst == pdobj->pilsobj->vrubysyntax)
  441. {
  442. /* Ruby pronunciation line is first */
  443. if (cpQuery >= pdobj->cpStartMain)
  444. {
  445. fMain = fTrue;
  446. }
  447. }
  448. else
  449. {
  450. /* Main text line is first */
  451. if (cpQuery < pdobj->cpStartRuby)
  452. {
  453. fMain = fTrue;
  454. }
  455. }
  456. if (fMain)
  457. {
  458. plssubl = pdobj->plssublMain;
  459. dupAdj = 0;
  460. dvpAdj = 0;
  461. }
  462. return CreateQueryResult(plssubl, dupAdj, dvpAdj, plsqin, plsqout);
  463. }
  464. /* V R U B I D I S P L A Y */
  465. /*----------------------------------------------------------------------------
  466. %%Function: VRubyDisplay
  467. %%Contact: antons
  468. ----------------------------------------------------------------------------*/
  469. LSERR WINAPI VRubyDisplay(
  470. PDOBJ pdobj, /*(IN): dobj to display */
  471. PCDISPIN pcdispin) /*(IN): display info */
  472. {
  473. LSERR lserr;
  474. UINT kDispMode = pcdispin->kDispMode;
  475. POINTUV ptAdd;
  476. POINT ptLine;
  477. /* display first line */
  478. lserr = LsDisplaySubline(pdobj->plssublMain, &pcdispin->ptPen, kDispMode,
  479. pcdispin->prcClip);
  480. if (lserr != lserrNone) return lserr;
  481. ptAdd.u = pdobj->dupOffsetRuby;
  482. ptAdd.v = pdobj->dvpOffsetRuby;
  483. LsPointXYFromPointUV(&pcdispin->ptPen, pdobj->lstflowParent, &ptAdd, &ptLine);
  484. return LsDisplaySubline(pdobj->plssublRuby, &ptLine, kDispMode, pcdispin->prcClip);
  485. }
  486. /* V R U B I D E S T R O Y D O B J */
  487. /*----------------------------------------------------------------------------
  488. %%Function: VRubyDestroyDobj
  489. %%Contact: antons
  490. ----------------------------------------------------------------------------*/
  491. LSERR WINAPI VRubyDestroyDobj(
  492. PDOBJ pdobj) /*(IN): dobj to destroy */
  493. {
  494. return VRubyFreeDobj (pdobj);
  495. }
  496. /* V R U B Y E N U M */
  497. /*----------------------------------------------------------------------------
  498. %%Function: VRubyEnum
  499. %%Contact: antons
  500. ----------------------------------------------------------------------------*/
  501. LSERR WINAPI VRubyEnum (
  502. PDOBJ pdobj, /*(IN): dobj to enumerate */
  503. PLSRUN plsrun, /*(IN): from DNODE */
  504. PCLSCHP plschp, /*(IN): from DNODE */
  505. LSCP cp, /*(IN): from DNODE */
  506. LSDCP dcp, /*(IN): from DNODE */
  507. LSTFLOW lstflow, /*(IN): text flow*/
  508. BOOL fReverse, /*(IN): enumerate in reverse order */
  509. BOOL fGeometryNeeded, /*(IN): */
  510. const POINT *ppt, /*(IN): starting position (top left), iff fGeometryNeeded */
  511. PCHEIGHTS pcheights, /*(IN): from DNODE, relevant iff fGeometryNeeded */
  512. long dupRun ) /*(IN): from DNODE, relevant iff fGeometryNeeded */
  513. {
  514. POINT ptMain;
  515. POINT ptRuby;
  516. POINTUV ptAdd;
  517. long dupMain = 0;
  518. long dupRuby = 0;
  519. LSERR lserr;
  520. LSTFLOW lstflowIgnored;
  521. if (fGeometryNeeded)
  522. {
  523. ptMain = *ppt;
  524. ptAdd.u = pdobj->dupOffsetRuby;
  525. ptAdd.v = pdobj->dvpOffsetRuby;
  526. LsPointXYFromPointUV(ppt, pdobj->lstflowParent, &ptAdd, &ptRuby);
  527. lserr = LssbGetDupSubline(pdobj->plssublMain, &lstflowIgnored, &dupMain);
  528. if (lserr != lserrNone) return lserr;
  529. lserr = LssbGetDupSubline(pdobj->plssublRuby, &lstflowIgnored, &dupRuby);
  530. if (lserr != lserrNone) return lserr;
  531. }
  532. return pdobj->pilsobj->vrcbk.pfnVRubyEnum (pdobj->pilsobj->pols, plsrun,
  533. plschp, cp, dcp, lstflow, fReverse, fGeometryNeeded, ppt, pcheights,
  534. dupRun, &ptMain, &pdobj->objdimMain.heightsPres, dupMain, &ptRuby,
  535. &pdobj->objdimRuby.heightsPres, dupRuby, pdobj->plssublMain,
  536. pdobj->plssublRuby);
  537. }
  538. /* V R U B I H A N D L E R I N I T */
  539. /*----------------------------------------------------------------------------
  540. %%Function: VRubyHandlerInit
  541. %%Contact: antons
  542. ----------------------------------------------------------------------------*/
  543. LSERR WINAPI LsGetVRubyLsimethods ( LSIMETHODS *plsim )
  544. {
  545. plsim->pfnCreateILSObj = VRubyCreateILSObj;
  546. plsim->pfnDestroyILSObj = VRubyDestroyILSObj;
  547. plsim->pfnSetDoc = VRubySetDoc;
  548. plsim->pfnCreateLNObj = VRubyCreateLNObj;
  549. plsim->pfnDestroyLNObj = VRubyDestroyLNObj;
  550. plsim->pfnFmt = VRubyFmt;
  551. plsim->pfnFmtResume = ObjHelpFmtResume;
  552. plsim->pfnGetModWidthPrecedingChar = ObjHelpGetModWidthChar;
  553. plsim->pfnGetModWidthFollowingChar = ObjHelpGetModWidthChar;
  554. plsim->pfnTruncateChunk = SobjTruncateChunk;
  555. plsim->pfnFindPrevBreakChunk = SobjFindPrevBreakChunk;
  556. plsim->pfnFindNextBreakChunk = SobjFindNextBreakChunk;
  557. plsim->pfnForceBreakChunk = SobjForceBreakChunk;
  558. plsim->pfnSetBreak = VRubySetBreak;
  559. plsim->pfnGetSpecialEffectsInside = VRubyGetSpecialEffectsInside;
  560. plsim->pfnFExpandWithPrecedingChar = ObjHelpFExpandWithPrecedingChar;
  561. plsim->pfnFExpandWithFollowingChar = ObjHelpFExpandWithFollowingChar;
  562. plsim->pfnCalcPresentation = VRubyCalcPresentation;
  563. plsim->pfnQueryPointPcp = VRubyQueryPointPcp;
  564. plsim->pfnQueryCpPpoint = VRubyQueryCpPpoint;
  565. plsim->pfnDisplay = VRubyDisplay;
  566. plsim->pfnDestroyDObj = VRubyDestroyDobj;
  567. plsim->pfnEnum = VRubyEnum;
  568. return lserrNone;
  569. }