From 7a0100e35a775c0092dfb87c077ccb15692c126d Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 15 Jul 2023 22:54:33 -0300 Subject: [PATCH] printer: Switch to static freetype on Windows, finally fixes #2221 --- .ci/build.sh | 8 -- .ci/static2dll.sh | 160 ------------------------------------- src/printer/CMakeLists.txt | 9 ++- src/printer/prt_escp.c | 69 +++------------- 4 files changed, 18 insertions(+), 228 deletions(-) delete mode 100755 .ci/static2dll.sh diff --git a/.ci/build.sh b/.ci/build.sh index f4f28dea6..cf420d4dd 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -288,7 +288,6 @@ then echo [-] Using MSYSTEM [$MSYSTEM] # Install dependencies only if we're in a new build and/or architecture. - freetype_dll="$cache_dir/freetype.$MSYSTEM.dll" if check_buildtag "$MSYSTEM" then # Update databases and keyring only if we're in a new build. @@ -333,9 +332,6 @@ then # Clean pacman cache when running under Jenkins to save disk space. [ "$CI" = "true" ] && rm -rf /var/cache/pacman/pkg - # Generate a new freetype DLL for this architecture. - rm -f "$freetype_dll" - # Save build tag to skip this later. Doing it here (once everything is # in place) is important to avoid potential issues with retried builds. save_buildtag "$MSYSTEM" @@ -796,10 +792,6 @@ then sevenzip="$pf/7-Zip/7z.exe" [ "$arch" = "32" -a -d "/c/Program Files (x86)" ] && pf="/c/Program Files (x86)" - # Archive freetype from cache or generate it from local MSYS installation. - [ ! -e "$freetype_dll" ] && .ci/static2dll.sh -p freetype2 /$MSYSTEM/lib/libfreetype.a "$freetype_dll" - cp -p "$freetype_dll" archive_tmp/freetype.dll - # Archive Ghostscript DLL from local official distribution installation. for gs in "$pf"/gs/gs*.*.* do diff --git a/.ci/static2dll.sh b/.ci/static2dll.sh deleted file mode 100755 index 030898752..000000000 --- a/.ci/static2dll.sh +++ /dev/null @@ -1,160 +0,0 @@ -#!/bin/sh -# -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. -# -# This file is part of the 86Box distribution. -# -# Script for converting MinGW static libraries into a DLL. -# -# -# Authors: RichardG, -# -# Copyright 2021 RichardG. -# - -def_file="static2dll.def" -seen_file="static2dll.seen" -libs_file="static2dll.libs" - -find_lib() { - # Try to find a static library's file. - local msystem_lib="/$(echo $MSYSTEM | tr '[:upper:]' '[:lower:]')/lib/lib" - if [ -e "$msystem_lib$1.a" ] - then - echo "$msystem_lib$1.a" - elif [ -e "$msystem_lib$1.dll.a" ] - then - echo "$msystem_lib$1.dll.a" - else - # Return dynamic reference to the library. - echo "-l$1" - return 1 - fi -} - -add_lib() { - # Always make sure this lib is listed after the last lib that depends on it. - old_libs=$(cat "$libs_file") - rm -f "$libs_file" - for lib in $old_libs - do - [ "$lib" != "$*" ] && echo "$lib" >> "$libs_file" - done - echo "$*" >> "$libs_file" - - # Add libstdc++ in the end if required. - if echo "$*" | grep -q "/" - then - grep -Eq -- "__cxa_|__gxx_" "$1" 2> /dev/null && add_lib -static -lstdc++ - fi - - # Add libiconv for libintl. - if echo "$*" | grep -q "libintl" - then - add_lib $(find_lib iconv) - fi - - # Add libuuid for glib. - if echo "$*" | grep -q "libglib" - then - add_lib $(find_lib uuid) - fi -} - -run_pkgconfig() { - local cache_file="static2dll.$1.cache" - if [ -e "$cache_file" ] - then - cat "$cache_file" - else - pkg-config --static --libs "$1" 2> /dev/null | tee "$cache_file" - fi -} - -parse_pkgconfig() { - # Parse arguments. - local layers=$1 - shift - local input_lib_name=$1 - shift - - # Don't process the same file again. - grep -q '^'$input_lib_name'$' "$seen_file" && return - echo $input_lib_name >> "$seen_file" - - echo "$layers" parse_pkgconfig $input_lib_name - - # Parse pkg-config arguments. - for arg in $* - do - local arg_base="$(echo $arg | cut -c1-2)" - if [ "x$arg_base" = "x-l" ] - then - # Don't process the same lib again. - local lib_name="$(echo $arg | cut -c3-)" - [ "x$lib_name" == "x$input_lib_name" ] && continue - - # Add lib path. - add_lib "$(find_lib $lib_name)" - - # Get this lib's dependencies through pkg-config. - local pkgconfig="$(run_pkgconfig "$lib_name")" - [ $? -eq 0 ] && parse_pkgconfig "$layers"'>' "$lib_name" $pkgconfig || echo $lib_name >> "$seen_file" - elif [ "x$(echo $arg_base | cut -c1)" = "x-" ] - then - # Ignore other arguments. - continue - else - # Add lib path. - add_lib "$arg" - fi - done -} - -# Parse arguments. -case $1 in - -p) # -p pkg_config_name static_lib_path out_dll - shift - base_pkgconfig=$(run_pkgconfig "$1") - base_path="$2" - base_name="$1" - ;; - - *) # pc_path static_lib_path out_dll - base_pkgconfig="$(grep ^Libs.private: $1 | cut -d: -f2-)" - base_path="$2" - base_name="$2" - ;; -esac - -# Check arguments. -if [ -z "$base_pkgconfig" -o -z "$base_path" -o -z "$base_name" ] -then - echo Usage: - echo static2dll.sh -p {pkgconfig_package_name} {static_lib_path} {out_dll_name} - echo static2dll.sh {pc_file_path} {static_lib_path} {out_dll_name} - exit 1 -fi - -# Produce .def file. -echo LIBRARY $(basename "$3") > "$def_file" -echo EXPORTS >> "$def_file" -nm "$base_path" | grep " [TC] " | sed "/ _/s// /" | awk '{ print $3 }' >> "$def_file" - -# Parse dependencies recursively. -rm -f "$seen_file" "$libs_file" "$libs_file.tmp" -touch "$seen_file" "$libs_file" -parse_pkgconfig '>' $base_name $base_pkgconfig - -# Produce final DLL. -dllwrap --def "$def_file" -o "$3" -Wl,--allow-multiple-definition "$base_path" $(cat "$libs_file") -status=$? -[ $status -eq 0 ] && rm -f "$def_file" "$seen_file" "$libs_file" "static2dll.*.cache" - -# Update final DLL timestamp. -touch -r "$base_path" "$3" - -exit $status diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt index c774258e2..4f4158476 100644 --- a/src/printer/CMakeLists.txt +++ b/src/printer/CMakeLists.txt @@ -20,4 +20,11 @@ if(APPLE) if (NOT GHOSTSCRIPT_LIB) message(WARNING "Could not find ghostscript. The library will not be bundled and any related features will not work.") endif() -endif () \ No newline at end of file +endif() + +find_package(PkgConfig REQUIRED) +pkg_check_modules(FREETYPE REQUIRED IMPORTED_TARGET freetype2) +target_link_libraries(86Box PkgConfig::FREETYPE) +if(STATIC_BUILD) + target_link_libraries(86Box -static ${FREETYPE_STATIC_LIBRARIES}) +endif() diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 5fc3646bc..b4099bc63 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -65,7 +65,6 @@ #include <86box/pit.h> #include <86box/path.h> #include <86box/plat.h> -#include <86box/plat_dynld.h> #include <86box/ui.h> #include <86box/lpt.h> #include <86box/video.h> @@ -85,45 +84,8 @@ #define PAGE_CPI 10.0 /* standard 10 cpi */ #define PAGE_LPI 6.0 /* standard 6 lpi */ -#ifdef _WIN32 -# define PATH_FREETYPE_DLL "freetype.dll" -#elif defined __APPLE__ -# define PATH_FREETYPE_DLL "libfreetype.6.dylib" -#else -# define PATH_FREETYPE_DLL "libfreetype.so.6" -#endif - /* FreeType library handles - global so they can be shared. */ -FT_Library ft_lib = NULL; -void *ft_handle = NULL; - -static int (*ft_Init_FreeType)(FT_Library *alibrary); -static int (*ft_Done_Face)(FT_Face face); -static int (*ft_New_Face)(FT_Library library, const char *filepathname, - FT_Long face_index, FT_Face *aface); -static int (*ft_Set_Char_Size)(FT_Face face, FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution); -static int (*ft_Set_Transform)(FT_Face face, FT_Matrix *matrix, - FT_Vector *delta); -static int (*ft_Get_Char_Index)(FT_Face face, FT_ULong charcode); -static int (*ft_Load_Glyph)(FT_Face face, FT_UInt glyph_index, - FT_Int32 load_flags); -static int (*ft_Render_Glyph)(FT_GlyphSlot slot, - FT_Render_Mode render_mode); - -static dllimp_t ft_imports[] = { - {"FT_Init_FreeType", &ft_Init_FreeType }, - { "FT_New_Face", &ft_New_Face }, - { "FT_Done_Face", &ft_Done_Face }, - { "FT_Set_Char_Size", &ft_Set_Char_Size }, - { "FT_Set_Transform", &ft_Set_Transform }, - { "FT_Get_Char_Index", &ft_Get_Char_Index}, - { "FT_Load_Glyph", &ft_Load_Glyph }, - { "FT_Render_Glyph", &ft_Render_Glyph }, - { NULL, NULL } -}; +FT_Library ft_lib = NULL; /* The fonts. */ #define FONT_DEFAULT 0 @@ -544,7 +506,7 @@ update_font(escp_t *dev) /* Release current font if we have one. */ if (dev->fontface) - ft_Done_Face(dev->fontface); + FT_Done_Face(dev->fontface); if (dev->print_quality == QUALITY_DRAFT) fn = FONT_FILE_DOTMATRIX; @@ -580,7 +542,7 @@ update_font(escp_t *dev) escp_log("Temp file=%s\n", path); /* Load the new font. */ - if (ft_New_Face(ft_lib, path, 0, &dev->fontface)) { + if (FT_New_Face(ft_lib, path, 0, &dev->fontface)) { escp_log("ESC/P: unable to load font '%s'\n", path); dev->fontface = NULL; } @@ -626,7 +588,7 @@ update_font(escp_t *dev) dev->actual_cpi /= 2.0 / 3.0; } - ft_Set_Char_Size(dev->fontface, + FT_Set_Char_Size(dev->fontface, (uint16_t) (hpoints * 64), (uint16_t) (vpoints * 64), dev->dpi, dev->dpi); @@ -636,7 +598,7 @@ update_font(escp_t *dev) matrix.xy = (FT_Fixed) (0.20 * 0x10000L); matrix.yx = 0; matrix.yy = 0x10000L; - ft_Set_Transform(dev->fontface, &matrix, 0); + FT_Set_Transform(dev->fontface, &matrix, 0); } } @@ -1611,9 +1573,9 @@ handle_char(escp_t *dev, uint8_t ch) /* ok, so we need to print the character now */ if (ft_lib) { - char_index = ft_Get_Char_Index(dev->fontface, dev->curr_cpmap[ch]); - ft_Load_Glyph(dev->fontface, char_index, FT_LOAD_DEFAULT); - ft_Render_Glyph(dev->fontface->glyph, FT_RENDER_MODE_NORMAL); + char_index = FT_Get_Char_Index(dev->fontface, dev->curr_cpmap[ch]); + FT_Load_Glyph(dev->fontface, char_index, FT_LOAD_DEFAULT); + FT_Render_Glyph(dev->fontface->glyph, FT_RENDER_MODE_NORMAL); } pen_x = PIXX + dev->fontface->glyph->bitmap_left; @@ -1986,23 +1948,12 @@ read_status(void *priv) static void * escp_init(void *lpt) { - const char *fn = PATH_FREETYPE_DLL; - escp_t *dev; - - /* Dynamically load FreeType. */ - if (ft_handle == NULL) { - ft_handle = dynld_module(fn, ft_imports); - if (ft_handle == NULL) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2111, (wchar_t *) IDS_2132); - return (NULL); - } - } + escp_t *dev; /* Initialize FreeType. */ if (ft_lib == NULL) { - if (ft_Init_FreeType(&ft_lib)) { + if (FT_Init_FreeType(&ft_lib)) { ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2111, (wchar_t *) IDS_2132); - dynld_close(ft_lib); ft_lib = NULL; return (NULL); }