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.

552 lines
16 KiB

  1. // formerly pffobj.cxx
  2. #include "precomp.hpp"
  3. INT APIENTRY EngPlusMultiByteToWideChar(
  4. UINT CodePage,
  5. LPWSTR WideCharString,
  6. INT BytesInWideCharString,
  7. LPSTR MultiByteString,
  8. INT BytesInMultiByteString
  9. )
  10. {
  11. return MultiByteToWideChar(CodePage, 0,
  12. MultiByteString,BytesInMultiByteString,
  13. WideCharString, BytesInWideCharString/sizeof(WCHAR)
  14. );
  15. // returns zero on error
  16. }
  17. INT APIENTRY EngWideCharToMultiByte(
  18. UINT CodePage,
  19. LPWSTR WideCharString,
  20. INT BytesInWideCharString,
  21. LPSTR MultiByteString,
  22. INT BytesInMultiByteString
  23. )
  24. {
  25. return WideCharToMultiByte(
  26. CodePage, 0,
  27. WideCharString, BytesInWideCharString,
  28. MultiByteString,BytesInMultiByteString,
  29. NULL, NULL
  30. );
  31. }
  32. VOID APIENTRY EngGetCurrentCodePage(
  33. PUSHORT pOemCodePage,
  34. PUSHORT pAnsiCodePage
  35. )
  36. {
  37. *pAnsiCodePage = (USHORT) GetACP();
  38. *pOemCodePage = (USHORT) GetOEMCP();
  39. }
  40. VOID APIENTRY EngUnmapFontFileFD(
  41. ULONG_PTR iFile
  42. )
  43. {
  44. FONTFILEVIEW *pffv = (FONTFILEVIEW *)iFile;
  45. pffv->mapCount--;
  46. if ((pffv->mapCount == 0) && pffv->pvView)
  47. {
  48. if (pffv->pwszPath)
  49. {
  50. UnmapViewOfFile(pffv->pvView);
  51. pffv->pvView = NULL;
  52. }
  53. }
  54. }
  55. BOOL APIENTRY EngMapFontFileFD(
  56. ULONG_PTR iFile,
  57. PULONG *ppjBuf,
  58. ULONG *pcjBuf
  59. )
  60. {
  61. FONTFILEVIEW *pffv = (FONTFILEVIEW *)iFile;
  62. BOOL bRet = FALSE;
  63. if (pffv->mapCount)
  64. {
  65. pffv->mapCount++;
  66. if (ppjBuf)
  67. {
  68. *ppjBuf = (PULONG)pffv->pvView;
  69. }
  70. if (pcjBuf)
  71. {
  72. *pcjBuf = pffv->cjView;
  73. }
  74. return TRUE;
  75. }
  76. if (pffv->pwszPath)
  77. {
  78. HANDLE hFile;
  79. if (Globals::IsNt)
  80. {
  81. hFile = CreateFileW(pffv->pwszPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  82. }
  83. else // Windows 9x - non-Unicode
  84. {
  85. AnsiStrFromUnicode ansiPath(pffv->pwszPath);
  86. if (ansiPath.IsValid())
  87. {
  88. hFile = CreateFileA(ansiPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  89. } else {
  90. hFile = INVALID_HANDLE_VALUE;
  91. }
  92. }
  93. if (hFile != INVALID_HANDLE_VALUE)
  94. {
  95. ULARGE_INTEGER lastWriteTime;
  96. if (GetFileTime(hFile, NULL, NULL, (FILETIME *) &lastWriteTime.QuadPart) &&
  97. lastWriteTime.QuadPart == pffv->LastWriteTime.QuadPart)
  98. {
  99. *pcjBuf = GetFileSize(hFile, NULL);
  100. if (*pcjBuf != -1)
  101. {
  102. HANDLE hFileMapping = CreateFileMappingA(hFile, 0, PAGE_READONLY, 0, 0, NULL); // "mappingobject");
  103. if (hFileMapping)
  104. {
  105. *ppjBuf = (PULONG)MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
  106. if (*ppjBuf)
  107. {
  108. bRet = TRUE;
  109. pffv->pvView = *ppjBuf;
  110. pffv->cjView = *pcjBuf;
  111. pffv->mapCount = 1;
  112. }
  113. CloseHandle(hFileMapping);
  114. }
  115. }
  116. }
  117. CloseHandle(hFile);
  118. }
  119. }
  120. return bRet;
  121. }
  122. GpFontFile *LoadFontMemImage(
  123. WCHAR* fontImageName,
  124. BYTE* fontMemoryImage,
  125. INT fontImageSize
  126. )
  127. {
  128. ULONG cwc = UnicodeStringLength(fontImageName) + 1;
  129. FONTFILEVIEW *pffv;
  130. if ((pffv = (FONTFILEVIEW *)GpMalloc(sizeof(FONTFILEVIEW))) == NULL)
  131. return NULL;
  132. else
  133. {
  134. PVOID pvImage;
  135. if ((pvImage = (PVOID)GpMalloc(fontImageSize)) == NULL)
  136. {
  137. GpFree(pffv);
  138. return NULL;
  139. }
  140. GpMemcpy(pvImage, fontMemoryImage, fontImageSize);
  141. pffv->LastWriteTime.QuadPart = 0;
  142. pffv->pvView = pvImage;
  143. pffv->cjView = fontImageSize;
  144. pffv->mapCount = 1;
  145. pffv->pwszPath = NULL;
  146. return (LoadFontInternal(fontImageName, cwc, pffv, TRUE));
  147. }
  148. }
  149. GpFontFile *LoadFontFile(WCHAR *awcPath)
  150. {
  151. // convert font file name to fully qualified path
  152. ULONG cwc = UnicodeStringLength(awcPath) + 1; // for term. zero
  153. FONTFILEVIEW *pffv;
  154. HANDLE hFile;
  155. if ((pffv = (FONTFILEVIEW *)GpMalloc(sizeof(FONTFILEVIEW))) == NULL)
  156. {
  157. return NULL;
  158. }
  159. pffv->LastWriteTime.QuadPart = 0;
  160. pffv->pvView = NULL;
  161. pffv->cjView = 0;
  162. pffv->mapCount = 0;
  163. pffv->pwszPath = awcPath;
  164. if (Globals::IsNt)
  165. {
  166. hFile = CreateFileW(pffv->pwszPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  167. }
  168. else // Windows 9x - non-Unicode
  169. {
  170. AnsiStrFromUnicode ansiPath(pffv->pwszPath);
  171. if (ansiPath.IsValid())
  172. {
  173. hFile = CreateFileA(ansiPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  174. } else {
  175. hFile = INVALID_HANDLE_VALUE;
  176. }
  177. }
  178. if (hFile != INVALID_HANDLE_VALUE)
  179. {
  180. if (!(pffv->cjView = GetFileSize(hFile, NULL)))
  181. {
  182. CloseHandle(hFile);
  183. goto error;
  184. }
  185. if (!GetFileTime(hFile, NULL, NULL, (FILETIME *) &pffv->LastWriteTime.QuadPart))
  186. {
  187. CloseHandle(hFile);
  188. goto error;
  189. }
  190. CloseHandle(hFile);
  191. return (LoadFontInternal(awcPath, cwc, pffv, FALSE));
  192. }
  193. error:
  194. GpFree(pffv);
  195. return NULL;
  196. }
  197. GpFontFile *LoadFontInternal(
  198. WCHAR * awcPath,
  199. ULONG cwc,
  200. FONTFILEVIEW * pffv,
  201. BOOL bMem
  202. )
  203. {
  204. GpFontFile *pFontFile = NULL;
  205. ULONG_PTR hffNew = ttfdSemLoadFontFile(// 1, // #OF FILES
  206. (ULONG_PTR *)&pffv,
  207. (ULONG) Globals::LanguageID // for english US
  208. );
  209. if (hffNew)
  210. {
  211. ULONG cFonts = ttfdQueryNumFaces(hffNew);
  212. if (cFonts && cFonts != FD_ERROR)
  213. {
  214. ULONG cjFontFile = offsetof(GpFontFile, aulData) +
  215. cFonts * sizeof(GpFontFace) +
  216. cFonts * sizeof(ULONG_PTR) +
  217. cwc * sizeof(WCHAR);
  218. pFontFile = (GpFontFile *)GpMalloc(cjFontFile);
  219. if (!pFontFile)
  220. {
  221. ttfdSemUnloadFontFile(hffNew);
  222. if (pffv->pwszPath == NULL)
  223. GpFree(pffv->pvView);
  224. GpFree(pffv);
  225. return NULL;
  226. }
  227. pFontFile->SizeOfThis = cjFontFile;
  228. // Connect GpFontFile's sharing the same hash bucket
  229. pFontFile->SetNext(NULL);
  230. pFontFile->SetPrev(NULL);
  231. // Point family names to appropriate memory
  232. pFontFile->AllocateNameHolders(
  233. (WCHAR **)(
  234. (BYTE *)pFontFile +
  235. offsetof(GpFontFile, aulData) +
  236. cFonts * sizeof(GpFontFace)), cFonts);
  237. // pwszPathname_ points to the Unicode upper case path
  238. // name of the associated font file which is stored at the
  239. // end of the data structure.
  240. pFontFile->pwszPathname_ = (WCHAR *)((BYTE *)pFontFile +
  241. offsetof(GpFontFile, aulData) +
  242. cFonts * sizeof(ULONG_PTR) +
  243. cFonts * sizeof(GpFontFace));
  244. UnicodeStringCopy(pFontFile->pwszPathname_, awcPath);
  245. pFontFile->cwc = cwc; // total for all strings
  246. // state
  247. pFontFile->flState = 0; // state (ready to die?)
  248. pFontFile->cLoaded = 1;
  249. pFontFile->cRealizedFace = 0; // total number of RFONTs
  250. pFontFile->bRemoved = FALSE; // number of referring FontFamily objects
  251. // RFONT list
  252. pFontFile->prfaceList = NULL; // pointer to head of doubly linked list
  253. // driver information
  254. pFontFile->hff = hffNew; // font driver handle to font file, RETURNED by DrvLoadGpFontFile
  255. // identifies the font driver, it could be a printer driver as well
  256. // ULONG ulCheckSum; // checksum info used for UFI's
  257. // fonts in this file (and filename slimed in)
  258. pFontFile->cFonts = cFonts; // number of fonts (same as chpfe)
  259. pFontFile->pfv = pffv; // FILEVIEW structure, passed to DrvLoadFontFile
  260. if (pFontFile->pfv->pwszPath) // not a memory image
  261. {
  262. pFontFile->pfv->pwszPath = pFontFile->pwszPathname_;
  263. }
  264. // loop over pfe's, init the data:
  265. GpFontFace *pfe = (GpFontFace *)pFontFile->aulData;
  266. for (ULONG iFont = 0; iFont < cFonts; iFont++)
  267. {
  268. pfe[iFont].pff = pFontFile; // pointer to physical font file object
  269. pfe[iFont].iFont = iFont + 1; // index of the font for IFI or device, 1 based
  270. pfe[iFont].flPFE = 0; //!!! REVIEW carefully
  271. if ((pfe[iFont].pifi = ttfdQueryFont(hffNew, (iFont + 1), &pfe[iFont].idifi)) == NULL )
  272. {
  273. VERBOSE(("Error setting pifi for entry %d.", iFont));
  274. ttfdSemUnloadFontFile(hffNew);
  275. GpFree(pFontFile);
  276. if (pffv->pwszPath == NULL)
  277. GpFree(pffv->pvView);
  278. GpFree(pffv);
  279. return NULL;
  280. }
  281. pfe[iFont].NumGlyphs = 0;
  282. pfe[iFont].NumGlyphs = pfe[iFont].pifi->cig;
  283. pfe[iFont].cGpFontFamilyRef = 0;
  284. pfe[iFont].lfCharset = DEFAULT_CHARSET;
  285. pfe[iFont].SetSymbol(FALSE);
  286. if (pfe[iFont].InitializeImagerTables() == FALSE)
  287. {
  288. VERBOSE(("Error initializing imager tables for entry %d.", iFont));
  289. ttfdSemUnloadFontFile(hffNew);
  290. GpFree(pFontFile);
  291. if (pffv->pwszPath == NULL)
  292. GpFree(pffv->pvView);
  293. GpFree(pffv);
  294. return NULL;
  295. }
  296. // Set the font family name from the first font entry
  297. pFontFile->SetFamilyName(iFont, ((WCHAR *)(((BYTE*) pfe[iFont].pifi) + pfe[iFont].pifi->dpwszFamilyName)));
  298. }
  299. }
  300. }
  301. if (pFontFile == NULL)
  302. {
  303. if (pffv->pwszPath == NULL)
  304. GpFree(pffv->pvView);
  305. GpFree(pffv);
  306. }
  307. return pFontFile;
  308. }
  309. VOID UnloadFontFile(GpFontFile *pFontFile)
  310. {
  311. return;
  312. }
  313. /******************************Public*Routine******************************\
  314. * bMakePathNameW (PWSZ pwszDst, PWSZ pwszSrc, PWSZ *ppwszFilePart)
  315. *
  316. * Converts the filename pszSrc into a fully qualified pathname pszDst.
  317. * The parameter pszDst must point to a WCHAR buffer at least
  318. * MAX_PATH*sizeof(WCHAR) bytes in size.
  319. *
  320. * An attempt is made find the file first in the new win95 directory
  321. * %windows%\fonts (which also is the first directory in secure font path,
  322. * if one is defined) and then we do the old fashioned windows stuff
  323. * where SearchPathW searches directories in usual order
  324. *
  325. * ppwszFilePart is set to point to the last component of the pathname (i.e.,
  326. * the filename part) in pwszDst. If this is null it is ignored.
  327. *
  328. * Returns:
  329. * TRUE if sucessful, FALSE if an error occurs.
  330. *
  331. * History:
  332. * Mon 02-Oct-1995 -by- Bodin Dresevic [BodinD]
  333. * update: added font path stuff
  334. * 30-Sep-1991 -by- Gilman Wong [gilmanw]
  335. * Wrote it.
  336. \**************************************************************************/
  337. extern "C" int __cdecl
  338. HackStrncmp(
  339. const char *str1,
  340. const char *str2,
  341. size_t count
  342. ) ;
  343. BOOL MakePathName(
  344. WCHAR *dst, WCHAR *src
  345. )
  346. {
  347. WCHAR* pwszF;
  348. ULONG path_length = 0; // essential to initialize
  349. if (OSInfo::IsNT)
  350. {
  351. // ASSERTGDI(Globals::FontsDir, "gpwcFontsDir not initialized\n");
  352. // if relative path
  353. if ( (src[0] != L'\\') && !((src[1] == L':') && (src[2] == L'\\')) )
  354. {
  355. // find out if the font file is in %windir%\fonts
  356. path_length = SearchPathW(
  357. Globals::FontsDirW,
  358. src,
  359. NULL,
  360. MAX_PATH,
  361. dst,
  362. &pwszF);
  363. #ifdef DEBUG_PATH
  364. TERSE(("SPW1: pwszSrc = %ws", src));
  365. if (path_length)
  366. TERSE(("SPW1: pwszDst = %ws", dst));
  367. #endif // DEBUG_PATH
  368. }
  369. // Search for file using default windows path and return full pathname.
  370. // We will only do so if we did not already find the font in the
  371. // %windir%\fonts directory or if pswzSrc points to the full path
  372. // in which case search path is ignored
  373. if (path_length == 0)
  374. {
  375. path_length = SearchPathW (
  376. NULL,
  377. src,
  378. NULL,
  379. MAX_PATH,
  380. dst,
  381. &pwszF);
  382. #ifdef DEBUG_PATH
  383. TERSE(("SPW2: pwszSrc = %ws", src));
  384. if (path_length)
  385. TERSE(("SPW2: pwszDst = %ws", dst));
  386. #endif // DEBUG_PATH
  387. }
  388. } else {
  389. /* Windows 9x */
  390. CHAR* pwszFA;
  391. CHAR srcA[MAX_PATH];
  392. CHAR dstA[MAX_PATH];
  393. CHAR file_partA[MAX_PATH];
  394. memset(srcA, 0, sizeof(srcA));
  395. memset(dstA, 0, sizeof(dstA));
  396. memset(file_partA, 0, sizeof(file_partA));
  397. WideCharToMultiByte(CP_ACP, 0, src, UnicodeStringLength(src), srcA, MAX_PATH, 0, 0);
  398. // ASSERTGDI(Globals::FontsDir, "gpwcFontsDir not initialized\n");
  399. // if relative path
  400. if ( (srcA[0] != '\\') && !((srcA[1] == ':') && (srcA[2] == '\\')) )
  401. {
  402. // find out if the font file is in %windir%\fonts
  403. path_length = SearchPathA(
  404. Globals::FontsDirA,
  405. srcA,
  406. NULL,
  407. MAX_PATH,
  408. dstA,
  409. (char**)&pwszFA);
  410. }
  411. // Search for file using default windows path and return full pathname.
  412. // We will only do so if we did not already find the font in the
  413. // %windir%\fonts directory or if pswzSrc points to the full path
  414. // in which case search path is ignored
  415. if (path_length == 0)
  416. {
  417. path_length = SearchPathA (
  418. NULL,
  419. srcA,
  420. NULL,
  421. MAX_PATH,
  422. dstA,
  423. &pwszFA);
  424. #ifdef DEBUG_PATH
  425. TERSE(("SPW2: pwszSrc = %ws", src));
  426. if (path_length)
  427. TERSE(("SPW2: pwszDst = %ws", dst));
  428. #endif // DEBUG_PATH
  429. }
  430. MultiByteToWideChar(CP_ACP, 0, dstA, strlen(dstA), dst, MAX_PATH);
  431. dst[path_length] = 0; /* null termination */
  432. }
  433. // If search was successful return TRUE:
  434. return (path_length != 0);
  435. }