Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
CMake example that shows how you can build Freetype2 with support for Harfbuzz and Harfbuzz with support for Freetype2. This example uses ExternalProject which is the standard way to include external dependencies. Note that we have to patch Freetype2 and Harfbuzz because their CMakelists are not fully CMake compatible (still depend on pkg-config…
#!/bin/sh
d=${PWD}
id=${d}/install
if [ ! -d build ] ; then
mkdir build
fi
cd build
cmake -DCMAKE_INSTALL_PREFIX=${id} \
-DCMAKE_BUILD_TYPE=Release \
..
if [ $? -ne 0 ] ; then
echo "Failed to configure"
exit
fi
cmake --build . --target install --config Release
if [ $? -ne 0 ] ; then
echo "Failed to build"
exit
fi
cd ${id}/bin
./test_freetype_hb
# This CMake file will build Freetype and Harfbuzz as external
# projects. We follow the build description as described here:
# https://sourceforge.net/projects/freetype/files/freetype2/2.5.3/ So,
# first we build Freetype2 w/o Harfbuzz, then we build Harfbuzz with
# freetype support after which we rebuild Freetype2 again.
#
# Both CMake files of Freetype2 and Harfbuzz are depending on
# pkg-config to find the dependencies for both projects. I've
# included a patch for Freetype2 and Harfbuzz which allows you to
# build Freetype2 and Harbuzz with pure CMake features. So I removed
# the dependency of pkg-config.
cmake_minimum_required(VERSION 3.4)
project(FreetypeHarfbuzz)
include(ExternalProject)
ExternalProject_Add(
freetype2a
GIT_REPOSITORY git://git.savannah.gnu.org/freetype/freetype2.git
GIT_SHALLOW 1
GIT_TAG 7e50824288fac5a36c2938fdb3e1c949ea53f982
CMAKE_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> -DWITH_PNG=Off
UPDATE_COMMAND ""
)
ExternalProject_Get_Property(freetype2a install_dir)
set(freetype2a_install_dir install_dir)
ExternalProject_Add(
harfbuzz
DEPENDS freetype2a
#PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/harfbuzz_freetype_fix.patch
PATCH_COMMAND patch -p1 < ${CMAKE_CURRENT_LIST_DIR}/harfbuzz_freetype_fix.patch
URL https://github.com/behdad/harfbuzz/releases/download/1.4.7/harfbuzz-1.4.7.tar.bz2
CMAKE_ARGS -DCMAKE_PREFIX_PATH=${freetype2a_install_dir} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DHB_HAVE_FREETYPE=On
UPDATE_COMMAND ""
)
ExternalProject_Add(
freetype2b
GIT_REPOSITORY git://git.savannah.gnu.org/freetype/freetype2.git
GIT_SHALLOW 1
GIT_TAG 7e50824288fac5a36c2938fdb3e1c949ea53f982
PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/freetype_harfbuzz_fix.patch
CMAKE_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DWITH_PNG=Off
UPDATE_COMMAND ""
)
include_directories(
${CMAKE_INSTALL_PREFIX}/include/harfbuzz
${CMAKE_INSTALL_PREFIX}/include/freetype2
)
if (WIN32)
if (CMAKE_BUILD_TYPE STREQUAL "Release")
list(APPEND libs ${CMAKE_INSTALL_PREFIX}/lib/freetype.lib)
else()
list(APPEND libs ${CMAKE_INSTALL_PREFIX}/lib/freetyped.lib)
endif()
list(APPEND libs ${CMAKE_INSTALL_PREFIX}/lib/harfbuzz.lib )
endif()
if (UNIX)
list(APPEND libs
${CMAKE_INSTALL_PREFIX}/lib/libfreetype.a
${CMAKE_INSTALL_PREFIX}/lib/libharfbuzz.a
-lz
-lbz2
)
endif()
if (APPLE)
find_library(fr_coretext CoreText)
find_library(fr_corefoundation CoreFoundation)
find_library(fr_coregraphics CoreGraphics)
list(APPEND libs
${fr_coretext}
${fr_corefoundation}
${fr_coregraphics}
)
endif()
add_executable(test_freetype_hb test_freetype_hb.cpp)
install(TARGETS test_freetype_hb DESTINATION bin)
add_dependencies(test_freetype_hb freetype2b harfbuzz)
target_link_libraries(test_freetype_hb ${libs})
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d1b053e..b0b851d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -163,11 +163,25 @@ set(SHARED_LIBRARY_VERSION ${VERSION_MAJOR}.${VERSION_MINOR})
# Compiler definitions for building the library
add_definitions(-DFT2_BUILD_LIBRARY)
-
-# Find dependencies
-foreach (d ZLIB BZip2 PNG HarfBuzz)
+# Find harfbuzz
+find_library(hb_lib harfbuzz)
+if (NOT hb_lib MATCHES NOTFOUND)
+ set(HARFBUZZ_LIBRARIES ${hb_lib})
+endif()
+
+find_path(hb_path harfbuzz)
+if (NOT hb_path MATCHES NOTFOUND)
+ set(HARFBUZZ_INCLUDE_DIRS ${hb_path}/harfbuzz)
+endif()
+
+if (NOT hb_path MATCHES NOTFOUND AND NOT hb_lib MATCHES NOTFOUND)
+ set(HARFBUZZ_FOUND TRUE)
+ message(STATUS "Building with Harfbuzz")
+endif()
+
+# Find dependencies
+foreach (d ZLIB BZip2 PNG)
string(TOUPPER "${d}" D)
-
if (DEFINED WITH_${d} OR DEFINED WITH_${D})
if (WITH_${d} OR WITH_${D})
find_package(${d} QUIET REQUIRED)
@@ -254,6 +268,7 @@ if (HARFBUZZ_FOUND)
"/\\* +(#define +FT_CONFIG_OPTION_USE_HARFBUZZ) +\\*/" "\\1"
FTOPTION_H "${FTOPTION_H}")
endif ()
+
file(WRITE "${PROJECT_BINARY_DIR}/include/freetype/config/ftoption.h-new"
"${FTOPTION_H}")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
diff --git a/builds/cmake/FindHarfBuzz.cmake b/builds/cmake/FindHarfBuzz.cmake
deleted file mode 100644
index f394b82..0000000
--- a/builds/cmake/FindHarfBuzz.cmake
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (c) 2012, Intel Corporation
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice, this
-# list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of Intel Corporation nor the names of its contributors may
-# be used to endorse or promote products derived from this software without
-# specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-#
-# Try to find Harfbuzz include and library directories.
-#
-# After successful discovery, this will set for inclusion where needed:
-# HARFBUZZ_INCLUDE_DIRS - containg the HarfBuzz headers
-# HARFBUZZ_LIBRARIES - containg the HarfBuzz library
-
-include(FindPkgConfig)
-
-pkg_check_modules(PC_HARFBUZZ harfbuzz>=0.9.7)
-
-find_path(HARFBUZZ_INCLUDE_DIRS NAMES hb.h
- HINTS ${PC_HARFBUZZ_INCLUDE_DIRS} ${PC_HARFBUZZ_INCLUDEDIR}
-)
-
-find_library(HARFBUZZ_LIBRARIES NAMES harfbuzz
- HINTS ${PC_HARFBUZZ_LIBRARY_DIRS} ${PC_HARFBUZZ_LIBDIR}
-)
-
-# HarfBuzz 0.9.18 split ICU support into a separate harfbuzz-icu library.
-if ("${PC_HARFBUZZ_VERSION}" VERSION_GREATER "0.9.17")
- if (HarfBuzz_FIND_REQUIRED)
- set(_HARFBUZZ_REQUIRED REQUIRED)
- else ()
- set(_HARFBUZZ_REQUIRED "")
- endif ()
- pkg_check_modules(PC_HARFBUZZ_ICU harfbuzz-icu>=0.9.18 ${_HARFBUZZ_REQUIRED})
- find_library(HARFBUZZ_ICU_LIBRARIES NAMES harfbuzz-icu
- HINTS ${PC_HARFBUZZ_ICU_LIBRARY_DIRS} ${PC_HARFBUZZ_ICU_LIBDIR}
- )
- if (HARFBUZZ_ICU_LIBRARIES)
- list(APPEND HARFBUZZ_LIBRARIES "${HARFBUZZ_ICU_LIBRARIES}")
- endif ()
- set(_HARFBUZZ_EXTRA_REQUIRED_VAR "HARFBUZZ_ICU_LIBRARIES")
-else ()
- set(_HARFBUZZ_EXTRA_REQUIRED_VAR "")
-endif ()
-
-include(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(HarfBuzz DEFAULT_MSG HARFBUZZ_INCLUDE_DIRS
- HARFBUZZ_LIBRARIES ${_HARFBUZZ_EXTRA_REQUIRED_VAR})
-
-mark_as_advanced(
- HARFBUZZ_ICU_LIBRARIES
- HARFBUZZ_INCLUDE_DIRS
- HARFBUZZ_LIBRARIES
-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ee313566..519a4165 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -183,29 +183,19 @@ set(project_headers
## Find and include needed header folders and libraries
if (HB_HAVE_FREETYPE)
+
+ include(FindFreetype)
+ if (NOT FREETYPE_FOUND)
+ message(FATAL_ERROR "HB_HAVE_FREETYPE was set, but we failed to find it. Maybe add a CMAKE_PREFIX_PATH= to your Freetype2 install prefix")
+ endif()
+
+ list(APPEND THIRD_PARTY_LIBS ${FREETYPE_LIBRARIES})
+ include_directories(AFTER ${FREETYPE_INCLUDE_DIRS})
add_definitions(-DHAVE_FREETYPE=1 -DHAVE_FT_FACE_GETCHARVARIANTINDEX=1)
- # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindFreetype2.cmake
- find_package(PkgConfig)
- pkg_check_modules(PC_FREETYPE2 QUIET freetype2)
-
- find_path(FREETYPE2_HEADER_DIR NAMES freetype.h HINTS ${PC_FREETYPE2_INCLUDE_DIRS} ${PC_FREETYPE2_INCLUDEDIR} $ENV{FREETYPE_DIR}/include PATH_SUFFIXES freetype)
- find_path(FREETYPE2_ROOT_INCLUDE_DIR NAMES freetype/freetype.h HINTS ${PC_FREETYPE2_INCLUDE_DIRS} ${PC_FREETYPE2_INCLUDEDIR} $ENV{FREETYPE_DIR}/include)
- if (CMAKE_BUILD_TYPE MATCHES Debug)
- set(FREETYPE2_LIBRARY_NAME freetyped)
- else ()
- set(FREETYPE2_LIBRARY_NAME freetype)
- endif ()
- find_library(FREETYPE2_LIBRARIES ${FREETYPE2_LIBRARY_NAME} HINTS ${PC_FREETYPE2_LIBDIR} ${PC_FREETYPE2_LIBRARY_DIRS} $ENV{FREETYPE_DIR}/lib)
-
- include_directories(AFTER ${FREETYPE2_HEADER_DIR} ${FREETYPE2_ROOT_INCLUDE_DIR})
-
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-ft.cc)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-ft.h)
- list(APPEND THIRD_PARTY_LIBS ${FREETYPE2_LIBRARIES})
-
- mark_as_advanced(FREETYPE2_HEADER_DIR FREETYPE2_ROOT_INCLUDE_DIR FREETYPE2_LIBRARIES)
endif ()
if (HB_HAVE_GRAPHITE2)
#include <stdio.h>
#include <stdlib.h>
#include <hb.h>
#include <hb-ft.h>
int main() {
printf("Freetype with Harfbuzz\n");
FT_Library ft_lib;
FT_Face ft_face;
FT_Error ft_error;
if ((ft_error = FT_Init_FreeType(&ft_lib))) {
printf("Failed to init Freetype.\n");
exit(EXIT_FAILURE);
}
if ((ft_error = FT_New_Face(ft_lib, "./../../DroidSans.ttf", 0, &ft_face))) {
printf("Failed to create new Freetype Face.\n");
exit(EXIT_FAILURE);
}
if ((ft_error = FT_Set_Char_Size(ft_face, 36 * 64, 36 * 64, 0, 0))) {
printf("Failed to set the char size.\n");
exit(EXIT_FAILURE);
}
hb_font_t* hb_font;
hb_font = hb_ft_font_create(ft_face, NULL);
/* etc... */
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.