Skip to content

Add Android-specific font matching functionality to Poppler

Shivodit Gill requested to merge shivoditg/poppler:gsoc-fontmatcher into master

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.
  • 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 by setupBaseFonts(). 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.
    • 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
  • 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.

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

Merge request reports