When using file based streams, extra caution should be taken when some of the referenced files are specified using relative paths as in the following example:
DT_STREAM_FILE(sd, "dtype.inf"); dtEngineIniViaStream(&engine, &sd, DV_NULL)
or
DT_STREAM_FILE(sd, "fonts/Andes.ttf"); dtFontAddViaStream(engine, font_format_id, fuid, fcnr, cmap_id, caching, hinting, &sd);
Although relative paths can in certain situations provide more flexibility than absolute (i.e. fully qualified) paths, they might become a potential source of problems because they are relative to the current working directory. Consider, for example, what happens if D-Type Engine is initialized using dtype.inf that contains relative file paths:
If your application changes the current working directory (for example, using the Windows SetCurrentDirectory function) before initializing D-Type Engine, and you pass to dtEngineIniViaStream (or pdEngineIniViaStream) a relative path to dtype.inf, your initialization will almost certainly fail.
If your application changes the current working directory (for example, using the Windows SetCurrentDirectory function) after initializing D-Type Engine, your will likely make the Temporary Folder and/or Char Translation and Alignment (.ccv) files inaccessible to D-Type Engine. As a result, you might experience various problems later during the execution of your application — typically this will cause D-Type Engine to use more RAM than necessary (since it will not be able to store its temporary resources in the Temporary Folder) and/or it will fail to perform proper character translation and alignment when opening fonts (since it will not be able to access the Char Translation and Alignment files).
If the current working directory is not set correctly or is arbitrary (for example, when runing a program from a command line), your initialization will likely fail.
In this case, please consider the following solutions:
Ensure that the file based stream descriptor that is passed to dtEngineIniViaStream (or pdEngineIniViaStream) contains an absolute (i.e. fully qualified) file name and use only absolute paths in the dtype.inf and dtype.fls files.
For example, if your application ships with its own installer, you could create the dtype.inf file (and dtype.fls if necessary) during the setup phase. All the paths in those files must be absolute and point to the folder in which your application is installed. Then, when you call dtEngineIniViaStream (or pdEngineIniViaStream), you only need to ensure that file_name is absolute and properly points to your dtype.inf file.
Alternatively, create your own dtype.inf file (and dtype.fls if necessary) on disk every time before your application initializes D-Type Engine. Again, all the paths in those files must be absolute. Then pass the fully qualified file name of this dynamically created file to dtEngineIniViaStream (or pdEngineIniViaStream).
A very similar but a little bit more efficient method is to create the dtype.inf initialization file in memory rather than on disk. Again, all the paths in this memory file must be absolute. Then pass this dynamically created memory file to dtEngineIniViaStream (or pdEngineIniViaStream). See below for an example.
Another good method is to correctly set your current working directory using the Windows SetCurrentDirectory (or equivalnet) function as soon as your application starts (and make sure you do not change it later). Then you can call dtEngineIniViaStream (or pdEngineIniViaStream) and all your paths can be relative to the current working directory.
Once again, please note that relative paths are relative. They are relative to your current working directory. Therefore, if the current working directory changes before or after calling dtEngineIniViaStream, pdEngineIniViaStream, dtFontAddViaStream or dtFontAddViaStreams, your paths may become invalid.
The following code snippet illustrates one way to initialize D-Type Engine without using any relative paths. In this example we use a template to create the main initialization file in memory, while all the referenced secondary initialization files remain in a file based system (but are accessed using absolute paths).
DT_CHAR* ini_template = "# OPTIONAL SECONDARY INITIALIZATION FILES\r\n" \ "{\r\n" \ "-1,NONE\r\n" \ "0,%ssystem\\ini\\dtype.pat\r\n" \ "0,%ssystem\\ini\\gs256.gsl\r\n" \ "}\r\n" \ "\r\n" \ "# PARAMETERS FOR D-TYPE RASTERIZER\r\n" \ "{\r\n" \ "1200\r\n" \ "1000\r\n" \ "8\r\n" \ "0\r\n" \ "}\r\n" \ "\r\n" \ "# PARAMETERS FOR D-TYPE FONT ENGINE\r\n" \ "{\r\n" \ "2650000\r\n" \ "8000\r\n" \ "5000\r\n" \ "0\r\n" \ "6\r\n" \ "2\r\n" \ "1\r\n" \ "}\r\n" \ "\r\n" \ "# TEMPORARY FOLDER\r\n" \ "{\r\n" \ "%ssystem\\tmp\\\r\n" \ "}\r\n" \ "\r\n" \ "# FONT FACTORIES\r\n" \ "\r\n" \ "# CDTFontDType\r\n" \ "{\r\n" \ "0,0,DV_NULL\r\n" \ "-1\r\n" \ "}\r\n" \ "\r\n" \ "# CDTFontOpenTypeTtf\r\n" \ "{\r\n" \ "1,0,0,%ssystem\\ccv\\ot-mac-ascii.ccv,DV_NULL\r\n" \ "3,4,0,%ssystem\\ccv\\ot-win-unicode.ccv,DV_NULL\r\n" \ "-1\r\n" \ "}\r\n" \ "\r\n" \ "# CDTFontOpenTypeCff\r\n" \ "{\r\n" \ "6,0,0,%ssystem\\ccv\\ot-mac-ascii.ccv,DV_NULL\r\n" \ "5,4,0,%ssystem\\ccv\\ot-win-unicode.ccv,DV_NULL\r\n" \ "14,0,0,%ssystem\\ccv\\t1-adobe-std.ccv,INTERPRET_AS_BARE_CFF\r\n" \ "15,1,0,%ssystem\\ccv\\t1-iso-latin.ccv,INTERPRET_AS_BARE_CFF\r\n" \ "16,1,0,%ssystem\\ccv\\t1-win-unicode.ccv,INTERPRET_AS_BARE_CFF\r\n" \ "-1\r\n" \ "}\r\n" \ "\r\n" \ "# CDTFontType1\r\n" \ "{\r\n" \ "2,0,0,%ssystem\\ccv\\t1-adobe-std.ccv,DV_NULL\r\n" \ "7,1,0,%ssystem\\ccv\\t1-iso-latin.ccv,DV_NULL\r\n" \ "8,1,0,%ssystem\\ccv\\t1-win-unicode.ccv,DV_NULL\r\n" \ "-1\r\n" \ "}\r\n" \ "\r\n" \ "# CDTFontType3\r\n" \ "{\r\n" \ "11,1,0,%ssystem\\ccv\\t1-iso-latin.ccv,DV_NULL\r\n" \ "12,1,0,%ssystem\\ccv\\t1-win-unicode.ccv,DV_NULL\r\n" \ "-1\r\n" \ "}\r\n" \ "\r\n" \ "# LIST OF ADDITIONAL PARAMETERS\r\n" \ "{\r\n" \ "6291456\r\n" \ "1000\r\n" \ "-1\r\n" \ "}\r\n" \ "\r\n" \ "# LIST OF ADDITIONAL FILES\r\n" \ "{\r\n" \ "0,%ssystem\\misc\\map_thai.dat\r\n" \ "0,%ssystem\\misc\\en.hyp\r\n" \ "0,%ssystem\\misc\\fr.hyp\r\n" \ "0,%ssystem\\misc\\de.hyp\r\n" \ "0,%ssystem\\misc\\es.hyp\r\n" \ "-1\r\n" \ "}\r\n"; DT_CHAR ini_path[1024]; DT_CHAR mem_buffer[4096]; DT_SLONG mem_len; /* This path can be obtained dynamically during run time if necessary */ strcpy(ini_path, "C:\\Program Files\\My Application\\"); /* Check the size of initialization string to ensure spritnf doesn't cause buffer overrun */ if (strlen(ini_template) + 20 * strlen(ini_path) >= 4096) { /* size of string is too large */ return 0; } /* Make initialization string in memory from template */ sprintf(mem_buffer, ini_template, ini_path, ini_path, /* dtype.pat and gs256.gsl */ ini_path, /* temp folder */ ini_path, ini_path, /* CDTFontOpenTypeTtf */ ini_path, ini_path, ini_path, ini_path, ini_path /* CDTFontOpenTypeCff */ ini_path, ini_path, ini_path, /* CDTFontType1 */ ini_path, ini_path, /* CDTFontType3 */ ini_path, ini_path, ini_path, ini_path, ini_path); /* list of additional files */ mem_len = strlen(mem_buffer); /* Initialize D-Type engine */ DT_STREAM_MEMORY(sd, (DT_UBYTE*)mem_buffer, mem_len); return dtEngineIniViaStream(&engine, &sd, DV_NULL);