CMakeLists.txt | 17 +++++----- goo/ft_utils.cc | 71 +++++++++++++++++++++++++++++++++++++++++++ goo/ft_utils.h | 25 +++++++++++++++ poppler/CairoFontEngine.cc | 3 + poppler/Form.cc | 5 +-- qt5/src/QPainterOutputDev.cc | 3 + qt6/src/QPainterOutputDev.cc | 3 + splash/SplashFTFontFile.cc | 7 ++-- 8 files changed, 118 insertions(+), 16 deletions(-)
New commits: commit d24ff1963429f409d5286632108d46d34ae3f2b1 Author: Adrian Johnson <ajohn...@redneon.com> Date: Wed May 11 08:32:24 2022 +0930 Make FT support UTF-8 filenames on windows diff --git a/CMakeLists.txt b/CMakeLists.txt index 1cb16f75..11da7cfb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -352,20 +352,21 @@ configure_file(poppler/poppler-config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/popple find_program(GPERF gperf) set(poppler_SRCS - goo/gbase64.cc - goo/gbasename.cc - goo/gfile.cc - goo/GooTimer.cc goo/GooString.cc + goo/GooTimer.cc + goo/ImgWriter.cc + goo/JpegWriter.cc goo/NetPBMWriter.cc goo/PNGWriter.cc goo/TiffWriter.cc - goo/JpegWriter.cc - goo/ImgWriter.cc - goo/gstrtod.cc - goo/grandom.cc + goo/ft_utils.cc + goo/gbase64.cc + goo/gbasename.cc + goo/gfile.cc goo/glibc.cc goo/glibc_strtok_r.cc + goo/grandom.cc + goo/gstrtod.cc fofi/FoFiBase.cc fofi/FoFiEncodings.cc fofi/FoFiTrueType.cc diff --git a/goo/ft_utils.cc b/goo/ft_utils.cc new file mode 100644 index 00000000..fc89302e --- /dev/null +++ b/goo/ft_utils.cc @@ -0,0 +1,71 @@ +//======================================================================== +// +// ft_util.cc +// +// FreeType helper functions. +// +// This file is licensed under the GPLv2 or later +// +// Copyright (C) 2022 Adrian Johnson <ajohn...@redneon.com> +// +//======================================================================== + +#include <cstdio> + +#include "ft_utils.h" +#include "gfile.h" + +#ifdef _WIN32 +static unsigned long ft_stream_read(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) +{ + FILE *file = (FILE *)stream->descriptor.pointer; + fseek(file, offset, SEEK_SET); + return fread(buffer, 1, count, file); +} + +static void ft_stream_close(FT_Stream stream) +{ + FILE *file = (FILE *)stream->descriptor.pointer; + fclose(file); + delete stream; +} +#endif + +// Same as FT_New_Face() but handles UTF-8 filenames on Windows +FT_Error ft_new_face_from_file(FT_Library library, const char *filename_utf8, FT_Long face_index, FT_Face *aface) +{ +#ifdef _WIN32 + FILE *file; + long size; + + if (!filename_utf8) + return FT_Err_Invalid_Argument; + + file = openFile(filename_utf8, "rb"); + if (!file) + return FT_Err_Cannot_Open_Resource; + + fseek(file, 0, SEEK_END); + size = ftell(file); + rewind(file); + + if (size <= 0) + return FT_Err_Cannot_Open_Stream; + + FT_StreamRec *stream = new FT_StreamRec; + *stream = {}; + stream->size = size; + stream->read = ft_stream_read; + stream->close = ft_stream_close; + stream->descriptor.pointer = file; + + FT_Open_Args args = {}; + args.flags = FT_OPEN_STREAM; + args.stream = stream; + + return FT_Open_Face(library, &args, face_index, aface); +#else + // On POSIX, FT_New_Face mmaps font files. If not Windows, prefer FT_New_Face over our stdio.h based FT_Open_Face. + return FT_New_Face(library, filename_utf8, face_index, aface); +#endif +} diff --git a/goo/ft_utils.h b/goo/ft_utils.h new file mode 100644 index 00000000..7f4118dc --- /dev/null +++ b/goo/ft_utils.h @@ -0,0 +1,25 @@ +//======================================================================== +// +// ft_util.h +// +// FreeType helper functions. +// +// This file is licensed under the GPLv2 or later +// +// Copyright (C) 2022 Adrian Johnson <ajohn...@redneon.com> +// +//======================================================================== + +#ifndef FT_UTILS_H +#define FT_UTILS_H + +#include "config.h" +#include "poppler_private_export.h" + +#include <ft2build.h> +#include FT_FREETYPE_H + +// Same as FT_New_Face() but handles UTF-8 filenames on Windows +POPPLER_PRIVATE_EXPORT FT_Error ft_new_face_from_file(FT_Library library, const char *filename_utf8, FT_Long face_index, FT_Face *aface); + +#endif // FT_UTILS_H diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc index ddf1b557..f73b4201 100644 --- a/poppler/CairoFontEngine.cc +++ b/poppler/CairoFontEngine.cc @@ -47,6 +47,7 @@ #include "GlobalParams.h" #include <fofi/FoFiTrueType.h> #include <fofi/FoFiType1C.h> +#include "goo/ft_utils.h" #include "goo/gfile.h" #include "Error.h" #include "XRef.h" @@ -167,7 +168,7 @@ static std::optional<FreeTypeFontFace> createFreeTypeFontFace(FT_Library lib, co FreeTypeFontFace font_face; if (font_data.empty()) { - FT_Error err = FT_New_Face(lib, filename.c_str(), 0, &resource->face); + FT_Error err = ft_new_face_from_file(lib, filename.c_str(), 0, &resource->face); if (err) { delete resource; return {}; diff --git a/poppler/Form.cc b/poppler/Form.cc index acd52014..4a8511f6 100644 --- a/poppler/Form.cc +++ b/poppler/Form.cc @@ -45,6 +45,7 @@ #include <cstdlib> #include <cstring> #include <cctype> +#include "goo/ft_utils.h" #include "goo/gmem.h" #include "goo/gfile.h" #include "goo/GooString.h" @@ -2775,8 +2776,8 @@ Form::AddFontResult Form::addFontToDefaultResources(const std::string &filepath, const std::unique_ptr<FT_Library, void (*)(FT_Library *)> freetypeLibDeleter(&freetypeLib, [](FT_Library *l) { FT_Done_FreeType(*l); }); FT_Face face; - if (FT_New_Face(freetypeLib, filepath.c_str(), faceIndex, &face)) { - error(errIO, -1, "FT_New_Face failed for %s", filepath.c_str()); + if (ft_new_face_from_file(freetypeLib, filepath.c_str(), faceIndex, &face)) { + error(errIO, -1, "ft_new_face_from_file failed for %s", filepath.c_str()); return {}; } const std::unique_ptr<FT_Face, void (*)(FT_Face *)> faceDeleter(&face, [](FT_Face *f) { FT_Done_Face(*f); }); diff --git a/qt5/src/QPainterOutputDev.cc b/qt5/src/QPainterOutputDev.cc index 62f12727..db3758bd 100644 --- a/qt5/src/QPainterOutputDev.cc +++ b/qt5/src/QPainterOutputDev.cc @@ -40,6 +40,7 @@ #include <array> +#include "goo/ft_utils.h" #include "goo/gfile.h" #include "GlobalParams.h" #include "Error.h" @@ -552,7 +553,7 @@ void QPainterOutputDev::updateFont(GfxState *state) FT_Face freeTypeFace; if (fontLoc->locType != gfxFontLocEmbedded) { - if (FT_New_Face(m_ftLibrary, fontLoc->path.c_str(), faceIndex, &freeTypeFace)) { + if (ft_new_face_from_file(m_ftLibrary, fontLoc->path.c_str(), faceIndex, &freeTypeFace)) { error(errSyntaxError, -1, "Couldn't create a FreeType face for '{0:s}'", gfxFont->getName() ? gfxFont->getName()->c_str() : "(unnamed)"); return; } diff --git a/qt6/src/QPainterOutputDev.cc b/qt6/src/QPainterOutputDev.cc index 62f12727..db3758bd 100644 --- a/qt6/src/QPainterOutputDev.cc +++ b/qt6/src/QPainterOutputDev.cc @@ -40,6 +40,7 @@ #include <array> +#include "goo/ft_utils.h" #include "goo/gfile.h" #include "GlobalParams.h" #include "Error.h" @@ -552,7 +553,7 @@ void QPainterOutputDev::updateFont(GfxState *state) FT_Face freeTypeFace; if (fontLoc->locType != gfxFontLocEmbedded) { - if (FT_New_Face(m_ftLibrary, fontLoc->path.c_str(), faceIndex, &freeTypeFace)) { + if (ft_new_face_from_file(m_ftLibrary, fontLoc->path.c_str(), faceIndex, &freeTypeFace)) { error(errSyntaxError, -1, "Couldn't create a FreeType face for '{0:s}'", gfxFont->getName() ? gfxFont->getName()->c_str() : "(unnamed)"); return; } diff --git a/splash/SplashFTFontFile.cc b/splash/SplashFTFontFile.cc index f9343735..cb177045 100644 --- a/splash/SplashFTFontFile.cc +++ b/splash/SplashFTFontFile.cc @@ -23,6 +23,7 @@ #include <config.h> +#include "goo/ft_utils.h" #include "goo/gmem.h" #include "goo/GooString.h" #include "poppler/GfxFont.h" @@ -42,7 +43,7 @@ SplashFontFile *SplashFTFontFile::loadType1Font(SplashFTFontEngine *engineA, Spl int i; if (src->isFile) { - if (FT_New_Face(engineA->lib, src->fileName.c_str(), 0, &faceA)) { + if (ft_new_face_from_file(engineA->lib, src->fileName.c_str(), 0, &faceA)) { return nullptr; } } else { @@ -72,7 +73,7 @@ SplashFontFile *SplashFTFontFile::loadCIDFont(SplashFTFontEngine *engineA, Splas FT_Face faceA; if (src->isFile) { - if (FT_New_Face(engineA->lib, src->fileName.c_str(), 0, &faceA)) { + if (ft_new_face_from_file(engineA->lib, src->fileName.c_str(), 0, &faceA)) { return nullptr; } } else { @@ -89,7 +90,7 @@ SplashFontFile *SplashFTFontFile::loadTrueTypeFont(SplashFTFontEngine *engineA, FT_Face faceA; if (src->isFile) { - if (FT_New_Face(engineA->lib, src->fileName.c_str(), faceIndexA, &faceA)) { + if (ft_new_face_from_file(engineA->lib, src->fileName.c_str(), faceIndexA, &faceA)) { return nullptr; } } else {