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.

3911 lines
108 KiB

  1. /******************Module*Header********************************************\
  2. * Module Name: dcquery.c *
  3. * *
  4. * Client side stubs for functions that query the DC in the server. *
  5. * *
  6. * Created: 05-Jun-1991 01:43:56 *
  7. * Author: Charles Whitmer [chuckwh] *
  8. * *
  9. * Copyright (c) 1991-1999 Microsoft Corporation *
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #if DBG
  14. FLONG gflDebug = 0;
  15. #endif
  16. // This macro retrieves the current code page, carefully masking off the
  17. // charset:
  18. #define GET_CODE_PAGE(hdc,pDcAttr) \
  19. ((!(pDcAttr->ulDirty_ & DIRTY_CHARSET) ? pDcAttr->iCS_CP \
  20. : NtGdiGetCharSet(hdc)) & 0xffff)
  21. BOOL bIsDBCSString(LPCSTR psz, int cc);
  22. /******************************Public*Routine******************************\
  23. * vOutlineTextMetricWToOutlineTextMetricA
  24. *
  25. * Convert from OUTLINETEXTMETRICA (ANSI structure) to OUTLINETEXTMETRICW
  26. * (UNICODE structure).
  27. *
  28. * Note:
  29. * This function is capable of converting in place (in and out buffers
  30. * can be the same).
  31. *
  32. * Returns:
  33. * TTRUE if successful, FALSE otherwise.
  34. *
  35. * History:
  36. * 02-Mar-1992 -by- Gilman Wong [gilmanw]
  37. * Wrote it.
  38. \**************************************************************************/
  39. VOID vOutlineTextMetricWToOutlineTextMetricA (
  40. LPOUTLINETEXTMETRICA potma,
  41. OUTLINETEXTMETRICW * potmw,
  42. TMDIFF * ptmd
  43. )
  44. {
  45. // Size.
  46. potma->otmSize = potmw->otmSize;
  47. // Convert the textmetrics.
  48. vTextMetricWToTextMetricStrict(
  49. &potma->otmTextMetrics,
  50. &potmw->otmTextMetrics);
  51. potma->otmTextMetrics.tmFirstChar = ptmd->chFirst;
  52. potma->otmTextMetrics.tmLastChar = ptmd->chLast;
  53. potma->otmTextMetrics.tmDefaultChar = ptmd->chDefault;
  54. potma->otmTextMetrics.tmBreakChar = ptmd->chBreak;
  55. // for Win 64 we need to copy these fields one by one due to alignement difference
  56. potma->otmFiller = potmw->otmFiller;
  57. potma->otmPanoseNumber = potmw->otmPanoseNumber;
  58. potma->otmfsSelection = potmw->otmfsSelection;
  59. potma->otmfsType = potmw->otmfsType;
  60. potma->otmsCharSlopeRise = potmw->otmsCharSlopeRise;
  61. potma->otmsCharSlopeRun = potmw->otmsCharSlopeRun;
  62. potma->otmItalicAngle = potmw->otmItalicAngle;
  63. potma->otmEMSquare = potmw->otmEMSquare;
  64. potma->otmAscent = potmw->otmAscent;
  65. potma->otmDescent = potmw->otmDescent;
  66. potma->otmLineGap = potmw->otmLineGap;
  67. potma->otmsCapEmHeight = potmw->otmsCapEmHeight;
  68. potma->otmsXHeight = potmw->otmsXHeight;
  69. potma->otmrcFontBox = potmw->otmrcFontBox;
  70. potma->otmMacAscent = potmw->otmMacAscent;
  71. potma->otmMacDescent = potmw->otmMacDescent;
  72. potma->otmMacLineGap = potmw->otmMacLineGap;
  73. potma->otmusMinimumPPEM = potmw->otmusMinimumPPEM;
  74. potma->otmptSubscriptSize = potmw->otmptSubscriptSize;
  75. potma->otmptSubscriptOffset = potmw->otmptSubscriptOffset;
  76. potma->otmptSuperscriptSize = potmw->otmptSuperscriptSize;
  77. potma->otmptSuperscriptOffset = potmw->otmptSuperscriptOffset;
  78. potma->otmsStrikeoutSize = potmw->otmsStrikeoutSize;
  79. potma->otmsStrikeoutPosition = potmw->otmsStrikeoutPosition;
  80. potma->otmsUnderscoreSize = potmw->otmsUnderscoreSize;
  81. potma->otmsUnderscorePosition = potmw->otmsUnderscorePosition;
  82. // set the offsets to zero for now, this will be changed later if
  83. // the caller wanted strings as well
  84. potma->otmpFamilyName = NULL;
  85. potma->otmpFaceName = NULL;
  86. potma->otmpStyleName = NULL;
  87. potma->otmpFullName = NULL;
  88. }
  89. /******************************Public*Routine******************************\
  90. *
  91. * vGenerateANSIString
  92. *
  93. * Effects: Generates Ansi string which consists of consecutive ansi chars
  94. * [iFirst, iLast] inclusive. The string is stored in the buffer
  95. * puchBuf that the user must ensure is big enough
  96. *
  97. *
  98. *
  99. * History:
  100. * 24-Feb-1992 -by- Bodin Dresevic [BodinD]
  101. * Wrote it.
  102. \**************************************************************************/
  103. VOID vGenerateAnsiString(UINT iFirst, UINT iLast, PUCHAR puchBuf)
  104. {
  105. // Generate string (terminating NULL not needed).
  106. ASSERTGDI((iFirst <= iLast) && (iLast < 256), "gdi!_vGenerateAnsiString\n");
  107. for ( ; iFirst <= iLast; iFirst++)
  108. *puchBuf++ = (UCHAR) iFirst;
  109. }
  110. /******************************Public*Routine******************************\
  111. *
  112. * bSetUpUnicodeString
  113. *
  114. * Effects:
  115. *
  116. * Warnings:
  117. *
  118. * History:
  119. * 25-Feb-1992 -by- Bodin Dresevic [BodinD]
  120. * Wrote it.
  121. \**************************************************************************/
  122. BOOL bSetUpUnicodeString(
  123. IN UINT iFirst, // first ansi char
  124. IN UINT iLast, // last char
  125. IN PUCHAR puchTmp, // buffer for an intermediate ansi string
  126. OUT PWCHAR pwc, // output fuffer with a unicode string
  127. IN UINT dwCP // ansi codepage
  128. )
  129. {
  130. UINT c = iLast - iFirst + 1;
  131. vGenerateAnsiString(iFirst,iLast,puchTmp);
  132. return MultiByteToWideChar(
  133. dwCP, 0,
  134. puchTmp,c,
  135. pwc, c*sizeof(WCHAR));
  136. }
  137. /******************************Public*Routine******************************\
  138. * GetAspectRatioFilterEx *
  139. * GetBrushOrgEx *
  140. * *
  141. * Client side stubs which all get mapped to GetPoint. *
  142. * *
  143. * Fri 07-Jun-1991 18:01:50 -by- Charles Whitmer [chuckwh] *
  144. * Wrote them. *
  145. \**************************************************************************/
  146. BOOL APIENTRY GetAspectRatioFilterEx(HDC hdc,LPSIZE psizl)
  147. {
  148. FIXUP_HANDLE(hdc);
  149. return(NtGdiGetDCPoint(hdc,DCPT_ASPECTRATIOFILTER,(PPOINTL) psizl));
  150. }
  151. BOOL APIENTRY GetBrushOrgEx(HDC hdc,LPPOINT pptl)
  152. {
  153. BOOL bRet = FALSE;
  154. PDC_ATTR pdcattr;
  155. FIXUP_HANDLE(hdc);
  156. PSHARED_GET_VALIDATE(pdcattr,hdc,DC_TYPE);
  157. if ((pdcattr != NULL) && (pptl != (LPPOINT)NULL))
  158. {
  159. *pptl = *((LPPOINT)&pdcattr->ptlBrushOrigin);
  160. bRet = TRUE;
  161. }
  162. else
  163. {
  164. GdiSetLastError(ERROR_INVALID_PARAMETER);
  165. }
  166. return(bRet);
  167. }
  168. BOOL APIENTRY GetDCOrgEx(HDC hdc,LPPOINT pptl)
  169. {
  170. FIXUP_HANDLE(hdc);
  171. return(NtGdiGetDCPoint(hdc,DCPT_DCORG,(PPOINTL)pptl));
  172. }
  173. // The old GetDCOrg is here because it was in the Beta and we are afraid
  174. // to remove it now. It would be nice to remove it.
  175. DWORD APIENTRY GetDCOrg(HDC hdc)
  176. {
  177. hdc;
  178. return(0);
  179. }
  180. /******************************Public*Routine******************************\
  181. * Client side stub for GetCurrentPositionEx.
  182. *
  183. * Wed 02-Sep-1992 -by- J. Andrew Goossen [andrewgo]
  184. * Wrote it.
  185. \**************************************************************************/
  186. BOOL APIENTRY GetCurrentPositionEx(HDC hdc,LPPOINT pptl)
  187. {
  188. BOOL bRet = FALSE;
  189. PDC_ATTR pDcAttr;
  190. FIXUP_HANDLE(hdc);
  191. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  192. if ((pDcAttr) && (pptl != (LPPOINT)NULL))
  193. {
  194. bRet = TRUE;
  195. if (pDcAttr->ulDirty_ & DIRTY_PTLCURRENT)
  196. {
  197. // If the logical-space version of the current position is invalid,
  198. // then the device-space version of the current position is
  199. // guaranteed to be valid. So we can reverse the current transform
  200. // on that to compute the logical-space version:
  201. *((POINTL*)pptl) = pDcAttr->ptfxCurrent;
  202. pptl->x = FXTOL(pptl->x);
  203. pptl->y = FXTOL(pptl->y);
  204. bRet = DPtoLP(hdc,pptl,1);
  205. if (bRet)
  206. {
  207. pDcAttr->ptlCurrent = *((POINTL*)pptl);
  208. pDcAttr->ulDirty_ &= ~DIRTY_PTLCURRENT;
  209. }
  210. }
  211. else
  212. {
  213. *((POINTL*)pptl) = pDcAttr->ptlCurrent;
  214. }
  215. }
  216. else
  217. {
  218. GdiSetLastError(ERROR_INVALID_PARAMETER);
  219. }
  220. return(bRet);
  221. }
  222. /******************************Public*Routine******************************\
  223. * GetPixel *
  224. * *
  225. * Client side stub. *
  226. * *
  227. * Fri 07-Jun-1991 18:01:50 -by- Charles Whitmer [chuckwh] *
  228. * Wrote it. *
  229. \**************************************************************************/
  230. DWORD APIENTRY GetPixel(HDC hdc,int x,int y)
  231. {
  232. PDC_ATTR pdca;
  233. COLORREF ColorRet = CLR_INVALID;
  234. FIXUP_HANDLE(hdc);
  235. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  236. if (pdca)
  237. {
  238. //
  239. // if the color is not a PaletteIndex and
  240. // ICM is on then translate
  241. //
  242. ColorRet = NtGdiGetPixel(hdc,x,y);
  243. if ( bNeedTranslateColor(pdca)
  244. &&
  245. ( IS_32BITS_COLOR(pdca->lIcmMode)
  246. ||
  247. ((ColorRet != CLR_INVALID) &&
  248. !(ColorRet & 0x01000000))
  249. )
  250. )
  251. {
  252. //
  253. // translate back color to original.
  254. //
  255. COLORREF NewColor;
  256. BOOL bStatus = IcmTranslateCOLORREF(hdc,
  257. pdca,
  258. ColorRet,
  259. &NewColor,
  260. ICM_BACKWARD);
  261. if (bStatus)
  262. {
  263. ColorRet = NewColor;
  264. }
  265. }
  266. }
  267. return(ColorRet);
  268. }
  269. /******************************Public*Routine******************************\
  270. * GetDeviceCaps
  271. *
  272. * We store the device caps for primary display dc and its compatible memory dcs
  273. * in the shared handle table.
  274. *
  275. * for printer dcs and meta dcs, we cache the dev info in the LDC structure.
  276. *
  277. * Fri 07-Jun-1991 18:01:50 -by- Charles Whitmer [chuckwh]
  278. * Wrote it.
  279. \**************************************************************************/
  280. int APIENTRY GetDeviceCaps(HDC hdc,int iCap)
  281. {
  282. BOOL bRet = FALSE;
  283. PDEVCAPS pCachedDevCaps = NULL;
  284. FIXUP_HANDLE(hdc);
  285. if (IS_ALTDC_TYPE(hdc))
  286. {
  287. PLDC pldc;
  288. // For the 16-bit metafile DC, returns only technology. return 0 for win3.1 compat.
  289. if (IS_METADC16_TYPE(hdc))
  290. return(iCap == TECHNOLOGY ? DT_METAFILE : 0);
  291. DC_PLDC(hdc,pldc,bRet);
  292. if (!(pldc->fl & LDC_CACHED_DEVCAPS))
  293. {
  294. bRet = NtGdiGetDeviceCapsAll (hdc, &pldc->DevCaps);
  295. if (bRet)
  296. {
  297. pCachedDevCaps = &pldc->DevCaps;
  298. pldc->fl |= LDC_CACHED_DEVCAPS;
  299. }
  300. }
  301. else
  302. {
  303. pCachedDevCaps = &pldc->DevCaps;
  304. bRet = TRUE;
  305. }
  306. }
  307. else
  308. {
  309. PDC_ATTR pDcAttr;
  310. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  311. if (pDcAttr)
  312. {
  313. ULONG fl = pDcAttr->ulDirty_;
  314. if (!(fl & DC_PRIMARY_DISPLAY))
  315. {
  316. return(NtGdiGetDeviceCaps(hdc,iCap));
  317. }
  318. else
  319. {
  320. pCachedDevCaps = pGdiDevCaps;
  321. bRet = TRUE;
  322. }
  323. }
  324. }
  325. if (!bRet)
  326. {
  327. GdiSetLastError(ERROR_INVALID_PARAMETER);
  328. return (0);
  329. }
  330. // actual code - copied from gre\miscgdi.cxx
  331. switch (iCap)
  332. {
  333. case DRIVERVERSION: // Version = 0100h for now
  334. return(pCachedDevCaps->ulVersion);
  335. case TECHNOLOGY: // Device classification
  336. return(pCachedDevCaps->ulTechnology);
  337. case HORZSIZE: // Horizontal size in millimeters
  338. return(pCachedDevCaps->ulHorzSizeM);
  339. case VERTSIZE: // Vertical size in millimeters
  340. return(pCachedDevCaps->ulVertSizeM);
  341. case HORZRES: // Horizontal width in pixels
  342. return(pCachedDevCaps->ulHorzRes);
  343. case VERTRES: // Vertical height in pixels
  344. return(pCachedDevCaps->ulVertRes);
  345. case BITSPIXEL: // Number of bits per pixel
  346. return(pCachedDevCaps->ulBitsPixel);
  347. case PLANES: // Number of planes
  348. return(pCachedDevCaps->ulPlanes);
  349. case NUMBRUSHES: // Number of brushes the device has
  350. return(-1);
  351. case NUMPENS: // Number of pens the device has
  352. return(pCachedDevCaps->ulNumPens);
  353. case NUMMARKERS: // Number of markers the device has
  354. return(0);
  355. case NUMFONTS: // Number of fonts the device has
  356. return(pCachedDevCaps->ulNumFonts);
  357. case NUMCOLORS: // Number of colors in color table
  358. return(pCachedDevCaps->ulNumColors);
  359. case PDEVICESIZE: // Size required for the device descriptor
  360. return(0);
  361. case CURVECAPS: // Curves capabilities
  362. return(CC_CIRCLES |
  363. CC_PIE |
  364. CC_CHORD |
  365. CC_ELLIPSES |
  366. CC_WIDE |
  367. CC_STYLED |
  368. CC_WIDESTYLED |
  369. CC_INTERIORS |
  370. CC_ROUNDRECT);
  371. case LINECAPS: // Line capabilities
  372. return(LC_POLYLINE |
  373. LC_MARKER |
  374. LC_POLYMARKER |
  375. LC_WIDE |
  376. LC_STYLED |
  377. LC_WIDESTYLED |
  378. LC_INTERIORS);
  379. case POLYGONALCAPS: // Polygonal capabilities
  380. return(PC_POLYGON |
  381. PC_RECTANGLE |
  382. PC_WINDPOLYGON |
  383. PC_TRAPEZOID |
  384. PC_SCANLINE |
  385. PC_WIDE |
  386. PC_STYLED |
  387. PC_WIDESTYLED |
  388. PC_INTERIORS);
  389. case TEXTCAPS: // Text capabilities
  390. return(pCachedDevCaps->ulTextCaps);
  391. case CLIPCAPS: // Clipping capabilities
  392. return(CP_RECTANGLE);
  393. case RASTERCAPS: // Bitblt capabilities
  394. return(pCachedDevCaps->ulRasterCaps);
  395. case SHADEBLENDCAPS: // shade and blend capabilities
  396. return(pCachedDevCaps->ulShadeBlendCaps);
  397. case ASPECTX: // Length of X leg
  398. return(pCachedDevCaps->ulAspectX);
  399. case ASPECTY: // Length of Y leg
  400. return(pCachedDevCaps->ulAspectY);
  401. case ASPECTXY: // Length of hypotenuse
  402. return(pCachedDevCaps->ulAspectXY);
  403. case LOGPIXELSX: // Logical pixels/inch in X
  404. return(pCachedDevCaps->ulLogPixelsX);
  405. case LOGPIXELSY: // Logical pixels/inch in Y
  406. return(pCachedDevCaps->ulLogPixelsY);
  407. case SIZEPALETTE: // # entries in physical palette
  408. return(pCachedDevCaps->ulSizePalette);
  409. case NUMRESERVED: // # reserved entries in palette
  410. return(20);
  411. case COLORRES:
  412. return(pCachedDevCaps->ulColorRes);
  413. case PHYSICALWIDTH: // Physical Width in device units
  414. return(pCachedDevCaps->ulPhysicalWidth);
  415. case PHYSICALHEIGHT: // Physical Height in device units
  416. return(pCachedDevCaps->ulPhysicalHeight);
  417. case PHYSICALOFFSETX: // Physical Printable Area x margin
  418. return(pCachedDevCaps->ulPhysicalOffsetX);
  419. case PHYSICALOFFSETY: // Physical Printable Area y margin
  420. return(pCachedDevCaps->ulPhysicalOffsetY);
  421. case VREFRESH: // Vertical refresh rate of the device
  422. return(pCachedDevCaps->ulVRefresh);
  423. case DESKTOPHORZRES: // Width of entire virtual desktop
  424. return(pCachedDevCaps->ulDesktopHorzRes);
  425. case DESKTOPVERTRES: // Height of entire virtual desktop
  426. return(pCachedDevCaps->ulDesktopVertRes);
  427. case BLTALIGNMENT: // Preferred blt alignment
  428. return(pCachedDevCaps->ulBltAlignment);
  429. case COLORMGMTCAPS: // Color Management capabilities
  430. return(pCachedDevCaps->ulColorManagementCaps);
  431. default:
  432. return(0);
  433. }
  434. }
  435. /******************************Public*Routine******************************\
  436. * GetDeviceCapsP
  437. *
  438. * Private version to get HORSIZE and VERTSIZE in micrometers
  439. * Copied from GetDeviceCaps
  440. *
  441. * \**************************************************************************/
  442. int GetDeviceCapsP(HDC hdc,int iCap)
  443. {
  444. BOOL bRet = FALSE;
  445. PDEVCAPS pCachedDevCaps = NULL;
  446. FIXUP_HANDLE(hdc);
  447. if (IS_ALTDC_TYPE(hdc))
  448. {
  449. PLDC pldc;
  450. DC_PLDC(hdc,pldc,bRet);
  451. if (!(pldc->fl & LDC_CACHED_DEVCAPS))
  452. {
  453. bRet = NtGdiGetDeviceCapsAll (hdc, &pldc->DevCaps);
  454. if (bRet)
  455. {
  456. pCachedDevCaps = &pldc->DevCaps;
  457. pldc->fl |= LDC_CACHED_DEVCAPS;
  458. }
  459. }
  460. else
  461. {
  462. pCachedDevCaps = &pldc->DevCaps;
  463. bRet = TRUE;
  464. }
  465. }
  466. else
  467. {
  468. PDC_ATTR pDcAttr;
  469. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  470. if (pDcAttr)
  471. {
  472. ULONG fl = pDcAttr->ulDirty_;
  473. if (!(fl & DC_PRIMARY_DISPLAY))
  474. {
  475. return(NtGdiGetDeviceCaps(hdc,iCap));
  476. }
  477. else
  478. {
  479. pCachedDevCaps = pGdiDevCaps;
  480. bRet = TRUE;
  481. }
  482. }
  483. }
  484. if (!bRet)
  485. {
  486. GdiSetLastError(ERROR_INVALID_PARAMETER);
  487. return (0);
  488. }
  489. // actual code - copied from gre\miscgdi.cxx
  490. switch (iCap)
  491. {
  492. case HORZSIZEP: // Horizontal size
  493. return(pCachedDevCaps->ulHorzSize);
  494. case VERTSIZEP: // Vertical size
  495. return(pCachedDevCaps->ulVertSize);
  496. default:
  497. return(0);
  498. }
  499. }
  500. /******************************Public*Routine******************************\
  501. * GetNearestColor *
  502. * *
  503. * Client side stub. *
  504. * *
  505. * Fri 07-Jun-1991 18:01:50 -by- Charles Whitmer [chuckwh] *
  506. * Wrote it. *
  507. \**************************************************************************/
  508. COLORREF APIENTRY GetNearestColor(HDC hdc,COLORREF color)
  509. {
  510. FIXUP_HANDLE(hdc);
  511. return(NtGdiGetNearestColor(hdc,color));
  512. }
  513. /******************************Public*Routine******************************\
  514. * GetArcDirection
  515. *
  516. * Client side stub.
  517. *
  518. * Fri 09-Apr-1992 -by- J. Andrew Goossen [andrewgo]
  519. * Wrote it.
  520. \**************************************************************************/
  521. int APIENTRY GetArcDirection(HDC hdc)
  522. {
  523. FIXUP_HANDLE(hdc);
  524. return(GetDCDWord(hdc,DDW_ARCDIRECTION,0));
  525. }
  526. /******************************Public*Routine******************************\
  527. * GetMiterLimit
  528. *
  529. * Client side stub.
  530. *
  531. * Fri 09-Apr-1992 -by- J. Andrew Goossen [andrewgo]
  532. * Wrote it.
  533. \**************************************************************************/
  534. int APIENTRY GetMiterLimit(HDC hdc, PFLOAT peMiterLimit)
  535. {
  536. FIXUP_HANDLE(hdc);
  537. return(NtGdiGetMiterLimit(hdc,FLOATPTRARG(peMiterLimit)));
  538. }
  539. /******************************Public*Routine******************************\
  540. * GetSystemPaletteUse *
  541. * *
  542. * Client side stub. *
  543. * *
  544. * Fri 07-Jun-1991 18:01:50 -by- Charles Whitmer [chuckwh] *
  545. * Wrote it. *
  546. \**************************************************************************/
  547. UINT APIENTRY GetSystemPaletteUse(HDC hdc)
  548. {
  549. FIXUP_HANDLE(hdc);
  550. return(NtGdiGetSystemPaletteUse(hdc));
  551. }
  552. /******************************Public*Routine******************************\
  553. * GetClipBox *
  554. * *
  555. * Client side stub. *
  556. * *
  557. * Fri 07-Jun-1991 18:01:50 -by- Charles Whitmer [chuckwh] *
  558. * Wrote it. *
  559. \**************************************************************************/
  560. int APIENTRY GetClipBox(HDC hdc,LPRECT prcl)
  561. {
  562. FIXUP_HANDLE(hdc);
  563. return(NtGdiGetAppClipBox(hdc,prcl));
  564. }
  565. /******************************Public*Routine******************************\
  566. *
  567. * BOOL APIENTRY GetTextMetrics(HDC hdc,LPTEXTMETRIC ptm)
  568. *
  569. * calls to the unicode version
  570. *
  571. * History:
  572. * 21-Aug-1991 -by- Bodin Dresevic [BodinD]
  573. * Wrote it.
  574. \**************************************************************************/
  575. BOOL APIENTRY GetTextMetricsA(HDC hdc,LPTEXTMETRICA ptm)
  576. {
  577. PDC_ATTR pDcAttr;
  578. BOOL bRet = FALSE;
  579. FIXUP_HANDLE(hdc);
  580. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  581. if (pDcAttr)
  582. {
  583. CFONT * pcf;
  584. TMW_INTERNAL tmw;
  585. ASSERTGDI(pDcAttr->hlfntNew,"GetTextMetricsW - hf is NULL\n");
  586. ENTERCRITICALSECTION(&semLocal);
  587. pcf = pcfLocateCFONT(hdc,pDcAttr,0,(PVOID)NULL,0, TRUE);
  588. bRet = bGetTextMetricsWInternal(hdc,&tmw,sizeof(tmw),pcf);
  589. // pcfLocateCFONT added a reference so now we need to remove it
  590. if (pcf)
  591. {
  592. DEC_CFONT_REF(pcf);
  593. }
  594. LEAVECRITICALSECTION(&semLocal);
  595. if (bRet)
  596. {
  597. vTextMetricWToTextMetric(ptm, &tmw);
  598. }
  599. }
  600. return(bRet);
  601. }
  602. /******************************Public*Routine******************************\
  603. *
  604. * BOOL APIENTRY GetTextMetricsW(HDC hdc,LPTEXTMETRICW ptmw)
  605. *
  606. * History:
  607. * 21-Aug-1991 -by- Bodin Dresevic [BodinD]
  608. * Wrote it.
  609. \**************************************************************************/
  610. BOOL APIENTRY GetTextMetricsW(HDC hdc,LPTEXTMETRICW ptmw)
  611. {
  612. PDC_ATTR pDcAttr;
  613. BOOL bRet = FALSE;
  614. FIXUP_HANDLE(hdc);
  615. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  616. if (pDcAttr)
  617. {
  618. CFONT * pcf;
  619. ASSERTGDI(pDcAttr->hlfntNew,"GetTextMetricsW - hf is NULL\n");
  620. ENTERCRITICALSECTION(&semLocal);
  621. pcf = pcfLocateCFONT(hdc,pDcAttr,0,(PVOID) NULL,0, TRUE);
  622. bRet = bGetTextMetricsWInternal(hdc,(TMW_INTERNAL *)ptmw,sizeof(TEXTMETRICW),pcf);
  623. // pcfLocateCFONT added a reference so now we need to remove it
  624. if (pcf)
  625. {
  626. DEC_CFONT_REF(pcf);
  627. }
  628. LEAVECRITICALSECTION(&semLocal);
  629. }
  630. return(bRet);
  631. }
  632. /******************************Public*Routine******************************\
  633. *
  634. * BOOL APIENTRY GetTextMetricsW(HDC hdc,LPTEXTMETRICW ptmw)
  635. *
  636. * History:
  637. * 21-Aug-1991 -by- Bodin Dresevic [BodinD]
  638. * Wrote it.
  639. \**************************************************************************/
  640. BOOL bGetTextMetricsWInternal(
  641. HDC hdc,
  642. TMW_INTERNAL *ptmw,
  643. int cjTM,
  644. CFONT *pcf
  645. )
  646. {
  647. BOOL bRet = FALSE;
  648. if (ptmw)
  649. {
  650. // if no pcf or we havn't cached the metrics
  651. if ((pcf == NULL) || !(pcf->fl & CFONT_CACHED_METRICS))
  652. {
  653. TMW_INTERNAL tmw;
  654. PDC_ATTR pDcAttr;
  655. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  656. bRet = NtGdiGetTextMetricsW(hdc,&tmw,sizeof(tmw));
  657. if (bRet)
  658. {
  659. memcpy(ptmw,&tmw,cjTM);
  660. if (pcf)
  661. {
  662. // we succeeded and we have a pcf so cache the data
  663. pcf->tmw = tmw;
  664. pcf->fl |= CFONT_CACHED_METRICS;
  665. }
  666. }
  667. }
  668. else
  669. {
  670. memcpy(ptmw,&pcf->tmw,cjTM);
  671. bRet = TRUE;
  672. }
  673. }
  674. return(bRet);
  675. }
  676. /******************************Public*Routine******************************\
  677. * GetTextExtentPoint32A (hdc,psz,c,psizl) *
  678. * GetTextExtentPointA (hdc,psz,c,psizl) *
  679. * *
  680. * Computes the text extent. The new 32 bit version returns the "correct" *
  681. * extent without an extra per for bitmap simulations. The other is *
  682. * Windows 3.1 compatible. Both just set a flag and pass the call to *
  683. * bGetTextExtentA. *
  684. * *
  685. * History: *
  686. * Thu 14-Jan-1993 04:11:26 -by- Charles Whitmer [chuckwh] *
  687. * Added code to compute it on the client side. *
  688. * *
  689. * 07-Aug-1991 -by- Bodin Dresevic [BodinD] *
  690. * Wrote it. *
  691. \**************************************************************************/
  692. // not in kernel, it is ok to do this much on the stack:
  693. #define CAPTURE_STRING_SIZE 130
  694. BOOL GetTextExtentPointAInternal(HDC hdc,LPCSTR psz,int c,LPSIZE psizl, FLONG fl)
  695. {
  696. CFONT *pcf;
  697. INT bRet;
  698. PWSZ pwszCapt;
  699. PDC_ATTR pDcAttr;
  700. DWORD dwCP;
  701. WCHAR awcCaptureBuffer[CAPTURE_STRING_SIZE];
  702. FIXUP_HANDLE(hdc);
  703. if (c <= 0)
  704. {
  705. // empty string, just return 0 for the extent
  706. if (c == 0)
  707. {
  708. psizl->cx = 0;
  709. psizl->cy = 0;
  710. bRet = TRUE;
  711. }
  712. else
  713. {
  714. GdiSetLastError(ERROR_INVALID_PARAMETER);
  715. bRet = FALSE;
  716. }
  717. return(bRet);
  718. }
  719. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  720. if (!pDcAttr)
  721. {
  722. GdiSetLastError(ERROR_INVALID_PARAMETER);
  723. bRet = FALSE;
  724. return(bRet);
  725. }
  726. dwCP = GET_CODE_PAGE(hdc, pDcAttr);
  727. if(guintDBCScp == dwCP)
  728. {
  729. QueryFontAssocStatus();
  730. if(fFontAssocStatus &&
  731. ((c == 1) || ((c == 2 && *(psz) && *((LPCSTR)(psz + 1)) == '\0'))))
  732. {
  733. //
  734. // If this function is called with only 1 char, and font association
  735. // is enabled, we should forcely convert the chars to Unicode with
  736. // codepage 1252.
  737. // This is for enabling to output Latin-1 chars ( > 0x80 in Ansi codepage )
  738. // Because, normally font association is enabled, we have no way to output
  739. // those charactres, then we provide the way, if user call TextOutA() with
  740. // A character and ansi font, we tempotary disable font association.
  741. // This might be Windows 3.1 (Korean/Taiwanese) version compatibility..
  742. //
  743. dwCP = 1252;
  744. }
  745. }
  746. if((dwCP == CP_ACP) ||
  747. (dwCP == guintAcp) ||
  748. (dwCP == guintDBCScp)
  749. )
  750. {
  751. #ifdef LANGPACK
  752. if (!gbLpk || (*fpLpkUseGDIWidthCache)(hdc, psz, c, pDcAttr->lTextAlign , FALSE))
  753. {
  754. #endif
  755. ENTERCRITICALSECTION(&semLocal);
  756. pcf = pcfLocateCFONT(hdc,pDcAttr,0,(PVOID)psz,c,TRUE);
  757. if (pcf != NULL)
  758. {
  759. BOOL bExit = TRUE;
  760. if(dwCP == guintDBCScp)
  761. {
  762. if (pcf->wd.sDBCSInc) // dbcs fixed pitch base font
  763. {
  764. bRet = bComputeTextExtentDBCS(pDcAttr,pcf,psz,c,fl,psizl);
  765. }
  766. else if (!bIsDBCSString(psz,c))
  767. {
  768. // linked case, base font is a latin font, but linked font
  769. // perhaps is a FE font. We know that base font is a latin font
  770. // because for FE proportional fonts we would never create pcf.
  771. // We are looking for this special case when the application asked
  772. // for Latin Face Name in the logfont, and a FE charset, but the string
  773. // passed in lackily does not contain DBCS glyphs.
  774. bRet = bComputeTextExtent(pDcAttr,pcf,(PVOID) psz,c,fl,psizl,TRUE);
  775. }
  776. else
  777. {
  778. bExit = FALSE;
  779. }
  780. }
  781. else
  782. {
  783. bRet = bComputeTextExtent(pDcAttr,pcf,(PVOID) psz,c,fl,psizl,TRUE);
  784. }
  785. DEC_CFONT_REF(pcf);
  786. if(bExit)
  787. {
  788. LEAVECRITICALSECTION(&semLocal);
  789. return(bRet);
  790. }
  791. }
  792. LEAVECRITICALSECTION(&semLocal);
  793. #ifdef LANGPACK
  794. }
  795. #endif
  796. }
  797. // Allocate the string buffer
  798. if (c <= CAPTURE_STRING_SIZE)
  799. {
  800. pwszCapt = awcCaptureBuffer;
  801. }
  802. else
  803. {
  804. pwszCapt = LOCALALLOC(c * sizeof(WCHAR));
  805. }
  806. if (pwszCapt)
  807. {
  808. c = MultiByteToWideChar(dwCP, 0, psz,c, pwszCapt, c*sizeof(WCHAR));
  809. if (c)
  810. {
  811. #ifdef LANGPACK
  812. if(gbLpk)
  813. {
  814. bRet = (*fpLpkGetTextExtentExPoint)(hdc, pwszCapt, c, -1, NULL, NULL,
  815. psizl, fl, 0);
  816. }
  817. else
  818. #endif
  819. bRet = NtGdiGetTextExtent(hdc,
  820. (LPWSTR)pwszCapt,
  821. c,
  822. psizl,
  823. fl);
  824. }
  825. else
  826. {
  827. GdiSetLastError(ERROR_INVALID_PARAMETER);
  828. bRet = FALSE;
  829. }
  830. if (pwszCapt != awcCaptureBuffer)
  831. LOCALFREE(pwszCapt);
  832. }
  833. else
  834. {
  835. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  836. bRet = FALSE;
  837. }
  838. return(bRet);
  839. }
  840. BOOL APIENTRY GetTextExtentPointA(HDC hdc,LPCSTR psz,int c,LPSIZE psizl)
  841. {
  842. return GetTextExtentPointAInternal(hdc,psz,c,psizl,GGTE_WIN3_EXTENT);
  843. }
  844. BOOL APIENTRY GetTextExtentPoint32A(HDC hdc,LPCSTR psz,int c,LPSIZE psizl)
  845. {
  846. return GetTextExtentPointAInternal(hdc,psz,c,psizl,0);
  847. }
  848. /******************************Public*Routine******************************\
  849. *
  850. * DWORD WINAPI GetCharacterPlacementA
  851. *
  852. * Effects:
  853. *
  854. * Warnings:
  855. *
  856. * History:
  857. * 27-Jul-1995 -by- Bodin Dresevic [BodinD]
  858. * Wrote it.
  859. \**************************************************************************/
  860. DWORD WINAPI GetCharacterPlacementA
  861. (
  862. HDC hdc,
  863. LPCSTR psz,
  864. int nCount,
  865. int nMaxExtent,
  866. LPGCP_RESULTSA pgcpa,
  867. DWORD dwFlags
  868. )
  869. {
  870. #define GCP_GLYPHS 80
  871. WCHAR *pwsz = NULL;
  872. WCHAR awc[GCP_GLYPHS];
  873. GCP_RESULTSW gcpw;
  874. DWORD dwRet;
  875. BOOL bOk = TRUE;
  876. int nBuffer;
  877. SIZE size;
  878. DWORD dwCP;
  879. FIXUP_HANDLE(hdc);
  880. size.cx = size.cy = 0;
  881. // nMaxExtent == -1 means that there is no MaxExtent
  882. if (!psz || (nCount <= 0) || ((nMaxExtent < 0) && (nMaxExtent != -1)))
  883. {
  884. WARNING("gdi!_GetCharactherPlacementA, bad parameters \n");
  885. GdiSetLastError(ERROR_INVALID_PARAMETER);
  886. return 0;
  887. }
  888. if (!pgcpa)
  889. {
  890. // just call GetTextExtentA, can usually be done on the client side
  891. if (!GetTextExtentPointA(hdc, psz, nCount, &size))
  892. {
  893. WARNING("GetCharacterPlacementW, GetTextExtentPointA failed\n");
  894. return 0;
  895. }
  896. // now backwards compatible win95 hack, chop off 32 bit values to 16 bits
  897. return (DWORD)((USHORT)size.cx) | (DWORD)(size.cy << 16);
  898. }
  899. // chop off nCount, win95 does it
  900. if (nCount > (int)pgcpa->nGlyphs)
  901. nCount = (int)pgcpa->nGlyphs;
  902. // unicode string buffer will at least be this many WCHAR's long:
  903. nBuffer = nCount;
  904. // now go on to compute the size of the GCP_RESULTSW that is required
  905. // to receive the results. If lpOutString is not NULL the structures
  906. // will have different pointers else they will be the same.
  907. gcpw.lpOrder = pgcpa->lpOrder ;
  908. gcpw.lpDx = pgcpa->lpDx ;
  909. gcpw.lpCaretPos = pgcpa->lpCaretPos;
  910. gcpw.lpClass = pgcpa->lpClass ;
  911. gcpw.lpGlyphs = pgcpa->lpGlyphs ;
  912. gcpw.nGlyphs = pgcpa->nGlyphs ;
  913. gcpw.nMaxFit = pgcpa->nMaxFit ;
  914. if (pgcpa->lpOutString)
  915. {
  916. nBuffer += nBuffer; // take into account space for gcpw.lpOutString
  917. }
  918. else
  919. {
  920. gcpw.lpOutString = NULL;
  921. gcpw.lStructSize = pgcpa->lStructSize;
  922. }
  923. // now allocate memory (if needed) for the unicode string and for
  924. // gcpw.lpOutString if needed.
  925. if (nBuffer <= GCP_GLYPHS)
  926. pwsz = awc;
  927. else
  928. pwsz = LOCALALLOC(nBuffer * sizeof(WCHAR));
  929. if (pwsz)
  930. {
  931. if (pgcpa->lpOutString)
  932. {
  933. gcpw.lpOutString = &pwsz[nCount];
  934. // we have replaced the ansi string by unicode string, this adds
  935. // nCount bytes to the size of the structure.
  936. gcpw.lStructSize = pgcpa->lStructSize + nCount;
  937. }
  938. // convert Ansi To Unicode based on the code page of the font selected in DC
  939. if
  940. (
  941. gcpw.nGlyphs = MultiByteToWideChar((dwCP = GetCodePage(hdc)), 0,
  942. psz, nCount,
  943. pwsz, nCount*sizeof(WCHAR))
  944. )
  945. {
  946. // If this is a DBCS font then we need to patch up the DX array since
  947. // there will be two DX values for each DBCS character. It is okay
  948. // to do this in place since GetCharacterPlacement modifies the DX
  949. // array anyway.
  950. if((dwFlags & GCP_JUSTIFYIN) &&
  951. (gcpw.lpDx) &&
  952. IS_ANY_DBCS_CODEPAGE(dwCP))
  953. {
  954. INT *pDxNew, *pDxOld;
  955. const char *pDBCSString;
  956. for(pDxNew = pDxOld = gcpw.lpDx, pDBCSString = psz;
  957. pDBCSString < psz + nCount;
  958. pDBCSString++
  959. )
  960. {
  961. if(IsDBCSLeadByteEx(dwCP,*pDBCSString))
  962. {
  963. pDBCSString++;
  964. pDxOld++;
  965. }
  966. *pDxNew++ = *pDxOld++;
  967. }
  968. }
  969. #ifdef LANGPACK
  970. if (gbLpk)
  971. {
  972. // If the LPK is loaded then pass the caller nGlyphs because it may generate
  973. // Glyphs more than nCount.
  974. gcpw.nGlyphs = pgcpa->nGlyphs;
  975. dwRet = (*fpLpkGetCharacterPlacement)(hdc, pwsz, nCount,nMaxExtent,
  976. &gcpw, dwFlags, 0);
  977. }
  978. else
  979. #endif
  980. {
  981. dwRet = NtGdiGetCharacterPlacementW(hdc,pwsz,nCount,nMaxExtent,
  982. &gcpw, dwFlags);
  983. }
  984. if (dwRet)
  985. {
  986. // copy out the data.... we use the original value of nCount
  987. // when specifying an output buffer size for the lpOutString buffer
  988. // since nCount on return will be Unicode character count which
  989. // may not be the same as DBCS character count
  990. int nOriginalCount = nCount;
  991. pgcpa->nGlyphs = nCount = gcpw.nGlyphs;
  992. pgcpa->nMaxFit = gcpw.nMaxFit;
  993. if (pgcpa->lpOutString)
  994. {
  995. if
  996. (
  997. !WideCharToMultiByte(
  998. (UINT)dwCP, // UINT CodePage
  999. 0, // DWORD dwFlags
  1000. gcpw.lpOutString, // LPWSTR lpWideCharStr
  1001. gcpw.nMaxFit, // int cchWideChar
  1002. pgcpa->lpOutString, // LPSTR lpMultiByteStr
  1003. nOriginalCount, // int cchMultiByte
  1004. NULL, // LPSTR lpDefaultChar
  1005. NULL) // LPBOOL lpUsedDefaultChar
  1006. )
  1007. {
  1008. bOk = FALSE;
  1009. }
  1010. }
  1011. }
  1012. else
  1013. {
  1014. bOk = FALSE;
  1015. }
  1016. }
  1017. else
  1018. {
  1019. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1020. bOk = FALSE;
  1021. }
  1022. if (pwsz != awc)
  1023. LOCALFREE(pwsz);
  1024. }
  1025. else
  1026. {
  1027. bOk = FALSE;
  1028. }
  1029. return (bOk ? dwRet : 0);
  1030. }
  1031. /******************************Public*Routine******************************\
  1032. *
  1033. * DWORD WINAPI GetCharacterPlacementW
  1034. * look at gdi32.def, just points to NtGdiGetCharacterPlacementW
  1035. *
  1036. * History:
  1037. * 26-Jul-1995 -by- Bodin Dresevic [BodinD]
  1038. * Wrote it.
  1039. \**************************************************************************/
  1040. #if LANGPACK
  1041. DWORD WINAPI GetCharacterPlacementW
  1042. (
  1043. HDC hdc,
  1044. LPCWSTR pwsz,
  1045. int nCount,
  1046. int nMaxExtent,
  1047. LPGCP_RESULTSW pgcpw,
  1048. DWORD dwFlags
  1049. )
  1050. {
  1051. SIZE size;
  1052. FIXUP_HANDLE(hdc);
  1053. size.cx = size.cy = 0;
  1054. // nMaxExtent == -1 means that there is no MaxExtent
  1055. if (!pwsz || (nCount <= 0) || ((nMaxExtent < 0) && (nMaxExtent != -1)))
  1056. {
  1057. WARNING("gdi!_GetCharactherPlacementW, bad parameters \n");
  1058. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1059. return 0;
  1060. }
  1061. if (!pgcpw)
  1062. {
  1063. // just call GetTextExtentW, can usually be done on the client side
  1064. if (!GetTextExtentPointW(hdc, pwsz, nCount, &size))
  1065. {
  1066. WARNING("GetCharacterPlacementW, GetTextExtentPointW failed\n");
  1067. return 0;
  1068. }
  1069. // now backwards compatible win95 hack, chop off 32 bit values to 16 bits
  1070. return (DWORD)((USHORT)size.cx) | (DWORD)(size.cy << 16);
  1071. }
  1072. // chop off nCount, win95 does it
  1073. if (nCount > (int)pgcpw->nGlyphs)
  1074. nCount = (int)pgcpw->nGlyphs;
  1075. if(gbLpk)
  1076. {
  1077. return((*fpLpkGetCharacterPlacement)(hdc,pwsz,nCount,nMaxExtent,pgcpw,
  1078. dwFlags,-1));
  1079. }
  1080. else
  1081. {
  1082. return NtGdiGetCharacterPlacementW(hdc,
  1083. (LPWSTR) pwsz,
  1084. nCount,
  1085. nMaxExtent,
  1086. pgcpw,
  1087. dwFlags);
  1088. }
  1089. }
  1090. #endif
  1091. /******************************Public*Routine******************************\
  1092. * BOOL bGetCharWidthA *
  1093. * *
  1094. * Client side stub for the various GetCharWidth*A functions. *
  1095. * *
  1096. * History: *
  1097. * Sat 16-Jan-1993 03:08:42 -by- Charles Whitmer [chuckwh] *
  1098. * Added code to do it on the client side. *
  1099. * *
  1100. * 28-Aug-1991 -by- Bodin Dresevic [BodinD] *
  1101. * Wrote it. *
  1102. \**************************************************************************/
  1103. #define GCW_WIN3_INT (GCW_WIN3 | GCW_INT)
  1104. #define GCW_WIN3_16INT (GCW_WIN3 | GCW_INT | GCW_16BIT)
  1105. #define GCW_SIZE(fl) ((fl >> 16) & 0xffff)
  1106. #define GCWFL(fltype,szType) (fltype | (sizeof(szType) << 16))
  1107. BOOL bGetCharWidthA
  1108. (
  1109. HDC hdc,
  1110. UINT iFirst,
  1111. UINT iLast,
  1112. ULONG fl,
  1113. PVOID pvBuf
  1114. )
  1115. {
  1116. PDC_ATTR pDcAttr;
  1117. LONG cwc;
  1118. CFONT *pcf = NULL;
  1119. PUCHAR pch;
  1120. PWCHAR pwc;
  1121. BOOL bRet = FALSE;
  1122. ULONG cjWidths;
  1123. DWORD dwCP;
  1124. BOOL bDBCSCodePage;
  1125. WCHAR awc[MAX_PATH];
  1126. PVOID pvResultBuffer;
  1127. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  1128. if (!pDcAttr)
  1129. {
  1130. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1131. return(bRet);
  1132. }
  1133. dwCP = GET_CODE_PAGE(hdc, pDcAttr);
  1134. bDBCSCodePage = IS_ANY_DBCS_CODEPAGE(dwCP);
  1135. // do parameter validation, check that in chars are indeed ascii
  1136. if ((bDBCSCodePage && !IsValidDBCSRange(iFirst,iLast)) ||
  1137. (!bDBCSCodePage &&
  1138. ((iFirst > iLast) || (iLast & 0xffffff00))) ||
  1139. (pvBuf == NULL))
  1140. {
  1141. WARNING("gdi!_bGetCharWidthA parameters \n");
  1142. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1143. return(bRet);
  1144. }
  1145. cwc = (LONG)(iLast - iFirst + 1);
  1146. ENTERCRITICALSECTION(&semLocal);
  1147. if ((dwCP == CP_ACP) ||
  1148. (dwCP == guintAcp)
  1149. || (dwCP == guintDBCScp)
  1150. )
  1151. {
  1152. pcf = pcfLocateCFONT(hdc,pDcAttr,iFirst,(PVOID) NULL,(UINT) cwc, TRUE);
  1153. }
  1154. if (pcf != (CFONT *) NULL)
  1155. {
  1156. BOOL bExit = TRUE;
  1157. if(dwCP == guintDBCScp)
  1158. {
  1159. if (pcf->wd.sDBCSInc) // dbcs fixed pitch base font
  1160. {
  1161. bRet = bComputeCharWidthsDBCS (pcf,iFirst,iLast,fl,pvBuf);
  1162. }
  1163. else if (iLast < 0x80)
  1164. {
  1165. // linked case, base font is a latin font, but linked font
  1166. // perhaps is a FE font. We know that base font is a latin font
  1167. // because for FE proportional fonts we would never create pcf.
  1168. // We are looking for this special case when the application asked
  1169. // for Latin Face Name in the logfont, and a FE charset, but the string
  1170. // passed in lackily does not contain DBCS glyphs.
  1171. bRet = bComputeCharWidths(pcf,iFirst,iLast,fl,pvBuf);
  1172. }
  1173. else
  1174. {
  1175. bExit = FALSE;
  1176. }
  1177. }
  1178. else
  1179. {
  1180. bRet = bComputeCharWidths(pcf,iFirst,iLast,fl,pvBuf);
  1181. }
  1182. DEC_CFONT_REF(pcf);
  1183. if(bExit)
  1184. {
  1185. LEAVECRITICALSECTION(&semLocal);
  1186. return(bRet);
  1187. }
  1188. }
  1189. LEAVECRITICALSECTION(&semLocal);
  1190. // Let the server do it.
  1191. cjWidths = cwc * GCW_SIZE(fl);
  1192. //
  1193. // Non kernel mode call
  1194. //
  1195. // What if user's buffer is set up for 16 bit return?? Then we need
  1196. // to allocate buffer for 32 bit date and convert to user's buffer after
  1197. // the call
  1198. pvResultBuffer = pvBuf;
  1199. if (fl & GCW_16BIT)
  1200. {
  1201. // User's buffer is 16 bit, make 32 a bit
  1202. // temp buffer
  1203. pvResultBuffer = LOCALALLOC(cwc * sizeof(LONG));
  1204. if (pvResultBuffer == NULL) {
  1205. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1206. return(bRet);
  1207. }
  1208. }
  1209. // Kernel mode, use users buffer for return data
  1210. // convert to unicode
  1211. if(bDBCSCodePage)
  1212. {
  1213. bRet = bSetUpUnicodeStringDBCS(iFirst,
  1214. iLast,
  1215. (PUCHAR) pvResultBuffer,
  1216. awc,
  1217. dwCP,
  1218. GetCurrentDefaultChar(hdc));
  1219. }
  1220. else
  1221. {
  1222. bRet = bSetUpUnicodeString(iFirst,iLast,pvResultBuffer,awc,dwCP);
  1223. }
  1224. if(bRet)
  1225. {
  1226. bRet = NtGdiGetCharWidthW(hdc,
  1227. 0,
  1228. cwc,
  1229. awc,
  1230. (LONG)(fl & (GCW_INT | GCW_WIN3)),
  1231. pvResultBuffer);
  1232. }
  1233. if (bRet)
  1234. {
  1235. //
  1236. // May need to convert to 16 bit user buffer
  1237. //
  1238. if (fl & GCW_16BIT)
  1239. {
  1240. PWORD pw = pvBuf;
  1241. PDWORD pi = (int *)pvResultBuffer;
  1242. PDWORD piEnd = pi + cwc;
  1243. ASSERTGDI(pvResultBuffer != pvBuf, "Local buffer not allocated properly");
  1244. while (pi != piEnd)
  1245. {
  1246. *pw++ = (WORD)(*pi++);
  1247. }
  1248. LOCALFREE(pvResultBuffer);
  1249. }
  1250. }
  1251. return(bRet);
  1252. }
  1253. /******************************Public*Routine******************************\
  1254. *
  1255. * BOOL APIENTRY GetCharWidthA
  1256. *
  1257. * History:
  1258. * 25-Feb-1992 -by- Bodin Dresevic [BodinD]
  1259. * Wrote it.
  1260. \**************************************************************************/
  1261. BOOL APIENTRY GetCharWidthA
  1262. (
  1263. IN HDC hdc,
  1264. IN UINT iFirst,
  1265. IN UINT iLast,
  1266. OUT LPINT lpWidths
  1267. )
  1268. {
  1269. FIXUP_HANDLE(hdc);
  1270. return bGetCharWidthA(hdc,iFirst,iLast,GCWFL(GCW_WIN3_INT,int),(PVOID)lpWidths);
  1271. }
  1272. BOOL APIENTRY GetCharWidth32A
  1273. (
  1274. IN HDC hdc,
  1275. IN UINT iFirst,
  1276. IN UINT iLast,
  1277. OUT LPINT lpWidths
  1278. )
  1279. {
  1280. FIXUP_HANDLE(hdc);
  1281. return bGetCharWidthA(hdc,iFirst,iLast,GCWFL(GCW_INT,int),(PVOID)lpWidths);
  1282. }
  1283. /******************************Public*Routine******************************\
  1284. *
  1285. * GetCharWidthFloatA
  1286. *
  1287. * History:
  1288. * 22-Feb-1992 -by- Bodin Dresevic [BodinD]
  1289. * Wrote it.
  1290. \**************************************************************************/
  1291. BOOL APIENTRY GetCharWidthFloatA
  1292. (
  1293. IN HDC hdc,
  1294. IN UINT iFirst,
  1295. IN UINT iLast,
  1296. OUT PFLOAT lpWidths
  1297. )
  1298. {
  1299. FIXUP_HANDLE(hdc);
  1300. return bGetCharWidthA(hdc,iFirst,iLast,GCWFL(0,FLOAT),(PVOID)lpWidths);
  1301. }
  1302. /******************************Public*Routine******************************\
  1303. *
  1304. * BOOL bGetCharWidthW
  1305. *
  1306. * GetCharWidthW and GetCharWidthFloatW
  1307. *
  1308. * History:
  1309. * 28-Aug-1991 -by- Bodin Dresevic [BodinD]
  1310. * Wrote it.
  1311. \**************************************************************************/
  1312. BOOL bGetCharWidthW
  1313. (
  1314. HDC hdc,
  1315. UINT iFirst, // unicode value
  1316. UINT iLast, // unicode value
  1317. ULONG fl,
  1318. PVOID pvBuf
  1319. )
  1320. {
  1321. LONG cwc;
  1322. BOOL bRet = FALSE;
  1323. // do parameter validation, check that in chars are indeed unicode
  1324. if ((pvBuf == (PVOID)NULL) || (iFirst > iLast) || (iLast & 0xffff0000))
  1325. {
  1326. WARNING("gdi!_bGetCharWidthW parameters \n");
  1327. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1328. return(bRet);
  1329. }
  1330. cwc = (LONG)(iLast - iFirst + 1);
  1331. if(iLast < 0x80)
  1332. {
  1333. CFONT *pcf = NULL;
  1334. PDC_ATTR pDcAttr;
  1335. DWORD dwCP;
  1336. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  1337. if (!pDcAttr)
  1338. {
  1339. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1340. return(FALSE);
  1341. }
  1342. dwCP = GET_CODE_PAGE(hdc, pDcAttr);
  1343. ENTERCRITICALSECTION(&semLocal);
  1344. if ((dwCP == CP_ACP) ||
  1345. (dwCP == guintAcp)
  1346. || (dwCP == guintDBCScp)
  1347. )
  1348. {
  1349. pcf = pcfLocateCFONT(hdc,pDcAttr,iFirst,(PVOID) NULL,(UINT) cwc, TRUE);
  1350. }
  1351. if (pcf != NULL)
  1352. {
  1353. bRet = bComputeCharWidths(pcf,iFirst,iLast,fl,pvBuf);
  1354. DEC_CFONT_REF(pcf);
  1355. if(bRet)
  1356. {
  1357. LEAVECRITICALSECTION(&semLocal);
  1358. return (bRet);
  1359. }
  1360. }
  1361. LEAVECRITICALSECTION(&semLocal);
  1362. }
  1363. //
  1364. // kernel mode
  1365. //
  1366. bRet = NtGdiGetCharWidthW(
  1367. hdc,
  1368. iFirst,
  1369. cwc,
  1370. NULL,
  1371. (LONG)(fl & (GCW_INT | GCW_WIN3)),
  1372. pvBuf);
  1373. return(bRet);
  1374. }
  1375. /******************************Public*Routine******************************\
  1376. *
  1377. * BOOL APIENTRY GetCharWidthFloatW
  1378. *
  1379. * History:
  1380. * 22-Feb-1992 -by- Bodin Dresevic [BodinD]
  1381. * Wrote it.
  1382. \**************************************************************************/
  1383. BOOL APIENTRY GetCharWidthFloatW
  1384. (
  1385. HDC hdc,
  1386. UINT iFirst,
  1387. UINT iLast,
  1388. PFLOAT lpWidths
  1389. )
  1390. {
  1391. FIXUP_HANDLE(hdc);
  1392. return bGetCharWidthW(hdc,iFirst,iLast,0,(PVOID)lpWidths);
  1393. }
  1394. /******************************Public*Routine******************************\
  1395. *
  1396. * BOOL APIENTRY GetCharWidthW
  1397. *
  1398. * History:
  1399. * 25-Feb-1992 -by- Bodin Dresevic [BodinD]
  1400. * Wrote it.
  1401. \**************************************************************************/
  1402. BOOL APIENTRY GetCharWidthW
  1403. (
  1404. HDC hdc,
  1405. UINT iFirst,
  1406. UINT iLast,
  1407. LPINT lpWidths
  1408. )
  1409. {
  1410. FIXUP_HANDLE(hdc);
  1411. return bGetCharWidthW(hdc,iFirst,iLast,GCW_WIN3_INT,(PVOID)lpWidths);
  1412. }
  1413. BOOL APIENTRY GetCharWidth32W
  1414. (
  1415. HDC hdc,
  1416. UINT iFirst,
  1417. UINT iLast,
  1418. LPINT lpWidths
  1419. )
  1420. {
  1421. FIXUP_HANDLE(hdc);
  1422. return bGetCharWidthW(hdc,iFirst,iLast,GCW_INT,(PVOID)lpWidths);
  1423. }
  1424. /******************************Public*Routine******************************\
  1425. *
  1426. * WINGDIAPI BOOL WINAPI GetCharWidthI(HDC, UINT, UINT, PWCHAR, LPINT);
  1427. *
  1428. * if pgi == NULL use the consecutive range
  1429. * giFirst, giFirst + 1, ...., giFirst + cgi - 1
  1430. *
  1431. * if pgi != NULL ignore giFirst and use cgi indices pointed to by pgi
  1432. *
  1433. * History:
  1434. * 28-Aug-1996 -by- Bodin Dresevic [BodinD]
  1435. * Wrote it.
  1436. \**************************************************************************/
  1437. BOOL WINAPI GetCharWidthI(
  1438. HDC hdc,
  1439. UINT giFirst,
  1440. UINT cgi,
  1441. LPWORD pgi,
  1442. LPINT piWidths
  1443. )
  1444. {
  1445. BOOL bRet = FALSE;
  1446. // do parameter validation
  1447. if (!piWidths || (!pgi && (giFirst & 0xffff0000)))
  1448. {
  1449. WARNING("gdi! GetCharWidthI parameters \n");
  1450. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1451. return(bRet);
  1452. }
  1453. if (!cgi)
  1454. return TRUE; // quick exit
  1455. // kernel mode
  1456. bRet = NtGdiGetCharWidthW(
  1457. hdc,
  1458. giFirst,
  1459. cgi,
  1460. (PWCHAR)pgi,
  1461. (GCW_INT | GCW_GLYPH_INDEX),
  1462. (PVOID)piWidths);
  1463. return bRet;
  1464. }
  1465. /******************************Public*Routine******************************\
  1466. *
  1467. * BOOL APIENTRY GetTextExtentPointW(HDC hdc,LPWSTR pwsz,DWORD cwc,LPSIZE psizl)
  1468. *
  1469. *
  1470. * History:
  1471. * 07-Aug-1991 -by- Bodin Dresevic [BodinD]
  1472. * Wrote it.
  1473. \**************************************************************************/
  1474. #define QUICK_BUFSIZE 0xFF
  1475. BOOL GetTextExtentPointWInternal(
  1476. HDC hdc,LPCWSTR pwsz,int cwc,LPSIZE psizl, FLONG fl
  1477. )
  1478. {
  1479. WCHAR *pwc;
  1480. CFONT *pcf;
  1481. INT bRet;
  1482. PDC_ATTR pDcAttr;
  1483. BOOL bCache;
  1484. INT i;
  1485. WCHAR wcTest = 0;
  1486. int ii = cwc;
  1487. FIXUP_HANDLE(hdc);
  1488. if (cwc <= 0)
  1489. {
  1490. // empty string, just return 0 for the extent
  1491. if (cwc == 0)
  1492. {
  1493. psizl->cx = 0;
  1494. psizl->cy = 0;
  1495. return(TRUE);
  1496. }
  1497. else
  1498. {
  1499. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1500. return(FALSE);
  1501. }
  1502. }
  1503. // Let's see if we can take advantage of the ANSI client side GetTextExtent
  1504. // code. If we can convert everything from Unicode to ANSI by ignoring the
  1505. // high byte and it fits into our quick buffer then we can. In the future
  1506. // we will probably want to do a quick Unicode to ANSI conversion using
  1507. // something other than sign extension so we don't mess up non 1252 CP locales
  1508. // by making them go through the slow code all the time.
  1509. // We need to use this performance optimization if an LPK is installed
  1510. // and some condiditions are met (LTR text alignment, ..etc)
  1511. pwc = (WCHAR *) pwsz;
  1512. unroll_here:
  1513. switch(ii)
  1514. {
  1515. default:
  1516. wcTest |= pwc[9];
  1517. case 9:
  1518. wcTest |= pwc[8];
  1519. case 8:
  1520. wcTest |= pwc[7];
  1521. case 7:
  1522. wcTest |= pwc[6];
  1523. case 6:
  1524. wcTest |= pwc[5];
  1525. case 5:
  1526. wcTest |= pwc[4];
  1527. case 4:
  1528. wcTest |= pwc[3];
  1529. case 3:
  1530. wcTest |= pwc[2];
  1531. case 2:
  1532. wcTest |= pwc[1];
  1533. case 1:
  1534. wcTest |= pwc[0];
  1535. }
  1536. if ((ii > 10) && !(wcTest & 0xFF80))
  1537. {
  1538. ii -= 10;
  1539. pwc += 10;
  1540. goto unroll_here;
  1541. }
  1542. if (!(wcTest & 0xFF80))
  1543. {
  1544. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  1545. if (!pDcAttr)
  1546. {
  1547. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1548. return(FALSE);
  1549. }
  1550. #ifdef LANGPACK
  1551. if (!gbLpk || (*fpLpkUseGDIWidthCache)(hdc, (LPCSTR) pwsz,cwc, pDcAttr->lTextAlign , TRUE)) {
  1552. #endif
  1553. ENTERCRITICALSECTION(&semLocal);
  1554. pcf = pcfLocateCFONT(hdc,pDcAttr,0,(PVOID)pwsz,cwc, FALSE);
  1555. if (pcf != NULL)
  1556. {
  1557. bRet = bComputeTextExtent(pDcAttr,pcf,(PVOID) pwsz,cwc,fl,psizl,FALSE);
  1558. DEC_CFONT_REF(pcf);
  1559. if(bRet)
  1560. {
  1561. LEAVECRITICALSECTION(&semLocal);
  1562. return (bRet);
  1563. }
  1564. }
  1565. LEAVECRITICALSECTION(&semLocal);
  1566. #ifdef LANGPACK
  1567. }
  1568. #endif
  1569. }
  1570. #ifdef LANGPACK
  1571. if(gbLpk)
  1572. {
  1573. return(*fpLpkGetTextExtentExPoint)(hdc, pwsz, cwc, -1, NULL, NULL,
  1574. psizl, fl, -1);
  1575. }
  1576. #endif
  1577. return NtGdiGetTextExtent(hdc,
  1578. (LPWSTR)pwsz,
  1579. cwc,
  1580. psizl,
  1581. fl);
  1582. }
  1583. BOOL APIENTRY GetTextExtentPointW(HDC hdc,LPCWSTR pwsz,int cwc,LPSIZE psizl)
  1584. {
  1585. return GetTextExtentPointWInternal(hdc, pwsz, cwc, psizl, GGTE_WIN3_EXTENT);
  1586. }
  1587. BOOL APIENTRY GetTextExtentPoint32W(HDC hdc,LPCWSTR pwsz,int cwc,LPSIZE psizl)
  1588. {
  1589. return GetTextExtentPointWInternal(hdc, pwsz, cwc, psizl, 0);
  1590. }
  1591. /******************************Public*Routine******************************\
  1592. *
  1593. * GetTextExtentPointI, index version
  1594. *
  1595. * History:
  1596. * 28-Aug-1996 -by- Bodin Dresevic [BodinD]
  1597. * Wrote it.
  1598. \**************************************************************************/
  1599. BOOL APIENTRY GetTextExtentPointI(HDC hdc, LPWORD pgiIn, int cgi, LPSIZE psize)
  1600. {
  1601. return NtGdiGetTextExtent(hdc, (LPWSTR)pgiIn, cgi , psize, GGTE_GLYPH_INDEX);
  1602. }
  1603. /******************************Public*Routine******************************\
  1604. *
  1605. * GetFontUnicodeRanges(HDC, LPGLYPHSET)
  1606. *
  1607. * return Unicode content of the font.
  1608. *
  1609. * History:
  1610. * 28-Aug-1996 -by- Bodin Dresevic [BodinD]
  1611. * Wrote it.
  1612. \**************************************************************************/
  1613. #if 0
  1614. DWORD WINAPI GetFontUnicodeRanges(HDC hdc, LPGLYPHSET pgs)
  1615. {
  1616. return NtGdiGetFontUnicodeRanges(hdc, pgs);
  1617. }
  1618. #endif
  1619. /******************************Public*Routine******************************\
  1620. *
  1621. * GetGlyphIndicesA(HDC, LPCSTR, int, LPWORD, DWORD mode);
  1622. *
  1623. * cmap based conversion, if (mode) indicate that glyph is not supported in the
  1624. * font by putting FFFF in the output array
  1625. *
  1626. * If successfull, the function returns the number of indicies in pgi buffer.
  1627. *
  1628. * History:
  1629. * 28-Aug-1996 -by- Bodin Dresevic [BodinD]
  1630. * Wrote it.
  1631. \**************************************************************************/
  1632. DWORD WINAPI GetGlyphIndicesA(
  1633. HDC hdc,
  1634. LPCSTR psz,
  1635. int c,
  1636. LPWORD pgi,
  1637. DWORD iMode)
  1638. {
  1639. DWORD dwRet = GDI_ERROR;
  1640. PWSZ pwszCapt;
  1641. PDC_ATTR pDcAttr;
  1642. DWORD dwCP;
  1643. WCHAR awcCaptureBuffer[CAPTURE_STRING_SIZE];
  1644. FIXUP_HANDLE(hdc);
  1645. if (c <= 0)
  1646. {
  1647. // empty string, just return 0 for the extent
  1648. if (c == 0)
  1649. {
  1650. dwRet = 0;
  1651. }
  1652. else
  1653. {
  1654. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1655. dwRet = GDI_ERROR;
  1656. }
  1657. return(dwRet);
  1658. }
  1659. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  1660. if (!pDcAttr)
  1661. {
  1662. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1663. dwRet = GDI_ERROR;
  1664. return dwRet;
  1665. }
  1666. dwCP = GET_CODE_PAGE(hdc, pDcAttr);
  1667. if(guintDBCScp == dwCP)
  1668. {
  1669. QueryFontAssocStatus();
  1670. if(fFontAssocStatus &&
  1671. ((c == 1) || ((c == 2 && *(psz) && *((LPCSTR)(psz + 1)) == '\0'))))
  1672. {
  1673. //
  1674. // If this function is called with only 1 char, and font association
  1675. // is enabled, we should forcely convert the chars to Unicode with
  1676. // codepage 1252.
  1677. // This is for enabling to output Latin-1 chars ( > 0x80 in Ansi codepage )
  1678. // Because, normally font association is enabled, we have no way to output
  1679. // those charactres, then we provide the way, if user call TextOutA() with
  1680. // A character and ansi font, we tempotary disable font association.
  1681. // This might be Windows 3.1 (Korean/Taiwanese) version compatibility..
  1682. //
  1683. dwCP = 1252;
  1684. }
  1685. }
  1686. // Allocate the string buffer
  1687. if (c <= CAPTURE_STRING_SIZE)
  1688. {
  1689. pwszCapt = awcCaptureBuffer;
  1690. }
  1691. else
  1692. {
  1693. pwszCapt = LOCALALLOC(c * sizeof(WCHAR));
  1694. }
  1695. if (pwszCapt)
  1696. {
  1697. c = MultiByteToWideChar(dwCP, 0, psz,c, pwszCapt, c*sizeof(WCHAR));
  1698. if (c)
  1699. {
  1700. dwRet = NtGdiGetGlyphIndicesW(hdc,
  1701. (LPWSTR)pwszCapt,
  1702. c,
  1703. pgi,
  1704. iMode);
  1705. }
  1706. else
  1707. {
  1708. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1709. dwRet = GDI_ERROR;
  1710. }
  1711. if (pwszCapt != awcCaptureBuffer)
  1712. LOCALFREE(pwszCapt);
  1713. }
  1714. else
  1715. {
  1716. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1717. dwRet = GDI_ERROR;
  1718. }
  1719. return dwRet;
  1720. }
  1721. /******************************Public*Routine******************************\
  1722. *
  1723. * GetGlyphIndicesW(HDC, LPCSTR, int, LPWORD, DWORD);
  1724. *
  1725. * cmap based conversion, if (mode) indicate that glyph is not supported in the
  1726. * font by putting FFFF in the output array
  1727. *
  1728. * History:
  1729. * 28-Aug-1996 -by- Bodin Dresevic [BodinD]
  1730. * Wrote it.
  1731. \**************************************************************************/
  1732. #if 0
  1733. DWORD WINAPI GetGlyphIndicesW(
  1734. HDC hdc,
  1735. LPCWSTR pwc,
  1736. int cwc,
  1737. LPWORD pgi,
  1738. DWORD iMode)
  1739. {
  1740. return NtGdiGetGlyphIndicesW(hdc, pwc, cwc, pgi, iMode);
  1741. }
  1742. #endif
  1743. /******************************Public*Routine******************************\
  1744. *
  1745. * int APIENTRY GetTextFaceA(HDC hdc,int c,LPSTR psz)
  1746. *
  1747. * History:
  1748. * 30-Aug-1991 -by- Bodin Dresevic [BodinD]
  1749. * Wrote it.
  1750. \**************************************************************************/
  1751. int APIENTRY GetTextFaceA(HDC hdc,int c,LPSTR psz)
  1752. {
  1753. ULONG cRet = 0;
  1754. ULONG cbAnsi = 0;
  1755. FIXUP_HANDLE(hdc);
  1756. if ( (psz != (LPSTR) NULL) && (c <= 0) )
  1757. {
  1758. WARNING("gdi!GetTextFaceA(): invalid parameter\n");
  1759. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1760. return cRet;
  1761. }
  1762. {
  1763. //
  1764. // Kernel mode, allocate a buffer for WCAHR return
  1765. //
  1766. // WINBUG #82833 2-7-2000 bhouse Possible cleanup work in GetTextFaceA
  1767. // Old Comment:
  1768. // - This allocates a temp buffer, then NtGdi does it again
  1769. //
  1770. PWCHAR pwch = (PWCHAR)NULL;
  1771. if (c > 0)
  1772. {
  1773. pwch = (WCHAR *)LOCALALLOC(c * sizeof(WCHAR));
  1774. if (pwch == (WCHAR *)NULL)
  1775. {
  1776. WARNING("gdi!GetTextFaceA(): Memory allocation error\n");
  1777. cRet = 0;
  1778. return(cRet);
  1779. }
  1780. }
  1781. cRet = NtGdiGetTextFaceW(hdc,c,(LPWSTR)pwch,FALSE);
  1782. if(cRet && (guintDBCScp != 0xFFFFFFFF) && !psz )
  1783. {
  1784. WCHAR *pwcTmp;
  1785. // now we need to actually need to get the string for DBCS code pages
  1786. // so that we can compute the proper multi-byte length
  1787. if(pwcTmp = (WCHAR*)LOCALALLOC(cRet*sizeof(WCHAR)))
  1788. {
  1789. UINT cwTmp;
  1790. cwTmp = NtGdiGetTextFaceW(hdc,cRet,pwcTmp, FALSE);
  1791. RtlUnicodeToMultiByteSize(&cbAnsi,pwcTmp,cwTmp*sizeof(WCHAR));
  1792. LOCALFREE(pwcTmp);
  1793. }
  1794. else
  1795. {
  1796. WARNING("gdi!GetTextFaceA(): UNICODE to ANSI conversion failed\n");
  1797. cRet = 0;
  1798. }
  1799. }
  1800. else
  1801. {
  1802. cbAnsi = cRet;
  1803. }
  1804. //
  1805. // If successful and non-NULL buffer, convert back to ANSI.
  1806. //
  1807. if ( (cRet != 0) && (psz != (LPSTR) NULL) && (pwch != (WCHAR*)NULL))
  1808. {
  1809. if(!(cbAnsi = WideCharToMultiByte(CP_ACP,0,pwch,cRet,psz,c,NULL,NULL)))
  1810. {
  1811. WARNING("gdi!GetTextFaceA(): UNICODE to ANSI conversion failed\n");
  1812. cRet = 0;
  1813. }
  1814. }
  1815. if (pwch != (PWCHAR)NULL)
  1816. {
  1817. LOCALFREE(pwch);
  1818. }
  1819. }
  1820. //
  1821. // return for user and kernel mode
  1822. //
  1823. return( ((cRet == 0 ) || (psz == NULL) || psz[cbAnsi-1] != 0 ) ? cbAnsi : cbAnsi-1 );
  1824. }
  1825. /******************************Public*Routine******************************\
  1826. *
  1827. * DWORD APIENTRY GetTextFaceAliasW(HDC hdc,DWORD c,LPWSTR pwsz)
  1828. *
  1829. * History:
  1830. * 24-Feb-1998 -by- Yung-Jen Tony Tsai [YungT]
  1831. * Wrote it.
  1832. \**************************************************************************/
  1833. int APIENTRY GetTextFaceAliasW(HDC hdc,int c,LPWSTR pwsz)
  1834. {
  1835. int cRet = 0;
  1836. FIXUP_HANDLE(hdc);
  1837. if ( (pwsz != (LPWSTR) NULL) && (c == 0) )
  1838. {
  1839. WARNING("gdi!GetTextFaceAliasW(): invalid parameter\n");
  1840. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1841. return cRet;
  1842. }
  1843. cRet = NtGdiGetTextFaceW(hdc,c,pwsz,TRUE);
  1844. return(cRet);
  1845. }
  1846. /******************************Public*Routine******************************\
  1847. *
  1848. * DWORD APIENTRY GetTextFaceW(HDC hdc,DWORD c,LPWSTR pwsz)
  1849. *
  1850. * History:
  1851. * 13-Aug-1991 -by- Bodin Dresevic [BodinD]
  1852. * Wrote it.
  1853. \**************************************************************************/
  1854. int APIENTRY GetTextFaceW(HDC hdc,int c,LPWSTR pwsz)
  1855. {
  1856. int cRet = 0;
  1857. FIXUP_HANDLE(hdc);
  1858. if ( (pwsz != (LPWSTR) NULL) && (c <= 0) )
  1859. {
  1860. WARNING("gdi!GetTextFaceW(): invalid parameter\n");
  1861. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1862. return cRet;
  1863. }
  1864. cRet = NtGdiGetTextFaceW(hdc,c,pwsz,FALSE);
  1865. return(cRet);
  1866. }
  1867. /******************************Public*Routine******************************\
  1868. *
  1869. * vTextMetricWToTextMetricStrict (no char conversion)
  1870. *
  1871. * Effects: return FALSE if UNICODE chars have no ASCI equivalents
  1872. *
  1873. *
  1874. * History:
  1875. * 20-Aug-1991 -by- Bodin Dresevic [BodinD]
  1876. * Wrote it.
  1877. \**************************************************************************/
  1878. VOID FASTCALL vTextMetricWToTextMetricStrict
  1879. (
  1880. LPTEXTMETRICA ptm,
  1881. LPTEXTMETRICW ptmw
  1882. )
  1883. {
  1884. ptm->tmHeight = ptmw->tmHeight ; // DWORD
  1885. ptm->tmAscent = ptmw->tmAscent ; // DWORD
  1886. ptm->tmDescent = ptmw->tmDescent ; // DWORD
  1887. ptm->tmInternalLeading = ptmw->tmInternalLeading ; // DWORD
  1888. ptm->tmExternalLeading = ptmw->tmExternalLeading ; // DWORD
  1889. ptm->tmAveCharWidth = ptmw->tmAveCharWidth ; // DWORD
  1890. ptm->tmMaxCharWidth = ptmw->tmMaxCharWidth ; // DWORD
  1891. ptm->tmWeight = ptmw->tmWeight ; // DWORD
  1892. ptm->tmOverhang = ptmw->tmOverhang ; // DWORD
  1893. ptm->tmDigitizedAspectX = ptmw->tmDigitizedAspectX ; // DWORD
  1894. ptm->tmDigitizedAspectY = ptmw->tmDigitizedAspectY ; // DWORD
  1895. ptm->tmItalic = ptmw->tmItalic ; // BYTE
  1896. ptm->tmUnderlined = ptmw->tmUnderlined ; // BYTE
  1897. ptm->tmStruckOut = ptmw->tmStruckOut ; // BYTE
  1898. ptm->tmPitchAndFamily = ptmw->tmPitchAndFamily ; // BYTE
  1899. ptm->tmCharSet = ptmw->tmCharSet ; // BYTE
  1900. }
  1901. VOID FASTCALL vTextMetricWToTextMetric
  1902. (
  1903. LPTEXTMETRICA ptma,
  1904. TMW_INTERNAL *ptmi
  1905. )
  1906. {
  1907. vTextMetricWToTextMetricStrict(ptma,&ptmi->tmw);
  1908. ptma->tmFirstChar = ptmi->tmdTmw.chFirst ;
  1909. ptma->tmLastChar = ptmi->tmdTmw.chLast ;
  1910. ptma->tmDefaultChar = ptmi->tmdTmw.chDefault;
  1911. ptma->tmBreakChar = ptmi->tmdTmw.chBreak ;
  1912. }
  1913. /******************************Public*Routine******************************\
  1914. * GetTextExtentExPointA
  1915. *
  1916. * History:
  1917. * 06-Jan-1992 -by- Gilman Wong [gilmanw]
  1918. * Wrote it.
  1919. \**************************************************************************/
  1920. BOOL APIENTRY GetTextExtentExPointA (
  1921. HDC hdc,
  1922. LPCSTR lpszString,
  1923. int cchString,
  1924. int nMaxExtent,
  1925. LPINT lpnFit,
  1926. LPINT lpnDx,
  1927. LPSIZE lpSize
  1928. )
  1929. {
  1930. WCHAR *pwsz = NULL;
  1931. WCHAR awc[GCP_GLYPHS];
  1932. INT aiDx[GCP_GLYPHS];
  1933. INT *pDx;
  1934. BOOL bRet = FALSE;
  1935. DWORD dwCP;
  1936. BOOL bZeroSize = FALSE;
  1937. FIXUP_HANDLE(hdc);
  1938. // some parameter checking. In a single check we will both make sure that
  1939. // cchString is not negative and if positive, that it is not bigger than
  1940. // ULONG_MAX / (sizeof(ULONG) + sizeof(WCHAR)). This restriction is necessary
  1941. // for one of the memory allocations in ntgdi.c allocates
  1942. // cchString * (sizeof(ULONG) + sizeof(WCHAR)).
  1943. // Clearly, the result of this multiplication has to fit in ULONG for the
  1944. // alloc to make sense:
  1945. // also there is a validity check to be performed on nMaxExtent. -1 is the only
  1946. // legal negative value of nMaxExtent, this basically means
  1947. // that nMaxExtent can be ignored. All other negative values of nMaxExtent are
  1948. // not considered legal input.
  1949. if
  1950. (
  1951. ((ULONG)cchString > (ULONG_MAX / (sizeof(ULONG)+sizeof(WCHAR))))
  1952. ||
  1953. (nMaxExtent < -1)
  1954. )
  1955. {
  1956. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1957. return bRet;
  1958. }
  1959. if(cchString == 0)
  1960. bZeroSize = TRUE;
  1961. // now allocate memory (if needed) for the unicode string if needed
  1962. if (cchString <= GCP_GLYPHS)
  1963. {
  1964. pwsz = awc;
  1965. pDx = aiDx;
  1966. }
  1967. else
  1968. {
  1969. pwsz = LOCALALLOC((cchString+1) * (sizeof(WCHAR) + sizeof(INT)));
  1970. pDx = (INT*) &pwsz[(cchString+1)&~1];
  1971. }
  1972. if (pwsz)
  1973. {
  1974. UINT cwcWideChars;
  1975. // convert Ansi To Unicode based on the code page of the font selected in DC
  1976. dwCP = GetCodePage(hdc);
  1977. if( bZeroSize || ( cwcWideChars = MultiByteToWideChar(dwCP,
  1978. 0,
  1979. lpszString, cchString,
  1980. pwsz, cchString*sizeof(WCHAR))) )
  1981. {
  1982. BOOL bDBCSFont = IS_ANY_DBCS_CODEPAGE(dwCP) ? TRUE : FALSE;
  1983. if(bZeroSize){
  1984. cwcWideChars = 0;
  1985. pwsz[0] = (WCHAR) 0x0;
  1986. }
  1987. #ifdef LANGPACK
  1988. if(gbLpk)
  1989. {
  1990. bRet = (*fpLpkGetTextExtentExPoint)(hdc, pwsz, cwcWideChars, nMaxExtent,
  1991. lpnFit, bDBCSFont ? pDx : lpnDx,
  1992. lpSize, 0, 0);
  1993. }
  1994. else
  1995. #endif
  1996. bRet = NtGdiGetTextExtentExW(hdc,
  1997. pwsz,
  1998. cwcWideChars,
  1999. nMaxExtent,
  2000. lpnFit,
  2001. bDBCSFont ? pDx : lpnDx,
  2002. lpSize,
  2003. 0);
  2004. if (bDBCSFont && bRet)
  2005. {
  2006. // if this is a DBCS font then we need to make some adjustments
  2007. int i, j;
  2008. int cchFit, cwc;
  2009. // first compute return the proper fit in multi byte characters
  2010. if (lpnFit)
  2011. {
  2012. cwc = *lpnFit;
  2013. cchFit = WideCharToMultiByte(dwCP, 0, pwsz, cwc, NULL, 0, NULL, NULL);
  2014. *lpnFit = cchFit;
  2015. }
  2016. else
  2017. {
  2018. cwc = cwcWideChars;
  2019. cchFit = cchString;
  2020. }
  2021. // next copy the dx array. we duplicate the dx value for the high
  2022. // and low byte of DBCS characters.
  2023. if(lpnDx)
  2024. {
  2025. for(i = 0, j = 0; i < cchFit; j++)
  2026. {
  2027. if(IsDBCSLeadByteEx(dwCP,lpszString[i]))
  2028. {
  2029. lpnDx[i++] = pDx[j];
  2030. lpnDx[i++] = pDx[j];
  2031. }
  2032. else
  2033. {
  2034. lpnDx[i++] = pDx[j];
  2035. }
  2036. }
  2037. // I claim that we should be at exactly at the end of the Unicode
  2038. // string once we are here if not we need to examine the above loop
  2039. // to make sure it works properly [gerritv]
  2040. ASSERTGDI(j == cwc,
  2041. "GetTextExtentExPointA: problem converting DX array\n");
  2042. }
  2043. }
  2044. }
  2045. else
  2046. {
  2047. GdiSetLastError(ERROR_INVALID_PARAMETER);
  2048. }
  2049. if (pwsz != awc)
  2050. LOCALFREE(pwsz);
  2051. }
  2052. return bRet;
  2053. }
  2054. /******************************Public*Routine******************************\
  2055. * GetTextExtentExPointW
  2056. *
  2057. * History:
  2058. * 06-Jan-1992 -by- Gilman Wong [gilmanw]
  2059. * Wrote it.
  2060. \**************************************************************************/
  2061. BOOL APIENTRY GetTextExtentExPointW (
  2062. HDC hdc,
  2063. LPCWSTR lpwszString,
  2064. int cwchString,
  2065. int nMaxExtent,
  2066. LPINT lpnFit,
  2067. LPINT lpnDx,
  2068. LPSIZE lpSize
  2069. )
  2070. {
  2071. #ifdef LANGPACK
  2072. if(gbLpk)
  2073. {
  2074. return (*fpLpkGetTextExtentExPoint)(hdc, lpwszString, cwchString, nMaxExtent,
  2075. lpnFit, lpnDx, lpSize, 0, -1);
  2076. }
  2077. else
  2078. #endif
  2079. return NtGdiGetTextExtentExW(hdc,
  2080. (LPWSTR)lpwszString,
  2081. cwchString,
  2082. nMaxExtent,
  2083. lpnFit,
  2084. lpnDx,
  2085. lpSize,
  2086. 0);
  2087. }
  2088. /******************************Public*Routine******************************\
  2089. *
  2090. * GetTextExtentExPointWPri,
  2091. * The same as GetTextExtentExPointW, the only difference is that
  2092. * lpk is bypassed, whether installed or not. This routine is actually called
  2093. * by lpk when it is installed.
  2094. *
  2095. * History:
  2096. * 03-Jun-1997 -by- Bodin Dresevic [BodinD]
  2097. * Wrote it.
  2098. \**************************************************************************/
  2099. BOOL APIENTRY GetTextExtentExPointWPri (
  2100. HDC hdc,
  2101. LPCWSTR lpwszString,
  2102. int cwchString,
  2103. int nMaxExtent,
  2104. LPINT lpnFit,
  2105. LPINT lpnDx,
  2106. LPSIZE lpSize
  2107. )
  2108. {
  2109. return NtGdiGetTextExtentExW(hdc,
  2110. (LPWSTR)lpwszString,
  2111. cwchString,
  2112. nMaxExtent,
  2113. lpnFit,
  2114. lpnDx,
  2115. lpSize,
  2116. 0);
  2117. }
  2118. /******************************Public*Routine******************************\
  2119. *
  2120. * BOOL APIENTRY GetTextExtentExPointI
  2121. *
  2122. *
  2123. * History:
  2124. * 09-Sep-1996 -by- Bodin Dresevic [BodinD]
  2125. * Wrote it.
  2126. \**************************************************************************/
  2127. BOOL APIENTRY GetTextExtentExPointI (
  2128. HDC hdc,
  2129. LPWORD lpwszString,
  2130. int cwchString,
  2131. int nMaxExtent,
  2132. LPINT lpnFit,
  2133. LPINT lpnDx,
  2134. LPSIZE lpSize
  2135. )
  2136. {
  2137. return NtGdiGetTextExtentExW(hdc,
  2138. (LPWSTR)lpwszString,
  2139. cwchString,
  2140. nMaxExtent,
  2141. lpnFit,
  2142. lpnDx,
  2143. lpSize,
  2144. GTEEX_GLYPH_INDEX);
  2145. }
  2146. /******************************Public*Routine******************************\
  2147. *
  2148. * bGetCharABCWidthsA
  2149. *
  2150. * works for both floating point and integer version depending on bInt
  2151. *
  2152. * History:
  2153. * 24-Feb-1992 -by- Bodin Dresevic [BodinD]
  2154. * Wrote it.
  2155. \**************************************************************************/
  2156. BOOL bGetCharABCWidthsA (
  2157. HDC hdc,
  2158. UINT wFirst,
  2159. UINT wLast,
  2160. FLONG fl,
  2161. PVOID pvBuf // if (fl & GCABCW_INT) pabc else pabcf,
  2162. )
  2163. {
  2164. BOOL bRet = FALSE;
  2165. ULONG cjData, cjWCHAR, cjABC;
  2166. ULONG cChar = wLast - wFirst + 1;
  2167. DWORD dwCP = GetCodePage(hdc);
  2168. BOOL bDBCSCodePage;
  2169. bDBCSCodePage = IS_ANY_DBCS_CODEPAGE(dwCP);
  2170. // Parameter checking.
  2171. FIXUP_HANDLE(hdc);
  2172. if((pvBuf == (PVOID) NULL) ||
  2173. (bDBCSCodePage && !IsValidDBCSRange(wFirst,wLast)) ||
  2174. (!bDBCSCodePage && ((wFirst > wLast) || (wLast > 255))))
  2175. {
  2176. WARNING("gdi!_GetCharABCWidthsA(): bad parameter\n");
  2177. GdiSetLastError(ERROR_INVALID_PARAMETER);
  2178. return(FALSE);
  2179. }
  2180. // Compute buffer space needed in memory window.
  2181. // Buffer will be input array of WCHAR followed by output arrary of ABC.
  2182. // Because ABC need 32-bit alignment, cjWCHAR is rounded up to DWORD boundary.
  2183. cjABC = cChar * ((fl & GCABCW_INT) ? sizeof(ABC) : sizeof(ABCFLOAT));
  2184. cjWCHAR = ALIGN4(cChar * sizeof(WCHAR));
  2185. cjData = cjWCHAR + cjABC;
  2186. //
  2187. // WINBUG 82840 2-7-2000 bhouse Possible cleanup in bGetCharABCWidthsA
  2188. // Old Comment:
  2189. // - if vSetUpUnicodeString,x could be moved to ntgdi,
  2190. // we wouldn't need to allocated temp buffers twice
  2191. //
  2192. // Allocate memory for temp buffer, fill in with proper char values
  2193. //
  2194. // Write the unicode string [wFirst,wLast] at the top of the buffer.
  2195. // vSetUpUnicodeString requires a tmp CHAR buffer; we'll cheat a little
  2196. // and use the ABC return buffer (this assumes that ABC is bigger
  2197. // than a CHAR or USHORT in the case of DBCS). We can get away with this b
  2198. // because this memory is an output buffer for the server call.
  2199. //
  2200. {
  2201. PUCHAR pjTempBuffer = LOCALALLOC(cjData);
  2202. PUCHAR pwcABC = pjTempBuffer + cjWCHAR;
  2203. PWCHAR pwcCHAR = (PWCHAR)pjTempBuffer;
  2204. if (pjTempBuffer == (PUCHAR)NULL)
  2205. {
  2206. bRet = FALSE;
  2207. }
  2208. else
  2209. {
  2210. if(bDBCSCodePage)
  2211. {
  2212. bRet = bSetUpUnicodeStringDBCS(wFirst,
  2213. wLast,
  2214. pwcABC,
  2215. pwcCHAR,
  2216. dwCP,
  2217. GetCurrentDefaultChar(hdc));
  2218. }
  2219. else
  2220. {
  2221. bRet = bSetUpUnicodeString(wFirst,
  2222. wLast,
  2223. pwcABC,
  2224. pwcCHAR, dwCP);
  2225. }
  2226. //
  2227. // call GDI
  2228. //
  2229. if(bRet)
  2230. {
  2231. bRet = NtGdiGetCharABCWidthsW(hdc,
  2232. wFirst,
  2233. cChar,
  2234. (PWCHAR)pwcCHAR,
  2235. (fl & GCABCW_INT),
  2236. (PVOID)pwcABC);
  2237. }
  2238. //
  2239. // If OK, then copy return data out of window.
  2240. //
  2241. if (bRet)
  2242. {
  2243. RtlCopyMemory((PBYTE) pvBuf,pwcABC, cjABC);
  2244. }
  2245. LOCALFREE(pjTempBuffer);
  2246. }
  2247. }
  2248. return bRet;
  2249. }
  2250. /******************************Public*Routine******************************\
  2251. * BOOL APIENTRY GetCharABCWidthsA (
  2252. *
  2253. * We want to get ABC spaces
  2254. * for a contiguous set of input codepoints (that range from wFirst to wLast).
  2255. * The set of corresponding UNICODE codepoints is not guaranteed to be
  2256. * contiguous. Therefore, we will translate the input codepoints here and
  2257. * pass the server a buffer of UNICODE codepoints.
  2258. *
  2259. * History:
  2260. * 20-Jan-1992 -by- Gilman Wong [gilmanw]
  2261. * Wrote it.
  2262. \**************************************************************************/
  2263. BOOL APIENTRY GetCharABCWidthsA (
  2264. HDC hdc,
  2265. UINT wFirst,
  2266. UINT wLast,
  2267. LPABC lpABC
  2268. )
  2269. {
  2270. return bGetCharABCWidthsA(hdc,wFirst,wLast,GCABCW_INT,(PVOID)lpABC);
  2271. }
  2272. /******************************Public*Routine******************************\
  2273. *
  2274. * GetCharABCWidthsFloatA
  2275. *
  2276. * History:
  2277. * 22-Feb-1992 -by- Bodin Dresevic [BodinD]
  2278. * Wrote it.
  2279. \**************************************************************************/
  2280. BOOL APIENTRY GetCharABCWidthsFloatA
  2281. (
  2282. IN HDC hdc,
  2283. IN UINT iFirst,
  2284. IN UINT iLast,
  2285. OUT LPABCFLOAT lpABCF
  2286. )
  2287. {
  2288. return bGetCharABCWidthsA(hdc,iFirst,iLast,0,(PVOID)lpABCF);
  2289. }
  2290. /******************************Public*Routine******************************\
  2291. *
  2292. * bGetCharABCWidthsW
  2293. *
  2294. * History:
  2295. * 22-Feb-1992 -by- Bodin Dresevic [BodinD]
  2296. * Wrote it.
  2297. \**************************************************************************/
  2298. BOOL bGetCharABCWidthsW (
  2299. IN HDC hdc,
  2300. IN UINT wchFirst,
  2301. IN UINT wchLast,
  2302. IN FLONG fl,
  2303. OUT PVOID pvBuf
  2304. )
  2305. {
  2306. BOOL bRet = FALSE;
  2307. ULONG cwch = wchLast - wchFirst + 1;
  2308. // Parameter checking.
  2309. FIXUP_HANDLE(hdc);
  2310. if ( (pvBuf == (PVOID)NULL) || (wchFirst > wchLast) )
  2311. {
  2312. WARNING("gdi!GetCharABCWidthsW(): bad parameter\n");
  2313. GdiSetLastError(ERROR_INVALID_PARAMETER);
  2314. return(FALSE);
  2315. }
  2316. //
  2317. // kernel mode
  2318. //
  2319. bRet = NtGdiGetCharABCWidthsW(
  2320. hdc,
  2321. wchFirst,
  2322. cwch,
  2323. (PWCHAR)NULL,
  2324. fl,
  2325. (PVOID)pvBuf);
  2326. return(bRet);
  2327. }
  2328. /******************************Public*Routine******************************\
  2329. * BOOL APIENTRY GetCharABCWidthsW (
  2330. * IN HDC hdc,
  2331. * IN WORD wchFirst,
  2332. * IN WORD wchLast,
  2333. * OUT LPABC lpABC
  2334. * )
  2335. *
  2336. * For this case, we can truly assume that we want to get ABC character
  2337. * widths for a contiguous set of UNICODE codepoints from wchFirst to
  2338. * wchLast (inclusive). So we will call the server using wchFirst, but
  2339. * with an empty input buffer.
  2340. *
  2341. * History:
  2342. * 20-Jan-1992 -by- Gilman Wong [gilmanw]
  2343. * Wrote it.
  2344. \**************************************************************************/
  2345. BOOL APIENTRY GetCharABCWidthsW (
  2346. HDC hdc,
  2347. UINT wchFirst,
  2348. UINT wchLast,
  2349. LPABC lpABC
  2350. )
  2351. {
  2352. return bGetCharABCWidthsW(hdc,wchFirst,wchLast,GCABCW_INT,(PVOID)lpABC);
  2353. }
  2354. /******************************Public*Routine******************************\
  2355. *
  2356. * GetCharABCWidthsFloatW
  2357. *
  2358. * Effects:
  2359. *
  2360. * Warnings:
  2361. *
  2362. * History:
  2363. * 22-Feb-1992 -by- Bodin Dresevic [BodinD]
  2364. * Wrote it.
  2365. \**************************************************************************/
  2366. BOOL APIENTRY GetCharABCWidthsFloatW
  2367. (
  2368. HDC hdc,
  2369. UINT iFirst,
  2370. UINT iLast,
  2371. LPABCFLOAT lpABCF
  2372. )
  2373. {
  2374. return bGetCharABCWidthsW(hdc,iFirst,iLast,0,(PVOID)lpABCF);
  2375. }
  2376. /******************************Public*Routine******************************\
  2377. *
  2378. * GetCharABCWidthsI, index version
  2379. *
  2380. * if pgi == NULL use the consecutive range
  2381. * giFirst, giFirst + 1, ...., giFirst + cgi - 1
  2382. *
  2383. * if pgi != NULL ignore giFirst and use cgi indices pointed to by pgi
  2384. *
  2385. * History:
  2386. * 28-Aug-1996 -by- Bodin Dresevic [BodinD]
  2387. * Wrote it.
  2388. \**************************************************************************/
  2389. BOOL APIENTRY GetCharABCWidthsI(
  2390. HDC hdc,
  2391. UINT giFirst,
  2392. UINT cgi,
  2393. LPWORD pgi,
  2394. LPABC pabc
  2395. )
  2396. {
  2397. return NtGdiGetCharABCWidthsW(hdc,
  2398. giFirst,
  2399. cgi,
  2400. pgi,
  2401. GCABCW_INT | GCABCW_GLYPH_INDEX,
  2402. pabc
  2403. );
  2404. }
  2405. /******************************Public*Routine******************************\
  2406. * GetFontData
  2407. *
  2408. * Client side stub to GreGetFontData.
  2409. *
  2410. * History:
  2411. * 17-Feb-1992 -by- Gilman Wong [gilmanw]
  2412. * Wrote it.
  2413. \**************************************************************************/
  2414. DWORD APIENTRY GetFontData (
  2415. HDC hdc,
  2416. DWORD dwTable,
  2417. DWORD dwOffset,
  2418. PVOID pvBuffer,
  2419. DWORD cjBuffer
  2420. )
  2421. {
  2422. DWORD dwRet = (DWORD) -1;
  2423. FIXUP_HANDLE(hdc);
  2424. // if there is no buffer to copy data to, ignore possibly different
  2425. // from zero cjBuffer parameter. This is what win95 is doing.
  2426. if (cjBuffer && (pvBuffer == NULL))
  2427. cjBuffer = 0;
  2428. dwRet = NtGdiGetFontData(
  2429. hdc,
  2430. dwTable,
  2431. dwOffset,
  2432. pvBuffer,
  2433. cjBuffer);
  2434. return(dwRet);
  2435. }
  2436. /******************************Public*Routine******************************\
  2437. * GetGlyphOutline
  2438. *
  2439. * Client side stub to GreGetGlyphOutline.
  2440. *
  2441. * History:
  2442. * 17-Feb-1992 -by- Gilman Wong [gilmanw]
  2443. * Wrote it.
  2444. \**************************************************************************/
  2445. DWORD GetGlyphOutlineInternalW (
  2446. HDC hdc,
  2447. UINT uChar,
  2448. UINT fuFormat,
  2449. LPGLYPHMETRICS lpgm,
  2450. DWORD cjBuffer,
  2451. LPVOID pvBuffer,
  2452. CONST MAT2 *lpmat2,
  2453. BOOL bIgnoreRotation
  2454. )
  2455. {
  2456. DWORD dwRet = (DWORD) -1;
  2457. // Parameter validation.
  2458. FIXUP_HANDLE(hdc);
  2459. if ( (lpmat2 == (LPMAT2) NULL)
  2460. || (lpgm == (LPGLYPHMETRICS) NULL)
  2461. )
  2462. {
  2463. WARNING("gdi!GetGlyphOutlineW(): bad parameter\n");
  2464. return (dwRet);
  2465. }
  2466. if (pvBuffer == NULL)
  2467. cjBuffer = 0;
  2468. // Compute buffer space needed in memory window.
  2469. dwRet = NtGdiGetGlyphOutline(
  2470. hdc,
  2471. (WCHAR)uChar,
  2472. fuFormat,
  2473. lpgm,
  2474. cjBuffer,
  2475. pvBuffer,
  2476. (LPMAT2)lpmat2,
  2477. bIgnoreRotation);
  2478. return(dwRet);
  2479. }
  2480. DWORD APIENTRY GetGlyphOutlineW (
  2481. HDC hdc,
  2482. UINT uChar,
  2483. UINT fuFormat,
  2484. LPGLYPHMETRICS lpgm,
  2485. DWORD cjBuffer,
  2486. LPVOID pvBuffer,
  2487. CONST MAT2 *lpmat2
  2488. )
  2489. {
  2490. return( GetGlyphOutlineInternalW( hdc,
  2491. uChar,
  2492. fuFormat,
  2493. lpgm,
  2494. cjBuffer,
  2495. pvBuffer,
  2496. lpmat2,
  2497. FALSE ) );
  2498. }
  2499. DWORD APIENTRY GetGlyphOutlineInternalA (
  2500. HDC hdc,
  2501. UINT uChar,
  2502. UINT fuFormat,
  2503. LPGLYPHMETRICS lpgm,
  2504. DWORD cjBuffer,
  2505. LPVOID pvBuffer,
  2506. CONST MAT2 *lpmat2,
  2507. BOOL bIgnoreRotation
  2508. )
  2509. {
  2510. WCHAR wc;
  2511. BOOL bRet;
  2512. FIXUP_HANDLE(hdc);
  2513. // The ANSI interface is compatible with Win 3.1 and is intended
  2514. // to take a 2 byte uChar. Since we are 32-bit, this 16-bit UINT
  2515. // is now 32-bit. So we are only interested in the least significant
  2516. // word of the uChar passed into the 32-bit interface.
  2517. if (!(fuFormat & GGO_GLYPH_INDEX))
  2518. {
  2519. // the conversion needs to be done based on
  2520. // the current code page of the font selected in the dc
  2521. UCHAR Mbcs[2];
  2522. UINT Convert;
  2523. DWORD dwCP = GetCodePage(hdc);
  2524. if(IS_ANY_DBCS_CODEPAGE(dwCP) &&
  2525. IsDBCSLeadByteEx(dwCP, (char) (uChar >> 8)))
  2526. {
  2527. Mbcs[0] = (uChar >> 8) & 0xFF;
  2528. Mbcs[1] = uChar & 0xFF;
  2529. Convert = 2;
  2530. }
  2531. else
  2532. {
  2533. Mbcs[0] = uChar & 0xFF;
  2534. Convert = 1;
  2535. }
  2536. if(!(bRet = MultiByteToWideChar(dwCP, 0,
  2537. (LPCSTR)Mbcs,Convert,
  2538. &wc, sizeof(WCHAR))))
  2539. {
  2540. GdiSetLastError(ERROR_INVALID_PARAMETER);
  2541. }
  2542. }
  2543. else
  2544. {
  2545. // The uChar value is to be interpreted as glyph index and
  2546. // no conversion is necessary
  2547. wc = (WCHAR)uChar;
  2548. bRet = TRUE;
  2549. }
  2550. if (bRet)
  2551. {
  2552. bRet = GetGlyphOutlineInternalW(
  2553. hdc,
  2554. (UINT) wc,
  2555. fuFormat,
  2556. lpgm,
  2557. cjBuffer,
  2558. pvBuffer,
  2559. lpmat2,
  2560. bIgnoreRotation);
  2561. }
  2562. return bRet;
  2563. }
  2564. DWORD APIENTRY GetGlyphOutlineA (
  2565. HDC hdc,
  2566. UINT uChar,
  2567. UINT fuFormat,
  2568. LPGLYPHMETRICS lpgm,
  2569. DWORD cjBuffer,
  2570. LPVOID pvBuffer,
  2571. CONST MAT2 *lpmat2
  2572. )
  2573. {
  2574. return( GetGlyphOutlineInternalA( hdc,
  2575. uChar,
  2576. fuFormat,
  2577. lpgm,
  2578. cjBuffer,
  2579. pvBuffer,
  2580. lpmat2,
  2581. FALSE ) );
  2582. }
  2583. DWORD APIENTRY GetGlyphOutlineWow (
  2584. HDC hdc,
  2585. UINT uChar,
  2586. UINT fuFormat,
  2587. LPGLYPHMETRICS lpgm,
  2588. DWORD cjBuffer,
  2589. LPVOID pvBuffer,
  2590. CONST MAT2 *lpmat2
  2591. )
  2592. {
  2593. return( GetGlyphOutlineInternalA( hdc,
  2594. uChar,
  2595. fuFormat,
  2596. lpgm,
  2597. cjBuffer,
  2598. pvBuffer,
  2599. lpmat2,
  2600. TRUE ) );
  2601. }
  2602. /******************************Public*Routine******************************\
  2603. * GetOutlineTextMetricsW
  2604. *
  2605. * Client side stub to GreGetOutlineTextMetrics.
  2606. *
  2607. * History:
  2608. *
  2609. * Tue 20-Apr-1993 -by- Gerrit van Wingerden [gerritv]
  2610. * update: added bTTOnly stuff for Aldus escape in the WOW layer
  2611. *
  2612. * Thu 28-Jan-1993 -by- Bodin Dresevic [BodinD]
  2613. * update: added TMDIFF * stuff
  2614. *
  2615. * 17-Feb-1992 -by- Gilman Wong [gilmanw]
  2616. * Wrote it.
  2617. \**************************************************************************/
  2618. UINT APIENTRY GetOutlineTextMetricsWInternal (
  2619. HDC hdc,
  2620. UINT cjCopy, // refers to OTMW_INTERNAL, not to OUTLINETEXTMETRICSW
  2621. OUTLINETEXTMETRICW * potmw,
  2622. TMDIFF * ptmd
  2623. )
  2624. {
  2625. DWORD cjRet = (DWORD) 0;
  2626. FIXUP_HANDLE(hdc);
  2627. if (potmw == (OUTLINETEXTMETRICW *) NULL)
  2628. cjCopy = 0;
  2629. cjRet = NtGdiGetOutlineTextMetricsInternalW(
  2630. hdc,
  2631. cjCopy,
  2632. potmw,
  2633. ptmd);
  2634. return(cjRet);
  2635. }
  2636. /******************************Public*Routine******************************\
  2637. *
  2638. * UINT APIENTRY GetOutlineTextMetricsW (
  2639. *
  2640. * wrote the wrapper to go around the corresponding internal routine
  2641. *
  2642. * History:
  2643. * 28-Jan-1993 -by- Bodin Dresevic [BodinD]
  2644. * Wrote it.
  2645. \**************************************************************************/
  2646. UINT APIENTRY GetOutlineTextMetricsW (
  2647. HDC hdc,
  2648. UINT cjCopy,
  2649. LPOUTLINETEXTMETRICW potmw
  2650. )
  2651. {
  2652. TMDIFF tmd;
  2653. return GetOutlineTextMetricsWInternal(hdc, cjCopy, potmw, &tmd);
  2654. }
  2655. #define bAnsiSize(a,b,c) (NT_SUCCESS(RtlUnicodeToMultiByteSize((a),(b),(c))))
  2656. // vAnsiSize macro should only be used within GetOTMA, where bAnsiSize
  2657. // is not supposed to fail [bodind]
  2658. #if DBG
  2659. #define vAnsiSize(a,b,c) \
  2660. { \
  2661. BOOL bTmp = bAnsiSize(&cjString, pwszSrc, sizeof(WCHAR) * cwc); \
  2662. ASSERTGDI(bTmp, "gdi32!GetOTMA: bAnsiSize failed \n"); \
  2663. }
  2664. #else
  2665. #define vAnsiSize(a,b,c) bAnsiSize(a,b,c)
  2666. #endif //, non debug version
  2667. /******************************Public*Routine******************************\
  2668. * GetOutlineTextMetricsInternalA
  2669. *
  2670. * Client side stub to GreGetOutlineTextMetrics.
  2671. *
  2672. * History:
  2673. *
  2674. * 20-Apr-1993 -by- Gerrit van Wingerden [gerritv]
  2675. * Changed to GetOutlineTextMetricsInternalA from GetOutlineTextMetricsA
  2676. * to support all fonts mode for Aldus escape.
  2677. *
  2678. * 17-Feb-1992 -by- Gilman Wong [gilmanw]
  2679. * Wrote it.
  2680. \**************************************************************************/
  2681. UINT APIENTRY GetOutlineTextMetricsInternalA (
  2682. HDC hdc,
  2683. UINT cjCopy,
  2684. LPOUTLINETEXTMETRICA potma
  2685. )
  2686. {
  2687. UINT cjRet = 0;
  2688. UINT cjotma, cjotmw;
  2689. TMDIFF tmd;
  2690. OUTLINETEXTMETRICW *potmwTmp;
  2691. OUTLINETEXTMETRICA otmaTmp; // tmp buffer on the stack
  2692. FIXUP_HANDLE(hdc);
  2693. // Because we need to be able to copy cjCopy bytes of data from the
  2694. // OUTLINETEXTMETRICA structure, we need to allocate a temporary buffer
  2695. // big enough for the entire structure. This is because the UNICODE and
  2696. // ANSI versions of OUTLINETEXTMETRIC have mismatched offsets to their
  2697. // corresponding fields.
  2698. // Determine size of the buffer.
  2699. if ((cjotmw = GetOutlineTextMetricsWInternal(hdc, 0, NULL,&tmd)) == 0 )
  2700. {
  2701. WARNING("gdi!GetOutlineTextMetricsInternalA(): unable to determine size of buffer needed\n");
  2702. return (cjRet);
  2703. }
  2704. // get cjotma from tmd.
  2705. cjotma = (UINT)tmd.cjotma;
  2706. // if cjotma == 0, this is HONEST to God unicode font, can not convert
  2707. // strings to ansi
  2708. if (cjotma == 0)
  2709. {
  2710. WARNING("gdi!GetOutlineTextMetricsInternalA(): unable to determine cjotma\n");
  2711. return (cjRet);
  2712. }
  2713. // Early out. If NULL buffer, then just return the size.
  2714. if (potma == (LPOUTLINETEXTMETRICA) NULL)
  2715. return (cjotma);
  2716. // Allocate temporary buffers.
  2717. if ((potmwTmp = (OUTLINETEXTMETRICW*) LOCALALLOC(cjotmw)) == (OUTLINETEXTMETRICW*)NULL)
  2718. {
  2719. WARNING("gdi!GetOutlineTextMetricA(): memory allocation error OUTLINETEXTMETRICW buffer\n");
  2720. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  2721. return (cjRet);
  2722. }
  2723. // Call the UNICODE version of the call.
  2724. if (GetOutlineTextMetricsWInternal(hdc, cjotmw, potmwTmp,&tmd) == 0 )
  2725. {
  2726. WARNING("gdi!GetOutlineTextMetricsInternalA(): call to GetOutlineTextMetricsW() failed\n");
  2727. LOCALFREE(potmwTmp);
  2728. return (cjRet);
  2729. }
  2730. // Convert from OUTLINETEXTMETRICW to OUTLINETEXTMETRICA
  2731. vOutlineTextMetricWToOutlineTextMetricA(&otmaTmp, potmwTmp,&tmd);
  2732. // Copy data into return buffer. Do not copy strings.
  2733. cjRet = min(cjCopy, sizeof(OUTLINETEXTMETRICA));
  2734. RtlMoveMemory(potma,&otmaTmp,cjRet);
  2735. // Note that if
  2736. // offsetof(OUTLINETEXTMETRICA,otmpFamilyName) < cjCopy <= sizeof(OUTLINETEXTMETRICA)
  2737. // the offsets to strings have been set to zero [BodinD]
  2738. // If strings wanted, convert the strings to ANSI.
  2739. if (cjCopy > sizeof(OUTLINETEXTMETRICA))
  2740. {
  2741. ULONG cjString,cwc;
  2742. ULONG_PTR dpString;
  2743. ULONG_PTR dpStringEnd;
  2744. PWSZ pwszSrc;
  2745. // first have to make sure that we will not overwrite the end
  2746. // of the caller's buffer, if that is the case
  2747. if (cjCopy < cjotma)
  2748. {
  2749. // Win 31 spec is ambiguous about this case
  2750. // and by looking into the source code, it seems that
  2751. // they just overwrite the end of the buffer without
  2752. // even doing this check.
  2753. GdiSetLastError(ERROR_CAN_NOT_COMPLETE);
  2754. cjRet = 0;
  2755. goto GOTMA_clean_up;
  2756. }
  2757. // now we know that all the strings can fit, moreover we know that
  2758. // all string operations will succeed since we have called
  2759. // cjOTMA to do these same operations on the server side to give us
  2760. // cjotma [bodind]
  2761. // Note: have to do the backwards compatible casting below because Win 3.1 insists
  2762. // on using a PSTR as PTRDIFF (i.e., an offset).
  2763. // FAMILY NAME ------------------------------------------------------------
  2764. pwszSrc = (PWSZ) (((PBYTE) potmwTmp) + (ULONG_PTR) potmwTmp->otmpFamilyName);
  2765. cwc = wcslen(pwszSrc) + 1;
  2766. vAnsiSize(&cjString, pwszSrc, sizeof(WCHAR) * cwc);
  2767. // Convert from Unicode to ASCII.
  2768. dpString = sizeof(OUTLINETEXTMETRICA);
  2769. dpStringEnd = dpString + cjString;
  2770. ASSERTGDI(dpStringEnd <= cjCopy, "gdi32!GetOTMA: string can not fit1\n");
  2771. if (!bToASCII_N ((PBYTE)potma + dpString,cjString,pwszSrc,cwc))
  2772. {
  2773. WARNING("gdi!GetOutlineTextMetricsInternalA(): UNICODE->ASCII conv error \n");
  2774. cjRet = 0;
  2775. goto GOTMA_clean_up;
  2776. }
  2777. // Store string offset in the return structure.
  2778. potma->otmpFamilyName = (PSTR) dpString;
  2779. // FACE NAME --------------------------------------------------------------
  2780. pwszSrc = (PWSZ) (((PBYTE) potmwTmp) + (ULONG_PTR) potmwTmp->otmpFaceName);
  2781. cwc = wcslen(pwszSrc) + 1;
  2782. vAnsiSize(&cjString, pwszSrc, sizeof(WCHAR) * cwc);
  2783. dpString = dpStringEnd;
  2784. dpStringEnd = dpString + cjString;
  2785. ASSERTGDI(dpStringEnd <= cjCopy, "gdi32!GetOTMA: string can not fit2\n");
  2786. // Convert from Unicode to ASCII.
  2787. if (!bToASCII_N ((PBYTE)potma + dpString,cjString,pwszSrc,cwc))
  2788. {
  2789. WARNING("gdi!GetOutlineTextMetricsInternalA(): UNICODE->ASCII conv error \n");
  2790. cjRet = 0;
  2791. goto GOTMA_clean_up;
  2792. }
  2793. // Store string offset in return structure. Move pointers to next string.
  2794. potma->otmpFaceName = (PSTR) dpString;
  2795. // STYLE NAME -------------------------------------------------------------
  2796. pwszSrc = (PWSZ) (((PBYTE) potmwTmp) + (ULONG_PTR) potmwTmp->otmpStyleName);
  2797. cwc = wcslen(pwszSrc) + 1;
  2798. vAnsiSize(&cjString, pwszSrc, sizeof(WCHAR) * cwc);
  2799. dpString = dpStringEnd;
  2800. dpStringEnd = dpString + cjString;
  2801. ASSERTGDI(dpStringEnd <= cjCopy, "gdi32!GetOTMA: string can not fit3\n");
  2802. // Convert from Unicode to ASCII.
  2803. if (!bToASCII_N ((PBYTE)potma + dpString,cjString,pwszSrc,cwc))
  2804. {
  2805. WARNING("gdi!GetOutlineTextMetricsInternalA(): UNICODE->ASCII conv error \n");
  2806. cjRet = 0;
  2807. goto GOTMA_clean_up;
  2808. }
  2809. // Store string offset in return structure. Move pointers to next string.
  2810. potma->otmpStyleName = (PSTR)dpString;
  2811. // FULL NAME --------------------------------------------------------------
  2812. pwszSrc = (PWSZ) (((PBYTE) potmwTmp) + (ULONG_PTR) potmwTmp->otmpFullName);
  2813. cwc = wcslen(pwszSrc) + 1;
  2814. vAnsiSize(&cjString, pwszSrc, sizeof(WCHAR) * cwc);
  2815. dpString = dpStringEnd;
  2816. dpStringEnd = dpString + cjString;
  2817. ASSERTGDI(dpStringEnd <= cjCopy, "gdi32!GetOTMA: string can not fit4\n");
  2818. // Convert from Unicode to ASCII.
  2819. if (!bToASCII_N ((PBYTE)potma + dpString,cjString,pwszSrc,cwc))
  2820. {
  2821. WARNING("gdi!GetOutlineTextMetricsInternalA(): UNICODE->ASCII conv error \n");
  2822. cjRet = 0;
  2823. goto GOTMA_clean_up;
  2824. }
  2825. // Store string offset in return structure.
  2826. potma->otmpFullName = (PSTR) dpString;
  2827. //Sundown: safe to truncate ULONG
  2828. cjRet = (ULONG)dpStringEnd;
  2829. ASSERTGDI(cjRet == cjotma, "gdi32!GetOTMA: cjRet != dpStringEnd\n");
  2830. }
  2831. GOTMA_clean_up:
  2832. // Free temporary buffer.
  2833. LOCALFREE(potmwTmp);
  2834. // Fixup size field.
  2835. if (cjCopy >= sizeof(UINT)) // if it is possible to store otmSize
  2836. potma->otmSize = cjRet;
  2837. // Successful, so return size.
  2838. return (cjRet);
  2839. }
  2840. /******************************Public*Routine******************************\
  2841. * GetOutlineTextMetricsA
  2842. *
  2843. * Client side stub to GreGetOutlineTextMetrics.
  2844. *
  2845. * History:
  2846. * Tue 02-Nov-1993 -by- Bodin Dresevic [BodinD]
  2847. \**************************************************************************/
  2848. UINT APIENTRY GetOutlineTextMetricsA (
  2849. HDC hdc,
  2850. UINT cjCopy,
  2851. LPOUTLINETEXTMETRICA potma
  2852. )
  2853. {
  2854. return GetOutlineTextMetricsInternalA(hdc, cjCopy, potma);
  2855. }
  2856. /******************************Public*Routine******************************\
  2857. * *
  2858. * GetKerningPairs *
  2859. * *
  2860. * History: *
  2861. * Sun 23-Feb-1992 09:48:55 by Kirk Olynyk [kirko] *
  2862. * Wrote it. *
  2863. \**************************************************************************/
  2864. DWORD APIENTRY
  2865. GetKerningPairsW(
  2866. IN HDC hdc, // handle to application's DC
  2867. IN DWORD nPairs, // max no. KERNINGPAIR to be returned
  2868. OUT LPKERNINGPAIR lpKernPair // pointer to receiving buffer
  2869. )
  2870. {
  2871. ULONG sizeofMsg;
  2872. DWORD cRet = 0;
  2873. FIXUP_HANDLE(hdc);
  2874. if (nPairs == 0 && lpKernPair != (KERNINGPAIR*) NULL)
  2875. {
  2876. GdiSetLastError(ERROR_INVALID_PARAMETER);
  2877. return(0);
  2878. }
  2879. cRet = NtGdiGetKerningPairs(
  2880. hdc,
  2881. nPairs,
  2882. lpKernPair);
  2883. return(cRet);
  2884. }
  2885. /******************************Public*Routine******************************\
  2886. * GetKerningPairsA
  2887. *
  2888. * filters out pairs that are not contained in the code page of the font
  2889. * selected in DC
  2890. *
  2891. * History:
  2892. * 14-Mar-1996 -by- Xudong Wu [TessieW]
  2893. * Wrote it.
  2894. \**************************************************************************/
  2895. DWORD APIENTRY GetKerningPairsA
  2896. (
  2897. HDC hdc, // handle to application's DC
  2898. DWORD nPairs, // max no. KERNINGPAIR to be returned
  2899. LPKERNINGPAIR lpKernPair // pointer to receiving buffer
  2900. )
  2901. {
  2902. #define MAXKERNPAIR 300
  2903. DWORD i;
  2904. DWORD dwCP;
  2905. KERNINGPAIR tmpKernPair[MAXKERNPAIR];
  2906. DWORD cRet, cRet1;
  2907. KERNINGPAIR *pkp, *pkrn;
  2908. KERNINGPAIR UNALIGNED *pkrnLast;
  2909. BOOL bDBCS;
  2910. FIXUP_HANDLE(hdc);
  2911. if ((nPairs == 0) && (lpKernPair != (KERNINGPAIR*) NULL))
  2912. {
  2913. GdiSetLastError(ERROR_INVALID_PARAMETER);
  2914. return(0);
  2915. }
  2916. cRet = NtGdiGetKerningPairs(hdc, 0, NULL);
  2917. if (cRet == 0)
  2918. return(cRet);
  2919. if (cRet <= MAXKERNPAIR)
  2920. pkrn = tmpKernPair;
  2921. else
  2922. pkrn = LOCALALLOC(cRet * sizeof(KERNINGPAIR));
  2923. if (!pkrn)
  2924. {
  2925. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  2926. return 0;
  2927. }
  2928. cRet1 = NtGdiGetKerningPairs(hdc, cRet, pkrn);
  2929. if (cRet1 == 0 || cRet1 != cRet)
  2930. {
  2931. ASSERTGDI(FALSE, "NtGdiGetKerningPairs returns different values\n");
  2932. cRet = 0;
  2933. goto Cleanup;
  2934. }
  2935. pkp = pkrn;
  2936. pkrnLast = lpKernPair;
  2937. cRet = 0;
  2938. // GDI has returned iFirst and iSecond of the KERNINGPAIR structure in Unicode
  2939. // It is at this point that we translate them to the current code page
  2940. dwCP = GetCodePage(hdc);
  2941. bDBCS = IS_ANY_DBCS_CODEPAGE(dwCP);
  2942. for (i = 0; i < cRet1; i++,pkp++)
  2943. {
  2944. UCHAR ach[2], ach2[2];
  2945. BOOL bUsedDef[2];
  2946. ach[0] = ach[1] = 0; // insure zero extension
  2947. WideCharToMultiByte(dwCP,
  2948. 0,
  2949. &(pkp->wFirst),
  2950. 1,
  2951. ach,
  2952. sizeof(ach),
  2953. NULL,
  2954. &bUsedDef[0]);
  2955. if (!bUsedDef[0])
  2956. {
  2957. ach2[0] = ach2[1] = 0;
  2958. WideCharToMultiByte(dwCP,
  2959. 0,
  2960. &(pkp->wSecond),
  2961. 1,
  2962. ach2,
  2963. sizeof(ach2),
  2964. NULL,
  2965. &bUsedDef[1]);
  2966. if (!bUsedDef[1])
  2967. {
  2968. if (lpKernPair)
  2969. {
  2970. // do not overwrite the end of the buffer if it is provided
  2971. if (cRet >= nPairs)
  2972. break;
  2973. if (bDBCS)
  2974. {
  2975. if (IsDBCSLeadByteEx(dwCP,ach[0]))
  2976. {
  2977. pkrnLast->wFirst = (WORD)(ach[0] << 8 | ach[1]);
  2978. }
  2979. else
  2980. {
  2981. pkrnLast->wFirst = ach[0];
  2982. }
  2983. if (IsDBCSLeadByteEx(dwCP,ach2[0]))
  2984. {
  2985. pkrnLast->wSecond = (WORD)(ach2[0] << 8 | ach2[1]);
  2986. }
  2987. else
  2988. {
  2989. pkrnLast->wSecond = ach2[0];
  2990. }
  2991. }
  2992. else
  2993. {
  2994. pkrnLast->wFirst = ach[0];
  2995. pkrnLast->wSecond = ach2[0];
  2996. }
  2997. pkrnLast->iKernAmount = pkp->iKernAmount;
  2998. pkrnLast++;
  2999. }
  3000. cRet++;
  3001. }
  3002. }
  3003. }
  3004. Cleanup:
  3005. if (pkrn != tmpKernPair)
  3006. LOCALFREE(pkrn);
  3007. return cRet;
  3008. }
  3009. /*****************************Public*Routine******************************\
  3010. * FixBrushOrgEx
  3011. *
  3012. * for win32s
  3013. *
  3014. * History:
  3015. * 04-Jun-1992 -by- Eric Kutter [erick]
  3016. * Wrote it.
  3017. \**************************************************************************/
  3018. BOOL FixBrushOrgEx(HDC hdc, int x, int y, LPPOINT ptl)
  3019. {
  3020. return(FALSE);
  3021. }
  3022. /******************************Public*Function*****************************\
  3023. * GetColorAdjustment
  3024. *
  3025. * Get the color adjustment data for a given DC.
  3026. *
  3027. * History:
  3028. * 07-Aug-1992 -by- Wendy Wu [wendywu]
  3029. * Wrote it.
  3030. \**************************************************************************/
  3031. BOOL APIENTRY GetColorAdjustment(HDC hdc, LPCOLORADJUSTMENT pclradj)
  3032. {
  3033. FIXUP_HANDLE(hdc);
  3034. return(NtGdiGetColorAdjustment(hdc,pclradj));
  3035. }
  3036. /******************************Public*Routine******************************\
  3037. * GetETM
  3038. *
  3039. * Aldus Escape support
  3040. *
  3041. * History:
  3042. * 20-Oct-1993 -by- Bodin Dresevic [BodinD]
  3043. * Wrote it.
  3044. \**************************************************************************/
  3045. BOOL APIENTRY GetETM (HDC hdc, EXTTEXTMETRIC * petm)
  3046. {
  3047. BOOL bRet = FALSE;
  3048. FIXUP_HANDLE(hdc);
  3049. bRet = NtGdiGetETM(hdc,petm);
  3050. // path up the number of KerningPairs to match GetKerningPairsA
  3051. if (bRet && petm)
  3052. {
  3053. petm->etmNKernPairs = (WORD)GetKerningPairsA(hdc, 0, NULL);
  3054. }
  3055. return(bRet);
  3056. }
  3057. #if 0
  3058. /****************************Public*Routine********************************\
  3059. * GetCharWidthInfo
  3060. *
  3061. * Get the lMaxNegA lMaxNegC and lMinWidthD
  3062. *
  3063. * History:
  3064. * 09-Feb-1996 -by- Xudong Wu [tessiew]
  3065. * Wrote it
  3066. \***************************************************************************/
  3067. BOOL APIENTRY GetCharWidthInfo (HDC hdc, PCHWIDTHINFO pChWidthInfo)
  3068. {
  3069. return ( NtGdiGetCharWidthInfo(hdc, pChWidthInfo) );
  3070. }
  3071. #endif
  3072. #ifdef LANGPACK
  3073. /******************************Public*Routine******************************\
  3074. *
  3075. * bGetRealizationInfoInternal
  3076. *
  3077. * Retreives the realization_info from kernel, if not cached in shared
  3078. * memory
  3079. *
  3080. * History:
  3081. * 18-Aug-1997 -by- Samer Arafeh [SamerA]
  3082. * Wrote it.
  3083. \**************************************************************************/
  3084. BOOL bGetRealizationInfoInternal(
  3085. HDC hdc,
  3086. REALIZATION_INFO *pri,
  3087. CFONT *pcf
  3088. )
  3089. {
  3090. BOOL bRet = FALSE;
  3091. if (pri)
  3092. {
  3093. // if no pcf or we havn't cached the metrics
  3094. if ((pcf == NULL) || !(pcf->fl & CFONT_CACHED_RI) || pcf->timeStamp != pGdiSharedMemory->timeStamp)
  3095. {
  3096. REALIZATION_INFO ri;
  3097. PDC_ATTR pDcAttr;
  3098. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  3099. if( pcf != NULL && (pcf->fl & CFONT_PUBLIC) )
  3100. bRet = NtGdiGetRealizationInfo(hdc,&ri, pcf->hf);
  3101. else
  3102. bRet = NtGdiGetRealizationInfo(hdc,&ri, 0);
  3103. if (bRet)
  3104. {
  3105. *pri = ri;
  3106. if (pcf && !(pcf->fl & CFONT_PUBLIC))
  3107. {
  3108. // we succeeded and we have a pcf so cache the data
  3109. pcf->ri = ri;
  3110. pcf->fl |= CFONT_CACHED_RI;
  3111. pcf->timeStamp = pGdiSharedMemory->timeStamp;
  3112. }
  3113. }
  3114. }
  3115. else
  3116. {
  3117. *pri = pcf->ri;
  3118. bRet = TRUE;
  3119. }
  3120. }
  3121. return(bRet);
  3122. }
  3123. /******************************Public*Routine******************************\
  3124. *
  3125. * GdiRealizationInfo
  3126. *
  3127. * Try retreive the RealizationInfo from shared memory
  3128. *
  3129. * History:
  3130. * 18-Aug-1997 -by- Samer Arafeh [SamerA]
  3131. * Wrote it.
  3132. \**************************************************************************/
  3133. BOOL APIENTRY GdiRealizationInfo(HDC hdc,REALIZATION_INFO *pri)
  3134. {
  3135. BOOL bRet = FALSE;
  3136. PDC_ATTR pDcAttr;
  3137. FIXUP_HANDLE(hdc);
  3138. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  3139. if (pDcAttr)
  3140. {
  3141. CFONT * pcf;
  3142. ENTERCRITICALSECTION(&semLocal);
  3143. pcf = pcfLocateCFONT(hdc,pDcAttr,0,(PVOID) NULL,0,TRUE);
  3144. bRet = bGetRealizationInfoInternal(hdc,pri,pcf);
  3145. // pcfLocateCFONT added a reference so now we need to remove it
  3146. if (pcf)
  3147. {
  3148. DEC_CFONT_REF(pcf);
  3149. }
  3150. LEAVECRITICALSECTION(&semLocal);
  3151. }
  3152. else
  3153. {
  3154. // it could a public DC -OBJECT_OWNER_PUBLIC- (in which gpGdiShareMemory[hDC].pUser=NULL)
  3155. // so let's do it the expensive way by doing the kernel-transition...
  3156. bRet = NtGdiGetRealizationInfo(hdc,pri,0);
  3157. }
  3158. return(bRet);
  3159. }
  3160. #endif