From e45823b9c7e8e17c028732faf86ba0114ee2a13c Mon Sep 17 00:00:00 2001 From: Ronald Tse Date: Wed, 23 Mar 2022 23:26:06 +0800 Subject: [PATCH] Add Alpine Linux build (#28) * Add Alpine build * Implement release workflow Co-authored-by: Maxim Samsonov --- .github/workflows/alpine-build.yml | 55 ++++++++++++++++ .github/workflows/macos-build.yml | 1 + .github/workflows/release.yml | 30 +++++++++ .github/workflows/ubuntu-aarch64.yml | 1 + .github/workflows/ubuntu-build.yml | 1 + .github/workflows/windows-build.yml | 1 + .gitmodules | 2 +- CMakeLists.txt | 30 +++++++-- README.md | 26 ++++++-- src/lib/emf2svg_utils.c | 98 +++++++++++++++------------- 10 files changed, 186 insertions(+), 59 deletions(-) create mode 100644 .github/workflows/alpine-build.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/alpine-build.yml b/.github/workflows/alpine-build.yml new file mode 100644 index 00000000..b4c367bf --- /dev/null +++ b/.github/workflows/alpine-build.yml @@ -0,0 +1,55 @@ +name: Alpine build + +on: + push: + branches: [ master ] + paths-ignore: + - '.github/workflows/macos-build.yml' + - '.github/workflows/ubuntu-build.yml' + - '.github/workflows/ubuntu-aarch64.yml' + - '.github/workflows/windows-build.yml' + pull_request: + workflow_dispatch: + +env: + BUILD_TYPE: Release + +jobs: + Alpine-build: + runs-on: ubuntu-latest + container: + image: alpine:latest + + steps: + - name: Install packages + run: | + apk --no-cache --upgrade add build-base cmake libxml2-dev \ + libxml2-utils libpng-dev freetype-dev fontconfig-dev git valgrind \ + argp-standalone font-noto-hebrew font-noto-arabic +# font-noto-hebrew font-noto-arabic -- this is required for testing only +# [ tests/resources/emf/test-183.emf ] + + - uses: actions/checkout@v2 + with: + submodules: recursive + + - name: Configure CMake + env: + CC: gcc + CXX: g++ + run: cmake -B . -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + + - name: Build + run: | + cmake --build . --config ${{env.BUILD_TYPE}} + pwd + ls -l + + - name: Test well formed files + run: ./tests/resources/check_correctness.sh -r -s + + - name: Test corrupted files + run: ./tests/resources/check_correctness.sh -r -s -e tests/resources/emf-corrupted/ -xN + + - name: Test EA files + run: ./tests/resources/check_correctness.sh -r -s -e tests/resources/emf-ea/ diff --git a/.github/workflows/macos-build.yml b/.github/workflows/macos-build.yml index 0ee8467c..746c24ad 100644 --- a/.github/workflows/macos-build.yml +++ b/.github/workflows/macos-build.yml @@ -4,6 +4,7 @@ on: push: branches: [ master ] paths-ignore: + - '.github/workflows/alpine-build.yml' - '.github/workflows/ubuntu-build.yml' - '.github/workflows/ubuntu-aarch64.yml' - '.github/workflows/windows-build.yml' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..81554b10 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,30 @@ +name: release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + +jobs: + publish: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + submodules: recursive + + - name: Collect + run: | + cd .. + rm -rf libemf2svg/.git* + rm -rf libemf2svg/vcpkg/.git* + tar cvzf libemf2svg.tar.gz libemf2svg + + - name: Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: ${{github.workspace}}/../libemf2svg.tar.gz diff --git a/.github/workflows/ubuntu-aarch64.yml b/.github/workflows/ubuntu-aarch64.yml index 083bc86e..fdc58c50 100644 --- a/.github/workflows/ubuntu-aarch64.yml +++ b/.github/workflows/ubuntu-aarch64.yml @@ -4,6 +4,7 @@ on: push: branches: [ master ] paths-ignore: + - '.github/workflows/alpine-build.yml' - '.github/workflows/ubuntu-build.yml' - '.github/workflows/macos-build.yml' - '.github/workflows/windows-build.yml' diff --git a/.github/workflows/ubuntu-build.yml b/.github/workflows/ubuntu-build.yml index 484f2076..9393ead6 100644 --- a/.github/workflows/ubuntu-build.yml +++ b/.github/workflows/ubuntu-build.yml @@ -4,6 +4,7 @@ on: push: branches: [ master ] paths-ignore: + - '.github/workflows/alpine-build.yml' - '.github/workflows/macos-build.yml' - '.github/workflows/ubuntu-aarch64.yml' - '.github/workflows/windows-build.yml' diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 9370b743..949c74de 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -4,6 +4,7 @@ on: push: branches: [ master ] paths-ignore: + - '.github/workflows/alpine-build.yml' - '.github/workflows/macos-build.yml' - '.github/workflows/ubuntu-aarch64.yml' - '.github/workflows/ubuntu-build.yml' diff --git a/.gitmodules b/.gitmodules index 53e4058e..a0a57f3d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "vcpkg"] path = vcpkg - url = git@github.com:microsoft/vcpkg.git + url = https://github.com/microsoft/vcpkg.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 64a6d000..91e3e611 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required (VERSION 3.12) +include(CheckFunctionExists) include(ExternalProject) # Comments re MSVC build @@ -31,7 +32,6 @@ endif(VCPKG_TARGET_TRIPLET) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") - find_package(PNG REQUIRED) find_package(Freetype REQUIRED) find_package(Fontconfig REQUIRED) @@ -60,7 +60,6 @@ ExternalProject_Add(${FMEM_NAME} ) set(EXTERNAL_FMEM "fmem") - set(DEPS_UEMF libUEMF-0.2.5) add_custom_target(tag @@ -79,6 +78,8 @@ option(INDEX "print record indexes" OFF) option(STATIC "compile statically" OFF) option(FORCELE "force little endian architecture" OFF) +CHECK_FUNCTION_EXISTS(argp_parse HAVE_ARGP_PARSE_FUNCTION) + if(GCOV) SET(UNITTEST ON) SET(CMAKE_BUILD_TYPE "Debug") @@ -110,6 +111,7 @@ endif(STATIC) if(UNIX) link_libraries(m) + add_compile_options(-fPIC) endif(UNIX) if(NOT FORCELE) @@ -133,15 +135,16 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") endif() set(BREW_LIB_DIR ${BREW_PREFIX}/lib) set(EXTERNAL_ICONV "iconv") - set(EXTERNAL_ARGP "argp") add_definitions(-DDARWIN) endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") -# Find/build external dependancies if it is Microsoft Visual Studio build +# Find/build external dependencies if it is Microsoft Visual Studio build if(MSVC) find_package(Iconv REQUIRED) set(EXTERNAL_ICONV ${Iconv_LIBRARY}) +endif(MSVC) +if(MSVC) set(ARGP_NAME argp${EXTERNAL_LIB_DIR_SUFFIX}) ExternalProject_Add(${ARGP_NAME} PREFIX ${DEPS} @@ -150,9 +153,20 @@ if(MSVC) CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${DEPS} PATCH_COMMAND cd ${DEPS}/src/${ARGP_NAME} && git restore CMakeLists.txt && git apply ${PATCHES}/argp/CMakeLists.txt.patch ) - set(EXTERNAL_ARGP "argp-standalone") endif(MSVC) +if(HAVE_ARGP_PARSE_FUNCTION) + message(STATUS "Using bundled argp") +else(HAVE_ARGP_PARSE_FUNCTION) + if(MSVC) + message(STATUS "Building argp") + set(EXTERNAL_ARGP "argp-standalone") + else(MSVC) + message(STATUS "Using stand-alone argp") + set(EXTERNAL_ARGP "argp") + endif(MSVC) +endif(HAVE_ARGP_PARSE_FUNCTION) + # headers & library directories if(MSVC) include_directories( @@ -238,6 +252,12 @@ add_executable(emf2svg-conv src/conv/emf2svg.cpp) target_link_libraries(emf2svg-conv emf2svg ${EXTERNAL_ARGP} + ${PNG_LIBRARIES} + ${EXTERNAL_ICONV} + ${FREETYPE_LIBRARIES} + ${FONTCONFIG_LIBRARIES} + ${EXPAT_LIBRARY_RELEASE} + ${EXTERNAL_FMEM} ) if(GCOV) diff --git a/README.md b/README.md index 1f94b17d..d5e68947 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ Dependencies * libpng * libfontconfig * libfreetype -* fmem (https://github.com/Snaipe/fmem) -- a cross-platform library for opening memory-backed libc streams -* argp-standalone (https://github.com/bigcat26/argp-standalone) -- a standalone version of the argp argument parsing functions from glibc, Windows only +* fmem (https://github.com/tamatebako/fmem) -- a cross-platform library for opening memory-backed libc streams +* argp-standalone (https://github.com/tom42/argp-standalone) -- a standalone version of the argp argument parsing functions from glibc, Windows only fmem and argp-standalone libraries are integrated as CMake external projects. No additional installation or handling is required. @@ -52,9 +52,9 @@ apt-get install cmake pkg-config apt-get install libpng-dev libc6-dev libfontconfig1-dev libfreetype6-dev zlib1g-dev ``` -Installing the dependencies on OS X: +Installing the dependencies on macOS: ```bash -$ brew install argp-standalone +$ brew install argp-standalone cmake libpng freetype fontconfig gcc ``` Installing the dependencies on RHEL/CentOS/Fedora: @@ -62,6 +62,12 @@ Installing the dependencies on RHEL/CentOS/Fedora: yum install cmake libpng-devel freetype-devel fontconfig-devel gcc-c++ gcc ``` +Installing the dependencies on Alpine Linux: +```bash +apk --no-cache --upgrade add build-base clang cmake libxml2-dev \ + libxml2-utils libpng-dev freetype-dev fontconfig-dev git argp-standalone +``` + Installing the dependencies on Windows for MSVC native builds Dependencies are installed by vcpkg package manager. Installation is implemented as a step of CMake configuration procedure. @@ -227,11 +233,19 @@ EMF+ RECORDS: ChangeLogs ---------- -1.3.1: +1.5.0: + +* add alpine linux support + +1.4.0: + +* add aarch64 debian linux support + +1.3.0: * add MSVC 17 (2022) support -1.3.0: +1.3.0: * add MSVC Windows native build diff --git a/src/lib/emf2svg_utils.c b/src/lib/emf2svg_utils.c index 49221cf8..57659ca8 100644 --- a/src/lib/emf2svg_utils.c +++ b/src/lib/emf2svg_utils.c @@ -1428,65 +1428,69 @@ void text_convert(char *in, size_t size_in, char **out, size_t *size_out, states->currentDeviceContext.font_family, states->currentDeviceContext.font_weight, states->currentDeviceContext.font_italic); - switch (states->currentDeviceContext.font_charset) { - case U_HEBREW_CHARSET: - case U_ARABIC_CHARSET: - /* with Utf-8 strings, the strings must always be - * stored in logical order, not visual order. - * Unicode Bidirectional (bidi) Algorithm does the work - * of rendering the text properly. - * So we reverse the text to be in logical order. - * However, this seems imcomplete, - * Right to Left ordering can also be set in - * ExtTextOutOptions (EMR_*TEXTOUT* records) and EMR_SETLAYOUT - * records, and it's completely ignored here. - * FIXME this is probably to simplistic. - */ - reverse_utf8((char *)string, *size_out); - break; - case U_ANSI_CHARSET: - case U_DEFAULT_CHARSET: - case U_SYMBOL_CHARSET: - case U_SHIFTJIS_CHARSET: - case U_HANGUL_CHARSET: - case U_GB2312_CHARSET: - case U_CHINESEBIG5_CHARSET: - case U_GREEK_CHARSET: - case U_TURKISH_CHARSET: - case U_BALTIC_CHARSET: - case U_RUSSIAN_CHARSET: - case U_EASTEUROPE_CHARSET: - case U_THAI_CHARSET: - case U_JOHAB_CHARSET: - case U_MAC_CHARSET: - case U_OEM_CHARSET: - case U_VISCII_CHARSET: - case U_TCVN_CHARSET: - case U_KOI8_CHARSET: - case U_ISO3_CHARSET: - case U_ISO4_CHARSET: - case U_ISO10_CHARSET: - case U_CELTIC_CHARSET: - default: - break; + if (ret==0 && string!=NULL) { + switch (states->currentDeviceContext.font_charset) { + case U_HEBREW_CHARSET: + case U_ARABIC_CHARSET: + /* with Utf-8 strings, the strings must always be + * stored in logical order, not visual order. + * Unicode Bidirectional (bidi) Algorithm does the work + * of rendering the text properly. + * So we reverse the text to be in logical order. + * However, this seems imcomplete, + * Right to Left ordering can also be set in + * ExtTextOutOptions (EMR_*TEXTOUT* records) and EMR_SETLAYOUT + * records, and it's completely ignored here. + * FIXME this is probably to simplistic. + */ + reverse_utf8((char*)string, *size_out); + break; + case U_ANSI_CHARSET: + case U_DEFAULT_CHARSET: + case U_SYMBOL_CHARSET: + case U_SHIFTJIS_CHARSET: + case U_HANGUL_CHARSET: + case U_GB2312_CHARSET: + case U_CHINESEBIG5_CHARSET: + case U_GREEK_CHARSET: + case U_TURKISH_CHARSET: + case U_BALTIC_CHARSET: + case U_RUSSIAN_CHARSET: + case U_EASTEUROPE_CHARSET: + case U_THAI_CHARSET: + case U_JOHAB_CHARSET: + case U_MAC_CHARSET: + case U_OEM_CHARSET: + case U_VISCII_CHARSET: + case U_TCVN_CHARSET: + case U_KOI8_CHARSET: + case U_ISO3_CHARSET: + case U_ISO4_CHARSET: + case U_ISO10_CHARSET: + case U_CELTIC_CHARSET: + default: + break; + } } break; default: if (checkOutOfEMF(states, (uintptr_t)((uintptr_t)in + (uintptr_t)size_in))) { string = NULL; - return; } - - string = (uint8_t *)calloc((size_in + 1), 1); - strncpy((char *)string, in, size_in); - *size_out = size_in; + else { + string = (uint8_t *)calloc((size_in + 1), 1); + strncpy((char *)string, in, size_in); + *size_out = size_in; + } + break; } + if (ret != 0) string = NULL; if (string == NULL) { - return; + return; } int i = 0;