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.

2937 lines
83 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. text.cpp
  5. Abstract:
  6. font/text output handling functions implementation
  7. Environment:
  8. Windows Whistler
  9. Revision History:
  10. 04/6/99
  11. Created initial framework.
  12. --*/
  13. #include "lib.h"
  14. #include "gpd.h"
  15. #include "winres.h"
  16. #include "pdev.h"
  17. #include "common.h"
  18. #include "..\..\font\font.h"
  19. #include "xlpdev.h"
  20. #include "xldebug.h"
  21. #include <assert.h>
  22. #include "pclxlcmd.h"
  23. #include "pclxle.h"
  24. #include "xlgstate.h"
  25. #include "xloutput.h"
  26. #include "xltext.h"
  27. #include "xlbmpcvt.h"
  28. #include "pclxlcmn.h"
  29. #include "xltt.h"
  30. #include "math.h"
  31. //
  32. // TrueType outline format switch
  33. //
  34. #define CLASS12 1
  35. #define COMPGLYF 1
  36. //
  37. // Local functions prototypes
  38. //
  39. DWORD
  40. DwDownloadCompositeGlyph(
  41. PDEVOBJ pdevobj,
  42. ULONG ulFontID,
  43. PGLYF pGlyph);
  44. BOOL
  45. BDownloadGlyphData(
  46. PDEVOBJ pdevobj,
  47. ULONG ulFontID,
  48. DWORD dwGlyphID,
  49. HGLYPH hGlyph,
  50. PBYTE pubGlyphData,
  51. DWORD dwGlyphDataSize,
  52. BOOL bSpace);
  53. extern "C" HRESULT APIENTRY
  54. PCLXLDownloadCharGlyph(
  55. PDEVOBJ pdevobj,
  56. PUNIFONTOBJ pUFObj,
  57. HGLYPH hGlyph,
  58. PDWORD pdwWidth,
  59. OUT DWORD *pdwResult);
  60. //
  61. // XL Text entry point
  62. //
  63. extern "C" BOOL APIENTRY
  64. PCLXLTextOutAsBitmap(
  65. SURFOBJ *pso,
  66. STROBJ *pstro,
  67. FONTOBJ *pfo,
  68. CLIPOBJ *pco,
  69. RECTL *prclExtra,
  70. RECTL *prclOpaque,
  71. BRUSHOBJ *pboFore,
  72. BRUSHOBJ *pboOpaque,
  73. POINTL *pptlOrg,
  74. MIX mix)
  75. /*++
  76. Routine Description:
  77. IPrintOemUni TextOutAsBitmap interface
  78. Arguments:
  79. Return Value:
  80. Note:
  81. --*/
  82. {
  83. VERBOSE(("PCLXLTextOutAsBitmap() entry.\r\n"));
  84. PDEVOBJ pdevobj = (PDEVOBJ)pso->dhpdev;
  85. PXLPDEV pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  86. GLYPHPOS *pGlyphPos;
  87. PATHOBJ *pPathObj;
  88. GLYPHBITS *pGlyphBits;
  89. GLYPHDATA *pGlyphData;
  90. HRESULT hResult;
  91. ULONG ulJ, ulGlyphs, ulCount, ulcbBmpSize, ulcbLineAlign, ulcbLineSize;
  92. LONG lI;
  93. BOOL bMore;
  94. PBYTE pubBitmap;
  95. BYTE aubDataHdr[8];
  96. BYTE aubZero[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  97. DWORD adwColorTable[2];
  98. DWORD dwDataHdrSize;
  99. if (pstro->cGlyphs == 0)
  100. {
  101. VERBOSE(("PCLXLTextOutAsBitmap: cGlyphs = 0\n"));
  102. return TRUE;
  103. }
  104. XLOutput *pOutput = pxlpdev->pOutput;
  105. //
  106. // UNIDRV switchs the format of font in the middle of downloading
  107. // character glyphs. We need to end the BeginChar sequence.
  108. //
  109. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  110. {
  111. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  112. pOutput->Send_cmd(eEndChar);
  113. }
  114. ROP4 rop = UlVectMixToRop4(mix);
  115. if ( S_OK != pOutput->SetClip(pco) ||
  116. S_OK != pOutput->SetPenColor(NULL, NULL) ||
  117. S_OK != pOutput->Flush(pdevobj))
  118. return FALSE;
  119. STROBJ_vEnumStart(pstro);
  120. do
  121. {
  122. bMore = STROBJ_bEnum (pstro, &ulGlyphs, &pGlyphPos);
  123. if (bMore == DDI_ERROR)
  124. {
  125. return FALSE;
  126. }
  127. for (ulCount = 0; ulCount < ulGlyphs; ulCount++, pGlyphPos++)
  128. {
  129. //
  130. // get the path of the glyph from the FONTOBJ
  131. //
  132. if (!FONTOBJ_cGetGlyphs (pfo,
  133. FO_PATHOBJ,
  134. 1,
  135. &pGlyphPos->hg,
  136. (PVOID *)&pPathObj))
  137. {
  138. ERR(("PCLXLTextOutAsBitmap: cGetGlyphs failed\n"));
  139. hResult = S_FALSE;
  140. }
  141. else
  142. {
  143. if (S_OK == pOutput->Send_cmd(ePushGS) &&
  144. S_OK == pOutput->SetBrush(pboFore, pptlOrg) &&
  145. S_OK == pOutput->SetPageOrigin((uint16)pGlyphPos->ptl.x,
  146. (uint16)pGlyphPos->ptl.x) &&
  147. S_OK == pOutput->Path(pPathObj) &&
  148. S_OK == pOutput->Paint() &&
  149. S_OK == pOutput->Send_cmd(ePopGS))
  150. hResult = S_OK;
  151. else
  152. hResult = S_FALSE;
  153. }
  154. if (hResult == S_FALSE)
  155. {
  156. pOutput->Delete();
  157. adwColorTable[1] = 0x00FFFFFF;
  158. if (pboFore)
  159. {
  160. if (pboFore->iSolidColor == NOT_SOLID_COLOR)
  161. {
  162. adwColorTable[0] = BRUSHOBJ_ulGetBrushColor(pboFore);
  163. }
  164. else
  165. {
  166. adwColorTable[0] = pboFore->iSolidColor;
  167. }
  168. }
  169. else
  170. adwColorTable[0] = 0x00000000;
  171. //
  172. // get the path of the glyph from the FONTOBJ
  173. //
  174. if (!FONTOBJ_cGetGlyphs (pfo,
  175. FO_GLYPHBITS,
  176. 1,
  177. &pGlyphPos->hg,
  178. (PVOID *)&pGlyphData))
  179. {
  180. ERR(("PCLXLTextOutAsBitmap: cGetGlyphs failed\n"));
  181. return FALSE;
  182. }
  183. pGlyphBits = pGlyphData->gdf.pgb;
  184. ulcbLineSize = (pGlyphBits->sizlBitmap.cx + 7) >> 3;
  185. ulcbLineAlign = (sizeof(DWORD) - ulcbLineSize % sizeof(DWORD)) % sizeof(DWORD);
  186. ulcbBmpSize = (ulcbLineSize + ulcbLineAlign) * pGlyphBits->sizlBitmap.cy;
  187. if (ulcbBmpSize <= 0xff)
  188. {
  189. aubDataHdr[0] = PCLXL_dataLengthByte;
  190. aubDataHdr[1] = (BYTE)(ulcbBmpSize & 0xff);
  191. dwDataHdrSize = 2;
  192. }
  193. else
  194. {
  195. aubDataHdr[0] = PCLXL_dataLength;
  196. aubDataHdr[1] = (BYTE)(ulcbBmpSize & 0xff);
  197. aubDataHdr[2] = (BYTE)((ulcbBmpSize >> 8) & 0xff);
  198. aubDataHdr[3] = (BYTE)((ulcbBmpSize >> 16) & 0xff);
  199. aubDataHdr[4] = (BYTE)((ulcbBmpSize >> 24) & 0xff);
  200. dwDataHdrSize = 5;
  201. }
  202. //
  203. // Hack ROP for Print As Graphics
  204. //
  205. rop = 0xFC;
  206. if (S_OK == pOutput->SetCursor(pGlyphPos->ptl.x + pGlyphBits->ptlOrigin.x,
  207. pGlyphPos->ptl.y + pGlyphBits->ptlOrigin.y) &&
  208. S_OK == pOutput->SetROP3(GET_FOREGROUND_ROP3(rop)) &&
  209. S_OK == pOutput->SetPaintTxMode(eOpaque) &&
  210. S_OK == pOutput->SetSourceTxMode(eTransparent))
  211. {
  212. hResult = S_OK;
  213. }
  214. else
  215. {
  216. hResult = S_FALSE;
  217. }
  218. if (pOutput->GetDeviceColorDepth() != e24Bit)
  219. {
  220. if (S_OK == hResult &&
  221. S_OK == pOutput->SetColorSpace(eGray) &&
  222. S_OK == pOutput->Send_cmd(eSetColorSpace) &&
  223. S_OK == pOutput->SetBrush(pboFore, pptlOrg) &&
  224. S_OK == pOutput->SetOutputBPP(eDirectPixel, 1))
  225. {
  226. hResult = S_OK;
  227. }
  228. else
  229. {
  230. hResult = S_FALSE;
  231. }
  232. }
  233. else
  234. {
  235. if (S_OK == hResult &&
  236. S_OK == pOutput->SetColorSpace(eRGB) &&
  237. S_OK == pOutput->SetPaletteDepth(e8Bit) &&
  238. S_OK == pOutput->SetPaletteData(pOutput->GetDeviceColorDepth(), 2, adwColorTable) &&
  239. S_OK == pOutput->Send_cmd(eSetColorSpace) &&
  240. S_OK == pOutput->SetOutputBPP(eIndexedPixel, 1))
  241. {
  242. hResult = S_OK;
  243. }
  244. else
  245. {
  246. hResult = S_FALSE;
  247. }
  248. }
  249. if (S_OK == hResult &&
  250. S_OK == pOutput->SetSourceWidth((uint16)pGlyphBits->sizlBitmap.cx) &&
  251. S_OK == pOutput->SetSourceHeight((uint16)pGlyphBits->sizlBitmap.cy) &&
  252. S_OK == pOutput->SetDestinationSize((uint16)pGlyphBits->sizlBitmap.cx,
  253. (uint16)pGlyphBits->sizlBitmap.cy) &&
  254. S_OK == pOutput->Send_cmd(eBeginImage) &&
  255. S_OK == pOutput->ReadImage(pGlyphBits->sizlBitmap.cy, eNoCompression) &&
  256. S_OK == pOutput->Flush(pdevobj))
  257. hResult = S_OK;
  258. else
  259. hResult = S_FALSE;
  260. WriteSpoolBuf((PPDEV)pdevobj, aubDataHdr, dwDataHdrSize);
  261. pubBitmap = pGlyphBits->aj;
  262. //
  263. // Bitmap data has to be DWORD-align.
  264. //
  265. // Invert bitmap
  266. //
  267. for (lI = 0; lI < pGlyphBits->sizlBitmap.cy; lI ++)
  268. {
  269. for (ulJ = 0; ulJ < ulcbLineSize; ulJ++)
  270. {
  271. *(pubBitmap+ulJ) = ~*(pubBitmap+ulJ);
  272. }
  273. WriteSpoolBuf((PPDEV)pdevobj, pubBitmap, ulcbLineSize);
  274. pubBitmap += ulcbLineSize;
  275. WriteSpoolBuf((PPDEV)pdevobj, aubZero, ulcbLineAlign);
  276. }
  277. if (S_OK == hResult &&
  278. S_OK == pOutput->Send_cmd(eEndImage) &&
  279. S_OK == pOutput->Flush(pdevobj))
  280. hResult = S_OK;
  281. else
  282. hResult = S_FALSE;
  283. }
  284. else
  285. hResult = pOutput->Flush(pdevobj);
  286. }
  287. }
  288. while (bMore && hResult == S_OK);
  289. if (S_OK == hResult)
  290. return TRUE;
  291. else
  292. return FALSE;
  293. }
  294. extern "C" HRESULT APIENTRY
  295. PCLXLDownloadFontHeader(
  296. PDEVOBJ pdevobj,
  297. PUNIFONTOBJ pUFObj,
  298. OUT DWORD *pdwResult)
  299. /*++
  300. Routine Description:
  301. IPrintOemUni DownloadFontHeader interface
  302. Arguments:
  303. Return Value:
  304. Note:
  305. --*/
  306. {
  307. VERBOSE(("PCLXLDownloadFontHeader() entry.\r\n"));
  308. PXLPDEV pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  309. HRESULT hResult;
  310. if (NULL == pxlpdev)
  311. {
  312. ERR(("PCLXL:DownloadFontHeader Invalid pdevOEM.\r\n"));
  313. return S_FALSE;
  314. }
  315. //
  316. // UNIDRV switchs the format of font in the middle of downloading
  317. // character glyphs. We need to end the BeginChar sequence.
  318. //
  319. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  320. {
  321. XLOutput *pOutput = pxlpdev->pOutput;
  322. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  323. pOutput->Send_cmd(eEndChar);
  324. }
  325. if (pUFObj->dwFlags & UFOFLAG_TTDOWNLOAD_BITMAP)
  326. {
  327. VERBOSE(("PCLXLDownloadFontHeader() BITMAP.\n"));
  328. //
  329. // Get current text resolution
  330. //
  331. if (pxlpdev->dwTextRes == 0)
  332. {
  333. GETINFO_STDVAR StdVar;
  334. DWORD dwSizeNeeded;
  335. StdVar.dwSize = sizeof(GETINFO_STDVAR);
  336. StdVar.dwNumOfVariable = 1;
  337. StdVar.StdVar[0].dwStdVarID = FNT_INFO_TEXTYRES;
  338. StdVar.StdVar[0].lStdVariable = 0;
  339. pUFObj->pfnGetInfo(pUFObj,
  340. UFO_GETINFO_STDVARIABLE,
  341. &StdVar,
  342. StdVar.dwSize,
  343. &dwSizeNeeded);
  344. pxlpdev->dwTextRes = StdVar.StdVar[0].lStdVariable;
  345. }
  346. //
  347. // PCL XL FontHeader initialization
  348. // Get the max character number from GPD file.
  349. //
  350. PCLXL_FONTHEADER PCLXLFontHeader;
  351. PCLXLFontHeader.ubFormat = 0;
  352. PCLXLFontHeader.ubOrientation = ePortraitOrientation;
  353. PCLXLFontHeader.wMapping = 0x0200;
  354. PCLXLFontHeader.ubFontScallingTech = eBitmap;
  355. PCLXLFontHeader.ubVariety = 0;
  356. PCLXLFontHeader.wNumOfChars = SWAPW(1+((PPDEV)pdevobj)->pGlobals->dwMaxGlyphID - ((PPDEV)pdevobj)->pGlobals->dwMinGlyphID);
  357. //
  358. // BR Segment initialization
  359. //
  360. PCLXL_BR_SEGMENT PCLXLBRSegment;
  361. PCLXLBRSegment.wSignature = PCLXL_BR_SIGNATURE;
  362. PCLXLBRSegment.wSegmentSize = 0;
  363. PCLXLBRSegment.wSegmentSizeAlign = SWAPW(PCLXL_BR_SEGMENT_SIZE);
  364. PCLXLBRSegment.wXResolution = SWAPW(pxlpdev->dwTextRes);
  365. PCLXLBRSegment.wYResolution = SWAPW(pxlpdev->dwTextRes);
  366. //
  367. // NULL Segment initialization
  368. //
  369. PCLXL_NULL_SEGMENT PCLXLNULLSegment;
  370. PCLXLNULLSegment.wSignature = PCLXL_NULL_SIGNATURE;
  371. PCLXLNULLSegment.wSegmentSize = 0;
  372. PCLXLNULLSegment.wSegmentSizeAlign = 0;
  373. {
  374. //
  375. // Output
  376. //
  377. XLOutput *pOutput = pxlpdev->pOutput;
  378. //
  379. // BeginFontHeader
  380. //
  381. pOutput->Send_ubyte(0);
  382. pOutput->Send_attr_ubyte(eFontFormat);
  383. pOutput->Send_ubyte_array_header(16);
  384. pOutput->Write(PubGetFontName(pdevobj, pUFObj->ulFontID), PCLXL_FONTNAME_SIZE);
  385. pOutput->Send_attr_ubyte(eFontName);
  386. pOutput->Send_cmd(eBeginFontHeader);
  387. //
  388. // ReadFontHeader
  389. //
  390. uint32 uint32_FontHeaderSize;
  391. uint32_FontHeaderSize = sizeof(PCLXLFontHeader);
  392. pOutput->Send_uint16((uint16)uint32_FontHeaderSize);
  393. pOutput->Send_attr_ubyte(eFontHeaderLength);
  394. pOutput->Send_cmd(eReadFontHeader);
  395. pOutput->WriteByte(PCLXL_dataLengthByte);
  396. pOutput->WriteByte((ubyte)uint32_FontHeaderSize);
  397. pOutput->Write((PBYTE)&PCLXLFontHeader, uint32_FontHeaderSize);
  398. uint32_FontHeaderSize = sizeof(PCLXLBRSegment);
  399. pOutput->Send_uint16((uint16)uint32_FontHeaderSize);
  400. pOutput->Send_attr_ubyte(eFontHeaderLength);
  401. pOutput->Send_cmd(eReadFontHeader);
  402. pOutput->WriteByte(PCLXL_dataLengthByte);
  403. pOutput->WriteByte((ubyte)uint32_FontHeaderSize);
  404. pOutput->Write((PBYTE)&PCLXLBRSegment, uint32_FontHeaderSize);
  405. uint32_FontHeaderSize = sizeof(PCLXLNULLSegment);
  406. pOutput->Send_uint16((uint16)uint32_FontHeaderSize);
  407. pOutput->Send_attr_ubyte(eFontHeaderLength);
  408. pOutput->Send_cmd(eReadFontHeader);
  409. pOutput->WriteByte(PCLXL_dataLengthByte);
  410. pOutput->WriteByte((ubyte)uint32_FontHeaderSize);
  411. pOutput->Write((PBYTE)&PCLXLNULLSegment, uint32_FontHeaderSize);
  412. //
  413. // EndFontHeader
  414. //
  415. pOutput->Send_cmd(eEndFontHeader);
  416. pOutput->Flush(pdevobj);
  417. }
  418. *pdwResult = sizeof(PCLXL_FONTHEADER) +
  419. sizeof(PCLXL_BR_SEGMENT) +
  420. sizeof(PCLXL_NULL_SEGMENT);
  421. hResult = S_OK;
  422. }
  423. else
  424. if (pUFObj->dwFlags & UFOFLAG_TTDOWNLOAD_TTOUTLINE)
  425. {
  426. VERBOSE(("PCLXLDownloadFontHeader() OUTLINE.\n"));
  427. //
  428. // Get FONTOBJ
  429. //
  430. FONTOBJ *pFontObj;
  431. if (S_OK != GetFONTOBJ(pdevobj, pUFObj, &pFontObj))
  432. {
  433. ERR(("PCLXL:DownloadFontHeader UFO_GETINFO_FONTOBJ failed.\r\n"));
  434. return E_UNEXPECTED;
  435. }
  436. //
  437. // ASSUMPTION: pxlpdev->pTTFile is initialized in EnablePDEV.
  438. // The pointer is always available.
  439. //
  440. XLTrueType *pTTFile = pxlpdev->pTTFile;
  441. if (S_OK != pTTFile->SameFont(pFontObj))
  442. {
  443. if (S_OK != pTTFile->OpenTTFile(pFontObj))
  444. {
  445. ERR(("PCLXL:DownloadFontHeader XLTrueType>OpenTTFile failed.\r\n"));
  446. return E_UNEXPECTED;
  447. }
  448. }
  449. else
  450. pTTFile = pxlpdev->pTTFile;
  451. //
  452. // PCL XL FontHeader initialization
  453. // Get the max character number from GPD file.
  454. //
  455. PCLXL_FONTHEADER PCLXLFontHeader;
  456. PCLXLFontHeader.ubFormat = 0;
  457. PCLXLFontHeader.ubOrientation = ePortraitOrientation;
  458. PCLXLFontHeader.wMapping = 0x0200;
  459. PCLXLFontHeader.ubFontScallingTech = eTrueType;
  460. PCLXLFontHeader.ubVariety = 0;
  461. PCLXLFontHeader.wNumOfChars = SWAPW(1+((PPDEV)pdevobj)->pGlobals->dwMaxGlyphID - ((PPDEV)pdevobj)->pGlobals->dwMinGlyphID);
  462. //
  463. // PCL XL GT Table Directory
  464. //
  465. PTTDIR pTableDir;
  466. TTTag tag;
  467. DWORD dwI, dwTableOffset, dwNumTag, dwGTSegSize, dwDWAlign, dwTableSize;
  468. //
  469. // GetNumOfTag returns 11 tags including loca table.
  470. // Header requires
  471. // head
  472. // maxp
  473. // gdir
  474. // hhea (only for class 0)
  475. // hmtx (only for class 0)
  476. // vhea (only for vertical font and class 0)
  477. // vmtx (only for vertical font and class 0)
  478. //
  479. // Optional
  480. // cvt
  481. // fpgm
  482. // perp
  483. //
  484. // We need to get the number of Tag to download.
  485. // XLTrueType object caches available table directories includeing loca
  486. // table. Here we go through the cached table to see if which one of
  487. // above table is available.
  488. //
  489. // See truetype.h
  490. // TagID_first = 0. TagID_First is the number of tags which are used for
  491. // font header.
  492. //
  493. dwNumTag = 0;
  494. dwGTSegSize = 0;
  495. PCLXL_GT_TABLE_DIR PCLXLGTTblDir[TagID_Header];
  496. for (dwI = (USHORT)TagID_First; dwI < (USHORT)TagID_Header; dwI ++)
  497. {
  498. //
  499. // Check a table for the tag is available in the TrueType font.
  500. //
  501. tag = TTTag_INVALID;
  502. pTableDir = NULL;
  503. #if CLASS12
  504. //
  505. // Support only Class 1 and Class 2
  506. //
  507. if (dwI == TagID_hhea || dwI == TagID_hmtx ||
  508. dwI == TagID_vhea || dwI == TagID_vmtx )
  509. {
  510. continue;
  511. }
  512. #else
  513. //
  514. // Support Class 1 and Class 2 for horizontal font.
  515. // Class 0 for vertical font. PCL XL interpreter doesn't work fine.
  516. //
  517. if (S_OK != pTTFile->IsVertical())
  518. {
  519. if (dwI == TagID_hhea || dwI == TagID_hmtx ||
  520. dwI == TagID_vhea || dwI == TagID_vmtx )
  521. {
  522. continue;
  523. }
  524. }
  525. #endif
  526. if (S_OK == pTTFile->TagAndID(&dwI, &tag) &&
  527. S_OK == pTTFile->GetTableDir(tag, (PVOID*)&pTableDir))
  528. {
  529. //
  530. // dwTableOffset is an offset from the top of the TrueType
  531. // Soft Font Directory Header to the start of the table data in
  532. // the PCL XL embedded data stream.
  533. //
  534. if (pTableDir)
  535. {
  536. PCLXLGTTblDir[dwNumTag].dwTableTag = pTableDir->ulTag;
  537. //PCLXLGTTblDir[dwNumTag].dwTableCheckSum = pTableDir->ulCheckSum;
  538. PCLXLGTTblDir[dwNumTag].dwTableCheckSum = 0;
  539. PCLXLGTTblDir[dwNumTag].dwTableOffset = 0;
  540. //
  541. // DWORD alignment
  542. //
  543. dwTableSize = SWAPDW(pTableDir->ulLength);
  544. dwTableSize = ((dwTableSize + 3) >> 2) << 2;
  545. PCLXLGTTblDir[dwNumTag].dwTableSize = SWAPDW(dwTableSize);
  546. }
  547. dwNumTag ++;
  548. }
  549. else
  550. if (tag == TTTag_gdir)
  551. {
  552. //
  553. // 'gdir' special case.
  554. //
  555. PCLXLGTTblDir[dwNumTag].dwTableTag = TTTag_gdir;
  556. PCLXLGTTblDir[dwNumTag].dwTableCheckSum = 0;
  557. PCLXLGTTblDir[dwNumTag].dwTableOffset = 0;
  558. PCLXLGTTblDir[dwNumTag].dwTableSize = 0;
  559. dwNumTag ++;
  560. }
  561. }
  562. dwGTSegSize = sizeof(PCLXL_GT_TABLE_DIR_HEADER) +
  563. sizeof(TTDIR) * dwNumTag;
  564. dwTableOffset = sizeof(PCLXL_GT_TABLE_DIR_HEADER) +
  565. dwNumTag * sizeof(TTDIR);
  566. //
  567. // Set dwTableOffset in PCLXLGTTblDir
  568. //
  569. for (dwI = 0; dwI < dwNumTag; dwI ++)
  570. {
  571. //
  572. // Skip virtual glyph data table (gdir)
  573. //
  574. if (PCLXLGTTblDir[dwI].dwTableTag != TTTag_gdir)
  575. {
  576. PCLXLGTTblDir[dwI].dwTableOffset = SWAPDW(dwTableOffset);
  577. dwTableSize = SWAPDW(PCLXLGTTblDir[dwI].dwTableSize);
  578. dwTableOffset += dwTableSize;
  579. dwGTSegSize += dwTableSize;
  580. }
  581. else
  582. {
  583. //
  584. // Fill gdir table dir offset
  585. //
  586. PCLXLGTTblDir[dwNumTag - 1].dwTableOffset = 0;
  587. }
  588. VERBOSE(("PCLXLDownloadFontHeader:Tag[%d]=%c%c%c%c, Size=0x%0x, Offset=0x%0x\n",
  589. dwI,
  590. 0xff & PCLXLGTTblDir[dwI].dwTableTag,
  591. 0xff & (PCLXLGTTblDir[dwI].dwTableTag >> 8),
  592. 0xff & (PCLXLGTTblDir[dwI].dwTableTag >> 16),
  593. 0xff & (PCLXLGTTblDir[dwI].dwTableTag >> 24),
  594. PCLXLGTTblDir[dwI].dwTableSize,
  595. PCLXLGTTblDir[dwI].dwTableOffset));
  596. }
  597. //
  598. // PCL XL GT Segment initialization
  599. //
  600. PTTHEADER pTTHeader;
  601. if (S_OK != pTTFile->GetHeader(&pTTHeader))
  602. {
  603. ERR(("PCLXL:DownloadFontHeader XLTTFile::GetHeader failed.\r\n"));
  604. return S_FALSE;
  605. }
  606. PCLXL_GT_SEGMENT PCLXLGTSegment;
  607. PCLXLGTSegment.wSignature = PCLXL_GT_SIGNATURE;
  608. PCLXLGTSegment.wSegmentSize1 = HIWORD(dwGTSegSize);
  609. PCLXLGTSegment.wSegmentSize1 = SWAPW(PCLXLGTSegment.wSegmentSize1);
  610. PCLXLGTSegment.wSegmentSize2 = LOWORD(dwGTSegSize);
  611. PCLXLGTSegment.wSegmentSize2 = SWAPW(PCLXLGTSegment.wSegmentSize2);
  612. PCLXL_GT_TABLE_DIR_HEADER PCLXLDirHeader;
  613. //
  614. // N = Number of Tables
  615. // Search Range = (maximum power of 2 <= N) * 16
  616. // Entry Selector = Log2(maximum power of 2 <= N)
  617. // Range Shift = (N * 16) - Search Range
  618. //
  619. WORD wSearchRange, wEntrySelector, wTemp;
  620. wSearchRange = 2;
  621. for (wSearchRange = 2; wSearchRange <= dwNumTag; wSearchRange <<= 1);
  622. wSearchRange >>= 1;
  623. wTemp = wSearchRange;
  624. wSearchRange <<= 4;
  625. for (wEntrySelector = 0; wTemp > 1; wTemp >>= 1, wEntrySelector++);
  626. //
  627. // HP Monolithic driver set 'ttcf' in the SFNTVersion.
  628. //
  629. {
  630. HRESULT hRet;
  631. if (S_OK == (hRet = pTTFile->IsTTC()))
  632. {
  633. PCLXLDirHeader.dwSFNTVersion = TTTag_ttcf;
  634. }
  635. else if (S_FALSE == hRet)
  636. {
  637. PCLXLDirHeader.dwSFNTVersion = pTTHeader->dwSfntVersion;
  638. }
  639. else
  640. {
  641. ERR(("PCLXL:DownloadFontHeader XLTrueType.IsTTC failed.\r\n"));
  642. return E_UNEXPECTED;
  643. }
  644. }
  645. PCLXLDirHeader.wNumOfTables = SWAPW((WORD)dwNumTag);
  646. PCLXLDirHeader.wSearchRange = SWAPW(wSearchRange);
  647. PCLXLDirHeader.wEntrySelector= SWAPW(wEntrySelector);
  648. PCLXLDirHeader.wRangeShift = SWAPW((dwNumTag << 4) - wSearchRange);
  649. //
  650. // GC Segment initialization
  651. //
  652. PCLXL_GC_SEGMENT PCLXLGCSegment;
  653. PCLXLGCSegment.wSignature = PCLXL_GC_SIGNATURE;
  654. PCLXLGCSegment.wSegmentSize = 0;
  655. PCLXLGCSegment.wSegmentSizeAlign = SWAPW(PCLXL_GC_SEGMENT_HEAD_SIZE);
  656. PCLXLGCSegment.wFormat = 0;
  657. PCLXLGCSegment.wDefaultGalleyCharacter = 0xFFFF;
  658. PCLXLGCSegment.wNumberOfRegions = 0;
  659. //
  660. // NULL Segment initialization
  661. //
  662. PCLXL_NULL_SEGMENT PCLXLNULLSegment;
  663. PCLXLNULLSegment.wSignature = PCLXL_NULL_SIGNATURE;
  664. PCLXLNULLSegment.wSegmentSize = 0;
  665. PCLXLNULLSegment.wSegmentSizeAlign = 0;
  666. //
  667. // Output
  668. //
  669. *pdwResult = 0;
  670. XLOutput *pOutput = pxlpdev->pOutput;
  671. //
  672. // BeginFontHeader
  673. //
  674. pOutput->Send_ubyte(0);
  675. pOutput->Send_attr_ubyte(eFontFormat);
  676. pOutput->Send_ubyte_array_header(PCLXL_FONTNAME_SIZE);
  677. pOutput->Write(PubGetFontName(pdevobj, pUFObj->ulFontID), PCLXL_FONTNAME_SIZE);
  678. pOutput->Send_attr_ubyte(eFontName);
  679. pOutput->Send_cmd(eBeginFontHeader);
  680. //
  681. // FontHeader
  682. //
  683. uint32 uint32_FontHeaderSize;
  684. uint32_FontHeaderSize = sizeof(PCLXLFontHeader);
  685. pOutput->Send_uint16((uint16)uint32_FontHeaderSize);
  686. pOutput->Send_attr_ubyte(eFontHeaderLength);
  687. pOutput->Send_cmd(eReadFontHeader);
  688. pOutput->WriteByte(PCLXL_dataLengthByte);
  689. pOutput->WriteByte((ubyte)uint32_FontHeaderSize);
  690. pOutput->Write((PBYTE)&PCLXLFontHeader, uint32_FontHeaderSize);
  691. *pdwResult += sizeof(PCLXLFontHeader);
  692. //
  693. // GT Header
  694. //
  695. uint32_FontHeaderSize = sizeof(PCLXL_GT_SEGMENT);
  696. pOutput->Send_uint16((uint16)uint32_FontHeaderSize);
  697. pOutput->Send_attr_ubyte(eFontHeaderLength);
  698. pOutput->Send_cmd(eReadFontHeader);
  699. pOutput->WriteByte(PCLXL_dataLengthByte);
  700. pOutput->WriteByte((ubyte)uint32_FontHeaderSize);
  701. pOutput->Write((PBYTE)&PCLXLGTSegment, uint32_FontHeaderSize);
  702. *pdwResult += sizeof(PCLXL_GT_SEGMENT);
  703. //
  704. // TrueType Softfont Directory Header
  705. // Table Dir
  706. //
  707. uint32_FontHeaderSize = sizeof(PCLXL_GT_TABLE_DIR_HEADER);
  708. pOutput->Send_uint16((uint16)uint32_FontHeaderSize);
  709. pOutput->Send_attr_ubyte(eFontHeaderLength);
  710. pOutput->Send_cmd(eReadFontHeader);
  711. pOutput->WriteByte(PCLXL_dataLengthByte);
  712. pOutput->WriteByte((ubyte)uint32_FontHeaderSize);
  713. pOutput->Write((PBYTE)&PCLXLDirHeader, sizeof(PCLXLDirHeader));
  714. uint32_FontHeaderSize = sizeof(PCLXL_GT_TABLE_DIR) * dwNumTag;
  715. pOutput->Send_uint16((uint16)uint32_FontHeaderSize);
  716. pOutput->Send_attr_ubyte(eFontHeaderLength);
  717. pOutput->Send_cmd(eReadFontHeader);
  718. pOutput->WriteByte(PCLXL_dataLengthByte);
  719. pOutput->WriteByte((ubyte)uint32_FontHeaderSize);
  720. pOutput->Write((PBYTE)PCLXLGTTblDir, sizeof(PCLXL_GT_TABLE_DIR) * dwNumTag);
  721. pOutput->Flush(pdevobj);
  722. *pdwResult += sizeof(PCLXL_GT_TABLE_DIR);
  723. //
  724. // Table data
  725. //
  726. PBYTE pubData;
  727. const BYTE ubNullData[4] = {0, 0, 0, 0};
  728. for (dwI = (USHORT)TagID_First; dwI < (USHORT)TagID_Header; dwI ++)
  729. {
  730. #if CLASS12
  731. //
  732. // Support only Class 1 and Class 2
  733. //
  734. if (dwI == TagID_hhea || dwI == TagID_hmtx ||
  735. dwI == TagID_vhea || dwI == TagID_vmtx )
  736. {
  737. continue;
  738. }
  739. #else
  740. //
  741. // Support Class 1 and Class 2 for horizontal font.
  742. // Class 0 for vertical font. PCL XL interpreter doesn't work fine.
  743. //
  744. if (S_OK != pTTFile->IsVertical())
  745. {
  746. //
  747. // Support only Class 1 and Class 2
  748. //
  749. if (dwI == TagID_hhea || dwI == TagID_hmtx ||
  750. dwI == TagID_vhea || dwI == TagID_vmtx )
  751. {
  752. continue;
  753. }
  754. }
  755. #endif
  756. //
  757. // Check a table for the tag is available in the TrueType font.
  758. //
  759. tag = TTTag_INVALID;
  760. if (S_OK == pTTFile->TagAndID(&dwI, &tag) &&
  761. S_OK == pTTFile->GetTable(tag,
  762. (PVOID*)&pubData,
  763. &uint32_FontHeaderSize))
  764. {
  765. VERBOSE(("PCLXLDownloadFontHeader:Tag[%d]=%c%c%c%c\n",
  766. dwI,
  767. 0xff & tag,
  768. 0xff & (tag >> 8),
  769. 0xff & (tag >> 16),
  770. 0xff & (tag >> 24)));
  771. //
  772. // DWORD alignment
  773. //
  774. dwDWAlign = ((uint32_FontHeaderSize + 3) >> 2) << 2;
  775. if (dwDWAlign <= 0x2000)
  776. {
  777. pOutput->Send_uint16((uint16)(dwDWAlign));
  778. pOutput->Send_attr_ubyte(eFontHeaderLength);
  779. pOutput->Send_cmd(eReadFontHeader);
  780. if (dwDWAlign <= 0xFF)
  781. {
  782. pOutput->WriteByte(PCLXL_dataLengthByte);
  783. pOutput->WriteByte((ubyte)dwDWAlign);
  784. }
  785. else
  786. {
  787. pOutput->WriteByte(PCLXL_dataLength);
  788. pOutput->Write((PBYTE)&dwDWAlign, sizeof(uint32));
  789. }
  790. pOutput->Write(pubData, uint32_FontHeaderSize);
  791. if (uint32_FontHeaderSize = dwDWAlign - uint32_FontHeaderSize)
  792. pOutput->Write((PBYTE)ubNullData, uint32_FontHeaderSize);
  793. }
  794. else
  795. {
  796. DWORD dwRemain = dwDWAlign;
  797. DWORD dwx2000 = 0x2000;
  798. while (dwRemain >= 0x2000)
  799. {
  800. pOutput->Send_uint16((uint16)0x2000);
  801. pOutput->Send_attr_ubyte(eFontHeaderLength);
  802. pOutput->Send_cmd(eReadFontHeader);
  803. pOutput->WriteByte(PCLXL_dataLength);
  804. pOutput->Write((PBYTE)&dwx2000, sizeof(uint32));
  805. pOutput->Write(pubData, dwx2000);
  806. dwRemain -= 0x2000;
  807. uint32_FontHeaderSize -= 0x2000;
  808. pubData += 0x2000;
  809. }
  810. if (dwRemain > 0)
  811. {
  812. pOutput->Send_uint16((uint16)dwRemain);
  813. pOutput->Send_attr_ubyte(eFontHeaderLength);
  814. pOutput->Send_cmd(eReadFontHeader);
  815. if (dwRemain <= 0xFF)
  816. {
  817. pOutput->WriteByte(PCLXL_dataLengthByte);
  818. pOutput->WriteByte((ubyte)dwRemain);
  819. }
  820. else
  821. {
  822. pOutput->WriteByte(PCLXL_dataLength);
  823. pOutput->Write((PBYTE)&dwRemain, sizeof(uint32));
  824. }
  825. pOutput->Write(pubData, uint32_FontHeaderSize);
  826. if (uint32_FontHeaderSize = dwRemain - uint32_FontHeaderSize)
  827. pOutput->Write((PBYTE)ubNullData, uint32_FontHeaderSize);
  828. }
  829. }
  830. *pdwResult += + dwDWAlign;
  831. }
  832. }
  833. //
  834. // GC segment
  835. //
  836. // Current there is no region.
  837. //
  838. uint32_FontHeaderSize = sizeof(PCLXLGCSegment) - sizeof(PCLXL_GC_REGION);
  839. pOutput->Send_uint16((uint16)uint32_FontHeaderSize);
  840. pOutput->Send_attr_ubyte(eFontHeaderLength);
  841. pOutput->Send_cmd(eReadFontHeader);
  842. pOutput->WriteByte(PCLXL_dataLengthByte);
  843. pOutput->WriteByte((ubyte)uint32_FontHeaderSize);
  844. pOutput->Write((PBYTE)&PCLXLGCSegment, uint32_FontHeaderSize);
  845. //
  846. // NULL header
  847. //
  848. uint32_FontHeaderSize = sizeof(PCLXLNULLSegment);
  849. pOutput->Send_uint16((uint16)uint32_FontHeaderSize);
  850. pOutput->Send_attr_ubyte(eFontHeaderLength);
  851. pOutput->Send_cmd(eReadFontHeader);
  852. pOutput->WriteByte(PCLXL_dataLengthByte);
  853. pOutput->WriteByte((ubyte)uint32_FontHeaderSize);
  854. pOutput->Write((PBYTE)&PCLXLNULLSegment, uint32_FontHeaderSize);
  855. *pdwResult += sizeof(PCLXLNULLSegment);
  856. //
  857. // EndFontHeader
  858. //
  859. pOutput->Send_cmd(eEndFontHeader);
  860. pOutput->Flush(pdevobj);
  861. //
  862. // Download special characters.
  863. //
  864. {
  865. //
  866. // Get glyph data
  867. //
  868. PBYTE pubGlyphData;
  869. DWORD dwGlyphDataSize = 0;
  870. DWORD dwCompositeDataSize = 0;
  871. if (S_OK != (hResult = pTTFile->GetGlyphData(0,
  872. &pubGlyphData,
  873. &dwGlyphDataSize)))
  874. {
  875. ERR(("PCLXL:DownloadFontHeader GetGlyphData failed.\r\n"));
  876. return hResult;
  877. }
  878. //
  879. // Composte glyph handling.
  880. // http://www.microsoft.com/typography/OTSPEC/glyf.htm
  881. //
  882. // Space character can have data the size of which is ZERO!
  883. // We don't need to return S_FALSE here.
  884. //
  885. BOOL bSpace = FALSE;
  886. if (dwGlyphDataSize != 0 && NULL != pubGlyphData)
  887. {
  888. #if COMPGLYF
  889. if (((PGLYF)pubGlyphData)->numberOfContours == COMPONENTCTRCOUNT)
  890. {
  891. dwCompositeDataSize = DwDownloadCompositeGlyph(
  892. pdevobj,
  893. pUFObj->ulFontID,
  894. (PGLYF)pubGlyphData);
  895. }
  896. #endif
  897. }
  898. else
  899. {
  900. bSpace = TRUE;
  901. }
  902. //
  903. // Download actual 0 glyph data
  904. //
  905. if (! BDownloadGlyphData(pdevobj,
  906. pUFObj->ulFontID,
  907. 0xFFFF,
  908. 0,
  909. pubGlyphData,
  910. dwGlyphDataSize,
  911. bSpace))
  912. {
  913. ERR(("PCLXL:DownloadCharGlyph BDownloadGlyphData failed.\r\n"));
  914. return S_FALSE;
  915. }
  916. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  917. pOutput->Send_cmd(eEndChar);
  918. pOutput->Flush(pdevobj);
  919. }
  920. }
  921. else
  922. hResult = S_FALSE;
  923. //
  924. // Add 1 to TrueType font counter.
  925. //
  926. if (hResult == S_OK)
  927. {
  928. pxlpdev->dwNumOfTTFont ++;
  929. }
  930. return hResult;
  931. }
  932. extern "C" HRESULT APIENTRY
  933. PCLXLDownloadCharGlyph(
  934. PDEVOBJ pdevobj,
  935. PUNIFONTOBJ pUFObj,
  936. HGLYPH hGlyph,
  937. PDWORD pdwWidth,
  938. OUT DWORD *pdwResult)
  939. /*++
  940. Routine Description:
  941. IPrintOemUni DownloadCharGlyph interface
  942. Arguments:
  943. Return Value:
  944. Note:
  945. --*/
  946. {
  947. HRESULT hResult;
  948. uint32 uint32_datasize;
  949. VERBOSE(("PCLXLDownloadCharGlyph() entry.\r\n"));
  950. //
  951. // Initialize locals
  952. //
  953. hResult = E_UNEXPECTED;
  954. uint32_datasize = 0;
  955. //
  956. // Bitmap font download
  957. //
  958. if (pUFObj->dwFlags & UFOFLAG_TTDOWNLOAD_BITMAP)
  959. {
  960. VERBOSE(("PCLXLDownloadCharGlyph() BITMAP.\n"));
  961. hResult = S_OK;
  962. //
  963. // Get glyph data
  964. //
  965. GETINFO_GLYPHBITMAP GBmp;
  966. GLYPHBITS *pgb;
  967. DWORD dwBmpSize;
  968. WORD wTopOffset;
  969. GBmp.dwSize = sizeof(GETINFO_GLYPHBITMAP);
  970. GBmp.hGlyph = hGlyph;
  971. GBmp.pGlyphData = NULL;
  972. if (!pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_GLYPHBITMAP, &GBmp, 0, NULL))
  973. {
  974. ERR(("UNIFONTOBJ_GetInfo:UFO_GETINFO_GLYPHBITMAP failed.\r\n"));
  975. return S_FALSE;
  976. }
  977. //
  978. // Initalize header
  979. //
  980. PCLXL_BITMAP_CHAR BitmapChar;
  981. pgb = GBmp.pGlyphData->gdf.pgb;
  982. wTopOffset = (WORD)(- pgb->ptlOrigin.y);
  983. BitmapChar.ubFormat = 0;
  984. BitmapChar.ubClass = 0;
  985. BitmapChar.wLeftOffset = SWAPW(pgb->ptlOrigin.x);
  986. BitmapChar.wTopOffset = SWAPW(wTopOffset);
  987. BitmapChar.wCharWidth = SWAPW(pgb->sizlBitmap.cx);
  988. BitmapChar.wCharHeight = SWAPW(pgb->sizlBitmap.cy);
  989. dwBmpSize = pgb->sizlBitmap.cy * ((pgb->sizlBitmap.cx + 7) >> 3);
  990. uint32_datasize = dwBmpSize + sizeof(BitmapChar);
  991. //
  992. // Output
  993. //
  994. PXLPDEV pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  995. XLOutput *pOutput = pxlpdev->pOutput;
  996. //
  997. // BeginChar
  998. //
  999. // by GPD
  1000. //
  1001. // BeginChar
  1002. //
  1003. if (!(pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON))
  1004. {
  1005. pxlpdev->dwFlags |= XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1006. pOutput->Send_ubyte_array_header(PCLXL_FONTNAME_SIZE);
  1007. pOutput->Write(PubGetFontName(pdevobj, pUFObj->ulFontID), PCLXL_FONTNAME_SIZE);
  1008. pOutput->Send_attr_ubyte(eFontName);
  1009. pOutput->Send_cmd(eBeginChar);
  1010. }
  1011. //
  1012. // ReadChar
  1013. //
  1014. pOutput->Send_uint16((uint16)((PPDEV)pdevobj)->dwNextGlyph);
  1015. pOutput->Send_attr_ubyte(eCharCode);
  1016. if (0xFFFF0000 & uint32_datasize)
  1017. {
  1018. pOutput->Send_uint32(uint32_datasize);
  1019. }
  1020. else if (0x0000FF00)
  1021. {
  1022. pOutput->Send_uint16((uint16)uint32_datasize);
  1023. }
  1024. else
  1025. {
  1026. pOutput->Send_ubyte((ubyte)uint32_datasize);
  1027. }
  1028. pOutput->Send_attr_ubyte(eCharDataSize);
  1029. pOutput->Send_cmd(eReadChar);
  1030. if (uint32_datasize <= 0xff)
  1031. {
  1032. pOutput->WriteByte(PCLXL_dataLengthByte);
  1033. pOutput->WriteByte((ubyte)uint32_datasize);
  1034. }
  1035. else
  1036. {
  1037. pOutput->WriteByte(PCLXL_dataLength);
  1038. pOutput->Write((PBYTE)&uint32_datasize, sizeof(uint32));
  1039. }
  1040. pOutput->Write((PBYTE)&BitmapChar, sizeof(BitmapChar));
  1041. pOutput->Flush(pdevobj);
  1042. //
  1043. // Direct Write
  1044. //
  1045. WriteSpoolBuf((PPDEV)pdevobj, (PBYTE)pgb->aj, dwBmpSize);
  1046. //
  1047. // EndChar
  1048. // Now EndChar is sent by FlushCachedText
  1049. //pOutput->Send_cmd(eEndChar);
  1050. pOutput->Flush(pdevobj);
  1051. //
  1052. // Get fixed pitch TT width
  1053. //
  1054. pxlpdev->dwFixedTTWidth = (GBmp.pGlyphData->ptqD.x.HighPart + 15) / 16;
  1055. //
  1056. // Set pdwWidth and pdwResult
  1057. //
  1058. *pdwWidth = (GBmp.pGlyphData->ptqD.x.HighPart + 15) >> 4;
  1059. *pdwResult = (DWORD) uint32_datasize;
  1060. VERBOSE(("PCLXLDownloadCharGlyph() Width=%d, DataSize=%d\n", *pdwWidth, uint32_datasize));
  1061. }
  1062. else
  1063. //
  1064. // TrueType outline font download
  1065. //
  1066. if (pUFObj->dwFlags & UFOFLAG_TTDOWNLOAD_TTOUTLINE)
  1067. {
  1068. VERBOSE(("PCLXLDownloadCharGlyph() OUTLINE.\n"));
  1069. PXLPDEV pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  1070. FONTOBJ *pFontObj;
  1071. //
  1072. // Get FONTOBJ by calling pUFObj->pfnGetInfo.
  1073. //
  1074. if (S_OK != GetFONTOBJ(pdevobj, pUFObj, &pFontObj))
  1075. {
  1076. ERR(("PCLXL:DownloadCharGlyph UFO_GETINFO_FONTOBJ failed.\r\n"));
  1077. return E_UNEXPECTED;
  1078. }
  1079. //
  1080. // Open get a pointer to memory-maped TrueType.
  1081. //
  1082. // ASSUMPTION: pxlpdev->pTTFile is initialized in EnablePDEV.
  1083. // The pointer is always available.
  1084. //
  1085. XLTrueType *pTTFile = pxlpdev->pTTFile;
  1086. if (S_OK != pTTFile->SameFont(pFontObj))
  1087. {
  1088. pTTFile->OpenTTFile(pFontObj);
  1089. }
  1090. else
  1091. pTTFile = pxlpdev->pTTFile;
  1092. //
  1093. // Get glyph data
  1094. //
  1095. PBYTE pubGlyphData;
  1096. DWORD dwGlyphDataSize = 0;
  1097. DWORD dwCompositeDataSize = 0;
  1098. if (S_OK != (hResult = pTTFile->GetGlyphData(hGlyph,
  1099. &pubGlyphData,
  1100. &dwGlyphDataSize)))
  1101. {
  1102. ERR(("PCLXL:DownloadCharGlyph GetGlyphData failed.\r\n"));
  1103. return hResult;
  1104. }
  1105. //
  1106. // Composte glyph handling.
  1107. // http://www.microsoft.com/typography/OTSPEC/glyf.htm
  1108. //
  1109. // Space character can have data the size of which is ZERO!
  1110. // We don't need to return S_FALSE here.
  1111. //
  1112. BOOL bSpace;
  1113. if (dwGlyphDataSize != 0 && NULL != pubGlyphData)
  1114. {
  1115. #if COMPGLYF
  1116. if (((PGLYF)pubGlyphData)->numberOfContours == COMPONENTCTRCOUNT)
  1117. {
  1118. dwCompositeDataSize = DwDownloadCompositeGlyph(
  1119. pdevobj,
  1120. pUFObj->ulFontID,
  1121. (PGLYF)pubGlyphData);
  1122. }
  1123. #endif
  1124. bSpace = FALSE;
  1125. }
  1126. else
  1127. {
  1128. //
  1129. // For space character.
  1130. //
  1131. bSpace = TRUE;
  1132. }
  1133. //
  1134. // Download actual hGlyph's glyph data
  1135. //
  1136. if (! BDownloadGlyphData(pdevobj,
  1137. pUFObj->ulFontID,
  1138. ((PDEV*)pdevobj)->dwNextGlyph,
  1139. hGlyph,
  1140. pubGlyphData,
  1141. dwGlyphDataSize,
  1142. bSpace))
  1143. {
  1144. ERR(("PCLXL:DownloadCharGlyph BDownloadGlyphData failed.\r\n"));
  1145. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  1146. {
  1147. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1148. XLOutput *pOutput = pxlpdev->pOutput;
  1149. pOutput->Send_cmd(eEndChar);
  1150. }
  1151. return S_FALSE;
  1152. }
  1153. //
  1154. // It's Scalable font. We can't get the width.
  1155. //
  1156. *pdwWidth = 0;
  1157. //
  1158. // Size of memory to be used.
  1159. // There is a case where the size is zero. Add 1 to hack UNIDRV.
  1160. //
  1161. if (bSpace)
  1162. {
  1163. dwGlyphDataSize = 1;
  1164. }
  1165. *pdwResult = (DWORD) dwGlyphDataSize + dwCompositeDataSize;
  1166. }
  1167. return hResult;
  1168. }
  1169. BOOL
  1170. BDownloadGlyphData(
  1171. PDEVOBJ pdevobj,
  1172. ULONG ulFontID,
  1173. DWORD dwGlyphID,
  1174. HGLYPH hGlyph,
  1175. PBYTE pubGlyphData,
  1176. DWORD dwGlyphDataSize,
  1177. BOOL bSpace)
  1178. {
  1179. PCLXL_TRUETYPE_CHAR_C0 OutlineCharC0;
  1180. PCLXL_TRUETYPE_CHAR_C1 OutlineCharC1;
  1181. PCLXL_TRUETYPE_CHAR_C2 OutlineCharC2;
  1182. uint32 uint32_datasize;
  1183. PXLPDEV pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  1184. XLTrueType *pTTFile = pxlpdev->pTTFile;
  1185. XLOutput *pOutput = pxlpdev->pOutput;
  1186. if (!(pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON))
  1187. {
  1188. pxlpdev->dwFlags |= XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1189. pOutput->Send_ubyte_array_header(PCLXL_FONTNAME_SIZE);
  1190. pOutput->Write(PubGetFontName(pdevobj, ulFontID), PCLXL_FONTNAME_SIZE);
  1191. pOutput->Send_attr_ubyte(eFontName);
  1192. pOutput->Send_cmd(eBeginChar);
  1193. }
  1194. #if CLASS12
  1195. //
  1196. // Class 1 for Horizontal font
  1197. // Class 2 for Vertical font
  1198. //
  1199. if (S_OK != pTTFile->IsVertical())
  1200. {
  1201. USHORT usAdvanceWidth;
  1202. SHORT sLeftSideBearing;
  1203. if (S_OK != pTTFile->GetHMTXData(hGlyph, &usAdvanceWidth, &sLeftSideBearing))
  1204. {
  1205. ERR(("PCLXLDownloadFontHeader::GetHMTXData failed.\n"));
  1206. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  1207. {
  1208. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1209. pOutput->Delete();
  1210. }
  1211. return FALSE;
  1212. }
  1213. //
  1214. // The initialization of TrueType Glyphs Format 1 Class 1.
  1215. //
  1216. uint32_datasize = dwGlyphDataSize +
  1217. sizeof(OutlineCharC1.wCharDataSize) +
  1218. sizeof(OutlineCharC1.wLeftSideBearing) +
  1219. sizeof(OutlineCharC1.wAdvanceWidth) +
  1220. sizeof(OutlineCharC1.wTrueTypeGlyphID);
  1221. OutlineCharC1.ubFormat = 1;
  1222. OutlineCharC1.ubClass = 1;
  1223. OutlineCharC1.wCharDataSize = SWAPW((WORD)uint32_datasize);
  1224. OutlineCharC1.wLeftSideBearing = SWAPW((WORD)sLeftSideBearing);
  1225. OutlineCharC1.wAdvanceWidth = SWAPW((WORD)usAdvanceWidth);
  1226. OutlineCharC1.wTrueTypeGlyphID = SWAPW((WORD)hGlyph);
  1227. uint32_datasize += sizeof(OutlineCharC1.ubFormat) +
  1228. sizeof(OutlineCharC1.ubClass);
  1229. if (S_OK != pOutput->Send_uint16((uint16)dwGlyphID) ||
  1230. S_OK != pOutput->Send_attr_ubyte(eCharCode) ||
  1231. S_OK != pOutput->Send_uint16((uint16)uint32_datasize) ||
  1232. S_OK != pOutput->Send_attr_ubyte(eCharDataSize) ||
  1233. S_OK != pOutput->Send_cmd(eReadChar))
  1234. {
  1235. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  1236. {
  1237. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1238. pOutput->Delete();
  1239. }
  1240. return FALSE;
  1241. }
  1242. }
  1243. else
  1244. {
  1245. USHORT usAdvanceWidth;
  1246. SHORT sLeftSideBearing;
  1247. SHORT sTopSideBearing;
  1248. if (S_OK != pTTFile->GetVMTXData(hGlyph, &usAdvanceWidth, &sTopSideBearing, &sLeftSideBearing))
  1249. {
  1250. ERR(("PCLXLDownloadCharGlyph::GetVMTXData failed.\n"));
  1251. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  1252. {
  1253. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1254. pOutput->Delete();
  1255. }
  1256. return FALSE;
  1257. }
  1258. //
  1259. // The initialization of TrueType Glyphs Format 1 Class 2.
  1260. //
  1261. uint32_datasize = dwGlyphDataSize +
  1262. sizeof(OutlineCharC2.wLeftSideBearing) +
  1263. sizeof(OutlineCharC2.wTopSideBearing) +
  1264. sizeof(OutlineCharC2.wAdvanceWidth) +
  1265. sizeof(OutlineCharC2.wCharDataSize) +
  1266. sizeof(OutlineCharC2.wTrueTypeGlyphID);
  1267. OutlineCharC2.ubFormat = 1;
  1268. OutlineCharC2.ubClass = 2;
  1269. OutlineCharC2.wCharDataSize = SWAPW((WORD)uint32_datasize);
  1270. OutlineCharC2.wLeftSideBearing = SWAPW((WORD)sLeftSideBearing);
  1271. OutlineCharC2.wAdvanceWidth = SWAPW((WORD)usAdvanceWidth);
  1272. OutlineCharC2.wTopSideBearing = SWAPW((WORD)sTopSideBearing);
  1273. OutlineCharC2.wTrueTypeGlyphID = SWAPW((WORD)hGlyph);
  1274. uint32_datasize += sizeof(OutlineCharC2.ubFormat) +
  1275. sizeof(OutlineCharC2.ubClass);
  1276. if (S_OK != pOutput->Send_uint16((uint16)dwGlyphID) ||
  1277. S_OK != pOutput->Send_attr_ubyte(eCharCode) ||
  1278. S_OK != pOutput->Send_uint16((uint16)uint32_datasize) ||
  1279. S_OK != pOutput->Send_attr_ubyte(eCharDataSize) ||
  1280. S_OK != pOutput->Send_cmd(eReadChar))
  1281. {
  1282. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  1283. {
  1284. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1285. pOutput->Delete();
  1286. }
  1287. return FALSE;
  1288. }
  1289. }
  1290. #else{
  1291. //
  1292. // The initialization of TrueType Glyphs Format 1 Class 0.
  1293. //
  1294. uint32_datasize = dwGlyphDataSize +
  1295. sizeof(OutlineCharC0.wCharDataSize) +
  1296. sizeof(OutlineCharC0.wTrueTypeGlyphID);
  1297. OutlineCharC0.ubFormat = 1;
  1298. OutlineCharC0.ubClass = 0;
  1299. OutlineCharC0.wCharDataSize = SWAPW((WORD)uint32_datasize);
  1300. OutlineCharC0.wTrueTypeGlyphID = SWAPW((WORD)hGlyph);
  1301. uint32_datasize += sizeof(OutlineCharC0.ubFormat) +
  1302. sizeof(OutlineCharC0.ubClass);
  1303. if (S_OK != pOutput->Send_uint16((uint16)dwGlyphID) ||
  1304. S_OK != pOutput->Send_attr_ubyte(eCharCode) ||
  1305. S_OK != pOutput->Send_uint16((uint16)uint32_datasize) ||
  1306. S_OK != pOutput->Send_attr_ubyte(eCharDataSize) ||
  1307. S_OK != pOutput->Send_cmd(eReadChar))
  1308. {
  1309. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  1310. {
  1311. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1312. pOutput->Delete();
  1313. }
  1314. return FALSE;
  1315. }
  1316. }
  1317. #endif
  1318. if (uint32_datasize <= 0xff)
  1319. {
  1320. if (S_OK != pOutput->WriteByte(PCLXL_dataLengthByte) ||
  1321. S_OK != pOutput->WriteByte((ubyte)uint32_datasize))
  1322. {
  1323. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  1324. {
  1325. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1326. pOutput->Delete();
  1327. }
  1328. return FALSE;
  1329. }
  1330. }
  1331. else
  1332. {
  1333. if (S_OK != pOutput->WriteByte(PCLXL_dataLength) ||
  1334. S_OK != pOutput->Write((PBYTE)&uint32_datasize, sizeof(uint32)))
  1335. {
  1336. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  1337. {
  1338. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1339. pOutput->Delete();
  1340. }
  1341. return FALSE;
  1342. }
  1343. }
  1344. #if CLASS12
  1345. if (S_OK != pTTFile->IsVertical())
  1346. {
  1347. pOutput->Write((PBYTE)&OutlineCharC1, sizeof(OutlineCharC1));
  1348. }
  1349. else
  1350. {
  1351. pOutput->Write((PBYTE)&OutlineCharC2, sizeof(OutlineCharC2));
  1352. }
  1353. #else
  1354. pOutput->Write((PBYTE)&OutlineCharC0, sizeof(OutlineCharC0));
  1355. #endif
  1356. if (S_OK == pOutput->Flush(pdevobj))
  1357. {
  1358. if (!bSpace)
  1359. {
  1360. //
  1361. // Direct Write
  1362. //
  1363. dwGlyphDataSize = (DWORD)WriteSpoolBuf((PPDEV)pdevobj,
  1364. pubGlyphData,
  1365. dwGlyphDataSize);
  1366. }
  1367. return TRUE;
  1368. }
  1369. else
  1370. {
  1371. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  1372. {
  1373. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1374. pOutput->Delete();
  1375. }
  1376. return FALSE;
  1377. }
  1378. }
  1379. extern "C" HRESULT APIENTRY
  1380. PCLXLTTDownloadMethod(
  1381. PDEVOBJ pdevobj,
  1382. PUNIFONTOBJ pUFObj,
  1383. OUT DWORD *pdwResult)
  1384. /*++
  1385. Routine Description:
  1386. IPrintOemUni TTDownloadMethod interface
  1387. Arguments:
  1388. Return Value:
  1389. Note:
  1390. --*/
  1391. {
  1392. VERBOSE(("PCLXLTTDownloadMethod() entry.\r\n"));
  1393. //
  1394. // Error Check
  1395. //
  1396. if (NULL == pdevobj ||
  1397. NULL == pUFObj ||
  1398. NULL == pUFObj->pIFIMetrics ||
  1399. NULL == pdwResult )
  1400. {
  1401. ERR(("PCLXLTTDownloadMethod(): invalid parameters.\r\n"));
  1402. return E_UNEXPECTED;
  1403. }
  1404. //
  1405. // Initialize
  1406. //
  1407. *pdwResult = TTDOWNLOAD_GRAPHICS;
  1408. if (((PPDEV)pdevobj)->pGlobals->fontformat == UNUSED_ITEM)
  1409. {
  1410. //
  1411. // There is no font download format specified.
  1412. // Prints as graphics.
  1413. //
  1414. return S_OK;
  1415. }
  1416. //
  1417. // Return GRAPHICS for non-TrueType font
  1418. //
  1419. if ( !(pUFObj->pIFIMetrics->flInfo & FM_INFO_TECH_TRUETYPE) )
  1420. {
  1421. ERR(("PCLXLTTDownloadMethod(): invalid font.\r\n"));
  1422. return S_OK;
  1423. }
  1424. //
  1425. // Text As Graphics
  1426. //
  1427. if (((PPDEV)pdevobj)->pdmPrivate->dwFlags & DXF_TEXTASGRAPHICS)
  1428. {
  1429. return S_OK;
  1430. }
  1431. //
  1432. // Get XForm and X and Y scaling factors.
  1433. //
  1434. PXLPDEV pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  1435. FLOATOBJ_XFORM xform;
  1436. FLOATOBJ foXScale, foYScale;
  1437. if (S_OK != GetXForm(pdevobj, pUFObj, &xform) ||
  1438. S_OK != GetXYScale(&xform, &foXScale, &foYScale))
  1439. {
  1440. ERR(("PCLXLTTDownloadMethod(): Failed to get X and Y Scale.\r\n"));
  1441. return E_UNEXPECTED;
  1442. }
  1443. //
  1444. // Scale fwdUnitsPerEm
  1445. //
  1446. FLOATOBJ_MulLong(&foYScale, pUFObj->pIFIMetrics->fwdUnitsPerEm);
  1447. FLOATOBJ_MulLong(&foXScale, pUFObj->pIFIMetrics->fwdUnitsPerEm);
  1448. pxlpdev->fwdUnitsPerEm = (FWORD)FLOATOBJ_GetLong(&foYScale);
  1449. pxlpdev->fwdMaxCharWidth = (FWORD)FLOATOBJ_GetLong(&foXScale);
  1450. //
  1451. // Download as Bitmap softfont
  1452. //
  1453. if (((PPDEV)pdevobj)->pGlobals->fontformat == FF_HPPCL ||
  1454. ((PPDEV)pdevobj)->pGlobals->fontformat == FF_HPPCL_RES)
  1455. {
  1456. *pdwResult = TTDOWNLOAD_BITMAP;
  1457. return S_OK;
  1458. }
  1459. //
  1460. // Parse TrueType font
  1461. //
  1462. XLTrueType *pTTFile = pxlpdev->pTTFile;
  1463. FONTOBJ *pFontObj;
  1464. if (S_OK == GetFONTOBJ(pdevobj, pUFObj, &pFontObj))
  1465. {
  1466. if (S_OK != pTTFile->OpenTTFile(pFontObj))
  1467. {
  1468. ERR(("PCLXL:TTDownloadMethod(): Failed to open TT file.\n"));
  1469. return S_FALSE;
  1470. }
  1471. }
  1472. //
  1473. // Reverse width and height, if the font is a vertial font.
  1474. //
  1475. if (S_OK == pTTFile->IsVertical())
  1476. {
  1477. FWORD fwdTmp;
  1478. fwdTmp = pxlpdev->fwdUnitsPerEm;
  1479. pxlpdev->fwdUnitsPerEm = pxlpdev->fwdMaxCharWidth;
  1480. pxlpdev->fwdMaxCharWidth = fwdTmp;
  1481. }
  1482. //
  1483. // Always return TrueType Outline
  1484. //
  1485. *pdwResult = TTDOWNLOAD_TTOUTLINE;
  1486. VERBOSE(("PCLXLTTDownloadMethod() pdwResult=%d\n", *pdwResult));
  1487. return S_OK;
  1488. }
  1489. extern "C" HRESULT APIENTRY
  1490. PCLXLOutputCharStr(
  1491. PDEVOBJ pdevobj,
  1492. PUNIFONTOBJ pUFObj,
  1493. DWORD dwType,
  1494. DWORD dwCount,
  1495. PVOID pGlyph)
  1496. /*++
  1497. Routine Description:
  1498. IPrintOemUni OutputCharStr interface
  1499. Arguments:
  1500. Return Value:
  1501. Note:
  1502. --*/
  1503. {
  1504. PXLPDEV pxlpdev;
  1505. //
  1506. // UNIFONTOBJ callback data structures
  1507. //
  1508. GETINFO_GLYPHSTRING GStr;
  1509. GETINFO_GLYPHWIDTH GWidth;
  1510. //
  1511. // Device font TRANSDATA structure
  1512. //
  1513. PTRANSDATA pTransOrg, pTrans;
  1514. PPOINTL pptlCharAdvance;
  1515. PWORD pawChar;
  1516. PLONG plWidth;
  1517. DWORD dwGetInfo, dwI, dwcbInitSize;
  1518. VERBOSE(("PCLXLOutputCharStr() entry.\r\n"));
  1519. //
  1520. // Error parameter check
  1521. //
  1522. if (0 == dwCount ||
  1523. NULL == pGlyph ||
  1524. NULL == pUFObj )
  1525. {
  1526. ERR(("PCLXLOutptuChar: Invalid parameters\n"));
  1527. return E_UNEXPECTED;
  1528. }
  1529. pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  1530. //
  1531. // Get current text resolution
  1532. //
  1533. if (pxlpdev->dwTextRes == 0)
  1534. {
  1535. GETINFO_STDVAR StdVar;
  1536. DWORD dwSizeNeeded;
  1537. StdVar.dwSize = sizeof(GETINFO_STDVAR);
  1538. StdVar.dwNumOfVariable = 1;
  1539. StdVar.StdVar[0].dwStdVarID = FNT_INFO_TEXTYRES;
  1540. StdVar.StdVar[0].lStdVariable = 0;
  1541. pUFObj->pfnGetInfo(pUFObj,
  1542. UFO_GETINFO_STDVARIABLE,
  1543. &StdVar,
  1544. StdVar.dwSize,
  1545. &dwSizeNeeded);
  1546. pxlpdev->dwTextRes = StdVar.StdVar[0].lStdVariable;
  1547. }
  1548. //
  1549. // Allocate memory for character cache
  1550. //
  1551. if (0 == pxlpdev->dwMaxCharCount ||
  1552. pxlpdev->dwMaxCharCount < pxlpdev->dwCharCount + dwCount)
  1553. {
  1554. DWORD dwInitCount = INIT_CHAR_NUM;
  1555. //
  1556. // Calculate the initial data size
  1557. //
  1558. if (dwInitCount < pxlpdev->dwCharCount + dwCount)
  1559. {
  1560. dwInitCount = pxlpdev->dwCharCount + dwCount;
  1561. }
  1562. //
  1563. // Allocate memory
  1564. //
  1565. if (!(pptlCharAdvance = (PPOINTL)MemAlloc(sizeof(POINTL) * dwInitCount)) ||
  1566. !(pawChar = (PWORD)MemAlloc(sizeof(WORD) * dwInitCount)) )
  1567. {
  1568. ERR(("PCLXL:CharWidth buffer allocation failed.\n"));
  1569. if (pptlCharAdvance)
  1570. {
  1571. MemFree(pptlCharAdvance);
  1572. }
  1573. return E_UNEXPECTED;
  1574. }
  1575. //
  1576. // Copy the old buffer to new buffer
  1577. //
  1578. if (pxlpdev->dwCharCount > 0)
  1579. {
  1580. CopyMemory(pptlCharAdvance, pxlpdev->pptlCharAdvance, pxlpdev->dwCharCount * sizeof(POINTL));
  1581. CopyMemory(pawChar, pxlpdev->pawChar, pxlpdev->dwCharCount * sizeof(WORD));
  1582. }
  1583. if (pxlpdev->pptlCharAdvance)
  1584. MemFree(pxlpdev->pptlCharAdvance);
  1585. if (pxlpdev->pawChar)
  1586. MemFree(pxlpdev->pawChar);
  1587. pxlpdev->pptlCharAdvance = pptlCharAdvance;
  1588. pxlpdev->pawChar = pawChar;
  1589. pxlpdev->dwMaxCharCount = dwInitCount;
  1590. }
  1591. XLOutput *pOutput = pxlpdev->pOutput;
  1592. //
  1593. // Y cursor position is different from the previous OutputCharGlyph
  1594. // Flush the string cache
  1595. //
  1596. if (0 == pxlpdev->dwCharCount)
  1597. {
  1598. pxlpdev->lStartX =
  1599. pxlpdev->lX = ((TO_DATA*)((PFONTPDEV)pxlpdev->pPDev->pFontPDev)->ptod)->ptlFirstGlyph.x;
  1600. pxlpdev->lStartY =
  1601. pxlpdev->lY = ((TO_DATA*)((PFONTPDEV)pxlpdev->pPDev->pFontPDev)->ptod)->ptlFirstGlyph.y;
  1602. if (((TO_DATA*)((PFONTPDEV)pxlpdev->pPDev->pFontPDev)->ptod)->iRot)
  1603. {
  1604. pxlpdev->dwTextAngle = ((TO_DATA*)((PFONTPDEV)pxlpdev->pPDev->pFontPDev)->ptod)->iRot;
  1605. }
  1606. }
  1607. //
  1608. // Init pawChar
  1609. //
  1610. pawChar = pxlpdev->pawChar + pxlpdev->dwCharCount;
  1611. switch(dwType)
  1612. {
  1613. case TYPE_GLYPHHANDLE:
  1614. //
  1615. // Get TRANSDATA
  1616. //
  1617. GStr.dwSize = sizeof(GETINFO_GLYPHSTRING);
  1618. GStr.dwCount = dwCount;
  1619. GStr.dwTypeIn = TYPE_GLYPHHANDLE;
  1620. GStr.pGlyphIn = pGlyph;
  1621. GStr.dwTypeOut = TYPE_TRANSDATA;
  1622. GStr.pGlyphOut = NULL;
  1623. GStr.dwGlyphOutSize = 0;
  1624. dwGetInfo = GStr.dwSize;
  1625. //
  1626. // Get necessary buffer size
  1627. //
  1628. pUFObj->pfnGetInfo(pUFObj,
  1629. UFO_GETINFO_GLYPHSTRING,
  1630. &GStr,
  1631. dwGetInfo,
  1632. &dwGetInfo);
  1633. if (!GStr.dwGlyphOutSize)
  1634. {
  1635. ERR(("PCLXLOutptuChar: GetInfo( 1st GLYPHSTRING) failed\n"));
  1636. return E_UNEXPECTED;
  1637. }
  1638. if (NULL == pxlpdev->pTransOrg ||
  1639. dwCount * sizeof(TRANSDATA) > pxlpdev->dwcbTransSize ||
  1640. GStr.dwGlyphOutSize > pxlpdev->dwcbTransSize)
  1641. {
  1642. dwcbInitSize = INIT_CHAR_NUM * sizeof(TRANSDATA);
  1643. if (dwcbInitSize < GStr.dwGlyphOutSize)
  1644. {
  1645. dwcbInitSize = GStr.dwGlyphOutSize;
  1646. }
  1647. if (dwcbInitSize < dwCount * sizeof(TRANSDATA))
  1648. {
  1649. dwcbInitSize = dwCount * sizeof(TRANSDATA);
  1650. }
  1651. if (NULL == pxlpdev->pTransOrg)
  1652. {
  1653. MemFree(pxlpdev->pTransOrg);
  1654. }
  1655. if ((pTransOrg = (PTRANSDATA)MemAlloc(dwcbInitSize)) == NULL)
  1656. {
  1657. ERR(("PCLXLOutptuChar: MemAlloc failed\n"));
  1658. return E_UNEXPECTED;
  1659. }
  1660. pxlpdev->pTransOrg = pTransOrg;
  1661. pxlpdev->dwcbTransSize = dwcbInitSize;
  1662. }
  1663. else
  1664. {
  1665. pTransOrg = pxlpdev->pTransOrg;
  1666. }
  1667. GStr.pGlyphOut = (PVOID)pTransOrg;
  1668. if (!pUFObj->pfnGetInfo(pUFObj,
  1669. UFO_GETINFO_GLYPHSTRING,
  1670. &GStr,
  1671. dwGetInfo,
  1672. &dwGetInfo))
  1673. {
  1674. ERR(("PCLXLOutptuChar: GetInfo( 2nd GLYPHSTRING) failed\n"));
  1675. return E_UNEXPECTED;
  1676. }
  1677. pTrans = pTransOrg;
  1678. for (dwI = 0; dwI < dwCount; dwI++, pTrans++)
  1679. {
  1680. switch(pTrans->ubType & MTYPE_FORMAT_MASK)
  1681. {
  1682. case MTYPE_COMPOSE:
  1683. ERR(("PCLXL:OutputCharGlyph: Unsupported ubType\n"));
  1684. break;
  1685. case MTYPE_DIRECT:
  1686. VERBOSE(("PCLXLOutputCharStr:%c\n", pTrans->uCode.ubCode));
  1687. *pawChar++ = pTrans->uCode.ubCode;
  1688. break;
  1689. case MTYPE_PAIRED:
  1690. *pawChar++ = *(PWORD)(pTrans->uCode.ubPairs);
  1691. break;
  1692. }
  1693. }
  1694. break;
  1695. case TYPE_GLYPHID:
  1696. for (dwI = 0; dwI < dwCount; dwI++, pawChar++)
  1697. {
  1698. CopyMemory(pawChar, (PDWORD)pGlyph + dwI, sizeof(WORD));
  1699. }
  1700. break;
  1701. }
  1702. //
  1703. // Get Character width
  1704. //
  1705. //
  1706. // Store char position info
  1707. //
  1708. pptlCharAdvance = pxlpdev->pptlCharAdvance + pxlpdev->dwCharCount;
  1709. //
  1710. // dwCharCount holds the number of chars in the character cache
  1711. // dwCharCount = 0: Store start X pos
  1712. // Current Y pos
  1713. //
  1714. if (pxlpdev->dwCharCount == 0)
  1715. {
  1716. //
  1717. // UNIDRV hack
  1718. // Get the first character position.
  1719. //
  1720. pxlpdev->lPrevX =
  1721. pxlpdev->lStartX =
  1722. pxlpdev->lX = ((TO_DATA*)((PFONTPDEV)pxlpdev->pPDev->pFontPDev)->ptod)->ptlFirstGlyph.x;
  1723. pxlpdev->lPrevY =
  1724. pxlpdev->lStartY =
  1725. pxlpdev->lY = ((TO_DATA*)((PFONTPDEV)pxlpdev->pPDev->pFontPDev)->ptod)->ptlFirstGlyph.y;
  1726. VERBOSE(("PCLXLOutputCharStr: %d",pxlpdev->lStartX));
  1727. }
  1728. GLYPHPOS *pgp = ((TO_DATA*)((PFONTPDEV)pxlpdev->pPDev->pFontPDev)->ptod)->pgp;
  1729. if (pxlpdev->dwCharCount > 0)
  1730. {
  1731. if (pxlpdev->dwCharCount < ((TO_DATA*)((PFONTPDEV)pxlpdev->pPDev->pFontPDev)->ptod)->cGlyphsToPrint)
  1732. {
  1733. pgp += pxlpdev->dwCharCount;
  1734. }
  1735. (pptlCharAdvance - 1)->x = pgp->ptl.x - pxlpdev->lPrevX;
  1736. (pptlCharAdvance - 1)->y = pgp->ptl.y - pxlpdev->lPrevY;
  1737. }
  1738. for (dwI = 0; dwI < dwCount - 1; dwI ++, pptlCharAdvance ++, pgp ++)
  1739. {
  1740. pptlCharAdvance->x = pgp[1].ptl.x - pgp->ptl.x;
  1741. pptlCharAdvance->y = pgp[1].ptl.y - pgp->ptl.y;
  1742. VERBOSE((",(%d, %d)", pptlCharAdvance->x, pptlCharAdvance->y));
  1743. }
  1744. VERBOSE(("\n"));
  1745. pptlCharAdvance->x = pptlCharAdvance->y = 0;
  1746. pxlpdev->lPrevX = pgp->ptl.x;
  1747. pxlpdev->lPrevY = pgp->ptl.y;
  1748. pxlpdev->dwCharCount += dwCount;
  1749. return S_OK;
  1750. }
  1751. extern "C" HRESULT APIENTRY
  1752. PCLXLSendFontCmd(
  1753. PDEVOBJ pdevobj,
  1754. PUNIFONTOBJ pUFObj,
  1755. PFINVOCATION pFInv)
  1756. /*++
  1757. Routine Description:
  1758. IPrintOemUni SendFontCmd interface
  1759. Arguments:
  1760. Return Value:
  1761. Note:
  1762. --*/
  1763. {
  1764. VERBOSE(("PCLXLSendFontCmd() entry.\r\n"));
  1765. CHAR cSymbolSet[16];
  1766. PBYTE pubCmd;
  1767. if (NULL == pFInv ||
  1768. NULL == pFInv->pubCommand ||
  1769. 0 == pFInv->dwCount )
  1770. {
  1771. VERBOSE(("PCLXLSendFontCmd: unexpected FINVOCATION\n"));
  1772. return S_OK;
  1773. }
  1774. PXLPDEV pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  1775. XLOutput *pOutput = pxlpdev->pOutput;
  1776. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  1777. {
  1778. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1779. pOutput->Send_cmd(eEndChar);
  1780. }
  1781. if (pUFObj->dwFlags & UFOFLAG_TTFONT)
  1782. {
  1783. if (pFInv->dwCount == sizeof(DWORD))
  1784. {
  1785. if (pUFObj->dwFlags & UFOFLAG_TTDOWNLOAD_BITMAP)
  1786. {
  1787. pOutput->SetFont(kFontTypeTTBitmap,
  1788. PubGetFontName(pdevobj, pUFObj->ulFontID),
  1789. pxlpdev->fwdUnitsPerEm,
  1790. pxlpdev->fwdMaxCharWidth,
  1791. 0x0002,
  1792. (DWORD)0);
  1793. }
  1794. else
  1795. {
  1796. DWORD dwFontSimulation = pUFObj->dwFlags & (UFOFLAG_TTOUTLINE_BOLD_SIM|UFOFLAG_TTOUTLINE_ITALIC_SIM|UFOFLAG_TTOUTLINE_VERTICAL);
  1797. //
  1798. // UFOFLAG_TTOUTLINE_BOLD_SIM = 0x08
  1799. // UFOFLAG_TTOUTLINE_ITALIC_SIM = 0x10
  1800. // UFOFLAG_TTOUTLINE_VERTICAL = 0x20
  1801. //
  1802. // XLOUTPUT_FONTSIM_BOLD = 0x01
  1803. // XLOUTPUT_FONTSIM_ITALIC = 0x02
  1804. // XLOUTPUT_FONTSIM_VERTICAL = 0x03
  1805. //
  1806. dwFontSimulation >>= 3;
  1807. pOutput->SetFont(kFontTypeTTOutline,
  1808. PubGetFontName(pdevobj, pUFObj->ulFontID),
  1809. pxlpdev->fwdUnitsPerEm,
  1810. pxlpdev->fwdMaxCharWidth,
  1811. 0x0002,
  1812. dwFontSimulation);
  1813. }
  1814. }
  1815. else
  1816. {
  1817. VERBOSE(("PCLXLSendFontCmd: unexpected FINVOCATION\n"));
  1818. return S_FALSE;
  1819. }
  1820. }
  1821. else
  1822. {
  1823. DWORD dwSizeNeeded, dwSize, dwSymbolSet;
  1824. pubCmd = pFInv->pubCommand;
  1825. pubCmd += pFInv->dwCount;
  1826. pubCmd --;
  1827. //
  1828. // Get a symbol set
  1829. //
  1830. // ASSUMPTION: Font selecton string is like following!!!!
  1831. //
  1832. // "Courier 590"
  1833. // 12345678901234567890
  1834. // the size of font name is 16. Plus space and symbol set number.
  1835. //
  1836. if (pFInv->dwCount < 0x11)
  1837. {
  1838. ERR(("PCLXL:SendFontCmd: Invalid font selection command.\n"));
  1839. return E_UNEXPECTED;
  1840. }
  1841. dwSize = 0;
  1842. while (*pubCmd != 0x20 && dwSize < pFInv->dwCount)
  1843. {
  1844. pubCmd--;
  1845. dwSize ++;
  1846. }
  1847. if (dwSize != 0)
  1848. {
  1849. pubCmd++;
  1850. CopyMemory(cSymbolSet, pubCmd, dwSize);
  1851. }
  1852. cSymbolSet[dwSize] = NULL;
  1853. dwSymbolSet = (DWORD)atoi(cSymbolSet);
  1854. //
  1855. // Get FONTOBJ
  1856. //
  1857. FONTOBJ *pFontObj;
  1858. GetFONTOBJ(pdevobj, pUFObj, &pFontObj);
  1859. //
  1860. // Get XForm
  1861. //
  1862. FLOATOBJ foXScale, foYScale;
  1863. FLOATOBJ_XFORM xform;
  1864. if (S_OK != GetXForm(pdevobj, pUFObj, &xform) ||
  1865. S_OK != GetXYScale(&xform, &foXScale, &foYScale))
  1866. {
  1867. return E_UNEXPECTED;
  1868. }
  1869. //
  1870. // Scale Height and Width
  1871. //
  1872. // Is X scaled differently from Y?
  1873. // If so, set X.
  1874. //
  1875. DWORD dwFontWidth;
  1876. FLOATOBJ_MulLong(&foYScale, pUFObj->pIFIMetrics->fwdUnitsPerEm);
  1877. FLOATOBJ_MulLong(&foXScale, pUFObj->pIFIMetrics->fwdUnitsPerEm);
  1878. pxlpdev->dwFontHeight = (FWORD)FLOATOBJ_GetLong(&foYScale);
  1879. pxlpdev->dwFontWidth = (FWORD)FLOATOBJ_GetLong(&foXScale);
  1880. if (S_OK == IsXYSame(&xform))
  1881. {
  1882. dwFontWidth = 0;
  1883. }
  1884. else
  1885. {
  1886. dwFontWidth = pxlpdev->dwFontWidth;
  1887. }
  1888. BYTE aubFontName[PCLXL_FONTNAME_SIZE + 1];
  1889. CopyMemory(aubFontName, pFInv->pubCommand, PCLXL_FONTNAME_SIZE);
  1890. aubFontName[PCLXL_FONTNAME_SIZE] = NULL;
  1891. pOutput->SetFont(kFontTypeDevice,
  1892. (PBYTE)aubFontName,
  1893. pxlpdev->dwFontHeight,
  1894. dwFontWidth,
  1895. dwSymbolSet,
  1896. 0);
  1897. }
  1898. pOutput->Flush(pdevobj);
  1899. if (pxlpdev->dwFlags & XLPDEV_FLAGS_RESET_FONT)
  1900. {
  1901. BSaveFont(pdevobj);
  1902. }
  1903. return S_OK;
  1904. }
  1905. HRESULT
  1906. FlushCachedText(
  1907. PDEVOBJ pdevobj)
  1908. /*++
  1909. Routine Description:
  1910. Arguments:
  1911. Return Value:
  1912. Note:
  1913. --*/
  1914. {
  1915. PXLPDEV pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  1916. DWORD dwI;
  1917. VERBOSE(("PCLXLFlushCachedText: Flush cached characters:%d\r\n", pxlpdev->dwCharCount));
  1918. if (pxlpdev->dwCharCount == 0)
  1919. return S_OK;
  1920. XLOutput *pOutput = pxlpdev->pOutput;
  1921. PWORD pawChar = pxlpdev->pawChar;
  1922. PPOINTL pptlCharAdvance = pxlpdev->pptlCharAdvance;
  1923. sint16 sint16_advance;
  1924. ubyte ubyte_advance;
  1925. XLGState *pGState = pxlpdev->pOutput;
  1926. if (pxlpdev->dwFlags & XLPDEV_FLAGS_CHARDOWNLOAD_ON)
  1927. {
  1928. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_CHARDOWNLOAD_ON;
  1929. pOutput->Send_cmd(eEndChar);
  1930. }
  1931. //
  1932. // Flush cached char string
  1933. //
  1934. //
  1935. // Reselect font
  1936. //
  1937. if (pxlpdev->dwFlags & XLPDEV_FLAGS_RESET_FONT)
  1938. {
  1939. BYTE aubFontName[PCLXL_FONTNAME_SIZE + 1];
  1940. VERBOSE(("PCLXLFlushCachedText: ResetFont\n"));
  1941. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_RESET_FONT;
  1942. pxlpdev->pXLFont->GetFontName(aubFontName);
  1943. pOutput->SetFont(pxlpdev->pXLFont->GetFontType(),
  1944. aubFontName,
  1945. pxlpdev->pXLFont->GetFontHeight(),
  1946. pxlpdev->pXLFont->GetFontWidth(),
  1947. pxlpdev->pXLFont->GetFontSymbolSet(),
  1948. pxlpdev->pXLFont->GetFontSimulation());
  1949. }
  1950. //
  1951. // Set cursor
  1952. //
  1953. pOutput->SetCursor(pxlpdev->lStartX, pxlpdev->lStartY);
  1954. //
  1955. // Set text angle
  1956. //
  1957. if (pxlpdev->dwTextAngle && kFontTypeTTBitmap != pGState->GetFontType())
  1958. {
  1959. pOutput->Send_uint16((uint16)pxlpdev->dwTextAngle);
  1960. pOutput->Send_attr_ubyte(eCharAngle);
  1961. pOutput->Send_cmd(eSetCharAngle);
  1962. }
  1963. //
  1964. // Characters
  1965. //
  1966. pOutput->Send_uint16_array_header((uint16)pxlpdev->dwCharCount);
  1967. VERBOSE(("String = "));
  1968. for (dwI = 0; dwI < pxlpdev->dwCharCount; dwI ++, pawChar++)
  1969. {
  1970. pOutput->Write((PBYTE)pawChar, sizeof(WORD));
  1971. VERBOSE(("0x%x ", *pawChar));
  1972. }
  1973. VERBOSE(("\r\n"));
  1974. pOutput->Send_attr_ubyte(eTextData);
  1975. //
  1976. // X advance
  1977. //
  1978. VERBOSE(("Advance(0x%x)(x,y) = (%d,%d),", pptlCharAdvance, pptlCharAdvance->x, pptlCharAdvance->y));
  1979. BOOL bXUByte = TRUE;
  1980. BOOL bYUByte = TRUE;
  1981. BOOL bXAdvanceTrue = FALSE;
  1982. BOOL bYAdvanceTrue = FALSE;
  1983. for (dwI = 0; dwI < pxlpdev->dwCharCount; dwI ++, pptlCharAdvance++)
  1984. {
  1985. //
  1986. // If the char advance is ubyte, set bUByte flag to optimize XSpacing
  1987. //
  1988. if (pptlCharAdvance->x & 0xffffff00)
  1989. bXUByte = FALSE;
  1990. if (pptlCharAdvance->y & 0xffffff00)
  1991. bYUByte = FALSE;
  1992. if (pptlCharAdvance->x != 0)
  1993. bXAdvanceTrue = TRUE;
  1994. if (pptlCharAdvance->y != 0)
  1995. bYAdvanceTrue = TRUE;
  1996. }
  1997. //
  1998. // X Advance
  1999. //
  2000. if (bXAdvanceTrue)
  2001. {
  2002. pptlCharAdvance = pxlpdev->pptlCharAdvance;
  2003. VERBOSE(("X = "));
  2004. if (bXUByte == TRUE)
  2005. {
  2006. //
  2007. // ubyte XSpacing
  2008. //
  2009. pOutput->Send_ubyte_array_header((uint16)pxlpdev->dwCharCount);
  2010. for (dwI = 0; dwI < pxlpdev->dwCharCount; dwI ++, pptlCharAdvance++)
  2011. {
  2012. ubyte_advance = (ubyte)pptlCharAdvance->x;
  2013. pOutput->Write((PBYTE)&ubyte_advance, sizeof(ubyte));
  2014. #if DBG
  2015. VERBOSE(("%d ", ubyte_advance));
  2016. if (0 == ubyte_advance)
  2017. {
  2018. VERBOSE(("\nXSpacing is zero!.\n"));
  2019. }
  2020. #endif
  2021. }
  2022. }
  2023. else
  2024. {
  2025. //
  2026. // sint16 XSpacing
  2027. //
  2028. pOutput->Send_sint16_array_header((uint16)pxlpdev->dwCharCount);
  2029. for (dwI = 0; dwI < pxlpdev->dwCharCount; dwI ++, pptlCharAdvance++)
  2030. {
  2031. sint16_advance = (sint16)pptlCharAdvance->x;
  2032. pOutput->Write((PBYTE)&sint16_advance, sizeof(sint16));
  2033. #if DBG
  2034. VERBOSE(("%d ", sint16_advance));
  2035. if (0 == sint16_advance)
  2036. {
  2037. VERBOSE(("\nXSpacing is zero!.\n"));
  2038. }
  2039. #endif
  2040. }
  2041. }
  2042. VERBOSE(("\r\n"));
  2043. pOutput->Send_attr_ubyte(eXSpacingData);
  2044. }
  2045. //
  2046. // Y Advance
  2047. //
  2048. if (bYAdvanceTrue)
  2049. {
  2050. pptlCharAdvance = pxlpdev->pptlCharAdvance;
  2051. VERBOSE(("Y = "));
  2052. if (bYUByte == TRUE)
  2053. {
  2054. //
  2055. // ubyte YSpacing
  2056. //
  2057. pOutput->Send_ubyte_array_header((uint16)pxlpdev->dwCharCount);
  2058. for (dwI = 0; dwI < pxlpdev->dwCharCount; dwI ++, pptlCharAdvance++)
  2059. {
  2060. ubyte_advance = (ubyte)pptlCharAdvance->y;
  2061. pOutput->Write((PBYTE)&ubyte_advance, sizeof(ubyte));
  2062. #if DBG
  2063. VERBOSE(("%d ", ubyte_advance));
  2064. if (0 == ubyte_advance)
  2065. {
  2066. VERBOSE(("\nYSpacing is zero!.\n"));
  2067. }
  2068. #endif
  2069. }
  2070. }
  2071. else
  2072. {
  2073. //
  2074. // sint16 YSpacing
  2075. //
  2076. pOutput->Send_sint16_array_header((uint16)pxlpdev->dwCharCount);
  2077. for (dwI = 0; dwI < pxlpdev->dwCharCount; dwI ++, pptlCharAdvance++)
  2078. {
  2079. sint16_advance = (sint16)pptlCharAdvance->y;
  2080. pOutput->Write((PBYTE)&sint16_advance, sizeof(sint16));
  2081. #if DBG
  2082. VERBOSE(("%d ", sint16_advance));
  2083. if (0 == sint16_advance)
  2084. {
  2085. VERBOSE(("\nYSpacing is zero!.\n"));
  2086. }
  2087. #endif
  2088. }
  2089. }
  2090. VERBOSE(("\r\n"));
  2091. pOutput->Send_attr_ubyte(eYSpacingData);
  2092. }
  2093. pOutput->Send_cmd(eText);
  2094. //
  2095. // Reset text angle
  2096. //
  2097. if (pxlpdev->dwTextAngle && kFontTypeTTBitmap != pGState->GetFontType())
  2098. {
  2099. pOutput->Send_uint16(0);
  2100. pOutput->Send_attr_ubyte(eCharAngle);
  2101. pOutput->Send_cmd(eSetCharAngle);
  2102. pxlpdev->dwTextAngle = 0;
  2103. }
  2104. pOutput->Flush(pdevobj);
  2105. pxlpdev->dwCharCount = 0;
  2106. return S_OK;
  2107. }
  2108. HRESULT
  2109. GetFONTOBJ(
  2110. PDEVOBJ pdevobj,
  2111. PUNIFONTOBJ pUFObj,
  2112. FONTOBJ **ppFontObj)
  2113. /*++
  2114. Routine Description:
  2115. Arguments:
  2116. Return Value:
  2117. Note:
  2118. --*/
  2119. {
  2120. //
  2121. // Error Check
  2122. //
  2123. if (NULL == ppFontObj ||
  2124. pdevobj->dwSize != sizeof(DEVOBJ) )
  2125. {
  2126. ERR(("PCLXL:GetFONTOBJ: invalid parameter[s].\n"));
  2127. return E_UNEXPECTED;
  2128. }
  2129. PXLPDEV pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  2130. DWORD dwGetInfo;
  2131. GETINFO_FONTOBJ GFontObj;
  2132. dwGetInfo =
  2133. GFontObj.dwSize = sizeof(GETINFO_FONTOBJ);
  2134. GFontObj.pFontObj = NULL;
  2135. if (!pUFObj->pfnGetInfo(pUFObj,
  2136. UFO_GETINFO_FONTOBJ,
  2137. &GFontObj,
  2138. dwGetInfo,
  2139. &dwGetInfo))
  2140. {
  2141. ERR(("PCLXL:GetXForm: GetInfo(FONTOBJ) failed\n"));
  2142. return E_UNEXPECTED;
  2143. }
  2144. *ppFontObj = GFontObj.pFontObj;
  2145. return S_OK;
  2146. }
  2147. HRESULT
  2148. GetXForm(
  2149. PDEVOBJ pdevobj,
  2150. PUNIFONTOBJ pUFObj,
  2151. FLOATOBJ_XFORM* pxform)
  2152. /*++
  2153. Routine Description:
  2154. Arguments:
  2155. Return Value:
  2156. Note:
  2157. --*/
  2158. {
  2159. //
  2160. // Error Check
  2161. //
  2162. if (NULL == pxform ||
  2163. NULL == pdevobj ||
  2164. pdevobj->dwSize != sizeof(DEVOBJ) )
  2165. {
  2166. ERR(("PCLXL:GetXForm: invalid parameter[s].\n"));
  2167. return E_UNEXPECTED;
  2168. }
  2169. FONTOBJ *pFontObj;
  2170. if (S_OK != GetFONTOBJ(pdevobj, pUFObj, &pFontObj))
  2171. {
  2172. ERR(("PCLXL:GetXForm: GetFONTOBJ failed.\n"));
  2173. return E_UNEXPECTED;
  2174. }
  2175. XFORMOBJ *pxo = FONTOBJ_pxoGetXform(pFontObj);
  2176. XFORMOBJ_iGetFloatObjXform(pxo, pxform);
  2177. return S_OK;
  2178. }
  2179. HRESULT
  2180. GetXYScale(
  2181. FLOATOBJ_XFORM *pxform,
  2182. FLOATOBJ *pfoXScale,
  2183. FLOATOBJ *pfoYScale)
  2184. /*++
  2185. Routine Description:
  2186. Arguments:
  2187. Return Value:
  2188. Note:
  2189. --*/
  2190. {
  2191. //
  2192. // Error Check
  2193. //
  2194. if (NULL == pxform ||
  2195. NULL == pfoXScale ||
  2196. NULL == pfoYScale )
  2197. {
  2198. ERR(("PCLXL:GetXYScale: invalid parameter[s].\n"));
  2199. return E_UNEXPECTED;
  2200. }
  2201. #if 0
  2202. if( pxform->eM11 )
  2203. {
  2204. //
  2205. // Either 0 or 180 rotation
  2206. //
  2207. if( pxform->eM11 > 0 )
  2208. {
  2209. //
  2210. // Normal case, 0 degree rotation
  2211. //
  2212. *pfoXScale = pxform->eM11;
  2213. *pfoYScale = pxform->eM22;
  2214. }
  2215. else
  2216. {
  2217. //
  2218. // Reverse case, 180 degree rotation
  2219. //
  2220. *pfoXScale = -pxform->eM11;
  2221. *pfoYScale = -pxform->eM22;
  2222. }
  2223. }
  2224. else
  2225. {
  2226. //
  2227. // Must be 90 or 270 degree rotation
  2228. //
  2229. if( pxform->eM12 < 0 )
  2230. {
  2231. //
  2232. // The 90 degree case
  2233. //
  2234. *pfoXScale = pxform->eM21;
  2235. *pfoYScale = -pxform->eM12;
  2236. }
  2237. else
  2238. {
  2239. //
  2240. // The 270 degree case
  2241. //
  2242. *pfoXScale = -pxform->eM21;
  2243. *pfoYScale = pxform->eM12;
  2244. }
  2245. }
  2246. #else
  2247. if (pxform->eM21 == 0 && pxform->eM12 == 0)
  2248. {
  2249. //
  2250. // 0 or 180 degree rotation
  2251. //
  2252. if( pxform->eM11 > 0 )
  2253. {
  2254. //
  2255. // The 0 degree case
  2256. //
  2257. *pfoXScale = pxform->eM11;
  2258. *pfoYScale = pxform->eM22;
  2259. }
  2260. else
  2261. {
  2262. //
  2263. // The 180 degree case
  2264. //
  2265. *pfoXScale = -pxform->eM11;
  2266. *pfoYScale = -pxform->eM22;
  2267. }
  2268. }
  2269. else
  2270. if (pxform->eM11 == 0 && pxform->eM22 == 0)
  2271. {
  2272. //
  2273. // Must be 90 or 270 degree rotation
  2274. //
  2275. if( pxform->eM21 < 0 )
  2276. {
  2277. //
  2278. // The 90 degree case
  2279. //
  2280. *pfoXScale = -pxform->eM21;
  2281. *pfoYScale = pxform->eM12;
  2282. }
  2283. else
  2284. {
  2285. //
  2286. // The 270 degree case
  2287. //
  2288. *pfoXScale = pxform->eM21;
  2289. *pfoYScale = -pxform->eM12;
  2290. }
  2291. }
  2292. else
  2293. {
  2294. #pragma warning( disable: 4244)
  2295. *pfoXScale = sqrt(pxform->eM11 * pxform->eM11 +
  2296. pxform->eM12 * pxform->eM12);
  2297. *pfoYScale = sqrt(pxform->eM22 * pxform->eM22 +
  2298. pxform->eM21 * pxform->eM21);
  2299. #pragma warning( default: 4244)
  2300. }
  2301. #endif
  2302. return S_OK;
  2303. }
  2304. HRESULT
  2305. IsXYSame(
  2306. FLOATOBJ_XFORM *pxform)
  2307. /*++
  2308. Routine Description:
  2309. Arguments:
  2310. Return Value:
  2311. Note:
  2312. --*/
  2313. {
  2314. BOOL bRet;
  2315. FLOATOBJ eM11 = pxform->eM11;
  2316. if (FLOATOBJ_EqualLong(&eM11, 0))
  2317. {
  2318. return S_OK;
  2319. }
  2320. //
  2321. // 0-90 or 180-270 case
  2322. // (eM11 > 0 & eM22 > 0)
  2323. // (eM12 < 0 & eM21 < 0)
  2324. //
  2325. // eM11 = (eM11 - eM22) / eM11;
  2326. //
  2327. FLOATOBJ_Sub(&(eM11), &(pxform->eM22));
  2328. FLOATOBJ_Div(&(eM11), &(pxform->eM11));
  2329. //
  2330. // eM11 < 0.5%
  2331. //
  2332. bRet = FLOATOBJ_LessThanLong(&(eM11), FLOATL_IEEE_0_005F)
  2333. & FLOATOBJ_GreaterThanLong(&(eM11), FLOATL_IEEE_0_005MF);
  2334. if (!bRet)
  2335. {
  2336. //
  2337. // 90-180 or 270-360 case
  2338. // (eM11 < 0, eM22 > 0)
  2339. // (eM11 > 0, eM22 < 0)
  2340. //
  2341. // eM11 = (eM11 + eM22) / eM11;
  2342. //
  2343. eM11 = pxform->eM11;
  2344. FLOATOBJ_Add(&(eM11), &(pxform->eM22));
  2345. FLOATOBJ_Div(&(eM11), &(pxform->eM11));
  2346. //
  2347. // eM11 < 0.5%
  2348. //
  2349. bRet = FLOATOBJ_LessThanLong(&(eM11), FLOATL_IEEE_0_005F)
  2350. & FLOATOBJ_GreaterThanLong(&(eM11), FLOATL_IEEE_0_005MF);
  2351. }
  2352. if (bRet)
  2353. return S_OK;
  2354. else
  2355. return S_FALSE;
  2356. }
  2357. DWORD
  2358. DwDownloadCompositeGlyph(
  2359. PDEVOBJ pdevobj,
  2360. ULONG ulFontID,
  2361. PGLYF pGlyph)
  2362. /*++
  2363. Routine Description:
  2364. Download composite glyph data.
  2365. Arguments:
  2366. pdevobj - a pointer to PDEVOBJ
  2367. ulFontID - font ID for this glyph.
  2368. pGlyph - a pointer to GLYF data structure.
  2369. Return Value:
  2370. Note:
  2371. --*/
  2372. {
  2373. PXLPDEV pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  2374. XLTrueType *pTTFile = pxlpdev->pTTFile;
  2375. PBYTE pubCGlyphData = (PBYTE)pGlyph;
  2376. DWORD dwCGlyphDataSize, dwRet;
  2377. dwRet = 0;
  2378. if (pGlyph->numberOfContours != COMPONENTCTRCOUNT)
  2379. {
  2380. //
  2381. // Error check. Make sure that this is a composite glyph.
  2382. //
  2383. return dwRet;
  2384. }
  2385. //
  2386. // According to TrueType font spec, if numberOfContours == -1,
  2387. // it has composite glyph data.
  2388. //
  2389. // When downloading special glyphs, specify the value 0xFFFF for the
  2390. // CharCode attribute to the ReadChar operator.
  2391. // This "special" CharCode value tells PCL XL 2.0 that
  2392. // it is a "special" glyph.
  2393. //
  2394. // pCGlyf points an array of CGLYF. pCGlyf->flags says that there is
  2395. // at least one more composite glyph available.
  2396. // I need to go through all glyph data.
  2397. //
  2398. PCGLYF pCGlyf = (PCGLYF)(pubCGlyphData + sizeof(GLYF));
  2399. SHORT sFlags;
  2400. BOOL bSpace;
  2401. do
  2402. {
  2403. //
  2404. // Swap bytes in any date in TrueType font, since it's Motorola-style ordering (Big Endian).
  2405. //
  2406. sFlags = SWAPW(pCGlyf->flags);
  2407. //
  2408. // Get glyph data from TrueType font object.
  2409. //
  2410. if (S_OK != pTTFile->GetGlyphData( SWAPW(pCGlyf->glyphIndex),
  2411. &pubCGlyphData,
  2412. &dwCGlyphDataSize))
  2413. {
  2414. ERR(("PCLXL:DownloadCharGlyph GetGlyphData failed.\r\n"));
  2415. return FALSE;
  2416. }
  2417. if (NULL != pubCGlyphData && dwCGlyphDataSize != 0)
  2418. {
  2419. if (((PGLYF)pubCGlyphData)->numberOfContours == COMPONENTCTRCOUNT)
  2420. {
  2421. //
  2422. // A recursive call to DwDownloadCompositeGlyph for this glyph.
  2423. //
  2424. dwRet += DwDownloadCompositeGlyph(pdevobj, ulFontID, (PGLYF)pubCGlyphData);
  2425. }
  2426. bSpace = FALSE;
  2427. }
  2428. else
  2429. {
  2430. bSpace = TRUE;
  2431. }
  2432. //
  2433. // Download the actual glyph data for this glyph with 0xFFFF.
  2434. // Special character (PCL XL 2.0)
  2435. //
  2436. if (!BDownloadGlyphData(pdevobj,
  2437. ulFontID,
  2438. 0xFFFF,
  2439. SWAPW(pCGlyf->glyphIndex),
  2440. pubCGlyphData,
  2441. dwCGlyphDataSize,
  2442. bSpace))
  2443. {
  2444. ERR(("PCLXL:DownloadCharGlyph BDownloadGlyphData failed.\r\n"));
  2445. return dwRet;
  2446. }
  2447. dwRet += dwCGlyphDataSize;
  2448. //
  2449. // If ARG_1_AND_2_ARE_WORDS is set, the arguments are words.
  2450. // Otherwise, they are bytes.
  2451. //
  2452. PBYTE pByte = (PBYTE)pCGlyf;
  2453. if (sFlags & ARG_1_AND_2_ARE_WORDS)
  2454. {
  2455. pByte += sizeof(CGLYF);
  2456. }
  2457. else
  2458. {
  2459. pByte += sizeof(CGLYF_BYTE);
  2460. }
  2461. pCGlyf = (PCGLYF)pByte;
  2462. } while (sFlags & MORE_COMPONENTS);
  2463. return dwRet;
  2464. }
  2465. inline BOOL
  2466. BSaveFont(
  2467. PDEVOBJ pdevobj)
  2468. {
  2469. PXLPDEV pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  2470. pxlpdev->dwFlags |= XLPDEV_FLAGS_RESET_FONT;
  2471. if (NULL == pxlpdev->pXLFont)
  2472. {
  2473. pxlpdev->pXLFont = new XLFont;
  2474. if (NULL == pxlpdev->pXLFont)
  2475. {
  2476. return FALSE;
  2477. }
  2478. }
  2479. XLGState *pGState = pxlpdev->pOutput;
  2480. BYTE aubFontName[PCLXL_FONTNAME_SIZE + 1];
  2481. pGState->GetFontName(aubFontName);
  2482. pxlpdev->pXLFont->SetFont(pGState->GetFontType(),
  2483. aubFontName,
  2484. pGState->GetFontHeight(),
  2485. pGState->GetFontWidth(),
  2486. pGState->GetFontSymbolSet(),
  2487. pGState->GetFontSimulation());
  2488. pGState->ResetFont();
  2489. return TRUE;
  2490. }