LEADTOOLS Draw Engine and Multi-Platform Considerations

Parts of the LEADTOOLS SDKs require the use of a draw (rendering) engine. For instance, loading a Microsoft Word DOCX file as a raster image requires first creating a drawing surface. Then, any file objects such as text, shapes, and images are rendered onto the surface. Rendering text requires resolving the fonts used (determining whether they exist on the system or need replacing). Font operations are also used during text recognition to find the text's properties and determine when to generate the final output.

All of this is handled internally and automatically by LEADTOOLS. In certain situations, however, customization is necessary to produce the desired results.

In the following discussion, "other platforms" refers to platforms other than the Windows desktop. These are platforms such as Linux, Android, macOS, iOS, and Universal Windows Platform (UWP).

Draw Engines

LEADTOOLS ships with the following draw engines, defined by the L_DrawEngineType enumeration:

L_DrawEngineType_Default

The default engine for Windows is an internal rendering engine which uses Windows GDI/GDI+. This engine produces the fastest results for Windows.

In other platform environments, L_DrawEngineType_Default is the same as L_DrawEngineType_Multiplatform.

The default engine is included in the following DLL/Library/Assembly:

Platform DLL/Library/Assembly
Windows .NET Leadtools.Drawing.dll
Windows CDLL ltdrw?.dll
Linux N/A
Android N/A
macOS N/A
iOS N/A
UWP N/A

L_DrawEngineType_Multi-platform

The multi-platform engine is also an internal rendering engine. It uses code independent of the operating system. This engine will always produce the same exact rendering results across all platforms. Currently, this engine is based on the OpenGL and FreeType libraries.

Currently, this is the default(only) rendering engine type supported by LEADTOOLS for other platform environments.

The multi-platform engine is included in the following DLL/Library/Assembly:

Platform DLL/Library/Assembly
Windows .NET Leadtools.Drawing.MP.dll
Windows CDLL ltdrwmp?.dll
Linux libltdrw.so
Android libleadtools.drawing.so
macOS Leadtools.Drawing.framework
iOS Leadtools.Drawing.framework
UWP Leadtools.Drawing.Native.dll

Set the draw engine (globally) at the start or at any point of an application with the L_DrawSetEngineOptions function. This can be done easily, as shown in the following code:

c++
// First get the current options 
L_DrawEngineOptions options; 
memset(&options, 0, sizeof(L_DrawEngineOptions)); 
options.uStructSize = sizeof(L_DrawEngineOptions); 
L_DrawGetEngineOptions(&options); 
 
// Set the engine and re-set 
options.EngineType = L_DrawEngineType_Multiplatform; 
L_DrawSetEngineOptions(&options); 

Containers and Azure App Services

Some Docker Containers or Microsoft Azure App Services use a version of LEADTOOLS which lacks most of the GDI/GDI+ functionality. Under these conditions, errors can occur if LEADTOOLS is set to use L_DrawEngineType_Default. To avoid this, set the application to use L_DrawEngineType_Multiplatform at the start of the application, as shown in the code above.

Shadow Fonts

Sometimes LEADTOOLS will have to create a font based on its family name only (for example, when a Microsoft Word DOCX file containing a font of family name "Arial" is rendered.) Here, LEADTOOLS will use the current drawing engine to create an internal font object. In a Windows environment this is not a problem: almost all Windows Desktops will have the "Arial" font family installed globally on the system. However, Linux or Android environments may not have the font. The rendering engine will then use the system's standard font substitution (https://en.wikipedia.org/wiki/Font_substitution) to replace the font with the most suitable one available. In the case of "Arial", this might be the "Generic Sans Serif" font.

Font substitution can produce different results when running under Windows as opposed to Linux. Also, the font the system will use depends on the operating system version and any extra components installed. For instance, "Arial" can be installed on Linux systems using the Microsoft Fonts package for Linux. If this component is installed, "Arial" is found and used; otherwise, "Generic Sans Serif" will be used.

The draw engine can ask the system if a font will be substituted, and can override this behavior to supply its own font data instead. LEADTOOLS setups ship with free fonts, hand-picked to be the most suitable substitution for the most common fonts found in documents. The fonts are stored in this folder:

[Your Installation Folder]\Bin\Common\ShadowFonts

By using shadow fonts, LEADTOOLS can ensure that the document will:

Font Substitution Control

The L_DrawShadowFontMode enumeration members control how and when font substitution occurs, as follows:

DrawShadowFontMode Description
L_DrawShadowFontMode_Auto Default mode. Same as L_DrawShadowFontMode_SystemFirst in Windows. Same as L_DrawShadowFontMode_ShadowFirst in other platforms.
L_DrawShadowFontMode_SystemFirst Tries the system (operating system) first. If the font is not available, tries the shadow fonts directory. This is the default mode in Windows.
L_DrawShadowFontMode_ShadowFirst Tries the shadow fonts first. If the font is not available, tries the system. This is the default mode in the other platforms.

If the operation fails, then LEADTOOLS will use the system's font substitution. For instance, assume the mode is set to L_DrawShadowFontMode_SystemFirst while running on a Linux machine and LEADTOOLS is trying to create an "Arial" font which is not installed in the system. The following logic is used:

  1. First checks the system if "Arial" is installed. If so, it uses it.
  2. If no "Arial" font is installed, then checks if the shadow font directory is set and a font with the name "lt-liberationsans-regular.ttf" is found. If so, it uses it.
  3. If that font is not found, lets Linux substitute the font. This will usually create a "Generic Sans Serif" font.

The shadow font mode can be set globally at the start or during any point of an application using LEADTOOLS as follows:

c++
// First get the current options 
L_DrawEngineOptions options; 
memset(&options, 0, sizeof(L_DrawEngineOptions)); 
options.uStructSize = sizeof(L_DrawEngineOptions); 
L_DrawGetEngineOptions(&options); 
 
// Set the shadow font mode and re-set 
options.ShadowFontMode = L_DrawShadowFontMode_ShadowFirst; 
L_DrawSetEngineOptions(&options); 

The following code can be used to get or set the folder where LEADTOOLS looks for the shadow fonts in the system:

c++
L_TCHAR path[MAX_PATH]; 
// Get 
L_GetResourceDirectory(L_LEADResourceDirectory_Fonts, path, _countof(path)); 
// Set 
L_SetResourceDirectory(L_LEADResourceDirectory_Fonts, path); 

User Fonts

Applications may have a requirement to use custom fonts that are not installed on the operating system (for example, to load and render a PDF or DOCX file containing a private non-system font that is shipped with the application). Adding the font to the operating system requires elevated administrative privileges and a separate process to distribute and install the fonts.

LEADTOOLS supports custom private fonts with the L_DrawAddUserFontFromFile and L_DrawAddUserFontFromMemory functions.

These functions allow the application to add custom font(s) to the current process using LEADTOOLS only. Afterwards, LEADTOOLS will treat this font as if it were installed on the operating system and can participate as any other system font in any font substitution described in the section above. Standard TrueType (.ttf) and OpenType (.otf) fonts are currently supported.

L_DrawClearUserFonts can be used to delete all user fonts previously added to LEADTOOLS.

This sample code will add all the fonts found in a private application directory to LEADTOOLS:

c++
// C++17 std::filesystem 
#include <filesystem> 
 
static int AddUserFonts(const L_TCHAR* fontsDirectory) 
{ 
   L_INT ret; 
 
   // Optional: Clear any previous user fonts. 
   ret = L_DrawClearUserFonts(); 
   if(ret != SUCCESS) 
      return ret; 
 
   for(const auto& entry : std::filesystem::directory_iterator(fontsDirectory)) 
   { 
      auto path = entry.path(); 
 
      // Is it a font file? 
      if(path.has_extension()) 
      { 
         auto extension = path.extension(); 
         if(extension == L_TEXT(".ttf") || extension == L_TEXT(".otf")) 
         { 
            const L_TCHAR* fontFile = path.c_str(); 
            ret = L_DrawAddUserFontFromFile(fontFile); 
            if(ret != SUCCESS) 
               return ret; 
         } 
      } 
   } 
 
   return SUCCESS; 
} 

Multi-Platform Identical Rendering on OCR and Document Writer

In order to produce identical rendering when using OCR or Document Writer on multiple platforms (such as Windows and Linux), the following conditions must be satisfied:

For instance, consider an application which is using LEADTOOLS to use the Document Reader/Writer including OCR. This application can be deployed on both Windows and Linux machines. Further, one of the requirements might be that the application should produce 100% identical rendering across all platforms. To achieve this, insert the following code at the start of the application:

c++
// C++17 std::filesystem 
#include <filesystem> 
 
static void Initialize(const L_TCHAR* applicationDirectory) 
{ 
   // First get the current options 
   L_DrawEngineOptions options; 
   memset(&options, 0, sizeof(L_DrawEngineOptions)); 
   options.uStructSize = sizeof(L_DrawEngineOptions); 
   L_DrawGetEngineOptions(&options); 
 
   // Set up LEADTOOLS to use the multi-platform draw engine 
 
   options.EngineType = L_DrawEngineType_Multiplatform; 
 
   // Always use the shadow fonts first: 
   options.ShadowFontMode = L_DrawShadowFontMode_ShadowFirst; 
 
   // Set the options 
   L_DrawSetEngineOptions(&options); 
 
   // Set the shadow fonts directory (under LEADTOOLS/ShadowFonts in this system) 
   std::filesystem::path shadowDirPath = applicationDirectory; 
   shadowDirPath.append(L_TEXT("LEADTOOLS")); 
   shadowDirPath.append(L_TEXT("ShadowFonts")); 
   L_SetResourceDirectory(L_LEADResourceDirectory_Fonts, shadowDirPath.c_str()); 
} 

Help Version 20.0.2020.4.3
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2020 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Raster Imaging C API Help