|
|
1.1 root 1: //--------------------------------------------------------------------------
2: //
3: // Module Name: FONTINST.C
4: //
5: // Brief Description: This module contains the PostScript font installer
6: // for Windows NT, and supporting routines.
7: //
8: // Author: Kent Settle (kentse)
9: // Created: 09-Jan-1992
10: //
11: // Copyright (c) 1991-1992 Microsoft Corporation
12: //--------------------------------------------------------------------------
13:
14: #include <stddef.h>
15: #include <stdlib.h>
16: #include <string.h>
17: #include "pscript.h"
18: #include <winspool.h>
19: #include "dlgdefs.h"
20: #include "pscrptui.h"
21: #include "help.h"
22:
23: extern PVOID MapFile(PWSTR);
24: extern BOOL CreatePFMFromAFM(PWSTR, PWSTR);
25: extern LPWSTR GetDriverDirectory(HANDLE);
26:
27: // declarations of routines defined within this module.
28:
29: BOOL InsertInstalledFont(HWND, PWSTR);
30: BOOL InsertNewFont(HWND, PWSTR);
31: PSTR LocateKeyword(PSTR, PSTR);
32: BOOL ExtractFullName(PSTR, PSTR);
33: BOOL ExtractFontName(PSZ, PSZ);
34: BOOL PFBToPFA(PWSTR, PWSTR);
35: BOOL LocateFile(HWND, PWSTR, int, WIN32_FIND_DATA *, HANDLE *);
36:
37: // global Data
38:
39: WCHAR wstrFontInstDir[MAX_PATH];
40: DWORD cInstalledFonts, cNewFonts;
41:
42:
43: //--------------------------------------------------------------------------
44: // BOOL APIENTRY FontInstDlgProc (HWND hwnd, UINT message, DWORD wParam,
45: // LONG lParam)
46: //
47: // This function processes messages for the "About" dialog box.
48: //
49: // Returns:
50: // This function returns TRUE if successful, FALSE otherwise.
51: //
52: // History:
53: // 06-Dec-1991 -by- Kent Settle (kentse)
54: // Wrote it.
55: //--------------------------------------------------------------------------
56:
57: LONG APIENTRY FontInstDlgProc (HWND hwnd, UINT message, DWORD wParam,
58: LONG lParam)
59: {
60: WCHAR wcbuf[MAX_PATH], wcbuftmp[MAX_PATH];
61: WCHAR wstringbuf[512];
62: HANDLE hFile;
63: WIN32_FIND_DATA FileFindData;
64: PRINTDATA *pdata;
65: DWORD cwBuf, i;
66: PWSTR pwstrPath;
67: HCURSOR hCursor;
68: BOOL bFound;
69: DWORD cToAdd, cToDelete, cSave;
70: int *pEntries, *pSave;
71: int iSelect;
72: LONG index;
73: PWSTR pwstrPFAFile;
74: PWSTR pwstrPFBFile;
75: PWSTR pwstrAFMFile;
76: PWSTR pwstrPFMFile;
77: PWSTR pwstrSave;
78: BOOL bAllAFMs;
79: BYTE *pjbitarray;
80: LPWSTR pDriverDirectory;
81:
82:
83: UNREFERENCED_PARAMETER (lParam);
84:
85: switch (message)
86: {
87: case WM_INITDIALOG:
88: // fill in the default source for new softfonts.
89:
90: SendDlgItemMessage (hwnd, IDD_NEW_FONT_DIR_EDIT_BOX, EM_LIMITTEXT,
91: MAX_PATH, 0);
92: LoadString(hModule, (IDS_DEFAULT_FONT_DIR + STRING_BASE),
93: wstringbuf, (sizeof(wstringbuf) / 2));
94: SetDlgItemText(hwnd, IDD_NEW_FONT_DIR_EDIT_BOX, wstringbuf);
95:
96: // reset the content of the new soft fonts and the installed
97: // soft fonts list boxes.
98:
99: SendDlgItemMessage (hwnd, IDD_NEW_FONT_LIST_BOX, LB_RESETCONTENT,
100: 0, 0);
101: SendDlgItemMessage (hwnd, IDD_INSTALLED_LIST_BOX, LB_RESETCONTENT,
102: 0, 0);
103:
104: // call the spooler to get the fully qualified path to search
105: // for installed fonts.
106:
107: pdata = (PRINTDATA *)lParam;
108:
109: // save the PRINTDATA.
110:
111: SetWindowLong(hwnd, GWL_USERDATA, lParam);
112:
113: // copy the fully qualified path name of the data file into
114: // local buffer. extract the directory name, as this is the
115: // same directory font files will go into.
116:
117: if (!(pDriverDirectory = GetDriverDirectory(pdata->hPrinter)))
118: {
119: RIP("PSCRPTUI!FontInstDialogProc: GetDriverDirectory failed.\n");
120: return(FALSE);
121: }
122:
123: wcsncpy(wcbuf, pDriverDirectory, (sizeof(wcbuf) / sizeof(WCHAR)));
124:
125: LocalFree(pDriverDirectory);
126:
127: // add a backslash to the end of the subdirectory.
128:
129: pwstrPath = wcbuf;
130: pwstrPath += wcslen(wcbuf);
131:
132: *pwstrPath++ = '\\';
133: *pwstrPath = '\0';
134:
135: // save a copy of the data file subdirectory for later use.
136:
137: wcsncpy(wstrFontInstDir, wcbuf, (sizeof(wstrFontInstDir) /
138: sizeof(WCHAR)));
139:
140: // append *.PFM to qualified path.
141:
142: LoadString(hModule, (IDS_ALL_PFM_FILES + STRING_BASE),
143: wstringbuf, (sizeof(wstringbuf) / sizeof(WCHAR)));
144:
145: cwBuf = wcslen(wstrFontInstDir);
146:
147: wcsncat(wcbuf, wstringbuf, (sizeof(wcbuf) / sizeof(WCHAR)) - cwBuf);
148:
149: // see if there are any installed fonts.
150:
151: cInstalledFonts = 0;
152: cNewFonts = 0;
153:
154: hFile = FindFirstFile(wcbuf, &FileFindData);
155:
156: if (hFile != (HANDLE)-1)
157: {
158: // we have at least one installed font. search for all the
159: // font files, inserting them into the list box.
160: // this could take a while, so set the cursor to the hourglass.
161:
162: hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
163:
164: // we could be putting several entries into the list box,
165: // and it would look bad to redraw after each one, so turn
166: // off redrawing until we are done.
167:
168: SendMessage(hwnd, WM_SETREDRAW, FALSE, 0L);
169:
170: // insert each font name found into the installed fonts
171: // list box.
172:
173: bFound = TRUE;
174:
175: while(bFound)
176: {
177: // create the fully qualified path name of the .PFA file to open.
178:
179: wcsncpy(wcbuf, wstrFontInstDir, (sizeof(wcbuf) / 2));
180: wcsncat(wcbuf, (PWSTR)FileFindData.cFileName,
181: (sizeof(wcbuf) / 2) - cwBuf);
182:
183: // put exception handling around this in case the network
184: // goes down in the middle of this.
185:
186: try
187: {
188: InsertInstalledFont(hwnd, wcbuf);
189: }
190: except (EXCEPTION_EXECUTE_HANDLER)
191: {
192: LoadString(hModule,
193: (IDS_NETWORK_GONE + STRING_BASE),
194: wstringbuf, (sizeof(wstringbuf) / 2));
195:
196: MessageBox(hwnd, wstringbuf, NULL, MB_ICONSTOP | MB_OK);
197:
198: return (FALSE);
199: }
200:
201: cInstalledFonts++;
202:
203: bFound = FindNextFile(hFile, &FileFindData);
204: }
205:
206: // now that we are done, turn on redrawing.
207:
208: SendMessage (hwnd, WM_SETREDRAW, TRUE, 0L);
209: InvalidateRect (hwnd, NULL, TRUE);
210:
211: // reset the cursor shape to what is was.
212:
213: SetCursor(hCursor);
214: }
215:
216: if ((hFile == (HANDLE)-1) || (cInstalledFonts == 0))
217: {
218: // there are no installed soft fonts.
219:
220: LoadString(hModule, (IDS_NO_INSTALLED + STRING_BASE),
221: wstringbuf, (sizeof(wstringbuf) / 2));
222:
223: SendDlgItemMessage (hwnd, IDD_INSTALLED_LIST_BOX, LB_ADDSTRING,
224: 0, (LONG)wstringbuf);
225: }
226:
227: // disable the delete pushbutton.
228:
229: EnableWindow(GetDlgItem(hwnd, IDD_DELETE_BUTTON), FALSE);
230:
231: // free up file finding resources.
232:
233: FindClose(hFile);
234:
235: // disable the add pushbutton until someone actually has
236: // opened some font files.
237:
238: EnableWindow(GetDlgItem(hwnd, IDD_ADD_BUTTON), FALSE);
239:
240: // intialize the help stuff.
241:
242: vHelpInit();
243:
244: // disable some stuff if the user does not have
245: // permission to change anything.
246:
247: if (!pdata->bPermission)
248: {
249: EnableWindow(GetDlgItem(hwnd, IDD_OPEN_BUTTON), FALSE);
250: EnableWindow(GetDlgItem(hwnd, IDD_NEW_FONT_LIST_BOX), FALSE);
251: EnableWindow(GetDlgItem(hwnd, IDD_NEW_FONT_DIR_EDIT_BOX), FALSE);
252: }
253:
254: return (TRUE);
255:
256: case WM_COMMAND:
257: pdata = (PRINTDATA *)GetWindowLong(hwnd, GWL_USERDATA);
258:
259: switch (LOWORD(wParam))
260: {
261: case IDD_OPEN_BUTTON:
262: // this could take a while, so set the cursor to the hourglass.
263:
264: hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
265:
266: // get the supposed path to the new soft fonts provided
267: // by the user.
268:
269: cwBuf = GetDlgItemText(hwnd, IDD_NEW_FONT_DIR_EDIT_BOX,
270: wcbuf, (sizeof(wcbuf) / 2));
271:
272: // check to see if it has trailing backslash, and add
273: // it if not.
274:
275: pwstrPath = wcbuf + cwBuf - 1;
276:
277: if (*pwstrPath != '\\')
278: {
279: pwstrPath++;
280: *pwstrPath = '\\';
281: cwBuf++;
282: }
283:
284: pwstrPath++;
285: *pwstrPath = '\0';
286:
287: // save a copy of the path to the source for later use.
288:
289: wcsncpy(wcbuftmp, wcbuf, (sizeof(wcbuftmp) / 2));
290:
291: // now that we have the source directory, concat "*.PFB"
292: // to it.
293:
294: LoadString(hModule, (IDS_ALL_PFB_FILES + STRING_BASE),
295: wstringbuf, (sizeof(wstringbuf) / 2));
296:
297: wcsncat(wcbuf, wstringbuf, (sizeof(wcbuf) / 2) - cwBuf);
298:
299: // find the .PFB files.
300:
301: if (!LocateFile(hwnd, wcbuf, IDS_PFB_NOT_FOUND,
302: &FileFindData, &hFile))
303: {
304: SetCursor(hCursor);
305: return(FALSE);
306: }
307:
308: // we could be putting several entries into the list box,
309: // and it would look bad to redraw after each one, so turn
310: // off redrawing until we are done.
311:
312: SendMessage(hwnd, WM_SETREDRAW, FALSE, 0L);
313:
314: bFound = TRUE;
315:
316: cwBuf = wcslen(wcbuftmp);
317:
318: while(bFound)
319: {
320: // create the fully qualified path name of the .PFB file to open.
321:
322: wcsncpy(wcbuf, wcbuftmp, (sizeof(wcbuf) / 2));
323: wcsncat(wcbuf, (PWSTR)FileFindData.cFileName,
324: (sizeof(wcbuf) / 2) - cwBuf);
325:
326: InsertNewFont(hwnd, wcbuf);
327: cNewFonts++;
328:
329: bFound = FindNextFile(hFile, &FileFindData);
330: }
331:
332: // free up file finding resources.
333:
334: FindClose(hFile);
335:
336: // reset the cursor shape to what it was.
337:
338: SetCursor(hCursor);
339:
340: // now that we are done, turn on redrawing.
341:
342: SendMessage (hwnd, WM_SETREDRAW, TRUE, 0L);
343: InvalidateRect (hwnd, NULL, TRUE);
344:
345: return(TRUE);
346:
347: case IDD_ADD_BUTTON:
348: // first see how many entries have been selected in
349: // the new fonts list box.
350:
351: cToAdd = SendDlgItemMessage(hwnd, IDD_NEW_FONT_LIST_BOX,
352: LB_GETSELCOUNT, 0, 0);
353:
354: // nothing to do if no entries selected.
355:
356: if (cToAdd == 0)
357: return(TRUE); //!!! maybe a message box? - kentse.
358:
359: // first find the .PFB files.
360:
361: // get the supposed path to the new soft fonts provided
362: // by the user.
363:
364: cwBuf = GetDlgItemText(hwnd, IDD_NEW_FONT_DIR_EDIT_BOX,
365: wcbuf, (sizeof(wcbuf) / 2));
366:
367: // check to see if it has trailing backslash, and add
368: // it if not.
369:
370: pwstrPath = wcbuf + cwBuf - 1;
371:
372: if (*pwstrPath != '\\')
373: {
374: pwstrPath++;
375: *pwstrPath = '\\';
376: cwBuf++;
377: }
378:
379: pwstrPath++;
380: *pwstrPath = '\0';
381:
382: // save a copy of the path to the source for later use.
383:
384: wcsncpy(wcbuftmp, wcbuf, (sizeof(wcbuftmp) / 2));
385:
386: // now that we have the source directory, concat "*.AFM"
387: // to it.
388:
389: LoadString(hModule, (IDS_ALL_PFB_FILES + STRING_BASE),
390: wstringbuf, (sizeof(wstringbuf) / 2));
391:
392: wcsncat(wcbuf, wstringbuf, (sizeof(wcbuf) / 2) - cwBuf);
393:
394: if (!LocateFile(hwnd, wcbuf, IDS_PFB_NOT_FOUND,
395: &FileFindData, &hFile))
396: return(FALSE);
397:
398: // this could take a while, so set the cursor to the hourglass.
399:
400: hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
401:
402: // save the count of new fonts to add.
403:
404: cSave = cToAdd;
405:
406: // get the list of selected entries.
407:
408: if (!(pEntries = (int *)LocalAlloc(LPTR, cToAdd * sizeof(int))))
409: {
410: RIP("FontInstDlgProc: LocalAlloc for pEntries failed.\n");
411: return(FALSE);
412: }
413:
414: pSave = pEntries;
415:
416: SendDlgItemMessage(hwnd, IDD_NEW_FONT_LIST_BOX,
417: LB_GETSELITEMS, cToAdd, (DWORD)pEntries);
418:
419: // create a new .PFA file from each .PFB file.
420:
421: while(cToAdd--)
422: {
423: // get the index of the new font to add.
424:
425: index = *pEntries;
426:
427: // when each entry was added to the new fonts list
428: // box, memory was allocated to store a pointer
429: // to the corresponding .PFB filename.
430:
431: pwstrPFBFile = (PWSTR)SendDlgItemMessage(hwnd,
432: IDD_NEW_FONT_LIST_BOX,
433: LB_GETITEMDATA,
434: index, 0);
435:
436: if (pwstrPFBFile == (PWSTR)LB_ERR)
437: {
438: RIP("FontInstDlgProc: LB_GETITEMDATA failed.");
439: LocalFree((LOCALHANDLE)pSave);
440: return(FALSE);
441: }
442:
443: // build the fully qualified pathname for the .PFA
444: // file to create.
445:
446: ASSERTPS((wcslen(wstrFontInstDir) < MAX_PATH),
447: "PSCRPTUI: wstrFontInstDir about to overrun buffer.\n");
448: wcsncpy(wcbuf, wstrFontInstDir, (sizeof(wcbuf) / 2));
449:
450: // save a pointer to the fully qualified pathname of
451: // the .PFB file.
452:
453: pwstrSave = pwstrPFBFile;
454:
455: // extract the filename itself. first, find the end
456: // of the string, then backup until we find the
457: // first '\' character.
458:
459: while (*pwstrPFBFile)
460: pwstrPFBFile++;
461:
462: while (*pwstrPFBFile != (WCHAR)'\\')
463: pwstrPFBFile--;
464:
465: pwstrPFBFile++;
466:
467: // pwstrPFBFile now points to the filename itself, so
468: // concat it with the directory.
469:
470: cwBuf = wcslen(wcbuf);
471:
472: wcsncat(wcbuf, pwstrPFBFile, (sizeof(wcbuf) / 2) - cwBuf);
473: pwstrPFBFile = pwstrSave;
474:
475: // now change the .PFB to .PFA.
476:
477: pwstrPFAFile = wcbuf;
478:
479: while (*pwstrPFAFile)
480: pwstrPFAFile++;
481:
482: // back up to the 'B', and overwrite it with 'A'.
483:
484: pwstrPFAFile--;
485: *pwstrPFAFile = (WCHAR)'A';
486:
487: // reset pointer back to start of fully qualified
488: // pathname.
489:
490: pwstrPFAFile = wcbuf;
491:
492: // create a .PFA file from the .PFB file.
493:
494: // put exception handling around this in case the
495: // networks goes down in the middle of this.
496:
497: try
498: {
499: if (!PFBToPFA(pwstrPFAFile, pwstrPFBFile))
500: return(FALSE);
501: }
502: except (EXCEPTION_EXECUTE_HANDLER)
503: {
504: LoadString(hModule,
505: (IDS_NETWORK_GONE + STRING_BASE),
506: wstringbuf, (sizeof(wstringbuf) / 2));
507:
508: MessageBox(hwnd, wstringbuf, NULL, MB_ICONSTOP | MB_OK);
509: return (FALSE);
510: }
511:
512: // get ready for next selected entry.
513:
514: pEntries++;
515: }
516:
517: // now that we have created the .PFA files from the .PFB
518: // files, it is time to create the .PFM file from the
519: // .AFM and .PFA files.
520:
521: // first find the .AFM files.
522:
523: // get the supposed path to the new soft fonts provided
524: // by the user.
525:
526: cwBuf = GetDlgItemText(hwnd, IDD_NEW_FONT_DIR_EDIT_BOX,
527: wcbuf, (sizeof(wcbuf) / 2));
528:
529: // check to see if it has trailing backslash, and add
530: // it if not.
531:
532: pwstrPath = wcbuf + cwBuf - 1;
533:
534: if (*pwstrPath != (WCHAR)'\\')
535: {
536: pwstrPath++;
537: *pwstrPath = (WCHAR)'\\';
538: cwBuf++;
539: }
540:
541: pwstrPath++;
542: *pwstrPath = (WCHAR)'\0';
543:
544: // save a copy of the path to the source for later use.
545:
546: wcsncpy(wcbuftmp, wcbuf, (sizeof(wcbuftmp) / 2));
547:
548: // now that we have the source directory, concat "*.AFM"
549: // to it.
550:
551: LoadString(hModule, (IDS_ALL_AFM_FILES + STRING_BASE),
552: wstringbuf, (sizeof(wstringbuf) / 2));
553:
554: wcsncat(wcbuf, wstringbuf, (sizeof(wcbuf) / 2) - cwBuf);
555:
556: if (!LocateFile(hwnd, wcbuf, IDS_AFM_NOT_FOUND,
557: &FileFindData, &hFile))
558: {
559: SetCursor(hCursor);
560: return(FALSE);
561: }
562:
563: // reset values to deal with .AFM files.
564:
565: cToAdd = cSave;
566: pEntries = pSave;
567:
568: // indicate we have not found all the .AFM files.
569:
570: bAllAFMs = FALSE;
571:
572: // allocate a bit array to keep track of which
573: // .AFM files have been found.
574:
575: pjbitarray = (BYTE *)LocalAlloc(LPTR, (cToAdd + 7) / 8);
576:
577: if (!pjbitarray)
578: {
579: RIP("PSCRPTUI!IDD_ADD_BUTTON: LocalAlloc for pjbitarray failed.\n");
580: SetCursor(hCursor);
581: return(FALSE);
582: }
583:
584: // initialize all bits to zero.
585:
586: memset((PVOID)pjbitarray, 0, (cToAdd + 7) / 8);
587:
588: // create a new .PFM file from each .AFM file and delete
589: // it's entry from the new fonts list box.
590:
591: while(!bAllAFMs)
592: {
593: // reset pointer.
594:
595: pEntries = pSave;
596:
597: for (i = 0; i < cToAdd; i++)
598: {
599: // check the bit in the bit array to see if
600: // this font is already installed.
601:
602: if ((BYTE)pjbitarray[i >> 3] & (BYTE)(1 << (i & 0x07)))
603: {
604: pEntries++;
605: continue;
606: }
607:
608: // get the index of the new font to add.
609:
610: index = *pEntries;
611:
612: // get the name of the new font to add.
613:
614: cwBuf = SendDlgItemMessage(hwnd, IDD_NEW_FONT_LIST_BOX,
615: LB_GETTEXT, index,
616: (DWORD)wcbuftmp);
617:
618: if (cwBuf == LB_ERR)
619: {
620: RIP("FontInstDlgProc: LB_GETTEXT failed.");
621: LocalFree((LOCALHANDLE)pSave);
622: return(FALSE);
623: }
624:
625: // when each entry was added to the new fonts list
626: // box, memory was allocated to store a pointer
627: // to the corresponding .PFB filename. get that
628: // pointer and create a pointer to .AFM filename.
629:
630: pwstrAFMFile = (PWSTR)SendDlgItemMessage(hwnd,
631: IDD_NEW_FONT_LIST_BOX,
632: LB_GETITEMDATA,
633: index, 0);
634:
635: if (pwstrAFMFile == (PWSTR)LB_ERR)
636: {
637: RIP("FontInstDlgProc: LB_GETITEMDATA failed.");
638: LocalFree((LOCALHANDLE)pSave);
639: return(FALSE);
640: }
641:
642: // save pointer to string.
643:
644: pwstrSave = pwstrAFMFile;
645:
646: // pwstrAFMFile is actually pointing to the .PFB
647: // filename. so overwrite the .PFB with .AFM.
648:
649: while (*pwstrAFMFile)
650: pwstrAFMFile++;
651:
652: // backup and overwrite PFB with AFM.
653:
654: pwstrAFMFile -= 3;
655: *pwstrAFMFile++ = (WCHAR)'A';
656: *pwstrAFMFile++ = (WCHAR)'F';
657: *pwstrAFMFile = (WCHAR)'M';
658:
659: // reset pointer to beginning of string.
660:
661: pwstrAFMFile = pwstrSave;
662:
663: // build the fully qualified pathname for the .PFM
664: // file to create.
665:
666: ASSERTPS((wcslen(wstrFontInstDir) < MAX_PATH),
667: "PSCRPTUI: wstrFontInstDir about to overrun buffer.\n");
668: wcsncpy(wcbuf, wstrFontInstDir, (sizeof(wcbuf) / 2));
669:
670: // save a pointer to the fully qualified pathname of
671: // the .AFM file.
672:
673: pwstrSave = pwstrAFMFile;
674:
675: // extract the filename itself. first, find the end
676: // of the string, then backup until we find the
677: // first '\' character.
678:
679: while (*pwstrAFMFile)
680: pwstrAFMFile++;
681:
682: while (*pwstrAFMFile != '\\')
683: pwstrAFMFile--;
684:
685: pwstrAFMFile++;
686:
687: // pwstrAFMFile now points to the filename itself, so
688: // concat it with the directory.
689:
690: cwBuf = wcslen(wcbuf);
691:
692: wcsncat(wcbuf, pwstrAFMFile, (sizeof(wcbuf) / 2) - cwBuf);
693: pwstrAFMFile = pwstrSave;
694:
695: // now change the .AFM to .PFM.
696:
697: pwstrPFMFile = wcbuf;
698:
699: while (*pwstrPFMFile)
700: pwstrPFMFile++;
701:
702: // back up to the 'A', and overwrite it with 'P'.
703:
704: pwstrPFMFile -= 3;
705: *pwstrPFMFile = (WCHAR)'P';
706:
707: // reset pointer back to start of fully qualified
708: // pathname.
709:
710: pwstrPFMFile = wcbuf;
711:
712: // create a .PFM file from the .AFM file. if
713: // this fails, it is most like due to the fact
714: // that this .AFM file is on another disk. so,
715: // just go to the next one for now.
716:
717: if (!CreatePFMFromAFM(pwstrAFMFile, pwstrPFMFile))
718: {
719: pEntries++;
720: continue;
721: }
722:
723: // we have now created both the and .PFM file
724: // for this font. we now know that there is at least
725: // one font installed, so check to see if this is
726: // this first one. if so, delete the no installed
727: // fonts entry from the list box.
728:
729: if (cInstalledFonts == 0)
730: SendDlgItemMessage(hwnd, IDD_INSTALLED_LIST_BOX,
731: LB_RESETCONTENT, 0, 0);
732:
733: // associate the pointer to the .PFA file name with it.
734: // remember, we allocated memory for pwstrPFBFile when this
735: // font file was opened. free that memory now.
736:
737: LocalFree((LOCALHANDLE)pwstrAFMFile);
738:
739: // allocate memory to store away the .PFM filename.
740:
741: if (!(pwstrPFMFile = (PWSTR)LocalAlloc(LPTR, wcslen(wcbuf) + 1)))
742: {
743: RIP("PSCRPTUI!IDD_ADD_BUTTON: LocalAlloc failed.\n");
744: return(FALSE);
745: }
746:
747: // add the font name to the installed fonts dialog box.
748:
749: index = SendDlgItemMessage(hwnd, IDD_INSTALLED_LIST_BOX,
750: LB_ADDSTRING, 0, (DWORD)wcbuftmp);
751:
752: // buf currently contains the fully qualified pathname
753: // of the PFM file.
754:
755: SendDlgItemMessage(hwnd, IDD_INSTALLED_LIST_BOX,
756: LB_SETITEMDATA, index,
757: (DWORD)pwstrPFMFile);
758:
759: // adjust the counters.
760:
761: cNewFonts--;
762: cInstalledFonts++;
763:
764: // set the bit in the bit array for this
765: // installed font.
766:
767: (BYTE)pjbitarray[i >> 3] |= (BYTE)(1 << (i & 0x07));
768:
769: // get ready for next selected entry.
770:
771: pEntries++;
772: }
773:
774: // see if we have found all the .AFM files.
775:
776: bAllAFMs = TRUE;
777:
778: for (i = 0; i < cToAdd; i++)
779: {
780: if (!((BYTE)pjbitarray[i >> 3] & (BYTE)(1 << (i & 0x07))))
781: {
782: bAllAFMs = FALSE;
783: break;
784: }
785: }
786:
787: // pop up a message box if we have not yet found
788: // all the .AFM files.
789:
790: if (!bAllAFMs)
791: {
792: LoadString(hModule,
793: (IDS_MORE_AFMS_NEEDED + STRING_BASE),
794: wstringbuf, (sizeof(wstringbuf) / 2));
795:
796: iSelect = MessageBox(hwnd, wstringbuf, NULL,
797: MB_ICONSTOP | MB_OKCANCEL);
798:
799: if (iSelect == IDCANCEL)
800: bAllAFMs = TRUE;
801: }
802: }
803:
804: // go backwards through the list, removing each
805: // item from the new fonts list box.
806:
807: pEntries--;
808:
809: while (cSave--)
810: {
811: // get the index of the new font to delete.
812:
813: index = *pEntries;
814:
815: // delete the entry from the new font list box.
816:
817: SendDlgItemMessage(hwnd, IDD_NEW_FONT_LIST_BOX,
818: LB_DELETESTRING, index, 0);
819:
820: pEntries--;
821: }
822:
823: // we just added all the selected fonts, therefore,
824: // there are no fonts selected to add.
825:
826: EnableWindow(GetDlgItem(hwnd, IDD_ADD_BUTTON), FALSE);
827:
828: // reset the cursor shape to what it was.
829:
830: SetCursor(hCursor);
831:
832: // now that we are done, turn on redrawing.
833:
834: SendMessage (hwnd, WM_SETREDRAW, TRUE, 0L);
835: InvalidateRect (hwnd, NULL, TRUE);
836:
837: // free up memory.
838:
839: LocalFree((LOCALHANDLE)pSave);
840: LocalFree((LOCALHANDLE)pjbitarray);
841:
842: return(TRUE);
843:
844: case IDD_DELETE_BUTTON:
845: // first see how many entries have been selected in
846: // the installed fonts list box.
847:
848: cToDelete = SendDlgItemMessage(hwnd, IDD_INSTALLED_LIST_BOX,
849: LB_GETSELCOUNT, 0, 0);
850:
851: // nothing to do if no entries selected.
852:
853: if (cToDelete == 0)
854: return(TRUE); //!!! maybe a message box? - kentse.
855:
856: // this could take a while, so set the cursor to the hourglass.
857:
858: hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
859:
860: // save the count.
861:
862: cSave = cToDelete;
863:
864: // get the list of selected entries.
865:
866: if (!(pEntries = (int *)LocalAlloc(LPTR, cToDelete * sizeof(int))))
867: {
868: RIP("PSCRPTUI!IDD_DELETE_BUTTON: LocalAlloc for pEntries failed.\n");
869: return(FALSE);
870: }
871:
872: pSave = pEntries;
873:
874: iSelect = SendDlgItemMessage(hwnd, IDD_INSTALLED_LIST_BOX,
875: LB_GETSELITEMS, cToDelete,
876: (DWORD)pEntries);
877:
878: if ((iSelect != (int)cToDelete) || (iSelect == LB_ERR))
879: {
880: RIP("PSCRPTUI!IDD_DELETE_BUTTON: LB_GETSELITEMS failed.\n");
881: LocalFree((LOCALHANDLE)pEntries);
882: return(FALSE);
883: }
884:
885: while (cToDelete--)
886: {
887: // get the index of the new font to add.
888:
889: index = *pEntries;
890:
891: // when each entry was added to the installed list
892: // box, memory was allocated to store a pointer
893: // to the corresponding .PFM filename.
894:
895: pwstrPFMFile = (PWSTR)SendDlgItemMessage(hwnd,
896: IDD_INSTALLED_LIST_BOX,
897: LB_GETITEMDATA,
898: index, 0);
899:
900: if (pwstrPFMFile == (PWSTR)LB_ERR)
901: {
902: RIP("PSCRPTUI!IDD_DELETE_BUTTON: LB_GETITEMDATA failed.\n");
903: LocalFree((LOCALHANDLE)pSave);
904: return(FALSE);
905: }
906:
907: // delete the file associated with the font.
908:
909: DeleteFile(pwstrPFMFile);
910:
911: // free up memory allocated when this entry was
912: // added to the installed fonts list box.
913:
914: LocalFree((LOCALHANDLE)pwstrPFMFile);
915:
916: // update the count of installed fonts.
917:
918: cInstalledFonts--;
919:
920: // get ready for next selected entry.
921:
922: pEntries++;
923: }
924:
925: // go backwards through the list, removing each
926: // item from the new fonts list box.
927:
928: pEntries--;
929:
930: while (cSave--)
931: {
932: // get the index of the new font to delete.
933:
934: index = *pEntries;
935:
936: // delete the entry from the new font list box.
937:
938: SendDlgItemMessage(hwnd, IDD_INSTALLED_LIST_BOX,
939: LB_DELETESTRING, index, 0);
940:
941: pEntries--;
942: }
943:
944: // we just deleted all the selected fonts, therefore,
945: // there are no fonts selected to delete.
946:
947: EnableWindow(GetDlgItem(hwnd, IDD_DELETE_BUTTON), FALSE);
948:
949: // free up memory.
950:
951: LocalFree((LOCALHANDLE)pSave);
952:
953: // reset the cursor shape to what it was.
954:
955: SetCursor(hCursor);
956:
957: break;
958:
959: case IDD_NEW_FONT_LIST_BOX:
960: if (HIWORD (wParam) != LBN_SELCHANGE)
961: return (FALSE);
962:
963: // if any of the items in the list box have been selected,
964: // enable the ADD button. if non of the items are
965: // selected, disable the ADD button.
966:
967: iSelect = SendDlgItemMessage(hwnd, IDD_NEW_FONT_LIST_BOX,
968: LB_GETSELCOUNT, 0, 0);
969:
970: if (iSelect == LB_ERR)
971: return(FALSE);
972:
973: if (iSelect > 0)
974: EnableWindow(GetDlgItem(hwnd, IDD_ADD_BUTTON), TRUE);
975: else
976: EnableWindow(GetDlgItem(hwnd, IDD_ADD_BUTTON), FALSE);
977:
978: break;
979:
980: case IDD_INSTALLED_LIST_BOX:
981: if (HIWORD (wParam) != LBN_SELCHANGE)
982: return (FALSE);
983:
984: // if any of the items in the list box have been selected,
985: // enable the DELETE button. if non of the items are
986: // selected, disable the DELETE button.
987:
988: iSelect = SendDlgItemMessage(hwnd, IDD_INSTALLED_LIST_BOX,
989: LB_GETSELCOUNT, 0, 0);
990:
991: if (iSelect == LB_ERR)
992: return(FALSE);
993:
994:
995: if ((iSelect > 0) && (cInstalledFonts > 0) && pdata->bPermission)
996: EnableWindow(GetDlgItem(hwnd, IDD_DELETE_BUTTON), TRUE);
997: else
998: EnableWindow(GetDlgItem(hwnd, IDD_DELETE_BUTTON), FALSE);
999:
1000: break;
1001:
1002: case IDD_HELP_BUTTON:
1003: vShowHelp(hwnd, HELP_CONTEXT, HLP_SFONT_INSTALLER,
1004: pdata->hPrinter);
1005: return(TRUE);
1006:
1007: case IDOK:
1008: if (pdata->bPermission)
1009: {
1010: // see how many entries are left in the new fonts
1011: // list box. delete the memory allocated for each
1012: // entry.
1013:
1014: cToDelete = SendDlgItemMessage(hwnd, IDD_NEW_FONT_LIST_BOX,
1015: LB_GETCOUNT, 0, 0);
1016:
1017: for (i = 0; i < cToDelete; i++)
1018: {
1019: pwstrPFBFile = (PWSTR)SendDlgItemMessage(hwnd,
1020: IDD_NEW_FONT_LIST_BOX,
1021: LB_GETITEMDATA, i, 0);
1022:
1023: if (pwstrPFBFile == (PWSTR)LB_ERR)
1024: {
1025: RIP("PSCRPTUI!IDOK: LB_GETITEMDATA failed.");
1026: return(FALSE);
1027: }
1028:
1029: LocalFree((LOCALHANDLE)pwstrPFBFile);
1030: }
1031: }
1032:
1033: // do the same for the installed fonts list box. in this
1034: // case, the memory will have been allocated whether
1035: // the user has change permission or not.
1036:
1037: cToDelete = SendDlgItemMessage(hwnd, IDD_INSTALLED_LIST_BOX,
1038: LB_GETCOUNT, 0, 0);
1039:
1040: for (i = 0; i < cToDelete; i++)
1041: {
1042: pwstrPFMFile = (PWSTR)SendDlgItemMessage(hwnd,
1043: IDD_INSTALLED_LIST_BOX,
1044: LB_GETITEMDATA, i, 0);
1045:
1046: if (pwstrPFMFile == (PWSTR)LB_ERR)
1047: {
1048: RIP("PSCRPTUI!IDOK: LB_GETITEMDATA failed.");
1049: return(FALSE);
1050: }
1051:
1052: LocalFree((LOCALHANDLE)pwstrPFMFile);
1053: }
1054:
1055: // let the world know we may have changed the fonts.
1056:
1057: if (pdata->bPermission)
1058: {
1059: SendMessage((HWND)-1, WM_FONTCHANGE, 0, 0);
1060: }
1061:
1062: // end the dialog.
1063:
1064: EndDialog (hwnd, TRUE);
1065: return(TRUE);
1066:
1067: case IDCANCEL:
1068: EndDialog (hwnd, IDCANCEL);
1069: return(TRUE);
1070:
1071: default:
1072: return(FALSE);
1073: }
1074: break;
1075:
1076: case WM_DESTROY:
1077: // clean up any used help stuff.
1078:
1079: vHelpDone(hwnd);
1080: return (TRUE);
1081:
1082: default:
1083: return (FALSE);
1084: }
1085: return (FALSE);
1086: }
1087:
1088:
1089: //--------------------------------------------------------------------------
1090: // BOOL InsertInstalledFont(hwnd, pwstrPFMFile)
1091: // HWND hwnd;
1092: // PWSTR pwstrPFMFile;
1093: //
1094: // This function takes a pointer to the filename for a given soft font,
1095: // extracts the font name from the file, and insert that into the
1096: // Installed Fonts list box.
1097: //
1098: // Returns:
1099: // This function returns no value.
1100: //
1101: // History:
1102: // 16-Dec-1991 -by- Kent Settle (kentse)
1103: // Wrote it.
1104: //--------------------------------------------------------------------------
1105:
1106: BOOL InsertInstalledFont(hwnd, pwstrPFMFile)
1107: HWND hwnd;
1108: PWSTR pwstrPFMFile;
1109: {
1110: CHAR cbuf[128];
1111: WCHAR wcbuf[128];
1112: CHAR *pBuffer;
1113: CHAR *pSoftFont;
1114: PWSTR pwstrFileName;
1115: DWORD index;
1116: PNTFM pntfm;
1117:
1118: // open the given .PFM file.
1119:
1120: if (!(pntfm = (PNTFM)MapFile(pwstrPFMFile)))
1121: {
1122: RIP("PSCRPTUI!InsertInstalledFont: MapFile failed.\n");
1123: return(FALSE);
1124: }
1125:
1126: // when we created the .PFA file, we stuck the following font information
1127: // at the beginning of each .PFA file: "%Full Name%Font Name%".
1128: // we want to extract the Full Name and insert that into the list
1129: // box.
1130:
1131: pSoftFont = (CHAR *)pntfm + pntfm->loSoftFont;
1132:
1133: // do nothing if this .PFM file does not contain a softfont.
1134:
1135: if (!pSoftFont)
1136: {
1137: UnmapViewOfFile((PVOID)pntfm);
1138: return(TRUE);
1139: }
1140:
1141: // skip over the first '%'.
1142:
1143: pSoftFont++;
1144:
1145: // copy the font name into a local buffer.
1146:
1147: pBuffer = cbuf;
1148:
1149: while (*pSoftFont != '%')
1150: *pBuffer++ = *pSoftFont++;
1151:
1152: // don't forget the NULL terminator.
1153:
1154: *pBuffer = '\0';
1155:
1156: // reset pointer to start of Full Name of font.
1157:
1158: pBuffer = cbuf;
1159:
1160: // insert font name into Installed Fonts list box.
1161:
1162: strcpy2WChar(wcbuf, pBuffer);
1163: index = SendDlgItemMessage(hwnd, IDD_INSTALLED_LIST_BOX, LB_ADDSTRING, 0,
1164: (DWORD)wcbuf);
1165:
1166: if ((index == LB_ERR) || (index == LB_ERRSPACE))
1167: {
1168: RIP("InsertInstalledFont: LB_ADDSTRING failed.\n");
1169: UnmapViewOfFile((PVOID)pntfm);
1170: return(FALSE);
1171: }
1172:
1173: // associate a pointer to the file name with each entry in the listbox.
1174: // create local copy of file name, since the copy pwstrPFMFile will probably
1175: // no longer exist when we need to access it.
1176:
1177: if (!(pwstrFileName = (PWSTR)LocalAlloc(LPTR, (wcslen(pwstrPFMFile) + 1) * 2)))
1178: {
1179: RIP("InsertInstalledFont: LocalAlloc for pwstrFileName failed.\n");
1180: UnmapViewOfFile((PVOID)pntfm);
1181: return(FALSE);
1182: }
1183:
1184: wcsncpy(pwstrFileName, pwstrPFMFile, wcslen(pwstrPFMFile) + 1);
1185:
1186: SendDlgItemMessage(hwnd, IDD_INSTALLED_LIST_BOX, LB_SETITEMDATA, index,
1187: (DWORD)pwstrFileName);
1188:
1189: // unmap the .PFM file.
1190:
1191: UnmapViewOfFile((PVOID)pntfm);
1192:
1193: return(TRUE);
1194: }
1195:
1196:
1197: //--------------------------------------------------------------------------
1198: // BOOL InsertNewFont(hwnd, pwstrPFBFile)
1199: // HWND hwnd;
1200: // PWSTR pwstrPFBFile;
1201: //
1202: // This function takes a pointer to the filename for a given soft font,
1203: // extracts the font name from the file, and insert that into the
1204: // New Fonts list box.
1205: //
1206: // Returns:
1207: // This function returns no value.
1208: //
1209: // History:
1210: // 23-Dec-1991 -by- Kent Settle (kentse)
1211: // Wrote it.
1212: //--------------------------------------------------------------------------
1213:
1214: BOOL InsertNewFont(hwnd, pwstrPFBFile)
1215: HWND hwnd;
1216: PWSTR pwstrPFBFile;
1217: {
1218: CHAR *pBuffer;
1219: CHAR strFullName[MAX_FULLNAME];
1220: WCHAR wstrFullName[MAX_FULLNAME];
1221: PFBHEADER pfbheader;
1222: HANDLE hFile;
1223: DWORD cBytesRead, cb;
1224: BOOL bRet;
1225: DWORD dwRet;
1226: PWSTR pwstrFileName;
1227: DWORD index;
1228:
1229: // open the given .PFB file.
1230:
1231: hFile = CreateFile(pwstrPFBFile, GENERIC_READ, FILE_SHARE_READ,
1232: 0, OPEN_EXISTING, 0, 0 );
1233: if (hFile == (HANDLE)-1)
1234: {
1235: RIP("InsertNewFont: CreateFile failed.\n");
1236: return(FALSE);
1237: }
1238:
1239: // read in the PFBHEADER.
1240:
1241: if(!(bRet = ReadFile(hFile, &pfbheader, sizeof(PFBHEADER), &cBytesRead,
1242: NULL) || cBytesRead != sizeof(PFBHEADER)))
1243: {
1244: RIP("InsertNewFont: ReadFile Failed.\n");
1245: CloseHandle(hFile);
1246: return(FALSE);
1247: }
1248:
1249: // make sure we have the header.
1250:
1251: if ((pfbheader.jCheck != CHECK_BYTE) || (pfbheader.jType == EOF_TYPE))
1252: {
1253: RIP("InsertNewFont: PFB Header not found.\n");
1254: SetLastError(ERROR_INVALID_DATA);
1255: CloseHandle(hFile);
1256: return(FALSE);
1257: }
1258:
1259: // find the size of the .PFB file. allocate memory to copy into,
1260: // leaving room for terminating NULL.
1261:
1262: cb = ((DWORD)pfbheader.ushilength << 16) + pfbheader.uslolength;
1263:
1264: if (!(pBuffer = (CHAR *)LocalAlloc(LPTR, cb + 1)))
1265: {
1266: RIP("InsertNewFont: LocalAlloc failed.\n");
1267: CloseHandle(hFile);
1268: return(FALSE);
1269: }
1270:
1271: // reset the file pointer and read in the entire file.
1272:
1273: dwRet = SetFilePointer(hFile, 0, 0, FILE_BEGIN);
1274:
1275: if (dwRet == -1)
1276: {
1277: RIP("InsertNewFont: SetFilePointer failed.\n");
1278: CloseHandle(hFile);
1279: LocalFree((LOCALHANDLE)pBuffer);
1280: return(FALSE);
1281: }
1282:
1283: if(!(bRet = ReadFile(hFile, pBuffer, cb, &cBytesRead, NULL) ||
1284: cBytesRead != cb))
1285: {
1286: RIP("InsertNewFont: ReadFile Failed.\n");
1287: CloseHandle(hFile);
1288: LocalFree((LOCALHANDLE)pBuffer);
1289: return(FALSE);
1290: }
1291:
1292: // NULL terminate it for good measure.
1293:
1294: *(pBuffer + cb) = '\0';
1295:
1296: // extract the full font name from the .PFB file. it is designated
1297: // by the /FullName keyword.
1298:
1299: if (!ExtractFullName(pBuffer, strFullName))
1300: {
1301: CloseHandle(hFile);
1302: LocalFree((LOCALHANDLE)pBuffer);
1303: return(FALSE);
1304: }
1305:
1306: // insert font name into New Fonts list box.
1307:
1308: strcpy2WChar(wstrFullName, strFullName);
1309:
1310: index = SendDlgItemMessage(hwnd, IDD_NEW_FONT_LIST_BOX, LB_ADDSTRING, 0,
1311: (DWORD)wstrFullName);
1312:
1313: if ((index == LB_ERR) || (index == LB_ERRSPACE))
1314: {
1315: RIP("InsertNewFont: LB_ADDSTRING failed.\n");
1316: CloseHandle(hFile);
1317: return(FALSE);
1318: }
1319:
1320: // associate a pointer to the file name with each entry in the listbox.
1321: // create local copy of file name, since the copy pwstrPFBFile will probably
1322: // no longer exist when we need to access it.
1323:
1324: if (!(pwstrFileName = (PWSTR)LocalAlloc(LPTR, (wcslen(pwstrPFBFile) + 1) * 2)))
1325: {
1326: RIP("InsertNewFont: LocalAlloc for pwstrFileName failed.\n");
1327: CloseHandle(hFile);
1328: return(FALSE);
1329: }
1330:
1331: wcsncpy(pwstrFileName, pwstrPFBFile, wcslen(pwstrPFBFile) + 1);
1332:
1333: SendDlgItemMessage(hwnd, IDD_NEW_FONT_LIST_BOX, LB_SETITEMDATA, index,
1334: (DWORD)pwstrFileName);
1335:
1336: // free up memory.
1337:
1338: LocalFree((LOCALHANDLE)pBuffer);
1339:
1340: // close the .PFB file.
1341:
1342: CloseHandle(hFile);
1343:
1344: return(TRUE);
1345: }
1346:
1347:
1348: //--------------------------------------------------------------------------
1349: // PSTR LocateKeyword(pBuffer, pstrKeyword)
1350: // PSTR pBuffer;
1351: // PSTR pstrKeyword;
1352: //
1353: // This function takes a pointer to a buffer, and a pointer to a null
1354: // terminated string. It searches the buffer for the string and returns
1355: // a pointer to the string if it is found.
1356: //
1357: // Returns:
1358: // This function returns a pointer to the keyword if it is found,
1359: // otherwise it returns NULL.
1360: //
1361: // History:
1362: // 03-Jan-1992 -by- Kent Settle (kentse)
1363: // Wrote it.
1364: //--------------------------------------------------------------------------
1365:
1366: PSTR LocateKeyword(pBuffer, pstrKeyword)
1367: PSTR pBuffer;
1368: PSTR pstrKeyword;
1369: {
1370: while(*pBuffer != '\0')
1371: {
1372: // search through the buffer until we find the keyword designator '/'.
1373:
1374: while(*pBuffer != '/')
1375: pBuffer++;
1376:
1377: if (!(strncmp(pstrKeyword, pBuffer, strlen(pstrKeyword))))
1378: break; // we found it.
1379:
1380: // not this keyword, continue the search.
1381:
1382: pBuffer ++;
1383: }
1384:
1385: // we did not find the keyword.
1386:
1387: if (*pBuffer == '\0')
1388: pBuffer = NULL;
1389:
1390: // we did find it, return a pointer to the '/' character at the
1391: // beginning of the keyword.
1392:
1393: return(pBuffer);
1394: }
1395:
1396:
1397: //--------------------------------------------------------------------------
1398: // BOOL ExtractFullName(pBuffer, pszFullName)
1399: // PSZ pBuffer;
1400: // PSZ pszFullName;
1401: //
1402: // This function takes a pointer to a buffer, and a pointer to a place
1403: // to store the actual FullName of the font.
1404: //
1405: // Returns:
1406: // This function returns TRUE if the fullname is found,
1407: // otherwise it returns FALSE.
1408: //
1409: // History:
1410: // 03-Jan-1992 -by- Kent Settle (kentse)
1411: // Wrote it.
1412: //--------------------------------------------------------------------------
1413:
1414: BOOL ExtractFullName(pBuffer, pstrFullName)
1415: PSTR pBuffer;
1416: PSTR pstrFullName;
1417: {
1418: CHAR buf[32];
1419:
1420: // extract the full font name from the .PFB file. it is designated
1421: // by the /FullName keyword.
1422:
1423: //!!! I want an ASCII string here. Should I do a LoadStringA or hardcode it
1424: //!!! or what??? -kentse.
1425: LoadStringA(hModule, IDS_FULLNAME + STRING_BASE, buf, sizeof(buf));
1426:
1427: if (!(pBuffer = LocateKeyword(pBuffer, buf)))
1428: {
1429: RIP("ExtractFullName: /FullName not found.\n");
1430: SetLastError(ERROR_INVALID_DATA);
1431: return(FALSE);
1432: }
1433:
1434: // if we got to this point, pBuffer will be pointing to
1435: // "/FullName (The Full Font Name)".
1436:
1437: // advance to the opening paren.
1438:
1439: while (*pBuffer != '(')
1440: pBuffer++;
1441:
1442: pBuffer++;
1443:
1444: // skip any white space.
1445:
1446: while (*pBuffer == ' ')
1447: pBuffer++;
1448:
1449: // pBuffer is now pointing to the first letter of the actual full name.
1450: // copy the name into our local buffer.
1451:
1452: while (*pBuffer != ')')
1453: *pstrFullName++ = *pBuffer++;
1454:
1455: // null terminate it.
1456:
1457: *pstrFullName = '\0';
1458:
1459: return(TRUE);
1460: }
1461:
1462:
1463: //--------------------------------------------------------------------------
1464: // BOOL ExtractFontName(pBuffer, pszFontName)
1465: // PSZ pBuffer;
1466: // PSZ pszFontName;
1467: //
1468: // This function takes a pointer to a buffer, and a pointer to a place
1469: // to store the actual FontName.
1470: //
1471: // Returns:
1472: // This function returns TRUE if the fullname is found,
1473: // otherwise it returns FALSE.
1474: //
1475: // History:
1476: // 07-Jan-1992 -by- Kent Settle (kentse)
1477: // Wrote it.
1478: //--------------------------------------------------------------------------
1479:
1480: BOOL ExtractFontName(pBuffer, pszFontName)
1481: PSZ pBuffer;
1482: PSZ pszFontName;
1483: {
1484: CHAR buf[32];
1485:
1486: // extract the font name from the .PFB file. it is designated
1487: // by the /FontName keyword.
1488:
1489: //!!! I want an ASCII string here. Should I do a LoadStringA or hardcode it
1490: //!!! or what??? -kentse.
1491:
1492: LoadStringA(hModule, (IDS_FONTNAME + STRING_BASE), buf, sizeof(buf));
1493:
1494: if (!(pBuffer = LocateKeyword(pBuffer, buf)))
1495: {
1496: RIP("ExtractFontName: /FontName not found.\n");
1497: SetLastError(ERROR_INVALID_DATA);
1498: return(FALSE);
1499: }
1500:
1501: // if we got to this point, pBuffer will be pointing to
1502: // "/FontName /The Font Name".
1503:
1504: // advance to the next '/' character.
1505:
1506: pBuffer++;
1507:
1508: while (*pBuffer != '/')
1509: pBuffer++;
1510:
1511: pBuffer++;
1512:
1513: // skip any white space.
1514:
1515: while (*pBuffer == ' ')
1516: pBuffer++;
1517:
1518: // pBuffer is now pointing to the first letter of the actual font name.
1519: // copy the name into our local buffer.
1520:
1521: while (*pBuffer != ' ')
1522: *pszFontName++ = *pBuffer++;
1523:
1524: // null terminate it.
1525:
1526: *pszFontName = '\0';
1527:
1528: return(TRUE);
1529: }
1530:
1531:
1532: //--------------------------------------------------------------------------
1533: // BOOL PFBToPFA(pwstrPFAFile, pwstrPFBFile)
1534: // PWSTR pwstrPFAFile;
1535: // PWSTR pwstrPFBFile;
1536: //
1537: // This function takes a pointer to a destination .PFA file and a source
1538: // .PFB file, then creates the .PFA from the .PFB file.
1539: //
1540: // Returns:
1541: // This function returns TRUE if the .PFA is successfully created,
1542: // otherwise it returns FALSE.
1543: //
1544: // History:
1545: // 07-Jan-1992 -by- Kent Settle (kentse)
1546: // Wrote it.
1547: //--------------------------------------------------------------------------
1548:
1549: BOOL PFBToPFA(pwstrPFAFile, pwstrPFBFile)
1550: PWSTR pwstrPFAFile;
1551: PWSTR pwstrPFBFile;
1552: {
1553: CHAR *pPFB;
1554: CHAR *pPFBTemp;
1555: CHAR szFullName[MAX_FULLNAME];
1556: CHAR szFontName[MAX_FONTNAME];
1557: HANDLE hPFAFile;
1558: DWORD cbToWrite1, cbToWrite2, cbWritten, cbSegment;
1559: DWORD cbPFA;
1560: CHAR buf[MAX_FULLNAME + MAX_FONTNAME + 6];
1561: DWORD i, dwRet;
1562: PFBHEADER pfbheader;
1563: CHAR *pSrc;
1564: CHAR *pDest;
1565: CHAR *pSave;
1566:
1567: // get a pointer to .PFB file.
1568:
1569: if (!(pPFB = MapFile(pwstrPFBFile)))
1570: {
1571: RIP("PSCRPTUI!PFBToPFA: MapFile failed.\n");
1572: return(FALSE);
1573: }
1574:
1575: // extract the full font name from the .PFB file. it is designated
1576: // by the /FullName keyword.
1577:
1578: if (!ExtractFullName(pPFB, szFullName))
1579: {
1580: UnmapViewOfFile((PVOID)pPFB);
1581: return(FALSE);
1582: }
1583:
1584: // extract the full font name from the .PFB file. it is designated
1585: // by the /FontName keyword.
1586:
1587: if (!ExtractFontName(pPFB, szFontName))
1588: {
1589: UnmapViewOfFile((PVOID)pPFB);
1590: return(FALSE);
1591: }
1592:
1593: // create the .PFA file.
1594:
1595: hPFAFile = CreateFile(pwstrPFAFile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
1596: CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1597:
1598: if (hPFAFile == INVALID_HANDLE_VALUE)
1599: {
1600: RIP("PSCRPTUI!PFBToPFA: CreateFile for .PFA file failed.\n");
1601: UnmapViewOfFile((PVOID)pPFB);
1602: return(FALSE);
1603: }
1604:
1605: // output a DWORD at the beginning of the file, containing the
1606: // length of the PFA file, NOT including this DWORD. for now,
1607: // we do not know the length of the file, so write out a place holder.
1608:
1609: cbPFA = 0;
1610: WriteFile(hPFAFile, (PVOID)&cbPFA, (DWORD)sizeof(cbPFA),
1611: (DWORD *)&cbWritten, (LPOVERLAPPED)NULL);
1612:
1613: if (cbWritten != sizeof(cbPFA))
1614: {
1615: RIP("PSCRPTUI!PFBToPFA: WriteFile to .PFA file failed.\n");
1616: CloseHandle(hPFAFile);
1617: UnmapViewOfFile((PVOID)pPFB);
1618: return(FALSE);
1619: }
1620:
1621: // we want to put the following string at the start of the .PFA file:
1622: // "%FullName%FontName%CRLF". build this string in a buffer.
1623:
1624: buf[0] = '%';
1625:
1626: strncpy(&buf[1], szFullName, strlen(szFullName));
1627:
1628: i = strlen(szFullName) + 1;
1629: buf [i++] = '%';
1630:
1631: strncpy(&buf[i], szFontName, strlen(szFontName));
1632:
1633: i += strlen(szFontName);
1634: buf[i++] = '%';
1635: buf[i++] = 0x0D; // ASCII carriage return.
1636: buf[i++] = 0x0A; // ASCII line feed.
1637: buf[i] = '\0'; // NULL terminator.
1638:
1639: // write the buffer to the .PFA file.
1640:
1641: cbToWrite1 = strlen(buf);
1642: cbPFA = cbToWrite1;
1643:
1644: WriteFile(hPFAFile, (PVOID)buf, (DWORD)cbToWrite1,
1645: (DWORD *)&cbWritten, (LPOVERLAPPED)NULL);
1646:
1647: if (cbWritten != cbToWrite1)
1648: {
1649: RIP("PSCRPTUI!PFBToPFA: WriteFile to .PFA file failed.\n");
1650: CloseHandle(hPFAFile);
1651: UnmapViewOfFile((PVOID)pPFB);
1652: return(FALSE);
1653: }
1654:
1655: // The PFB file format is a sequence of segments, each of which has a
1656: // header part and a data part. The header format, defined in the
1657: // struct PFBHEADER below, consists of a one byte sanity check number
1658: // (128) then a one byte segment type and finally a four byte length
1659: // field for the data following data. The length field is stored in
1660: // the file with the least significant byte first. read in each
1661: // PFBHEADER, then process the data following it until we are done.
1662:
1663: pPFBTemp = pPFB;
1664:
1665: while (TRUE)
1666: {
1667: // read in what should be a PFBHEADER.
1668:
1669: memcpy(&pfbheader, pPFBTemp, sizeof(PFBHEADER));
1670:
1671: // make sure we have the header.
1672:
1673: if (pfbheader.jCheck != CHECK_BYTE)
1674: {
1675: RIP("PSCRPTUI!PFBToPFA: PFB Header not found.\n");
1676: SetLastError(ERROR_INVALID_DATA);
1677: CloseHandle(hPFAFile);
1678: UnmapViewOfFile((PVOID)pPFB);
1679: return(FALSE);
1680: }
1681:
1682: // if we have hit the end of the .PFB file, then we are done.
1683:
1684: if (pfbheader.jType == EOF_TYPE)
1685: break;
1686:
1687: // get the length of the data in this segment.
1688:
1689: cbSegment = ((DWORD)pfbheader.ushilength << 16) + pfbheader.uslolength;
1690:
1691: // get a pointer to the data itself for this segment.
1692:
1693: pSrc = pPFBTemp + sizeof(PFBHEADER);
1694:
1695: // create a buffer to do the conversion into.
1696:
1697: if (!(pDest = (CHAR *)LocalAlloc(LPTR, cbSegment * 3)))
1698: {
1699: RIP("PSCRPTUI!PFBToPFA: LocalAlloc for pDest failed.\n");
1700: CloseHandle(hPFAFile);
1701: UnmapViewOfFile((PVOID)pPFB);
1702: return(FALSE);
1703: }
1704:
1705: // save the pointer for later use.
1706:
1707: pSave = pDest;
1708:
1709: if (pfbheader.jType == ASCII_TYPE)
1710: {
1711: // read in an ASCII block, convert CR's to CR/LF's and
1712: // write out to the .PFA file.
1713:
1714: cbToWrite2 = cbSegment; // total count of bytes written to buffer.
1715:
1716: for (i = 0; i < cbSegment; i++)
1717: {
1718: if (0x0D == (*pDest++ = *pSrc++))
1719: {
1720: *pDest++ = (BYTE)0x0A;
1721: cbToWrite2++;
1722: }
1723: }
1724: }
1725: else if (pfbheader.jType == BINARY_TYPE)
1726: {
1727: // read in a BINARY block, convert it to HEX and write
1728: // out to the .PFA file.
1729:
1730: cbToWrite2 = cbSegment * 2; // total count of bytes written to buffer.
1731:
1732: for (i = 0; i < cbSegment; i++)
1733: {
1734: *pDest++ = BinaryToHex((*pSrc >> 4) & 0x0F);
1735: *pDest++ = BinaryToHex(*pSrc & 0x0F);
1736: pSrc++;
1737:
1738: // output a CR/LF ever 64 bytes for readability.
1739:
1740: if ((i % 32) == 31)
1741: {
1742: *pDest++ = (BYTE)0x0D;
1743: *pDest++ = (BYTE)0x0A;
1744: cbToWrite2 += 2;
1745: }
1746: }
1747:
1748: // add a final CR/LF if non 64 byte boundary.
1749:
1750: if ((cbSegment % 32) != 31)
1751: {
1752: *pDest++ = (BYTE)0x0D;
1753: *pDest++ = (BYTE)0x0A;
1754: cbToWrite2 += 2;
1755: }
1756: }
1757: else
1758: {
1759: RIP("PSCRPTUI!PFBToPFA: PFB Header type invalid.\n");
1760: SetLastError(ERROR_INVALID_DATA);
1761: CloseHandle(hPFAFile);
1762: UnmapViewOfFile((PVOID)pPFB);
1763: LocalFree((LOCALHANDLE)pDest);
1764: return(FALSE);
1765: }
1766:
1767: // reset pointer to start of buffer.
1768:
1769: pDest = pSave;
1770:
1771: // write the buffer to the .PFA file.
1772:
1773: WriteFile(hPFAFile, (PVOID)pDest, (DWORD)cbToWrite2,
1774: (DWORD *)&cbWritten, (LPOVERLAPPED)NULL);
1775:
1776: if (cbWritten != cbToWrite2)
1777: {
1778: RIP("PSCRPTUI!PFBToPFA: WriteFile block to .PFA file failed.\n");
1779: CloseHandle(hPFAFile);
1780: UnmapViewOfFile((PVOID)pPFB);
1781: LocalFree((LOCALHANDLE)pDest);
1782: return(FALSE);
1783: }
1784:
1785: // update the counter of BYTES written out to the file.
1786:
1787: cbPFA += cbToWrite2;
1788:
1789: // point to the next PFBHEADER.
1790:
1791: pPFBTemp += cbSegment + sizeof(PFBHEADER);
1792:
1793: // free up memory.
1794:
1795: LocalFree((LOCALHANDLE)pDest);
1796: }
1797:
1798: // set file pointer back to the beginning of the file, and write out
1799: // the size of the file as the first DWORD of the file.
1800:
1801: dwRet = SetFilePointer(hPFAFile, 0, 0, FILE_BEGIN);
1802:
1803: if (dwRet == -1)
1804: {
1805: RIP("PSCRPTUIPFBToPFA: SetFilePointer failed.\n");
1806: CloseHandle(hPFAFile);
1807: UnmapViewOfFile((PVOID)pPFB);
1808: LocalFree((LOCALHANDLE)pDest);
1809: return(FALSE);
1810: }
1811:
1812: WriteFile(hPFAFile, (PVOID)&cbPFA, (DWORD)sizeof(cbPFA),
1813: (DWORD *)&cbWritten, (LPOVERLAPPED)NULL);
1814:
1815: if (cbWritten != sizeof(cbPFA))
1816: {
1817: RIP("PSCRPTUI!PFBToPFA: WriteFile to .PFA file failed.\n");
1818: CloseHandle(hPFAFile);
1819: UnmapViewOfFile((PVOID)pPFB);
1820: LocalFree((LOCALHANDLE)pDest);
1821: return(FALSE);
1822: }
1823:
1824: // close the .PFA file.
1825:
1826: CloseHandle(hPFAFile);
1827:
1828: if (!UnmapViewOfFile((PVOID)pPFB))
1829: RIP("PSCRPTUI!PFBToPFA: UnmapViewOfFile failed.\n");
1830:
1831: return(TRUE);
1832: }
1833:
1834:
1835: BOOL LocateFile(hwnd, pwstrSearchFile, idString, pFileFindData, phFile)
1836: HWND hwnd;
1837: PWSTR pwstrSearchFile;
1838: int idString;
1839: WIN32_FIND_DATA *pFileFindData;
1840: HANDLE *phFile;
1841: {
1842: WCHAR wstringbuf[256];
1843: DWORD Value;
1844: DWORD Error;
1845:
1846: // see if there are any specified files in the specified directory.
1847:
1848: while (TRUE)
1849: {
1850: *phFile = FindFirstFile(pwstrSearchFile, pFileFindData);
1851:
1852: // if FindFirstFile failed, try to figure out why.
1853:
1854: if (*phFile == (HANDLE)-1)
1855: {
1856: Error = GetLastError();
1857:
1858: if ((Error == ERROR_NOT_READY) ||
1859: (Error == ERROR_NO_MEDIA_IN_DRIVE))
1860: return(FALSE);
1861:
1862: if (Error == ERROR_FILE_NOT_FOUND)
1863: {
1864: LoadString(hModule,
1865: (idString + STRING_BASE),
1866: wstringbuf, (sizeof(wstringbuf) / 2));
1867:
1868: Value = MessageBox(hwnd, wstringbuf, NULL,
1869: MB_ICONSTOP | MB_RETRYCANCEL);
1870:
1871: if (Value == IDCANCEL)
1872: return(FALSE);
1873: }
1874:
1875: if (Error == ERROR_PATH_NOT_FOUND)
1876: {
1877: LoadString(hModule,
1878: (IDS_PATH_NOT_FOUND + STRING_BASE),
1879: wstringbuf, (sizeof(wstringbuf) / 2));
1880:
1881: Value = MessageBox(hwnd, wstringbuf, NULL,
1882: MB_ICONSTOP | MB_RETRYCANCEL);
1883:
1884: if (Value == IDCANCEL)
1885: return(FALSE);
1886: }
1887:
1888:
1889: //!!! isn't this how to highlight the text in the edit box??? - kentse
1890:
1891: // highlight the current text in the edit box.
1892:
1893: SendDlgItemMessage(hwnd, IDD_NEW_FONT_DIR_EDIT_BOX,
1894: EM_SETSEL, 0, 0x7FFF0000L);
1895: }
1896: else
1897: {
1898: // FindFirstFile must have worked, continue on.
1899:
1900: return(TRUE);
1901: }
1902: }
1903: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.