Add Android-specific font matching functionality to Poppler
This merge request has been created as part of GSoC'23 for KDE. It aims to add Android-specific font matching functionality in order to provide fonts for PDF files that have unembedded fonts.
Changes
-
In
CMakeLists.txt
:- Added a variable for the android based font matching functionality -
WITH_FONTCONFIGURATION_ANDROID
. It is set automatically when building for Android. - If Android is defined, then link the
android
library by adding it to poppler_LIBS variable.
- Added a variable for the android based font matching functionality -
-
In
poppler/GlobalParams.cc
-
Implemented
GlobalParams::findSystemFontFile()
- Uses the Android-NDK font matching API called AFontMatcher (supported only on API level 29 and above)
- In case the Android API level is below 29,
GlobalParams::findSystemFontFile()
does not compile the AFontMatcher code, and instead returns a nullptr instead of an actual path to a font file when called.
-
Implemented
GlobalParams::setupBaseFonts()
- Implemented the
displayFontTab
array of structs used bysetupBaseFonts()
. Instead of using .ttf and .pfa font files, it now uses .otf files for base-14 fonts. - Replaced the displayFontDirs const char array with an std::string that contains the absolute path of the directory containing the base-14 font files.
- Implemented the
-
New function -
GlobalParams::setFontDir()
- Android-only
- Used to set the font directory path where the base-14 fonts are located
- Used inside of the DocumentData::init() method after fonts are copied into the app's internal storage directory.
-
-
In
poppler/GlobalParams.h
- Added declaration for
GlobalParams::setFontDir()
as a static function
- Added declaration for
-
In
qt5/src/poppler-private.cc
- Added android-only code to
DocumentData::init()
in order to copy fonts from the assets folder of an android app. - Font files are copied from the assets/share/fonts directory of the apk. This path is currently hardcoded.
- The files are copied into a fonts directory created inside the application's internal storage folder.
- After copying, sets the path of the fonts directory inside GlobalParams.cc using
GlobalParams::setFontDir()
. If copying fails, an empty string is set instead. - The file-copying code is placed here because it requires the use of Qt5 functionality, which cannot be accessed from GlobalParams.cc.
- Added android-only code to
Results
Before
Video showing a PDF file with unembedded fonts displayed with poppler, before implementing the android-specific API: https://youtu.be/w-bNKVF95k0
After
Video showing the same PDF file with unembedded fonts displayed with poppler, after implementing the android-specific API: https://youtu.be/XmeIyXHI0jQ