Leaked source code of windows server 2003
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.

633 lines
18 KiB

  1. #include "lsmem.h"
  2. #include "limits.h"
  3. #include "tatenak.h"
  4. #include "objhelp.h"
  5. #include "lscbk.h"
  6. #include "lsdevres.h"
  7. #include "pdobj.h"
  8. #include "objdim.h"
  9. #include "plssubl.h"
  10. #include "plsdnode.h"
  11. #include "pilsobj.h"
  12. #include "lscrsubl.h"
  13. #include "lssubset.h"
  14. #include "lsdnset.h"
  15. #include "zqfromza.h"
  16. #include "sobjhelp.h"
  17. #include "lsdocinf.h"
  18. #include "fmti.h"
  19. #include "posichnk.h"
  20. #include "locchnk.h"
  21. #include "lsdnfin.h"
  22. #include "brko.h"
  23. #include "lspap.h"
  24. #include "plspap.h"
  25. #include "lsqsubl.h"
  26. #include "dispi.h"
  27. #include "lsdssubl.h"
  28. #include "lsems.h"
  29. #include "dispmisc.h"
  30. #include "lstfset.h"
  31. #include "sobjhelp.h"
  32. #define TATENAKAYOKO_ESC_CNT 1
  33. struct ilsobj
  34. {
  35. POLS pols;
  36. LSCBK lscbk;
  37. PLSC plsc;
  38. LSDEVRES lsdevres;
  39. LSESC lsescTatenakayoko;
  40. TATENAKAYOKOCBK tcbk; /* Callbacks to client application */
  41. };
  42. typedef struct SUBLINEDNODES
  43. {
  44. PLSDNODE plsdnStart;
  45. PLSDNODE plsdnEnd;
  46. } SUBLINEDNODES, *PSUBLINEDNODES;
  47. struct dobj
  48. {
  49. SOBJHELP sobjhelp; /* common simple object area */
  50. PILSOBJ pilsobj; /* ILS object */
  51. LSCP cpStart; /* Starting LS cp for object */
  52. LSTFLOW lstflowParent; /* text flow of the parent subline */
  53. LSTFLOW lstflowSubline; /* text flow in Tatenakayoko Subline
  54. (must be Rotate90 [lstflowParent] */
  55. PLSSUBL plssubl; /* Handle to subline for Tatenakayoko */
  56. long dvpDescentReserved; /* Part of descent reserved for client */
  57. OBJDIM objdimT; /* Objdim of the Tatenakayoko */
  58. /* (dupSubline, duvSubline) is vector from starting point of Tatenakayoko to */
  59. /* the starting point of its subline in coordinate system of parent subline */
  60. long dupSubline;
  61. long dvpSubline;
  62. };
  63. static const POINTUV pointuvOrigin00 = { 0, 0 };
  64. static const POINT pointOrigin00 = { 0, 0 };
  65. /* F R E E D O B J */
  66. /*----------------------------------------------------------------------------
  67. %%Function: TatenakayokoFreeDobj
  68. %%Contact: antons
  69. Free all resources associated with this Tatenakayoko dobj.
  70. ----------------------------------------------------------------------------*/
  71. static LSERR TatenakayokoFreeDobj(PDOBJ pdobj)
  72. {
  73. LSERR lserr = lserrNone;
  74. PILSOBJ pilsobj = pdobj->pilsobj;
  75. if (pdobj->plssubl != NULL)
  76. {
  77. lserr = LsDestroySubline(pdobj->plssubl);
  78. }
  79. pilsobj->lscbk.pfnDisposePtr(pilsobj->pols, pdobj);
  80. return lserr;
  81. }
  82. /* T A T E N A K A Y O K O C R E A T E I L S O B J */
  83. /*----------------------------------------------------------------------------
  84. %%Function: TatenakayokoCreateILSObj
  85. %%Contact: ricksa
  86. CreateILSObj
  87. Create the ILS object for all Tatenakayoko objects.
  88. ----------------------------------------------------------------------------*/
  89. LSERR WINAPI TatenakayokoCreateILSObj(
  90. POLS pols, /* (IN): client application context */
  91. PLSC plsc, /* (IN): LS context */
  92. PCLSCBK pclscbk, /* (IN): callbacks to client application */
  93. DWORD idObj, /* (IN): id of the object */
  94. PILSOBJ *ppilsobj) /* (OUT): object ilsobj */
  95. {
  96. PILSOBJ pilsobj;
  97. LSERR lserr;
  98. TATENAKAYOKOINIT tatenakayokoinit;
  99. tatenakayokoinit.dwVersion = TATENAKAYOKO_VERSION;
  100. /* Get initialization data */
  101. lserr = pclscbk->pfnGetObjectHandlerInfo(pols, idObj, &tatenakayokoinit);
  102. if (lserr != lserrNone)
  103. {
  104. *ppilsobj = NULL;
  105. return lserr;
  106. }
  107. pilsobj = pclscbk->pfnNewPtr(pols, sizeof(*pilsobj));
  108. if (pilsobj == NULL)
  109. {
  110. *ppilsobj = NULL;
  111. return lserrOutOfMemory;
  112. }
  113. pilsobj->pols = pols;
  114. pilsobj->lscbk = *pclscbk;
  115. pilsobj->plsc = plsc;
  116. pilsobj->lsescTatenakayoko.wchFirst = tatenakayokoinit.wchEndTatenakayoko;
  117. pilsobj->lsescTatenakayoko.wchLast = tatenakayokoinit.wchEndTatenakayoko;
  118. pilsobj->tcbk = tatenakayokoinit.tatenakayokocbk;
  119. *ppilsobj = pilsobj;
  120. return lserrNone;
  121. }
  122. /* T A T E N A K A Y O K O D E S T R O Y I L S O B J */
  123. /*----------------------------------------------------------------------------
  124. %%Function: TatenakayokoDestroyILSObj
  125. %%Contact: ricksa
  126. DestroyILSObj
  127. Free all resources assocaiated with Tatenakayoko ILS object.
  128. ----------------------------------------------------------------------------*/
  129. LSERR WINAPI TatenakayokoDestroyILSObj(
  130. PILSOBJ pilsobj) /* (IN): object ilsobj */
  131. {
  132. pilsobj->lscbk.pfnDisposePtr(pilsobj->pols, pilsobj);
  133. return lserrNone;
  134. }
  135. /* T A T E N A K A Y O K O S E T D O C */
  136. /*----------------------------------------------------------------------------
  137. %%Function: TatenakayokoSetDoc
  138. %%Contact: ricksa
  139. SetDoc
  140. Keep track of device information for scaling purposes.
  141. ----------------------------------------------------------------------------*/
  142. LSERR WINAPI TatenakayokoSetDoc(
  143. PILSOBJ pilsobj, /* (IN): object ilsobj */
  144. PCLSDOCINF pclsdocinf) /* (IN): initialization data of the document level */
  145. {
  146. pilsobj->lsdevres = pclsdocinf->lsdevres;
  147. return lserrNone;
  148. }
  149. /* T A T E N A K A Y O K O C R E A T E L N O B J */
  150. /*----------------------------------------------------------------------------
  151. %%Function: TatenakayokoCreateLNObj
  152. %%Contact: ricksa
  153. CreateLNObj
  154. Create the Line Object for the Tatenakayoko. No real need for a line
  155. object so don't allocated it.
  156. ----------------------------------------------------------------------------*/
  157. LSERR WINAPI TatenakayokoCreateLNObj(
  158. PCILSOBJ pcilsobj, /* (IN): object ilsobj */
  159. PLNOBJ *pplnobj) /* (OUT): object lnobj */
  160. {
  161. *pplnobj = (PLNOBJ) pcilsobj;
  162. return lserrNone;
  163. }
  164. /* T A T E N A K A Y O K O D E S T R O Y L N O B J */
  165. /*----------------------------------------------------------------------------
  166. %%Function: TatenakayokoDestroyLNObj
  167. %%Contact: ricksa
  168. DestroyLNObj
  169. Frees resources associated with the Tatenakayoko line object. Since
  170. there isn't any this is a no-op.
  171. ----------------------------------------------------------------------------*/
  172. LSERR WINAPI TatenakayokoDestroyLNObj(
  173. PLNOBJ plnobj) /* (OUT): object lnobj */
  174. {
  175. Unreferenced(plnobj);
  176. return lserrNone;
  177. }
  178. /* T A T E N A K A Y O K O F M T */
  179. /*----------------------------------------------------------------------------
  180. %%Function: TatenakayokoFmt
  181. %%Contact: ricksa
  182. Fmt
  183. Format the Tatenakayoko object.
  184. ----------------------------------------------------------------------------*/
  185. LSERR WINAPI TatenakayokoFmt(
  186. PLNOBJ plnobj, /* (IN): object lnobj */
  187. PCFMTIN pcfmtin, /* (IN): formatting input */
  188. FMTRES *pfmtres) /* (OUT): formatting result */
  189. {
  190. static LSTFLOW lstflowRotate90[] =
  191. {
  192. lstflowNE, /* [ lstflowES ] */
  193. lstflowNW, /* [ lstflowEN ] */
  194. lstflowEN, /* [ lstflowSE ] */
  195. lstflowES, /* [ lstflowSW ] */
  196. lstflowSE, /* [ lstflowWS ] */
  197. lstflowSW, /* [ lstflowWN ] */
  198. lstflowWN, /* [ lstflowNE ] */
  199. lstflowWS /* [ lstflowNW ] */
  200. };
  201. PDOBJ pdobj;
  202. LSERR lserr;
  203. PILSOBJ pilsobj = (PILSOBJ) plnobj;
  204. POLS pols = pilsobj->pols;
  205. LSCP cpStartMain = pcfmtin->lsfgi.cpFirst + 1;
  206. LSCP cpOut;
  207. LSTFLOW lstflow = pcfmtin->lsfgi.lstflow;
  208. FMTRES fmtres;
  209. FMTRES fmtr = fmtrCompletedRun;
  210. /*
  211. * Allocate the DOBJ
  212. */
  213. pdobj = pilsobj->lscbk.pfnNewPtr(pols, sizeof(*pdobj));
  214. if (NULL == pdobj)
  215. {
  216. return lserrOutOfMemory;
  217. }
  218. ZeroMemory(pdobj, sizeof(*pdobj));
  219. pdobj->pilsobj = pilsobj;
  220. pdobj->cpStart = pcfmtin->lsfgi.cpFirst;
  221. pdobj->lstflowParent = lstflow;
  222. pdobj->lstflowSubline = lstflowRotate90 [lstflow];
  223. /*
  224. * Build main line of text
  225. */
  226. lserr = FormatLine(pilsobj->plsc, cpStartMain, LONG_MAX, pdobj->lstflowSubline,
  227. &pdobj->plssubl, TATENAKAYOKO_ESC_CNT, &pilsobj->lsescTatenakayoko,
  228. &pdobj->objdimT, &cpOut, NULL, NULL, &fmtres);
  229. if (lserr != lserrNone)
  230. {
  231. TatenakayokoFreeDobj (pdobj);
  232. return lserr;
  233. }
  234. Assert (fmtres != fmtrExceededMargin);
  235. /*
  236. * Calculate the object dimensions.
  237. */
  238. lserr = pilsobj->tcbk.pfnGetTatenakayokoLinePosition(pols, pdobj->cpStart, pdobj->lstflowParent,
  239. pcfmtin->lsfrun.plsrun, pdobj->objdimT.dur,
  240. &pdobj->sobjhelp.objdimAll.heightsRef,
  241. &pdobj->sobjhelp.objdimAll.heightsPres,
  242. &pdobj->dvpDescentReserved);
  243. if (lserr != lserrNone)
  244. {
  245. TatenakayokoFreeDobj (pdobj);
  246. return lserr;
  247. }
  248. /* set width of Tatenakayoko relative to text flow of line that contains it. */
  249. pdobj->sobjhelp.objdimAll.dur = pdobj->objdimT.heightsRef.dvAscent
  250. + pdobj->objdimT.heightsRef.dvDescent;
  251. /*
  252. * Note: the + 2 in the following is because cpStartMain is + 1 from the
  253. * actual start of the object (it is the cpStartMain of the Tatenakayoko
  254. * data) and additional + 1 for the escape character at the end of the
  255. * tatenakayoko.
  256. */
  257. pdobj->sobjhelp.dcp = cpOut - cpStartMain + 2;
  258. lserr = LsdnFinishRegular(pilsobj->plsc, pdobj->sobjhelp.dcp,
  259. pcfmtin->lsfrun.plsrun, pcfmtin->lsfrun.plschp, pdobj,
  260. &pdobj->sobjhelp.objdimAll);
  261. if (lserr != lserrNone)
  262. {
  263. TatenakayokoFreeDobj (pdobj);
  264. return lserr;
  265. }
  266. lserr = LsdnSetRigidDup ( pilsobj->plsc, pcfmtin->plsdnTop,
  267. pdobj->objdimT.heightsPres.dvAscent +
  268. pdobj->objdimT.heightsPres.dvDescent );
  269. if (lserr != lserrNone)
  270. {
  271. TatenakayokoFreeDobj (pdobj);
  272. return lserr;
  273. }
  274. if (pcfmtin->lsfgi.urPen + pdobj->sobjhelp.objdimAll.dur > pcfmtin->lsfgi.urColumnMax)
  275. {
  276. fmtr = fmtrExceededMargin;
  277. }
  278. *pfmtres = fmtr;
  279. return lserrNone;
  280. }
  281. /* T A T E N A K A Y O K O G E T S P E C I A L E F F E C T S I N S I D E */
  282. /*----------------------------------------------------------------------------
  283. %%Function: TatenakayokoGetSpecialEffectsInside
  284. %%Contact: ricksa
  285. GetSpecialEffectsInside
  286. .
  287. ----------------------------------------------------------------------------*/
  288. LSERR WINAPI TatenakayokoGetSpecialEffectsInside(
  289. PDOBJ pdobj, /* (IN): dobj */
  290. UINT *pEffectsFlags) /* (OUT): Special effects for this object */
  291. {
  292. return LsGetSpecialEffectsSubline(pdobj->plssubl, pEffectsFlags);
  293. }
  294. /* G E T U F R O M L S T F L O W */
  295. /*----------------------------------------------------------------------------
  296. %%Function: GetUFromLstflow
  297. %%Contact: antons
  298. GetUFromLstflow
  299. Gets XY vector corresponding to U-direction of lstflow.
  300. ----------------------------------------------------------------------------*/
  301. void GetUFromLstflow (LSTFLOW lstflow, POINT * ppoint)
  302. {
  303. POINTUV ptOneU = {1, 0};
  304. LsPointXYFromPointUV (& pointOrigin00, lstflow, &ptOneU, ppoint);
  305. }
  306. /* G E T V F R O M L S T F L O W */
  307. /*----------------------------------------------------------------------------
  308. %%Function: GetVFromLstflow
  309. %%Contact: antons
  310. GetVFromLstflow
  311. Gets XY vector corresponding to V-direction of lstflow.
  312. ----------------------------------------------------------------------------*/
  313. void GetVFromLstflow (LSTFLOW lstflow, POINT * ppoint)
  314. {
  315. POINTUV ptOneV = {0, 1};
  316. LsPointXYFromPointUV (& pointOrigin00, lstflow, &ptOneV, ppoint);
  317. }
  318. /* T A T E N A K A Y O K O C A L C P R E S E N T A T I O N */
  319. /*----------------------------------------------------------------------------
  320. %%Function: TatenakayokoCalcPresentation
  321. %%Contact: antons
  322. CalcPresentation
  323. This just makes the line match the calculated presentation of the line.
  324. ----------------------------------------------------------------------------*/
  325. LSERR WINAPI TatenakayokoCalcPresentation(
  326. PDOBJ pdobj, /* (IN): dobj */
  327. long dup, /* (IN): dup of dobj */
  328. LSKJUST lskjust, /* (IN): Justification type */
  329. BOOL fLastVisibleOnLine ) /* (IN): Is this object last visible on line? */
  330. {
  331. POINTUV ptTemp;
  332. POINTUV pointuv;
  333. POINT ptSublineV;
  334. POINT ptParentU;
  335. Unreferenced (fLastVisibleOnLine);
  336. Unreferenced (lskjust);
  337. pdobj->dupSubline = 0;
  338. pdobj->dvpSubline = 0;
  339. GetUFromLstflow (pdobj->lstflowParent, &ptParentU);
  340. GetVFromLstflow (pdobj->lstflowSubline, &ptSublineV);
  341. /* Assert that Main U is parallel to Subline V */
  342. Assert (ptParentU.x * ptSublineV.y - ptParentU.y * ptSublineV.x == 0);
  343. pointuv.u = - (pdobj->sobjhelp.objdimAll.heightsPres.dvDescent
  344. - pdobj->dvpDescentReserved);
  345. pointuv.v = 0;
  346. LsPointUV2FromPointUV1 (pdobj->lstflowSubline, & pointuvOrigin00, & pointuv,
  347. pdobj->lstflowParent, & ptTemp);
  348. pdobj->dupSubline += ptTemp.u;
  349. pdobj->dvpSubline += ptTemp.v;
  350. if ((ptParentU.x == ptSublineV.x) && (ptParentU.y == ptSublineV.y))
  351. {
  352. pdobj->dupSubline += pdobj->objdimT.heightsPres.dvDescent;
  353. }
  354. else
  355. {
  356. pdobj->dupSubline += pdobj->objdimT.heightsPres.dvAscent;
  357. }
  358. Unreferenced(dup);
  359. return LsMatchPresSubline(pdobj->plssubl);
  360. }
  361. /* T A T E N A K A Y O K O Q U E R Y P O I N T P C P */
  362. /*----------------------------------------------------------------------------
  363. %%Function: TatenakayokoQueryPointPcp
  364. %%Contact: ricksa
  365. Map dup to dcp
  366. This just passes the offset of the subline to the helper function
  367. which will format the output.
  368. ----------------------------------------------------------------------------*/
  369. LSERR WINAPI TatenakayokoQueryPointPcp(
  370. PDOBJ pdobj, /*(IN): dobj to query */
  371. PCPOINTUV ppointuvQuery, /*(IN): query point (uQuery,vQuery) */
  372. PCLSQIN plsqin, /*(IN): query input */
  373. PLSQOUT plsqout) /*(OUT): query output */
  374. {
  375. Unreferenced(ppointuvQuery);
  376. return CreateQueryResult
  377. (pdobj->plssubl, pdobj->dupSubline, pdobj->dvpSubline, plsqin, plsqout);
  378. }
  379. /* T A T E N A K A Y O K O Q U E R Y C P P P O I N T */
  380. /*----------------------------------------------------------------------------
  381. %%Function: TatenakayokoQueryCpPpoint
  382. %%Contact: ricksa
  383. Map dcp to dup
  384. This just passes the offset of the subline to the helper function
  385. which will format the output.
  386. ----------------------------------------------------------------------------*/
  387. LSERR WINAPI TatenakayokoQueryCpPpoint(
  388. PDOBJ pdobj, /*(IN): dobj to query */
  389. LSDCP dcp, /*(IN): dcp for the query */
  390. PCLSQIN plsqin, /*(IN): query input */
  391. PLSQOUT plsqout) /*(OUT): query output */
  392. {
  393. Unreferenced(dcp);
  394. return CreateQueryResult(pdobj->plssubl,
  395. pdobj->dupSubline, pdobj->dvpSubline, plsqin, plsqout);
  396. }
  397. /* T A T E N A K A Y O K O D I S P L A Y */
  398. /*----------------------------------------------------------------------------
  399. %%Function: TatenakayokoDisplay
  400. %%Contact: ricksa
  401. Display
  402. This calculates the position of the subline for the
  403. display and then displays it.
  404. ----------------------------------------------------------------------------*/
  405. LSERR WINAPI TatenakayokoDisplay(
  406. PDOBJ pdobj, /*(IN): dobj to display */
  407. PCDISPIN pcdispin) /*(IN): info for display */
  408. {
  409. POINT ptLine;
  410. POINTUV ptAdd;
  411. ptAdd.u = pdobj->dupSubline;
  412. ptAdd.v = pdobj->dvpSubline;
  413. LsPointXYFromPointUV(&pcdispin->ptPen, pdobj->lstflowParent, &ptAdd, &ptLine);
  414. /* display the Tatenakayoko line */
  415. return LsDisplaySubline(pdobj->plssubl, &ptLine, pcdispin->kDispMode,
  416. pcdispin->prcClip);
  417. }
  418. /* T A T E N A K A Y O K O D E S T R O Y D O B J */
  419. /*----------------------------------------------------------------------------
  420. %%Function: TatenakayokoDestroyDobj
  421. %%Contact: ricksa
  422. DestroyDobj
  423. Free all resources connected with the input dobj.
  424. ----------------------------------------------------------------------------*/
  425. LSERR WINAPI TatenakayokoDestroyDobj(
  426. PDOBJ pdobj) /*(IN): dobj to destroy */
  427. {
  428. return TatenakayokoFreeDobj(pdobj);
  429. }
  430. /* T A T E N A K A Y O K O E N U M */
  431. /*----------------------------------------------------------------------------
  432. %%Function: TatenakayokoEnum
  433. %%Contact: ricksa
  434. Enum
  435. Enumeration callback - passed to client.
  436. ----------------------------------------------------------------------------*/
  437. LSERR WINAPI TatenakayokoEnum(
  438. PDOBJ pdobj, /*(IN): dobj to enumerate */
  439. PLSRUN plsrun, /*(IN): from DNODE */
  440. PCLSCHP plschp, /*(IN): from DNODE */
  441. LSCP cp, /*(IN): from DNODE */
  442. LSDCP dcp, /*(IN): from DNODE */
  443. LSTFLOW lstflow, /*(IN): text flow*/
  444. BOOL fReverse, /*(IN): enumerate in reverse order */
  445. BOOL fGeometryNeeded, /*(IN): */
  446. const POINT *pt, /*(IN): starting position (top left), iff fGeometryNeeded */
  447. PCHEIGHTS pcheights, /*(IN): from DNODE, relevant iff fGeometryNeeded */
  448. long dupRun) /*(IN): from DNODE, relevant iff fGeometryNeeded */
  449. {
  450. return pdobj->pilsobj->tcbk.pfnTatenakayokoEnum(pdobj->pilsobj->pols, plsrun,
  451. plschp, cp, dcp, lstflow, fReverse, fGeometryNeeded, pt, pcheights,
  452. dupRun, pdobj->lstflowParent, pdobj->plssubl);
  453. }
  454. /* T A T E N A K A Y O K O H A N D L E R I N I T */
  455. /*----------------------------------------------------------------------------
  456. %%Function: TatenakayokoHandlerInit
  457. %%Contact: ricksa
  458. Initialize global Tatenakayoko data and return LSIMETHODS.
  459. ----------------------------------------------------------------------------*/
  460. LSERR WINAPI LsGetTatenakayokoLsimethods(
  461. LSIMETHODS *plsim)
  462. {
  463. plsim->pfnCreateILSObj = TatenakayokoCreateILSObj;
  464. plsim->pfnDestroyILSObj = TatenakayokoDestroyILSObj;
  465. plsim->pfnSetDoc = TatenakayokoSetDoc;
  466. plsim->pfnCreateLNObj = TatenakayokoCreateLNObj;
  467. plsim->pfnDestroyLNObj = TatenakayokoDestroyLNObj;
  468. plsim->pfnFmt = TatenakayokoFmt;
  469. plsim->pfnFmtResume = ObjHelpFmtResume;
  470. plsim->pfnGetModWidthPrecedingChar = ObjHelpGetModWidthChar;
  471. plsim->pfnGetModWidthFollowingChar = ObjHelpGetModWidthChar;
  472. plsim->pfnTruncateChunk = SobjTruncateChunk;
  473. plsim->pfnFindPrevBreakChunk = SobjFindPrevBreakChunk;
  474. plsim->pfnFindNextBreakChunk = SobjFindNextBreakChunk;
  475. plsim->pfnForceBreakChunk = SobjForceBreakChunk;
  476. plsim->pfnSetBreak = ObjHelpSetBreak;
  477. plsim->pfnGetSpecialEffectsInside = TatenakayokoGetSpecialEffectsInside;
  478. plsim->pfnFExpandWithPrecedingChar = ObjHelpFExpandWithPrecedingChar;
  479. plsim->pfnFExpandWithFollowingChar = ObjHelpFExpandWithFollowingChar;
  480. plsim->pfnCalcPresentation = TatenakayokoCalcPresentation;
  481. plsim->pfnQueryPointPcp = TatenakayokoQueryPointPcp;
  482. plsim->pfnQueryCpPpoint = TatenakayokoQueryCpPpoint;
  483. plsim->pfnDisplay = TatenakayokoDisplay;
  484. plsim->pfnDestroyDObj = TatenakayokoDestroyDobj;
  485. plsim->pfnEnum = TatenakayokoEnum;
  486. return lserrNone;
  487. }