This function passes to the Font Engine a pointer to your own callback function that will receive errors or warnings that are encountered in bad fonts. The Font Engine supplies this pointer to font drivers when new fonts are added to the Font Catalog. Font drivers then call your function whenever they encounter errors or warnings in bad fonts.
Parameter | Description |
---|---|
engine |
Handle of the previously created Standard Engine instance. |
font_error_func |
A pointer to your own callback function that will receive errors that are encountered in fonts during execution. Your function must be declared as follows: void your_font_error_function(const DT_CHAR* error_message, void* user_param) where your_font_error_function is the name of your own C function, error_message a pointer to a standard ANSI C/C++ string containing information about the error or warning that your function will receive and user_param a pointer to your own data type that you will receive during the callback. The ANSI C/C++ string containing information about the error or warning that your function will receive contains at least three fields (and possibly more in the future) separated by a comma as illustrated below: font_driver_id, error_code, error_message The fields have the following meaning: font_driver_id — Identifies the font driver that initiated the callback. For example, this can be PFB, TTF, DTF, CFF, OTF etc. error_code — Identifies the error or warning. For example, this can be E1003, E1205, P2003, W1002 etc. The first letter identifies the severity of the problem: E indicates a serious error that will likely force the font driver to reject the font in question or some of its parts; P indicates a significant problem that the font driver will attempt to correct; W indicates a small problem or warning that the font driver will attempt to correct or ignore; M indicates an out-of-memory condition (that may or may not be caused by font instructions) and will likely force the font driver to reject the font in question or some of its parts; and U indicates an unknown or unspecified error type (that may or may not be caused by font instructions). The subsequent digits are the numeric error code and are specific to each font driver. error_message — A human-readable description of the problem in the plain English language. Your function is called only when errors or warnings are encountered in bad fonts. In other words, only bad or non-compliant fonts can trigger the callback. However, this can happen at various stages during font processing (e.g. when adding fonts to the Font Catalog, when requesting font information or rendering glyphs etc.). In other words, your function can be called at any time during the execution of your application. Therefore, do not make any assumptions about when your function will be called. Well designed compliant fonts should never trigger a callback. However, it is impossible to tell in advance whether or not a particular font or font instance will initiate a callback. If you wish to instruct Font Engine to stop supplying a pointer to font_error_func to font drivers when new fonts are added to the Font Catalog, set this parameter to DV_NULL. As a result, any new fonts (excluding multiple-master or variable font instances that are derived from existing fonts) that are added to the Font Catalog will not initiate callbacks any more. However, any fonts that have previously obtained a pointer to font_error_func (or their instances) will still initiate the callback when they encounter errors or warnings. Therefore, once you supply to the Font Engine a pointer to your callback function, that function must be able to accept callbacks at least until all the fonts that have obtained your pointer are permanently removed from the Font Catalog. |
user_param |
A void pointer to your own data type that you will receive during the callback. This pointer is passed back to your function during the callback to help you track the state of execution, identify the font being monitored or provide other information useful to your application. This pointer is not accessed or modified by D-Type Engine in any way; it is simply sent back to your function as supplied. You can set this parameter to DV_NULL if you have no need for it. |
If successful, the return value is 1. Otherwise, the function returns 0.
If your application is designed to access and utilize fonts from many different sources (either known or unknown), it is possible you will occasionally encounter bad fonts (i.e. fonts that will not open and/or render). Fonts are typically complex file structures (or more precisely programs) that require careful design and testing. In most cases the complexity is dictated by advanced architecture and versatility (as in TrueType or D-Type fonts) and in some cases is a consequence of a less than ideal design and/or architecture (as in Type 1 fonts). A font that works on one platform or in one program is not necessarily a good font. Each font format has specifications that (more or less) define how the font files should be designed and what rules and/or guidelines they are expected to follow. A font that respect all the rules and guidelines of its format specification is called a compliant font.
For ordinary users, it is not quite easy to determine which fonts are compliant and which ones are not. Fortunately, there are font validation tools that can help in this process. For example, Microsoft's Font Validator is an excellent tool to test and validate TrueType fonts. Surprisingly, it appears that some font formats do not have any suitable font validation tools. For example, at the time of writing this document, it is unknown to us whether Adobe has ever released a font validation tool for their Type 1 font format. This is certainly the format that could benefit most from such a tool.
Fortunately, D-Type Font Engine (or more precisely its font driver classes) can detect many errors in fonts and has a mechanism of reporting those errors back to the application and/or user. The dtFontSetErrorCallback is such a mechanism. This function is not intended to replace a full font validation process because errors are reported only as they are encountered and only for those font features that are directly implemented or supported by D-Type Font Engine. Also, errors returned by this function may not be specific enough to precisely pinpoint the problem. Still, this mechanism can provide a useful feedback to the application and/or font developer when testing or using fonts.
It should be noted that D-Type Font Engine is designed to accept all compliant fonts and, in addition, many non-compliant fonts. Our goal is to accept as many fonts as possible and not to reject them. Consequently, D-Type Font Engine will try very hard to open all fonts that it is presented with — even if they are non-compliant. When D-Type Font Engine finds a problem or inconsistency in a font, it will try to correct it or ignore it (as long as this is not dangerous). Only fonts that have serious problems will be rejected. Should you encounter a font that is being rejected or not rendered by D-Type Font Engine, there is a very good chance this is due to the font itself.
Most font manufacturers carefully design and test their fonts before releasing them to production. Still, font manufacturers depend on their font creation tools which may or may not produce compliant fonts. If you wish to report problems that are encountered in bad fonts to the end user (or font manufacturer), you may consider using the dtFontSetErrorCallback function.
Important Note for MS Windows Users: When passing D-Type a pointer to your own callback function, beware of the calling convention of your C/C++ environment. On MS Windows, all D-Type API functions that accept a pointer to your own callback function assume that your function uses the _cdecl convention. For example, in dtype.h on MS Windows the dtFontSetErrorCallback function is defined as follows:
DT_SWORD _stdcall dtFontSetErrorCallback(DT_DTENGINE engine, void (_cdecl *font_error_func)(const DT_CHAR* error_message, void* user_param), void* user_param);
Therefore, your own callback function must be defined as follows:
void _cdecl your_font_error_function(const DT_CHAR* error_message, void* your_param)
This note applies to any D-Type functions that expect a pointer to your own callback function (e.g. dtFontSetErrorCallback, pdDocSetDrawCallback, pdDocSetGlyphCallback, pdDocSetVectorCallback, txTextSetScriptCallback and possibly others in the future). Failing to add the _cdecl keyword may result in crashes and other undefined behavior, or your code may simply fail to compile.
void my_font_error_func(const DT_CHAR* error_message, void* user_param) { printf("Error message returned by D-Type Engine: %s\r\n", error_message); } dtFontSetErrorCallback(engine, my_font_error_func, DV_NULL);
Output:
Error message returned by D-Type Engine: PFB, E1027, Error parsing plain ASCII header Error message returned by D-Type Engine: PFB, U1044, An error was detected while processing CharStrings Error message returned by D-Type Engine: PFB, P1045, This is a bad font because NrOfGoodGlyphs<>NrOfDeclaredGlyphs Error message returned by D-Type Engine: PFB, E1019, Bad operand Error message returned by D-Type Engine: PFB, E1024, General charstring execution error Error message returned by D-Type Engine: PFB, U1046, Error(s) were detected