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.

749 lines
18 KiB

  1. // File: Parse.cpp
  2. // Author: Michael Marr (mikemarr)
  3. //
  4. // History:
  5. // -@- 09/23/97 (mikemarr) copied from projects\vector2d
  6. #include "StdAfx.h"
  7. #include "Parse.h"
  8. #define fGSCALE 1.f
  9. class CAdobeFormatConverter {
  10. public:
  11. CAdobeFormatConverter();
  12. ~CAdobeFormatConverter() {}
  13. HRESULT Parse(const char *pData, DWORD nFileLength, RenderCmd **ppCmds);
  14. private:
  15. HRESULT ParseProlog();
  16. HRESULT ParseScript();
  17. HRESULT ParseSetup();
  18. HRESULT ParseObjects();
  19. HRESULT ParseCompoundPath();
  20. HRESULT ParsePath();
  21. HRESULT ParsePaintStyle(const char *&pEnd);
  22. HRESULT ParsePathGeometry(const char *pEnd);
  23. HRESULT ParseTrailers();
  24. private:
  25. void EatLine();
  26. const char * FindNextLine(const char *pch);
  27. const char * FindLF(const char *pch);
  28. const char * FindSpace(const char *pch);
  29. private:
  30. const char * m_pData, *m_pLimit;
  31. float m_fWidth, m_fHeight;
  32. // float m_fMaxHeight;
  33. bool m_bNoBrush, m_bNoPen;
  34. DXFPOINT m_rgPoints[nMAXPOINTS];
  35. DXFPOINT * m_pCurPoint;
  36. BYTE m_rgCodes[nMAXPOINTS];
  37. BYTE * m_pCurCode;
  38. RenderCmd m_rgRenderCmds[nMAXPOLYS];
  39. RenderCmd * m_pCurRenderCmd;
  40. PolyInfo m_rgPolyInfos[nMAXPOLYS];
  41. PolyInfo * m_pCurPolyInfo;
  42. BrushInfo m_rgBrushInfos[nMAXBRUSHES];
  43. BrushInfo * m_pCurBrushInfo;
  44. PenInfo m_rgPenInfos[nMAXPENS];
  45. PenInfo * m_pCurPenInfo;
  46. };
  47. inline bool
  48. mmIsSpace(char ch)
  49. {
  50. return ((ch == ' ') || (ch == chLINEFEED) || (ch == chCARRIAGERETURN));
  51. // return isspace(ch) != 0;
  52. }
  53. inline bool
  54. mmIsDigit(char ch)
  55. {
  56. return ((ch >= '0') && (ch <= '9'));
  57. // return isdigit(ch) != 0;
  58. }
  59. float
  60. mmSimpleAtoF(const char *&pData)
  61. {
  62. const char *pSrc = pData;
  63. // eat white space
  64. while (mmIsSpace(*pSrc)) pSrc++;
  65. bool bNeg;
  66. if (*pSrc == '-') {
  67. bNeg = true;
  68. pSrc++;
  69. } else {
  70. bNeg = false;
  71. }
  72. // get digits before the decimal point
  73. float f;
  74. if (mmIsDigit(*pSrc)) {
  75. f = float(*pSrc++ - '0');
  76. while (mmIsDigit(*pSrc))
  77. f = f * 10.f + float(*pSrc++ - '0');
  78. } else {
  79. f = 0.f;
  80. }
  81. if (*pSrc == '.')
  82. pSrc++;
  83. // get digits after the decimal point
  84. float fDec = 0.1f;
  85. while (mmIsDigit(*pSrc)) {
  86. f += (float(*pSrc++ - '0') * fDec);
  87. fDec *= 0.1f;
  88. }
  89. // REVIEW: assume no exponent for now
  90. pData = pSrc;
  91. return (bNeg ? -f : f);
  92. }
  93. inline const char *
  94. CAdobeFormatConverter::FindLF(const char *pch)
  95. {
  96. // find the linefeed character
  97. while ((*pch != chLINEFEED) && (*pch != chCARRIAGERETURN)) pch++;
  98. MMASSERT(pch <= m_pLimit);
  99. return pch;
  100. }
  101. inline const char *
  102. CAdobeFormatConverter::FindNextLine(const char *pch)
  103. {
  104. // find the linefeed character
  105. while (*pch++ != chLINEFEED);
  106. // check if there is also carriage return
  107. if (*pch == chCARRIAGERETURN)
  108. pch++;
  109. MMASSERT(pch <= m_pLimit);
  110. return pch;
  111. }
  112. inline const char *
  113. CAdobeFormatConverter::FindSpace(const char *pch)
  114. {
  115. // find the linefeed character
  116. while (!mmIsSpace(*pch)) pch++;
  117. MMASSERT(pch <= m_pLimit);
  118. return pch;
  119. }
  120. inline void
  121. CAdobeFormatConverter::EatLine()
  122. {
  123. m_pData = FindNextLine(m_pData);
  124. }
  125. CAdobeFormatConverter::CAdobeFormatConverter()
  126. {
  127. m_pData = m_pLimit = NULL;
  128. m_fWidth = m_fHeight = 0.f;
  129. // m_fMaxHeight = 0.f;
  130. m_bNoBrush = m_bNoPen = true;
  131. }
  132. HRESULT
  133. CAdobeFormatConverter::Parse(const char *pData, DWORD nFileLength, RenderCmd **ppCmds)
  134. {
  135. // MMTRACE("Parse\n");
  136. HRESULT hr = S_OK;
  137. if (ppCmds == NULL)
  138. return E_POINTER;
  139. if (!pData || !nFileLength)
  140. return E_INVALIDARG;
  141. m_pData = pData;
  142. m_pLimit = pData + nFileLength;
  143. // intialize command storage stuff
  144. m_pCurPoint = m_rgPoints;
  145. m_pCurCode = m_rgCodes;
  146. m_pCurPolyInfo = m_rgPolyInfos;
  147. m_pCurRenderCmd = m_rgRenderCmds;
  148. m_pCurBrushInfo = m_rgBrushInfos;
  149. m_pCurPenInfo = m_rgPenInfos;
  150. CHECK_HR(hr = ParseProlog());
  151. CHECK_HR(hr = ParseScript());
  152. e_Exit:
  153. // write a stop command to the end
  154. m_pCurRenderCmd->nType = typeSTOP;
  155. m_pCurRenderCmd->pvData = NULL;
  156. *ppCmds = m_rgRenderCmds;
  157. return hr;
  158. }
  159. HRESULT
  160. CAdobeFormatConverter::ParseProlog()
  161. {
  162. // MMTRACE("ParseProlog\n");
  163. const char *szSearch;
  164. // extract the image dimensions
  165. float f1, f2;
  166. // bounding box is supposed to be a required field with the proper numbers
  167. szSearch = "%%BoundingBox:";
  168. m_pData = strstr(m_pData, szSearch);
  169. m_pData = FindSpace(m_pData);
  170. f1 = mmSimpleAtoF(m_pData);
  171. f2 = mmSimpleAtoF(m_pData);
  172. m_fWidth = mmSimpleAtoF(m_pData);
  173. m_fHeight = mmSimpleAtoF(m_pData);
  174. // if (sscanf(m_pData, "%f %f %f %f", &f1, &f2, &m_fWidth, &m_fHeight) != 4)
  175. // return E_FAIL;
  176. if ((m_fWidth <= 0.f) || (m_fHeight < 0.f))
  177. return E_FAIL;
  178. // m_fMaxHeight = float(m_nHeight);
  179. // search until we find end string
  180. szSearch = "%%EndProlog";
  181. m_pData = strstr(m_pData, szSearch);
  182. if (m_pData == NULL)
  183. return E_FAIL;
  184. EatLine();
  185. return S_OK;
  186. }
  187. HRESULT
  188. CAdobeFormatConverter::ParseScript()
  189. {
  190. // MMTRACE("ParseScript\n");
  191. HRESULT hr;
  192. if (FAILED(hr = ParseSetup()) ||
  193. FAILED(hr = ParseObjects()) ||
  194. FAILED(hr = ParseTrailers()))
  195. return hr;
  196. return S_OK;
  197. }
  198. HRESULT
  199. CAdobeFormatConverter::ParseSetup()
  200. {
  201. // MMTRACE("ParseSetup\n");
  202. const char *szSearch;
  203. // search until we find end string
  204. szSearch = "%%EndSetup";
  205. m_pData = strstr(m_pData, szSearch);
  206. if (m_pData == NULL)
  207. return E_FAIL;
  208. EatLine();
  209. return S_OK;
  210. }
  211. HRESULT
  212. CAdobeFormatConverter::ParseObjects()
  213. {
  214. // MMTRACE("ParseObjects\n");
  215. HRESULT hr = S_OK;
  216. const char *szPageTrailer = "%%PageTrailer";
  217. const char *szTrailer = "%%Trailer";
  218. int cPageTrailer = strlen(szPageTrailer);
  219. int cTrailer = strlen(szTrailer);
  220. // process dimensions
  221. /* const char *pEnd;
  222. pEnd = FindLF(m_pData);
  223. // pEnd = strchr(m_pData, '\n');
  224. if ((pEnd[-1] == 'b') && (pEnd[-2] == 'L')) {
  225. // get the dimensions out
  226. int n1, n2, n3, n4, n5, n6, n7, n8;
  227. if ((sscanf(m_pData, "%d %d %d %d %d %d %d %d %d %d %d",
  228. &n1, &n2, &n3, &n4, &n5, &n6, &n7, &n8, &m_nWidth, &m_nHeight) != 10) ||
  229. (m_nWidth <= 0) || (m_nHeight < 0))
  230. {
  231. return E_FAIL;
  232. }
  233. m_fMaxHeight = float(m_nHeight);
  234. m_pData = FindNextLine(pEnd);
  235. }
  236. pEnd = FindLF(m_pData);
  237. // pEnd = strchr(m_pData, '\n');
  238. if ((pEnd[-1] == 'n') && (pEnd[-2] == 'L')) {
  239. // skip layer information
  240. m_pData = FindNextLine(pEnd);
  241. }
  242. */
  243. for (;;) {
  244. switch (m_pData[0]) {
  245. case '%':
  246. if ((strncmp(m_pData, szPageTrailer, cPageTrailer) == 0) ||
  247. (strncmp(m_pData, szTrailer, cTrailer) == 0))
  248. {
  249. // end of object definitions
  250. goto e_Exit;
  251. } else {
  252. // comment
  253. EatLine();
  254. }
  255. break;
  256. case '*':
  257. if (m_pData[1] == 'u')
  258. CHECK_HR(hr = ParseCompoundPath());
  259. else {
  260. hr = E_FAIL;
  261. goto e_Exit;
  262. }
  263. break;
  264. default:
  265. CHECK_HR(hr = ParsePath());
  266. break;
  267. }
  268. }
  269. e_Exit:
  270. if (hr == S_OK)
  271. EatLine();
  272. return hr;
  273. }
  274. HRESULT
  275. CAdobeFormatConverter::ParseCompoundPath()
  276. {
  277. // MMTRACE("ParseCompoundPath\n");
  278. HRESULT hr = S_OK;
  279. // remove the "*u"
  280. MMASSERT((m_pData[0] == '*') && (m_pData[1] == 'u'));
  281. // if (strncmp(m_pData, "*u", 2) != 0)
  282. // return E_UNEXPECTED;
  283. EatLine();
  284. while (m_pData[0] != '*')
  285. CHECK_HR(hr = ParsePath());
  286. // remove the "*U"
  287. MMASSERT((m_pData[0] == '*') && (m_pData[1] == 'U'));
  288. // if (strncmp(m_pData, "*U", 2) != 0)
  289. // return E_UNEXPECTED;
  290. EatLine();
  291. e_Exit:
  292. return hr;
  293. }
  294. inline
  295. UINT GetUInt(const char *pData)
  296. {
  297. return (UINT) atoi(pData);
  298. }
  299. typedef DWORD FP;
  300. #define nEXPBIAS 127
  301. #define nEXPSHIFTS 23
  302. #define nEXPLSB (1 << nEXPSHIFTS)
  303. #define maskMANT (nEXPLSB - 1)
  304. #define FloatToFixed08(nDst, fSrc) MACSTART \
  305. float fTmp = fSrc; \
  306. DWORD nRaw = *((FP *) &(fTmp)); \
  307. if (nRaw < ((nEXPBIAS + 23 - 31) << nEXPSHIFTS)) \
  308. nDst = 0; \
  309. else \
  310. nDst = ((nRaw | nEXPLSB) << 8) >> ((nEXPBIAS + 23) - (nRaw >> nEXPSHIFTS)); \
  311. MACEND
  312. HRESULT
  313. CAdobeFormatConverter::ParsePaintStyle(const char *&pEnd)
  314. {
  315. HRESULT hr = S_OK;
  316. BOOL bNotDone = TRUE;
  317. // int nLineJoin = 1, nLineCap = 1;
  318. float fLineWidth = 1.f;
  319. float fGrayFill, fGrayStroke;
  320. float fCyan, fYellow, fMagenta, fBlack;
  321. bool bColorFill = false, bGrayFill = false, bGrayStroke = false;
  322. // parse paint style
  323. for (; pEnd; pEnd = FindLF(m_pData)) {
  324. switch(pEnd[-1]) {
  325. //
  326. // path attributes
  327. //
  328. case 'd': // process dash
  329. // REVIEW: skip this for now -- assume NULL pattern
  330. break;
  331. case 'j': // process line join type
  332. // REVIEW: skip this for now, since it is always 1
  333. // nLineJoin = mmSimpleAtoI(m_pData);
  334. break;
  335. case 'J': // process line cap type
  336. // REVIEW: skip this for now, since it is always 1
  337. // nLineCap = mmSimpleAtoI(m_pData);
  338. break;
  339. case 'w': // process line width
  340. // REVIEW: skip this for now, since it is always 1.f
  341. // fLineWidth = mmSimpleAtoF(m_pData);
  342. break;
  343. //
  344. // fill color
  345. //
  346. case 'g': // process gray color for fill
  347. fGrayFill = mmSimpleAtoF(m_pData);
  348. bGrayFill = true;
  349. break;
  350. case 'k': // process color
  351. fCyan = mmSimpleAtoF(m_pData);
  352. fMagenta = mmSimpleAtoF(m_pData);
  353. fYellow = mmSimpleAtoF(m_pData);
  354. fBlack = mmSimpleAtoF(m_pData);
  355. bColorFill = true;
  356. break;
  357. //
  358. // stroke color
  359. //
  360. case 'G': // process gray color for stroke
  361. fGrayStroke = mmSimpleAtoF(m_pData);
  362. bGrayStroke = true;
  363. break;
  364. default:
  365. goto Exit;
  366. break;
  367. }
  368. m_pData = FindNextLine(pEnd);
  369. // m_pData = pEnd + 1;
  370. }
  371. Exit:
  372. // output GDI commands
  373. //
  374. // create a brush
  375. //
  376. if (bColorFill || bGrayFill) {
  377. static DWORD nLastRed = 256, nLastGreen = 256, nLastBlue = 256;
  378. DWORD nTmpRed, nTmpGreen, nTmpBlue;
  379. if (bColorFill) {
  380. FloatToFixed08(nTmpRed, fCyan + fBlack); CLAMPMAX(nTmpRed, 255); nTmpRed = 255 - nTmpRed;
  381. FloatToFixed08(nTmpGreen, fMagenta + fBlack); CLAMPMAX(nTmpGreen, 255); nTmpGreen = 255 - nTmpGreen;
  382. FloatToFixed08(nTmpBlue, fYellow + fBlack); CLAMPMAX(nTmpBlue, 255); nTmpBlue = 255 - nTmpBlue;
  383. } else if (bGrayFill) {
  384. DWORD nTmpGray;
  385. FloatToFixed08(nTmpGray, fGrayFill); CLAMPMAX(nTmpGray, 255);
  386. nTmpRed = nTmpGreen = nTmpBlue = nTmpGray;
  387. }
  388. if ((nLastRed != nTmpRed) || (nLastGreen != nTmpGreen) || (nLastBlue != nTmpBlue)) {
  389. // define a new brush
  390. nLastRed = nTmpRed; nLastGreen = nTmpGreen; nLastBlue = nTmpBlue;
  391. // fprintf(m_pFile, "\t// select a new brush\n");
  392. // fprintf(m_pFile, "\tBrush.Color = DXSAMPLE(255, %d, %d, %d);\n", nRed, nGreen, nBlue);
  393. // fprintf(m_pFile, "\tpDX2D->SetBrush(&Brush);\n\n");
  394. m_pCurBrushInfo->Color = DXSAMPLE(255, BYTE(nTmpRed), BYTE(nTmpGreen), BYTE(nTmpBlue));
  395. m_pCurRenderCmd->nType = typeBRUSH;
  396. m_pCurRenderCmd->pvData = (void *) m_pCurBrushInfo++;
  397. m_pCurRenderCmd++;
  398. m_bNoBrush = false;
  399. }
  400. }
  401. // create a pen
  402. if (bGrayStroke) {
  403. static bool bPenInit = false;
  404. // we only have one pen in the simpsons.ai
  405. if (!bPenInit) {
  406. // if ((fGrayStroke != 0.f) || (nLineJoin != 1) || (nLineCap != 1)) {
  407. if (fGrayStroke != 0.f) {
  408. MMTRACE("error: can not support pen type\n");
  409. return E_FAIL;
  410. }
  411. bPenInit = true;
  412. // fprintf(m_pFile, "\t// select a new pen\n");
  413. // fprintf(m_pFile, "\tPen.Color = DXSAMPLE(255, 0, 0, 0);\n");
  414. // fprintf(m_pFile, "\tPen.Width = %.2ff;\n", fLineWidth * fGSCALE);
  415. // fprintf(m_pFile, "\tPen.Style = PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_ROUND | PS_JOIN_ROUND;\n");
  416. // fprintf(m_pFile, "\tpDX2D->SetPen(&Pen);\n\n");
  417. // REVIEW: only can make one kind of pen right now
  418. m_pCurPenInfo->Color = DXSAMPLE(255, 0, 0, 0);
  419. m_pCurPenInfo->fWidth = fLineWidth * fGSCALE;
  420. m_pCurPenInfo->dwStyle = PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_ROUND | PS_JOIN_ROUND;
  421. m_pCurRenderCmd->nType = typePEN;
  422. m_pCurRenderCmd->pvData = (void *) m_pCurPenInfo++;
  423. m_pCurRenderCmd++;
  424. m_bNoPen = false;
  425. }
  426. }
  427. return S_OK;
  428. }
  429. #define GetCoordX(_fX) ((_fX) * fGSCALE)
  430. #define GetCoordY(_fY) ((m_fHeight - (_fY)) * fGSCALE)
  431. HRESULT
  432. CAdobeFormatConverter::ParsePathGeometry(const char *pEnd)
  433. {
  434. HRESULT hr = S_OK;
  435. // float fX1, fY1, fXBez1, fYBez1, fXBez2, fYBez2;
  436. m_pCurPolyInfo->pPoints = m_pCurPoint;
  437. m_pCurPolyInfo->pCodes = m_pCurCode;
  438. // parse path geometry
  439. DWORD cPoints = 0;
  440. bool bFlatten = false;
  441. for (; pEnd; pEnd = FindLF(m_pData)) {
  442. switch(pEnd[-1]) {
  443. case 'm':
  444. // fprintf(m_pFile, "\t// define geometry path\n");
  445. // sscanf(m_pData, "%f %f", &fX1, &fY1);
  446. // fprintf(m_pFile, "\tppt = rgpt; pb = rgCodes;\n");
  447. // fprintf(m_pFile, "\tppt->x = %.2ff; ppt->y = %.2ff; *pb++ = PT_MOVETO; ppt++;\n", GetCoordX(fX1), GetCoordY(fY1));
  448. m_pCurPoint->x = GetCoordX(mmSimpleAtoF(m_pData));
  449. m_pCurPoint->y = GetCoordY(mmSimpleAtoF(m_pData));
  450. m_pCurPoint++;
  451. *m_pCurCode++ = PT_MOVETO;
  452. cPoints++;
  453. break;
  454. case 'L':
  455. case 'l':
  456. // sscanf(m_pData, "%f %f", &fX1, &fY1);
  457. // fprintf(m_pFile, "\tppt->x = %.2ff; ppt->y = %.2ff; *pb++ = PT_LINETO; ppt++;\n", GetCoordX(fX1), GetCoordY(fY1));
  458. m_pCurPoint->x = GetCoordX(mmSimpleAtoF(m_pData));
  459. m_pCurPoint->y = GetCoordY(mmSimpleAtoF(m_pData));
  460. m_pCurPoint++;
  461. *m_pCurCode++ = PT_LINETO;
  462. cPoints++;
  463. break;
  464. case 'C':
  465. case 'c':
  466. bFlatten = true;
  467. m_pCurPoint[0].x = GetCoordX(mmSimpleAtoF(m_pData));
  468. m_pCurPoint[0].y = GetCoordY(mmSimpleAtoF(m_pData));
  469. m_pCurPoint[1].x = GetCoordX(mmSimpleAtoF(m_pData));
  470. m_pCurPoint[1].y = GetCoordY(mmSimpleAtoF(m_pData));
  471. m_pCurPoint[2].x = GetCoordX(mmSimpleAtoF(m_pData));
  472. m_pCurPoint[2].y = GetCoordY(mmSimpleAtoF(m_pData));
  473. m_pCurPoint += 3;
  474. m_pCurCode[0] = PT_BEZIERTO;
  475. m_pCurCode[1] = PT_BEZIERTO;
  476. m_pCurCode[2] = PT_BEZIERTO;
  477. m_pCurCode += 3;
  478. cPoints += 3;
  479. // sscanf(m_pData, "%f %f %f %f %f %f", &fXBez1, &fYBez1, &fXBez2, &fYBez2, &fX1, &fY1);
  480. // fprintf(m_pFile, "\tppt[0].x = %.2ff; ppt[0].y = %.2ff; pb[0] = PT_BEZIERTO;\n", GetCoordX(fXBez1), GetCoordY(fYBez1));
  481. // fprintf(m_pFile, "\tppt[1].x = %.2ff; ppt[1].y = %.2ff; pb[1] = PT_BEZIERTO;\n", GetCoordX(fXBez2), GetCoordY(fYBez2));
  482. // fprintf(m_pFile, "\tppt[2].x = %.2ff; ppt[2].y = %.2ff; pb[2] = PT_BEZIERTO; ppt += 3; pb += 3;\n", GetCoordX(fX1), GetCoordY(fY1));
  483. break;
  484. default:
  485. goto Exit;
  486. break;
  487. }
  488. // skip the line
  489. m_pData = FindNextLine(pEnd);
  490. }
  491. Exit:
  492. // create the path
  493. // char *pFillType = (bFlatten ? "0" : "DX2D_NO_FLATTEN");
  494. if (cPoints) {
  495. DWORD dwFlags;
  496. switch(pEnd[-1]) {
  497. case 'f': // close path and fill
  498. if (m_bNoBrush) {
  499. // fprintf(m_pFile, "\tpDX2D->SetBrush(&Brush);\n"); m_nLines++;
  500. m_bNoBrush = false;
  501. }
  502. if (m_bNoPen == false) {
  503. // fprintf(m_pFile, "\tpDX2D->SetPen(NULL);\n"); m_nLines++;
  504. m_bNoPen = true;
  505. }
  506. dwFlags = DX2D_FILL;
  507. break;
  508. case 'S': // stroke path
  509. if (m_bNoPen) {
  510. // fprintf(m_pFile, "\tpDX2D->SetPen(&Pen);\n"); m_nLines++;
  511. m_bNoPen = false;
  512. }
  513. if (m_bNoBrush == false) {
  514. // fprintf(m_pFile, "\tpDX2D->SetBrush(NULL);\n"); m_nLines++;
  515. m_bNoBrush = true;
  516. }
  517. dwFlags = DX2D_STROKE;
  518. break;
  519. default:
  520. MMTRACE("error: unknown render mode -- aborting\n");
  521. return E_FAIL;
  522. break;
  523. }
  524. // fprintf(m_pFile, "\tpDX2D->AAPolyDraw(rgpt, rgCodes, %d, %s);\n", iPoint, pFillType);
  525. m_pCurPolyInfo->cPoints = cPoints;
  526. m_pCurPolyInfo->dwFlags = dwFlags | (bFlatten ? 0 : DX2D_NO_FLATTEN);
  527. m_pCurRenderCmd->nType = typePOLY;
  528. m_pCurRenderCmd->pvData = (PolyInfo *) m_pCurPolyInfo++;
  529. m_pCurRenderCmd++;
  530. m_pData = FindNextLine(pEnd);
  531. }
  532. return S_OK;
  533. }
  534. HRESULT
  535. CAdobeFormatConverter::ParsePath()
  536. {
  537. // MMTRACE("ParsePath\n");
  538. HRESULT hr;
  539. const char *pStart = m_pData, *pEnd = FindLF(m_pData);
  540. if (FAILED(hr = ParsePaintStyle(pEnd)))
  541. return hr;
  542. if (FAILED(hr = ParsePathGeometry(pEnd)))
  543. return hr;
  544. // skip it if we don't know how to deal with it
  545. if (pStart == m_pData) {
  546. // if ((m_pData[0] != 'L') || (m_pData[1] != 'B')) {
  547. // MMTRACE("warning: control data of unknown type -- ignoring line\n");
  548. // }
  549. m_pData = FindNextLine(pEnd);
  550. }
  551. return hr;
  552. }
  553. HRESULT
  554. CAdobeFormatConverter::ParseTrailers()
  555. {
  556. return S_OK;
  557. }
  558. HRESULT
  559. OpenFileMapping(const char *szFilename, LPHANDLE phMapping,
  560. DWORD *pnFileLength)
  561. {
  562. MMASSERT(szFilename && phMapping && pnFileLength);
  563. HRESULT hr = S_OK;
  564. HANDLE hFile = NULL, hMapping = NULL;
  565. DWORD nFileLength = 0, dwHighSize = 0;
  566. MMTRACE("Opening File: %s\n", szFilename);
  567. // open the file
  568. hFile = CreateFile(szFilename, GENERIC_READ, FILE_SHARE_READ, NULL,
  569. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
  570. if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE)) {
  571. MMTRACE("error: file not found - %s\n", szFilename);
  572. return STG_E_FILENOTFOUND;
  573. }
  574. // get the length of the file
  575. if (((nFileLength = GetFileSize(hFile, &dwHighSize)) == 0xFFFFFFFF) || dwHighSize ||
  576. // create a file mapping object
  577. ((hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL))
  578. {
  579. MMTRACE("error: creating file mapping\n");
  580. hr = E_FAIL;
  581. }
  582. MMTRACE("\tLength: %d\n", nFileLength);
  583. if (hFile)
  584. CloseHandle(hFile);
  585. *phMapping = hMapping;
  586. *pnFileLength = nFileLength;
  587. return hr;
  588. }
  589. #define szDEFFILENAME "\\dtrans\\tools\\simpsons\\simpsons.ai"
  590. HRESULT
  591. ParseAIFile(const char *szFilename, RenderCmd **ppCmds)
  592. {
  593. HRESULT hr = S_OK;
  594. static CAdobeFormatConverter afc;
  595. static RenderCmd s_CmdStop = {typeSTOP, NULL};
  596. DWORD nStartTick, nEndTick;
  597. DWORD nFileLength;
  598. HANDLE hMapping = NULL;
  599. char *pData = NULL;
  600. if (szFilename == NULL)
  601. szFilename = szDEFFILENAME;
  602. nStartTick = GetTickCount();
  603. CHECK_HR(hr = OpenFileMapping(szFilename, &hMapping, &nFileLength));
  604. // create a map view
  605. if ((pData = (char *) MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0)) == NULL) {
  606. hr = E_FAIL;
  607. goto e_Exit;
  608. }
  609. CHECK_HR(hr = afc.Parse(pData, nFileLength, ppCmds));
  610. e_Exit:
  611. if (pData)
  612. UnmapViewOfFile(pData);
  613. if (hMapping)
  614. CloseHandle(hMapping);
  615. if (FAILED(hr)) {
  616. // set to the null command list
  617. *ppCmds = &s_CmdStop;
  618. MMTRACE("\terror parsing file\n");
  619. } else {
  620. nEndTick = GetTickCount();
  621. sprintf(g_rgchTmpBuf, "\tParse Time: %d\n", nEndTick - nStartTick);
  622. OutputDebugString(g_rgchTmpBuf);
  623. }
  624. return hr;
  625. }