Re: Updated: CJK TrueType mappings and aliases for Windows installer

"Russell Lang" <[email protected]> Mon, 15 Nov 2004 19:46:58 +1100
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <419907B2.19350.2AF677E9@localhost>
Ray,

> It does occur to me that it 'would be nice' to rename the lib/cidfmap
> to something like lib/cidfmap.original. What do you think of this
> (I really don't like modifying the distributed files in place, but
> at least keep a backup -- as I would if I were to do it manually).

I have done this.  The original is renamed to cidfmap.bak

> > Are you approving committing it to GS CVS HEAD (for 8.50) and 
> > GS_8_1X?
> 
> Yes, but see suggestion above about *NOT* modifying the distributed
> cidfmap without at lease making a backup.
> 
> I *DO* think that this is OK to put into HEAD.

I haven't applied this patch yet.  Instead, please review the 
attached alternative implementation.  The main logic is now in the 
PostScript file mkcidfm.ps.  The Windows installer code builds a 
suitable command line for GS and then invokes GS to write the new 
cidfmap file.

Log Message:
Add utility mkcidfm.ps to create a cidfmap file based on fonts
found in a directory.
Change MS-Windows installer to optionally update lib/cidfmap 
with the CJK fonts found in the Windows font directory.

DETAILS:
Ghostscript does not ship with CJK fonts.
If support for Chinese, Japanese or Korean is added to MS-Windows,
CJK TrueType fonts and font collections are added to the MS-Windows 
fonts directory.  These can be used by ghostscript by specifying 
mapping and aliases in the lib/cidfmap file.  
This patch looks in the MS-Windows fonts directory for known 
CJK fonts, and if present it appends appropriate mappings or 
aliases to the lib/cidfmap file.
The font names and aliases are currently fixed, but can
be changed by editing mkcidfm.ps.

A new checkbox is added to the installer dialog
"Use Windows TrueType fonts for Chinese, Japanese and Korean"
Only if the user selects this will lib/cidfmap will be updated.
The default behaviour is that lib/cidfmap is unchanged.

_______________________________________________
gs-code-review mailing list
[email protected]
http://www.ghostscript.com/mailman/listinfo/gs-code-review
mkcidfm.ps (application/octet-stream, 7.4 KB) - not displayed
wincjk7.txt (application/octet-stream, 518 B)
diff -u l:/cvs/gs/doc/Psfiles.htm doc/Psfiles.htm
--- l:/cvs/gs/doc/Psfiles.htm	Wed Oct 27 08:22:33 2004
+++ doc/Psfiles.htm	Sun Nov 14 09:36:53 2004
@@ -733,6 +733,12 @@
 </dl>
 
 <dl>
+<dt><a href="../lib/mkcidfm.ps"><tt>mkcidfm.ps</tt></a>
+<dd>A utility for creating a CID font mapping table <b><tt>cidfmap</tt></b>
+from fonts found in a specified directory.
+</dl>
+
+<dl>
 <dt><a href="../lib/packfile.ps"><tt>packfile.ps</tt></a>
 <dd>A utility for compressing fonts into a single file.
 </dl>
wincjk8.txt (application/octet-stream, 8.7 KB)
diff -u l:/cvs/gs/src/dwinst.cpp src/dwinst.cpp
--- l:/cvs/gs/src/dwinst.cpp	Tue Mar 12 20:55:22 2002
+++ src/dwinst.cpp	Mon Nov 15 06:52:59 2004
@@ -244,6 +244,16 @@
 }
 
 
+void CInstall::AppendFileNew(const char *filename)
+{
+    FILE *f;
+    /* mark backup file for uninstall */
+    if ((f = fopen(m_szFileNew, "a")) != (FILE *)NULL) {
+	fputs(filename, f);
+	fputs("\n", f);
+	fclose(f);
+    }
+}
 
 // recursive mkdir
 // requires a full path to be specified, so ignores root \ 
diff -u l:/cvs/gs/src/dwinst.h src/dwinst.h
--- l:/cvs/gs/src/dwinst.h	Tue Mar 12 20:55:22 2002
+++ src/dwinst.h	Mon Nov 15 06:53:18 2004
@@ -63,6 +63,8 @@
 
 	void CleanUp(void);
 
+        void AppendFileNew(const char *filename);
+
 private:
 	BOOL m_bNoCopy;
 	BOOL m_bUseCommon;
diff -u l:/cvs/gs/src/dwsetup.cpp src/dwsetup.cpp
--- l:/cvs/gs/src/dwsetup.cpp	Sat Apr 12 21:04:21 2003
+++ src/dwsetup.cpp	Mon Nov 15 06:53:00 2004
@@ -113,6 +113,7 @@
 CHAR g_szAppName[MAXSTR];
 
 BOOL g_bInstallFonts = TRUE;
+BOOL g_bCJKFonts = FALSE;
 BOOL g_bAllUsers = FALSE;
 
 
@@ -139,6 +140,7 @@
 BOOL install_prog();
 BOOL install_fonts();
 BOOL make_filelist(int argc, char *argv[]);
+BOOL write_cidfmap(const char *gspath, const char *cidpath);
 
 
 //////////////////////////////////////////////////////////////////////
@@ -601,6 +603,9 @@
 			g_bInstallFonts = (SendDlgItemMessage(g_hMain, 
 				IDC_INSTALL_FONTS, BM_GETCHECK, 0, 0) 
 				== BST_CHECKED);
+			g_bCJKFonts = (SendDlgItemMessage(g_hMain, 
+				IDC_CJK_FONTS, BM_GETCHECK, 0, 0) 
+				== BST_CHECKED);
 			g_bAllUsers = (SendDlgItemMessage(hwnd, 
 				IDC_ALLUSERS, BM_GETCHECK, 0, 0
 				) == BST_CHECKED);
@@ -797,6 +802,43 @@
 		gs_addmess("Failed to end Start Menu update\n");
 		return FALSE;
 	}
+
+        /* Create lib/cidfmap */
+	if (g_bCJKFonts) {
+		FILE *f;
+		char szCIDFmap[MAXSTR];
+		char szCIDFmap_bak[MAXSTR];
+		char szGSPATH[MAXSTR];
+
+		/* backup old cidfmap */
+		strcpy(szCIDFmap, g_szTargetDir);
+		strcat(szCIDFmap, "\\");
+		strcat(szCIDFmap, cinst.GetMainDir());
+		strcat(szCIDFmap, "\\lib\\cidfmap");
+		strcpy(szCIDFmap_bak, szCIDFmap);
+		strcat(szCIDFmap_bak, ".bak");
+		gs_addmess("Backing up\n  ");
+		gs_addmess(szCIDFmap);
+		gs_addmess("\nto\n  ");
+		gs_addmess(szCIDFmap_bak);
+		gs_addmess("\n");
+		rename(szCIDFmap, szCIDFmap_bak);
+
+		/* mark backup for uninstall */
+		cinst.AppendFileNew(szCIDFmap_bak);
+
+		/* write new cidfmap */
+		gs_addmess("Writing cidfmap\n   ");
+		gs_addmess(szCIDFmap);
+		gs_addmess("\n");
+		strcpy(szGSPATH, g_szTargetDir);
+		strcat(szGSPATH, "\\");
+		strcat(szGSPATH, cinst.GetMainDir());
+		if (!write_cidfmap(szGSPATH, szCIDFmap)) {
+			gs_addmess("Failed to write cidfmap\n");
+			return FALSE;
+		}
+	}
 	
 	// consolidate logs into one uninstall file
 	if (cinst.MakeLog()) {
@@ -871,6 +913,84 @@
 	return TRUE;
 }
 
+//////////////////////////////////////////////////////////////////////
+// Create lib/cidfmap based on installed fonts
+//////////////////////////////////////////////////////////////////////
+
+/* Get the path to enumerate for fonts */
+int
+get_font_path(char *path, unsigned int pathlen)
+{
+    int i;
+    int len = GetWindowsDirectory(path, pathlen);
+    if (len == 0)
+       return -1;
+    if (pathlen - strlen(path) < 8)
+       return -1;
+    strncat(path, "/fonts", pathlen - strlen(path) - 7);
+    for (i = strlen(path)-1; i >= 0; i--)
+       if (path[i] == '\\')
+           path[i] = '/';
+    return len;
+}
+
+BOOL write_cidfmap(const char *gspath, const char *cidpath)
+{
+    char fontpath[MAXSTR];
+    char buf[4*MAXSTR];
+    STARTUPINFO siStartInfo;
+    PROCESS_INFORMATION piProcInfo;
+
+    get_font_path(fontpath, sizeof(fontpath)-1);
+
+    strcpy(buf, "\042");
+    strcat(buf, gspath);
+    strcat(buf, "\\bin\\gswin32c.exe\042 -q -dBATCH \042-sFONTDIR=");
+    strcat(buf, fontpath);
+    strcat(buf, "\042 \042");
+    strcat(buf, "-sCIDFMAP=");
+    strcat(buf, cidpath);
+    strcat(buf, "\042 \042");
+    strcat(buf, gspath);
+    strcat(buf, "\\lib\\mkcidfm.ps\042");
+
+    siStartInfo.cb = sizeof(STARTUPINFO);
+    siStartInfo.lpReserved = NULL;
+    siStartInfo.lpDesktop = NULL;
+    siStartInfo.lpTitle = NULL;  /* use executable name as title */
+    siStartInfo.dwX = siStartInfo.dwY = CW_USEDEFAULT;		/* ignored */
+    siStartInfo.dwXSize = siStartInfo.dwYSize = CW_USEDEFAULT;	/* ignored */
+    siStartInfo.dwXCountChars = 80;
+    siStartInfo.dwYCountChars = 25;
+    siStartInfo.dwFillAttribute = 0;			/* ignored */
+    siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
+    siStartInfo.wShowWindow = SW_HIDE;
+    siStartInfo.cbReserved2 = 0;
+    siStartInfo.lpReserved2 = NULL;
+    siStartInfo.hStdInput = NULL;
+    siStartInfo.hStdOutput = NULL;
+    siStartInfo.hStdError = NULL;
+
+    /* Create the child process. */
+    if (!CreateProcess(NULL,
+        (char *)buf,  /* command line                       */
+        NULL,          /* process security attributes        */
+        NULL,          /* primary thread security attributes */
+        FALSE,         /* handles are not inherited          */
+        0,             /* creation flags                     */
+        NULL,          /* environment                        */
+        NULL,          /* use parent's current directory     */
+        &siStartInfo,  /* STARTUPINFO pointer                */
+        &piProcInfo))  /* receives PROCESS_INFORMATION  */
+	    return FALSE;
+
+    /* We don't care if ghostscript fails, so just return */
+
+    CloseHandle(piProcInfo.hProcess);
+    CloseHandle(piProcInfo.hThread);
+
+    return TRUE;
+}
 
 
 //////////////////////////////////////////////////////////////////////
diff -u l:/cvs/gs/src/dwsetup.h src/dwsetup.h
--- l:/cvs/gs/src/dwsetup.h	Thu Feb 28 21:50:37 2002
+++ src/dwsetup.h	Mon Nov 15 06:53:02 2004
@@ -48,6 +48,7 @@
 #define IDC_TARGET                      1008
 #define IDC_ALLUSERS                    1009
 #define IDC_COPYRIGHT                   1010
+#define IDC_CJK_FONTS			1011
 
 
 #endif /* dwsetup_INCLUDED */
diff -u l:/cvs/gs/src/dwsetup.rc src/dwsetup.rc
--- l:/cvs/gs/src/dwsetup.rc	Fri Jan 30 08:40:57 2004
+++ src/dwsetup.rc	Mon Nov 15 06:52:45 2004
@@ -38,20 +38,24 @@
     ICON            IDR_MAIN,IDC_STATIC,11,17,20,20
     LTEXT           "This installs",IDC_STATIC,56,6,232,8
     LTEXT           "Product Name",IDC_PRODUCT_NAME,72,16,216,8
-    LTEXT           "Copyright (C) 1994-2004 artofcode LLC, Benicia, California, U.S.A.  All rights reserved. See the file PUBLIC for more details.\n\nRequires 20 Mbytes disk space.",
-                    IDC_COPYRIGHT,56,30,232,48
+    LTEXT           "Copyright (C) 1994-2004 artofcode LLC, Benicia, California, U.S.A.  All rights reserved.\n\nRequires 25 Mbytes disk space.",
+                    IDC_COPYRIGHT,56,30,232,40
 
-    LTEXT           "Install to directory",IDC_STATIC,8,92,56,8
-    CONTROL         "Install Fonts",IDC_INSTALL_FONTS,"Button",
-                    BS_AUTOCHECKBOX | WS_TABSTOP,160,90,85,12
-    EDITTEXT        IDC_TARGET_DIR,8,104,220,12,ES_AUTOHSCROLL
-    PUSHBUTTON      "Browse...",IDC_BROWSE_DIR,240,103,50,14
+    LTEXT           "Install to directory",IDC_STATIC,8,72,56,8
+    EDITTEXT        IDC_TARGET_DIR,8,84,220,12,ES_AUTOHSCROLL
+    PUSHBUTTON      "Browse...",IDC_BROWSE_DIR,240,83,50,14
 
-    LTEXT           "Add shortcuts to",IDC_STATIC,8,132,52,8
+    LTEXT           "Add shortcuts to",IDC_STATIC,8,112,52,8
     CONTROL         "All Users",IDC_ALLUSERS,"Button",
-		    BS_AUTOCHECKBOX | WS_TABSTOP,160,130,44,10
-    EDITTEXT        IDC_TARGET_GROUP,8,144,220,12,ES_AUTOHSCROLL
-    PUSHBUTTON      "Browse...",IDC_BROWSE_GROUP,240,143,50,14
+		    BS_AUTOCHECKBOX | WS_TABSTOP,160,110,44,10
+    EDITTEXT        IDC_TARGET_GROUP,8,124,220,12,ES_AUTOHSCROLL
+    PUSHBUTTON      "Browse...",IDC_BROWSE_GROUP,240,123,50,14
+
+    CONTROL         "Install Ghostscript Fonts",IDC_INSTALL_FONTS,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,8,142,220,12
+    CONTROL         "Use Windows TrueType fonts for Chinese, Japanese and Korean",IDC_CJK_FONTS,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,8,156,220,12
+
     PUSHBUTTON      "Cancel",IDCANCEL,8,178,50,14
     PUSHBUTTON      "Help",IDC_README,124,178,50,14
 END
diff -u l:/cvs/gs/src/dwuninst.cpp src/dwuninst.cpp
--- l:/cvs/gs/src/dwuninst.cpp	Thu Feb 28 21:50:37 2002
+++ src/dwuninst.cpp	Mon Nov 15 07:03:18 2004
@@ -34,7 +34,7 @@
 #define mkdir(x) _mkdir(x)
 #endif
 #define DELAY_STEP 500
-#define DELAY_FILE 5
+#define DELAY_FILE 0
 #define MAXSTR 256
 #define UNINSTALLKEY TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall")