diff --git a/CMakeLists.txt b/CMakeLists.txt index 25c320c7c..799c3e57e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,6 @@ CMAKE_DEPENDENT_OPTION(USE_WIIUSE "Support for wiimote input devices" ON if(APPLE AND NOT IOS) list(APPEND CMAKE_PREFIX_PATH /usr/local/opt) - include_directories(/usr/local/opt/fribidi/include/) include_directories(/usr/local/opt/openssl@1.1/include/) include_directories(/usr/local/opt/openssl@1.1/include/openssl/) include_directories(/usr/local/opt/freetype/include/freetype2/) @@ -370,7 +369,7 @@ if(NOT SERVER_ONLY) add_definitions(-DENABLE_SOUND) endif() -# Text handling in STK (We use freetype, harfbuzz, fribidi and libraqm for i18n text handling) +# Text handling in STK (We use freetype, harfbuzz and SheenBidifor i18n text handling) if (NOT SERVER_ONLY) # SheenBidi add_subdirectory("${PROJECT_SOURCE_DIR}/lib/sheenbidi") @@ -396,28 +395,6 @@ if (NOT SERVER_ONLY) include_directories("${HARFBUZZ_INCLUDEDIR}") MESSAGE(STATUS "Use system harfbuzz: ${HARFBUZZ_LIBRARY}") endif() - - # Fribidi - find_package(Fribidi) - if(FRIBIDI_FOUND) - include_directories(${FRIBIDI_INCLUDE_DIRS}) - else() - message(FATAL_ERROR "Fribidi not found. " - "Fribidi is required to display characters in SuperTuxKart.") - endif() - - # Libraqm - find_library(RAQM_LIBRARY NAMES raqm libraqm) - find_path(RAQM_INCLUDEDIR NAMES raqm.h PATHS) - if (NOT RAQM_LIBRARY OR NOT RAQM_INCLUDEDIR) - add_subdirectory("${PROJECT_SOURCE_DIR}/lib/libraqm") - include_directories("${PROJECT_SOURCE_DIR}/lib/libraqm") - SET(RAQM_LIBRARY raqm) - message(STATUS "System libraqm not found, use the bundled one.") - else() - include_directories("${RAQM_INCLUDEDIR}") - MESSAGE(STATUS "Use system libraqm: ${RAQM_LIBRARY}") - endif() endif() # OpenGL @@ -665,8 +642,6 @@ if(NOT SERVER_ONLY) ${JPEG_LIBRARIES} ${OGGVORBIS_LIBRARIES} ${OPENAL_LIBRARY} - ${RAQM_LIBRARY} - ${FRIBIDI_LIBRARIES} ${FREETYPE_LIBRARIES} ${HARFBUZZ_LIBRARY} ${SDL2_LIBRARY} diff --git a/android/Android.mk b/android/Android.mk index a72e9fdd4..69bea4958 100644 --- a/android/Android.mk +++ b/android/Android.mk @@ -72,13 +72,6 @@ include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) -# Fribidi -LOCAL_MODULE := fribidi -LOCAL_SRC_FILES := obj/fribidi/lib/.libs/libfribidi.a -include $(PREBUILT_STATIC_LIBRARY) -include $(CLEAR_VARS) - - # Freetype LOCAL_MODULE := freetype LOCAL_SRC_FILES := obj/freetype/objs/.libs/libfreetype.a @@ -93,23 +86,6 @@ include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) -# Raqm -LOCAL_MODULE := raqm -LOCAL_PATH := . -LOCAL_CPP_FEATURES += rtti -LOCAL_SRC_FILES := $(wildcard ../lib/libraqm/*.c) -LOCAL_CFLAGS := -Iobj/fribidi/include \ - -Iobj/freetype/include \ - -Iobj/harfbuzz/include \ - -DHAVE_DECL_HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES \ - -DHAVE_HB_BUFFER_SET_INVISIBLE_GLYPH \ - -DHAVE_HB_FT_FONT_CREATE_REFERENCED \ - -DHAVE_HB_FT_FONT_SET_LOAD_FLAGS \ - -std=c99 -include $(BUILD_STATIC_LIBRARY) -include $(CLEAR_VARS) - - # ifaddrs LOCAL_MODULE := ifaddrs LOCAL_PATH := . @@ -258,7 +234,6 @@ LOCAL_SRC_FILES := $(wildcard ../src/*.cpp) \ LOCAL_LDLIBS := -llog -landroid -lGLESv1_CM -lGLESv3 -lOpenSLES -ldl -lm LOCAL_CFLAGS := -I../lib/angelscript/include \ -I../lib/bullet/src \ - -I../lib/libraqm \ -I../lib/sheenbidi/Headers \ -I../lib/enet/include \ -I../lib/ifaddrs \ @@ -269,7 +244,6 @@ LOCAL_CFLAGS := -I../lib/angelscript/include \ -I../lib/sdl2/include \ -I../src \ -Iobj/curl/include \ - -Iobj/fribidi/include \ -Iobj/freetype/include \ -Iobj/harfbuzz/include \ -Iobj/libogg/include \ @@ -290,8 +264,7 @@ LOCAL_CPPFLAGS := -std=gnu++0x LOCAL_STATIC_LIBRARIES := irrlicht bullet enet ifaddrs angelscript mcpp SDL2 \ vorbisfile vorbis ogg openal curl libssl libcrypto \ - c++_static raqm fribidi sheenbidi harfbuzz freetype \ - graphics_utils + c++_static sheenbidi harfbuzz freetype graphics_utils include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) diff --git a/android/make.sh b/android/make.sh index be0c5606c..7d3288c54 100755 --- a/android/make.sh +++ b/android/make.sh @@ -322,21 +322,6 @@ if [ ! -f "$DIRNAME/obj/libpng.stamp" ]; then touch "$DIRNAME/obj/libpng.stamp" fi -# Fribidi -if [ ! -f "$DIRNAME/obj/fribidi.stamp" ]; then - echo "Compiling fribidi" - mkdir -p "$DIRNAME/obj/fribidi" - cp -a -f "$DIRNAME/../lib/fribidi/"* "$DIRNAME/obj/fribidi" - - cd "$DIRNAME/obj/fribidi" - ./configure --host=$HOST --enable-static=yes && - make $@ - check_error - mkdir -p "$DIRNAME/obj/fribidi/include/fribidi" - cp $DIRNAME/obj/fribidi/lib/*.h "$DIRNAME/obj/fribidi/include/fribidi" - touch "$DIRNAME/obj/fribidi.stamp" -fi - # Freetype bootstrap if [ ! -f "$DIRNAME/obj/freetype_bootstrap.stamp" ]; then echo "Compiling freetype" diff --git a/cmake/FindFribidi.cmake b/cmake/FindFribidi.cmake deleted file mode 100644 index 542554a68..000000000 --- a/cmake/FindFribidi.cmake +++ /dev/null @@ -1,35 +0,0 @@ -# - Find Fribidi -# Find the Fribidi includes and libraries -# -# Following variables are provided: -# FRIBIDI_FOUND -# True if Fribidi has been found -# FRIBIDI_INCLUDE_DIRS -# The include directories of Fribidi -# FRIBIDI_LIBRARIES -# Fribidi library list - -if(UNIX AND NOT APPLE) - include(FindPkgConfig) - pkg_check_modules(FRIBIDI fribidi) -else() - set(FRIBIDI_FOUND 0) -endif() - -if(NOT FRIBIDI_FOUND) - find_path(FRIBIDI_INCLUDE_DIR NAMES fribidi/fribidi.h PATHS /Library/Frameworks/fribidi.framework/Headers "${PROJECT_SOURCE_DIR}/${DEPENDENCIES}/include") - find_library(FRIBIDI_LIBRARY NAMES fribidi libfribidi PATHS /Library/Frameworks/fribidi.framework "${PROJECT_SOURCE_DIR}/${DEPENDENCIES}/lib") - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(Fribidi DEFAULT_MSG FRIBIDI_INCLUDE_DIR FRIBIDI_LIBRARY) - - if(APPLE) - set(FRIBIDI_INCLUDE_DIR "/Library/Frameworks/fribidi.framework/Headers") - endif() - - # Publish variables - set(FRIBIDI_INCLUDE_DIRS ${FRIBIDI_INCLUDE_DIR}) - set(FRIBIDI_LIBRARIES ${FRIBIDI_LIBRARY}) -endif() - -mark_as_advanced(FRIBIDI_INCLUDE_DIR FRIBIDI_LIBRARY) diff --git a/lib/libraqm/CMakeLists.txt b/lib/libraqm/CMakeLists.txt deleted file mode 100644 index 7aed4fb00..000000000 --- a/lib/libraqm/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -cmake_minimum_required(VERSION 2.6) - -if (NOT MSVC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") -endif() - -include(CheckFunctionExists) -include(CheckCSourceCompiles) -set(CMAKE_REQUIRED_INCLUDES ${HARFBUZZ_INCLUDEDIR}) -set(CMAKE_REQUIRED_LIBRARIES ${HARFBUZZ_LIBRARY}) - -CHECK_FUNCTION_EXISTS(hb_ft_font_create_referenced HAVE_hb_ft_font_create_referenced) -if (HAVE_hb_ft_font_create_referenced) - add_definitions(-DHAVE_HB_FT_FONT_CREATE_REFERENCED) -endif() - -CHECK_FUNCTION_EXISTS(hb_ft_font_set_load_flags HAVE_hb_ft_font_set_load_flags) -if (HAVE_hb_ft_font_set_load_flags) - add_definitions(-DHAVE_HB_FT_FONT_SET_LOAD_FLAGS) -endif() - -CHECK_FUNCTION_EXISTS(hb_buffer_set_invisible_glyph HAVE_hb_buffer_set_invisible_glyph) -if (HAVE_hb_buffer_set_invisible_glyph) - add_definitions(-DHAVE_HB_BUFFER_SET_INVISIBLE_GLYPH) -endif() - -CHECK_C_SOURCE_COMPILES( -" -#include -int main () -{ -#ifndef HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES - (void)HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES; -#endif - return 0; -} -" -HAVE_DECL_HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) -if (HAVE_DECL_HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) - add_definitions(-DHAVE_DECL_HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) -endif() - -add_library(raqm STATIC raqm.c) diff --git a/lib/libraqm/raqm-version.h b/lib/libraqm/raqm-version.h deleted file mode 100644 index d9d21147e..000000000 --- a/lib/libraqm/raqm-version.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright © 2011 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef _RAQM_H_IN_ -#error "Include instead." -#endif - -#ifndef _RAQM_VERSION_H_ -#define _RAQM_VERSION_H_ - -#define RAQM_VERSION_MAJOR 0 -#define RAQM_VERSION_MINOR 7 -#define RAQM_VERSION_MICRO 0 - -#define RAQM_VERSION_STRING "0.7.0" - -#define RAQM_VERSION_ATLEAST(major,minor,micro) \ - ((major)*10000+(minor)*100+(micro) <= \ - RAQM_VERSION_MAJOR*10000+RAQM_VERSION_MINOR*100+RAQM_VERSION_MICRO) - -#endif /* _RAQM_VERSION_H_ */ diff --git a/lib/libraqm/raqm-version.h.in b/lib/libraqm/raqm-version.h.in deleted file mode 100644 index 93b20d23f..000000000 --- a/lib/libraqm/raqm-version.h.in +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright © 2011 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef _RAQM_H_IN_ -#error "Include instead." -#endif - -#ifndef _RAQM_VERSION_H_ -#define _RAQM_VERSION_H_ - -#define RAQM_VERSION_MAJOR @RAQM_VERSION_MAJOR@ -#define RAQM_VERSION_MINOR @RAQM_VERSION_MINOR@ -#define RAQM_VERSION_MICRO @RAQM_VERSION_MICRO@ - -#define RAQM_VERSION_STRING "@RAQM_VERSION@" - -#define RAQM_VERSION_ATLEAST(major,minor,micro) \ - ((major)*10000+(minor)*100+(micro) <= \ - RAQM_VERSION_MAJOR*10000+RAQM_VERSION_MINOR*100+RAQM_VERSION_MICRO) - -#endif /* _RAQM_VERSION_H_ */ diff --git a/lib/libraqm/raqm.c b/lib/libraqm/raqm.c deleted file mode 100644 index 627eb06b1..000000000 --- a/lib/libraqm/raqm.c +++ /dev/null @@ -1,2080 +0,0 @@ -/* - * Copyright © 2015 Information Technology Authority (ITA) - * Copyright © 2016 Khaled Hosny - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#undef HAVE_CONFIG_H // Workaround for Fribidi 1.0.5 and earlier -#endif - -#include -#include - -#include -#include -#include - -#include "raqm.h" - -#if FRIBIDI_MAJOR_VERSION >= 1 -#define USE_FRIBIDI_EX_API -#endif - -/** - * SECTION:raqm - * @title: Raqm - * @short_description: A library for complex text layout - * @include: raqm.h - * - * Raqm is a light weight text layout library with strong emphasis on - * supporting languages and writing systems that require complex text layout. - * - * The main object in Raqm API is #raqm_t, it stores all the states of the - * input text, its properties, and the output of the layout process. - * - * To start, you create a #raqm_t object, add text and font(s) to it, run the - * layout process, and finally query about the output. For example: - * - * |[ - * #include "raqm.h" - * - * int - * main (int argc, char *argv[]) - * { - * const char *fontfile; - * const char *text; - * const char *direction; - * const char *language; - * int ret = 1; - * - * FT_Library library = NULL; - * FT_Face face = NULL; - * - * if (argc < 5) - * { - * printf ("Usage: %s FONT_FILE TEXT DIRECTION LANG\n", argv[0]); - * return 1; - * } - * - * fontfile = argv[1]; - * text = argv[2]; - * direction = argv[3]; - * language = argv[4]; - * - * if (FT_Init_FreeType (&library) == 0) - * { - * if (FT_New_Face (library, fontfile, 0, &face) == 0) - * { - * if (FT_Set_Char_Size (face, face->units_per_EM, 0, 0, 0) == 0) - * { - * raqm_t *rq = raqm_create (); - * if (rq != NULL) - * { - * raqm_direction_t dir = RAQM_DIRECTION_DEFAULT; - * - * if (strcmp (direction, "r") == 0) - * dir = RAQM_DIRECTION_RTL; - * else if (strcmp (direction, "l") == 0) - * dir = RAQM_DIRECTION_LTR; - * - * if (raqm_set_text_utf8 (rq, text, strlen (text)) && - * raqm_set_freetype_face (rq, face) && - * raqm_set_par_direction (rq, dir) && - * raqm_set_language (rq, language, 0, strlen (text)) && - * raqm_layout (rq)) - * { - * size_t count, i; - * raqm_glyph_t *glyphs = raqm_get_glyphs (rq, &count); - * - * ret = !(glyphs != NULL || count == 0); - * - * printf("glyph count: %zu\n", count); - * for (i = 0; i < count; i++) - * { - * printf ("gid#%d off: (%d, %d) adv: (%d, %d) idx: %d\n", - * glyphs[i].index, - * glyphs[i].x_offset, - * glyphs[i].y_offset, - * glyphs[i].x_advance, - * glyphs[i].y_advance, - * glyphs[i].cluster); - * } - * } - * - * raqm_destroy (rq); - * } - * } - * - * FT_Done_Face (face); - * } - * - * FT_Done_FreeType (library); - * } - * - * return ret; - * } - * ]| - * To compile this example: - * |[ - * cc -o test test.c `pkg-config --libs --cflags raqm` - * ]| - */ - -/* For enabling debug mode */ -/*#define RAQM_DEBUG 1*/ -#ifdef RAQM_DEBUG -#define RAQM_DBG(...) fprintf (stderr, __VA_ARGS__) -#else -#define RAQM_DBG(...) -#endif - -#ifdef RAQM_TESTING -# define RAQM_TEST(...) printf (__VA_ARGS__) -# define SCRIPT_TO_STRING(script) \ - char buff[5]; \ - hb_tag_to_string (hb_script_to_iso15924_tag (script), buff); \ - buff[4] = '\0'; -#else -# define RAQM_TEST(...) -#endif - -typedef enum { - RAQM_FLAG_NONE = 0, - RAQM_FLAG_UTF8 = 1 << 0 -} _raqm_flags_t; - -typedef struct { - FT_Face ftface; - hb_language_t lang; - hb_script_t script; -} _raqm_text_info; - -typedef struct _raqm_run raqm_run_t; - -struct _raqm { - int ref_count; - - uint32_t *text; - char *text_utf8; - size_t text_len; - - _raqm_text_info *text_info; - - raqm_direction_t base_dir; - raqm_direction_t resolved_dir; - - hb_feature_t *features; - size_t features_len; - - raqm_run_t *runs; - raqm_glyph_t *glyphs; - - _raqm_flags_t flags; - - int ft_loadflags; - int invisible_glyph; -}; - -struct _raqm_run { - int pos; - int len; - - hb_direction_t direction; - hb_script_t script; - hb_font_t *font; - hb_buffer_t *buffer; - - raqm_run_t *next; -}; - -static uint32_t -_raqm_u8_to_u32_index (raqm_t *rq, - uint32_t index); - -static bool -_raqm_init_text_info (raqm_t *rq) -{ - hb_language_t default_lang; - - if (rq->text_info) - return true; - - rq->text_info = malloc (sizeof (_raqm_text_info) * rq->text_len); - if (!rq->text_info) - return false; - - default_lang = hb_language_get_default (); - for (size_t i = 0; i < rq->text_len; i++) - { - rq->text_info[i].ftface = NULL; - rq->text_info[i].lang = default_lang; - rq->text_info[i].script = HB_SCRIPT_INVALID; - } - - return true; -} - -static void -_raqm_free_text_info (raqm_t *rq) -{ - if (!rq->text_info) - return; - - for (size_t i = 0; i < rq->text_len; i++) - { - if (rq->text_info[i].ftface) - FT_Done_Face (rq->text_info[i].ftface); - } - - free (rq->text_info); - rq->text_info = NULL; -} - -static bool -_raqm_compare_text_info (_raqm_text_info a, - _raqm_text_info b) -{ - if (a.ftface != b.ftface) - return false; - - if (a.lang != b.lang) - return false; - - if (a.script != b.script) - return false; - - return true; -} - -/** - * raqm_create: - * - * Creates a new #raqm_t with all its internal states initialized to their - * defaults. - * - * Return value: - * A newly allocated #raqm_t with a reference count of 1. The initial reference - * count should be released with raqm_destroy() when you are done using the - * #raqm_t. Returns %NULL in case of error. - * - * Since: 0.1 - */ -raqm_t * -raqm_create (void) -{ - raqm_t *rq; - - rq = malloc (sizeof (raqm_t)); - if (!rq) - return NULL; - - rq->ref_count = 1; - - rq->text = NULL; - rq->text_utf8 = NULL; - rq->text_len = 0; - - rq->text_info = NULL; - - rq->base_dir = RAQM_DIRECTION_DEFAULT; - rq->resolved_dir = RAQM_DIRECTION_DEFAULT; - - rq->features = NULL; - rq->features_len = 0; - - rq->runs = NULL; - rq->glyphs = NULL; - - rq->flags = RAQM_FLAG_NONE; - - rq->ft_loadflags = -1; - rq->invisible_glyph = 0; - - return rq; -} - -/** - * raqm_reference: - * @rq: a #raqm_t. - * - * Increases the reference count on @rq by one. This prevents @rq from being - * destroyed until a matching call to raqm_destroy() is made. - * - * Return value: - * The referenced #raqm_t. - * - * Since: 0.1 - */ -raqm_t * -raqm_reference (raqm_t *rq) -{ - if (rq) - rq->ref_count++; - - return rq; -} - -static void -_raqm_free_runs (raqm_t *rq) -{ - raqm_run_t *runs = rq->runs; - while (runs) - { - raqm_run_t *run = runs; - runs = runs->next; - - hb_buffer_destroy (run->buffer); - hb_font_destroy (run->font); - free (run); - } -} - -/** - * raqm_destroy: - * @rq: a #raqm_t. - * - * Decreases the reference count on @rq by one. If the result is zero, then @rq - * and all associated resources are freed. - * See cairo_reference(). - * - * Since: 0.1 - */ -void -raqm_destroy (raqm_t *rq) -{ - if (!rq || --rq->ref_count != 0) - return; - - free (rq->text); - free (rq->text_utf8); - _raqm_free_text_info (rq); - _raqm_free_runs (rq); - free (rq->glyphs); - free (rq); -} - -/** - * raqm_set_text: - * @rq: a #raqm_t. - * @text: a UTF-32 encoded text string. - * @len: the length of @text. - * - * Adds @text to @rq to be used for layout. It must be a valid UTF-32 text, any - * invalid character will be replaced with U+FFFD. The text should typically - * represent a full paragraph, since doing the layout of chunks of text - * separately can give improper output. - * - * Return value: - * %true if no errors happened, %false otherwise. - * - * Since: 0.1 - */ -bool -raqm_set_text (raqm_t *rq, - const uint32_t *text, - size_t len) -{ - if (!rq || !text) - return false; - - rq->text_len = len; - - /* Empty string, don’t fail but do nothing */ - if (!len) - return true; - - free (rq->text); - - rq->text = malloc (sizeof (uint32_t) * rq->text_len); - if (!rq->text) - return false; - - _raqm_free_text_info (rq); - if (!_raqm_init_text_info (rq)) - return false; - - memcpy (rq->text, text, sizeof (uint32_t) * rq->text_len); - - return true; -} - -/** - * raqm_set_text_utf8: - * @rq: a #raqm_t. - * @text: a UTF-8 encoded text string. - * @len: the length of @text. - * - * Same as raqm_set_text(), but for text encoded in UTF-8 encoding. - * - * Return value: - * %true if no errors happened, %false otherwise. - * - * Since: 0.1 - */ -bool -raqm_set_text_utf8 (raqm_t *rq, - const char *text, - size_t len) -{ - uint32_t *unicode; - size_t ulen; - bool ok; - - if (!rq || !text) - return false; - - /* Empty string, don’t fail but do nothing */ - if (!len) - { - rq->text_len = len; - return true; - } - - RAQM_TEST ("Text is: %s\n", text); - - rq->flags |= RAQM_FLAG_UTF8; - - rq->text_utf8 = malloc (sizeof (char) * len); - if (!rq->text_utf8) - return false; - - unicode = malloc (sizeof (uint32_t) * len); - if (!unicode) - return false; - - memcpy (rq->text_utf8, text, sizeof (char) * len); - - ulen = fribidi_charset_to_unicode (FRIBIDI_CHAR_SET_UTF8, - text, len, unicode); - - ok = raqm_set_text (rq, unicode, ulen); - - free (unicode); - return ok; -} - -/** - * raqm_set_par_direction: - * @rq: a #raqm_t. - * @dir: the direction of the paragraph. - * - * Sets the paragraph direction, also known as block direction in CSS. For - * horizontal text, this controls the overall direction in the Unicode - * Bidirectional Algorithm, so when the text is mainly right-to-left (with or - * without some left-to-right) text, then the base direction should be set to - * #RAQM_DIRECTION_RTL and vice versa. - * - * The default is #RAQM_DIRECTION_DEFAULT, which determines the paragraph - * direction based on the first character with strong bidi type (see [rule - * P2](http://unicode.org/reports/tr9/#P2) in Unicode Bidirectional Algorithm), - * which can be good enough for many cases but has problems when a mainly - * right-to-left paragraph starts with a left-to-right character and vice versa - * as the detected paragraph direction will be the wrong one, or when text does - * not contain any characters with string bidi types (e.g. only punctuation or - * numbers) as this will default to left-to-right paragraph direction. - * - * For vertical, top-to-bottom text, #RAQM_DIRECTION_TTB should be used. Raqm, - * however, provides limited vertical text support and does not handle rotated - * horizontal text in vertical text, instead everything is treated as vertical - * text. - * - * Return value: - * %true if no errors happened, %false otherwise. - * - * Since: 0.1 - */ -bool -raqm_set_par_direction (raqm_t *rq, - raqm_direction_t dir) -{ - if (!rq) - return false; - - rq->base_dir = dir; - - return true; -} - -/** - * raqm_set_language: - * @rq: a #raqm_t. - * @lang: a BCP47 language code. - * @start: index of first character that should use @face. - * @len: number of characters using @face. - * - * Sets a [BCP47 language - * code](https://www.w3.org/International/articles/language-tags/) to be used - * for @len-number of characters staring at @start. The @start and @len are - * input string array indices (i.e. counting bytes in UTF-8 and scaler values - * in UTF-32). - * - * This method can be used repeatedly to set different languages for different - * parts of the text. - * - * Return value: - * %true if no errors happened, %false otherwise. - * - * Stability: - * Unstable - * - * Since: 0.2 - */ -bool -raqm_set_language (raqm_t *rq, - const char *lang, - size_t start, - size_t len) -{ - hb_language_t language; - size_t end = start + len; - - if (!rq) - return false; - - if (!rq->text_len) - return true; - - if (rq->flags & RAQM_FLAG_UTF8) - { - start = _raqm_u8_to_u32_index (rq, start); - end = _raqm_u8_to_u32_index (rq, end); - } - - if (start >= rq->text_len || end > rq->text_len) - return false; - - if (!rq->text_info) - return false; - - language = hb_language_from_string (lang, -1); - for (size_t i = start; i < end; i++) - { - rq->text_info[i].lang = language; - } - - return true; -} - -/** - * raqm_add_font_feature: - * @rq: a #raqm_t. - * @feature: (transfer none): a font feature string. - * @len: length of @feature, -1 for %NULL-terminated. - * - * Adds a font feature to be used by the #raqm_t during text layout. This is - * usually used to turn on optional font features that are not enabled by - * default, for example `dlig` or `ss01`, but can be also used to turn off - * default font features. - * - * @feature is string representing a single font feature, in the syntax - * understood by hb_feature_from_string(). - * - * This function can be called repeatedly, new features will be appended to the - * end of the features list and can potentially override previous features. - * - * Return value: - * %true if parsing @feature succeeded, %false otherwise. - * - * Since: 0.1 - */ -bool -raqm_add_font_feature (raqm_t *rq, - const char *feature, - int len) -{ - hb_bool_t ok; - hb_feature_t fea; - - if (!rq) - return false; - - ok = hb_feature_from_string (feature, len, &fea); - if (ok) - { - rq->features_len++; - rq->features = realloc (rq->features, - sizeof (hb_feature_t) * (rq->features_len)); - if (!rq->features) - return false; - - rq->features[rq->features_len - 1] = fea; - } - - return ok; -} - -static hb_font_t * -_raqm_create_hb_font (raqm_t *rq, - FT_Face face) -{ - hb_font_t *font; - -#ifdef HAVE_HB_FT_FONT_CREATE_REFERENCED - font = hb_ft_font_create_referenced (face); -#else - FT_Reference_Face (face); - font = hb_ft_font_create (face, (hb_destroy_func_t) FT_Done_Face); -#endif - -#ifdef HAVE_HB_FT_FONT_SET_LOAD_FLAGS - if (rq->ft_loadflags >= 0) - hb_ft_font_set_load_flags (font, rq->ft_loadflags); -#else - (void)rq; -#endif - - return font; -} - -static bool -_raqm_set_freetype_face (raqm_t *rq, - FT_Face face, - size_t start, - size_t end) -{ - if (!rq) - return false; - - if (!rq->text_len) - return true; - - if (start >= rq->text_len || end > rq->text_len) - return false; - - if (!rq->text_info) - return false; - - for (size_t i = start; i < end; i++) - { - if (rq->text_info[i].ftface) - FT_Done_Face (rq->text_info[i].ftface); - rq->text_info[i].ftface = face; - FT_Reference_Face (face); - } - - return true; -} - -/** - * raqm_set_freetype_face: - * @rq: a #raqm_t. - * @face: an #FT_Face. - * - * Sets an #FT_Face to be used for all characters in @rq. - * - * See also raqm_set_freetype_face_range(). - * - * Return value: - * %true if no errors happened, %false otherwise. - * - * Since: 0.1 - */ -bool -raqm_set_freetype_face (raqm_t *rq, - FT_Face face) -{ - return _raqm_set_freetype_face (rq, face, 0, rq->text_len); -} - -/** - * raqm_set_freetype_face_range: - * @rq: a #raqm_t. - * @face: an #FT_Face. - * @start: index of first character that should use @face. - * @len: number of characters using @face. - * - * Sets an #FT_Face to be used for @len-number of characters staring at @start. - * The @start and @len are input string array indices (i.e. counting bytes in - * UTF-8 and scaler values in UTF-32). - * - * This method can be used repeatedly to set different faces for different - * parts of the text. It is the responsibility of the client to make sure that - * face ranges cover the whole text. - * - * See also raqm_set_freetype_face(). - * - * Return value: - * %true if no errors happened, %false otherwise. - * - * Since: 0.1 - */ -bool -raqm_set_freetype_face_range (raqm_t *rq, - FT_Face face, - size_t start, - size_t len) -{ - size_t end = start + len; - - if (!rq) - return false; - - if (!rq->text_len) - return true; - - if (rq->flags & RAQM_FLAG_UTF8) - { - start = _raqm_u8_to_u32_index (rq, start); - end = _raqm_u8_to_u32_index (rq, end); - } - - return _raqm_set_freetype_face (rq, face, start, end); -} - -/** - * raqm_set_freetype_load_flags: - * @rq: a #raqm_t. - * @flags: FreeType load flags. - * - * Sets the load flags passed to FreeType when loading glyphs, should be the - * same flags used by the client when rendering FreeType glyphs. - * - * This requires version of HarfBuzz that has hb_ft_font_set_load_flags(), for - * older version the flags will be ignored. - * - * Return value: - * %true if no errors happened, %false otherwise. - * - * Since: 0.3 - */ -bool -raqm_set_freetype_load_flags (raqm_t *rq, - int flags) -{ - if (!rq) - return false; - - rq->ft_loadflags = flags; - - return true; -} - -/** - * raqm_set_invisible_glyph: - * @rq: a #raqm_t. - * @gid: glyph id to use for invisible glyphs. - * - * Sets the glyph id to be used for invisible glyhphs. - * - * If @gid is negative, invisible glyphs will be suppressed from the output. - * This requires HarfBuzz 1.8.0 or later. If raqm is used with an earlier - * HarfBuzz version, the return value will be %false and the shaping behavior - * does not change. - * - * If @gid is zero, invisible glyphs will be rendered as space. - * This works on all versions of HarfBuzz. - * - * If @gid is a positive number, it will be used for invisible glyphs. - * This requires a version of HarfBuzz that has - * hb_buffer_set_invisible_glyph(). For older versions, the return value - * will be %false and the shaping behavior does not change. - * - * Return value: - * %true if no errors happened, %false otherwise. - * - * Since: 0.6 - */ -bool -raqm_set_invisible_glyph (raqm_t *rq, - int gid) -{ - if (!rq) - return false; - -#ifndef HAVE_HB_BUFFER_SET_INVISIBLE_GLYPH - if (gid > 0) - return false; -#endif - -#if !defined(HAVE_DECL_HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) || \ - !HAVE_DECL_HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES - if (gid < 0) - return false; -#endif - - rq->invisible_glyph = gid; - return true; -} - -static bool -_raqm_itemize (raqm_t *rq); - -static bool -_raqm_shape (raqm_t *rq); - -/** - * raqm_layout: - * @rq: a #raqm_t. - * - * Run the text layout process on @rq. This is the main Raqm function where the - * Unicode Bidirectional Text algorithm will be applied to the text in @rq, - * text shaping, and any other part of the layout process. - * - * Return value: - * %true if the layout process was successful, %false otherwise. - * - * Since: 0.1 - */ -bool -raqm_layout (raqm_t *rq) -{ - if (!rq) - return false; - - if (!rq->text_len) - return true; - - if (!rq->text_info) - return false; - - for (size_t i = 0; i < rq->text_len; i++) - { - if (!rq->text_info[i].ftface) - return false; - } - - if (!_raqm_itemize (rq)) - return false; - - if (!_raqm_shape (rq)) - return false; - - return true; -} - -static uint32_t -_raqm_u32_to_u8_index (raqm_t *rq, - uint32_t index); - -/** - * raqm_get_glyphs: - * @rq: a #raqm_t. - * @length: (out): output array length. - * - * Gets the final result of Raqm layout process, an array of #raqm_glyph_t - * containing the glyph indices in the font, their positions and other possible - * information. - * - * Return value: (transfer none): - * An array of #raqm_glyph_t, or %NULL in case of error. This is owned by @rq - * and must not be freed. - * - * Since: 0.1 - */ -raqm_glyph_t * -raqm_get_glyphs (raqm_t *rq, - size_t *length) -{ - size_t count = 0; - - if (!rq || !rq->runs || !length) - { - if (length) - *length = 0; - return NULL; - } - - for (raqm_run_t *run = rq->runs; run != NULL; run = run->next) - count += hb_buffer_get_length (run->buffer); - - *length = count; - - if (rq->glyphs) - free (rq->glyphs); - - rq->glyphs = malloc (sizeof (raqm_glyph_t) * count); - if (!rq->glyphs) - { - *length = 0; - return NULL; - } - - RAQM_TEST ("Glyph information:\n"); - - count = 0; - for (raqm_run_t *run = rq->runs; run != NULL; run = run->next) - { - size_t len; - hb_glyph_info_t *info; - hb_glyph_position_t *position; - - len = hb_buffer_get_length (run->buffer); - info = hb_buffer_get_glyph_infos (run->buffer, NULL); - position = hb_buffer_get_glyph_positions (run->buffer, NULL); - - for (size_t i = 0; i < len; i++) - { - rq->glyphs[count + i].index = info[i].codepoint; - rq->glyphs[count + i].cluster = info[i].cluster; - rq->glyphs[count + i].x_advance = position[i].x_advance; - rq->glyphs[count + i].y_advance = position[i].y_advance; - rq->glyphs[count + i].x_offset = position[i].x_offset; - rq->glyphs[count + i].y_offset = position[i].y_offset; - rq->glyphs[count + i].ftface = rq->text_info[info[i].cluster].ftface; - - RAQM_TEST ("glyph [%d]\tx_offset: %d\ty_offset: %d\tx_advance: %d\tfont: %s\n", - rq->glyphs[count + i].index, rq->glyphs[count + i].x_offset, - rq->glyphs[count + i].y_offset, rq->glyphs[count + i].x_advance, - rq->glyphs[count + i].ftface->family_name); - } - - count += len; - } - - if (rq->flags & RAQM_FLAG_UTF8) - { -#ifdef RAQM_TESTING - RAQM_TEST ("\nUTF-32 clusters:"); - for (size_t i = 0; i < count; i++) - RAQM_TEST (" %02d", rq->glyphs[i].cluster); - RAQM_TEST ("\n"); -#endif - - for (size_t i = 0; i < count; i++) - rq->glyphs[i].cluster = _raqm_u32_to_u8_index (rq, - rq->glyphs[i].cluster); - -#ifdef RAQM_TESTING - RAQM_TEST ("UTF-8 clusters: "); - for (size_t i = 0; i < count; i++) - RAQM_TEST (" %02d", rq->glyphs[i].cluster); - RAQM_TEST ("\n"); -#endif - } - return rq->glyphs; -} - -static bool -_raqm_resolve_scripts (raqm_t *rq); - -static hb_direction_t -_raqm_hb_dir (raqm_t *rq, FriBidiLevel level) -{ - hb_direction_t dir = HB_DIRECTION_LTR; - - if (rq->base_dir == RAQM_DIRECTION_TTB) - dir = HB_DIRECTION_TTB; - else if (FRIBIDI_LEVEL_IS_RTL (level)) - dir = HB_DIRECTION_RTL; - - return dir; -} - -typedef struct { - size_t pos; - size_t len; - FriBidiLevel level; -} _raqm_bidi_run; - -static void -_raqm_reverse_run (_raqm_bidi_run *run, const size_t len) -{ - assert (run); - - for (size_t i = 0; i < len / 2; i++) - { - _raqm_bidi_run temp = run[i]; - run[i] = run[len - 1 - i]; - run[len - 1 - i] = temp; - } -} - -static _raqm_bidi_run * -_raqm_reorder_runs (const FriBidiCharType *types, - const size_t len, - const FriBidiParType base_dir, - /* input and output */ - FriBidiLevel *levels, - /* output */ - size_t *run_count) -{ - FriBidiLevel level; - FriBidiLevel last_level = -1; - FriBidiLevel max_level = 0; - size_t run_start = 0; - size_t run_index = 0; - _raqm_bidi_run *runs = NULL; - size_t count = 0; - - if (len == 0) - { - *run_count = 0; - return NULL; - } - - assert (types); - assert (levels); - - /* L1. Reset the embedding levels of some chars: - 4. any sequence of white space characters at the end of the line. */ - for (int i = len - 1; - i >= 0 && FRIBIDI_IS_EXPLICIT_OR_BN_OR_WS (types[i]); i--) - { - levels[i] = FRIBIDI_DIR_TO_LEVEL (base_dir); - } - - /* Find max_level of the line. We don't reuse the paragraph - * max_level, both for a cleaner API, and that the line max_level - * may be far less than paragraph max_level. */ - for (int i = len - 1; i >= 0; i--) - { - if (levels[i] > max_level) - max_level = levels[i]; - } - - for (size_t i = 0; i < len; i++) - { - if (levels[i] != last_level) - count++; - - last_level = levels[i]; - } - - runs = malloc (sizeof (_raqm_bidi_run) * count); - - while (run_start < len) - { - size_t run_end = run_start; - while (run_end < len && levels[run_start] == levels[run_end]) - { - run_end++; - } - - runs[run_index].pos = run_start; - runs[run_index].level = levels[run_start]; - runs[run_index].len = run_end - run_start; - run_start = run_end; - run_index++; - } - - /* L2. Reorder. */ - for (level = max_level; level > 0; level--) - { - for (int i = count - 1; i >= 0; i--) - { - if (runs[i].level >= level) - { - int end = i; - for (i--; (i >= 0 && runs[i].level >= level); i--) - ; - _raqm_reverse_run (runs + i + 1, end - i); - } - } - } - - *run_count = count; - return runs; -} - -static bool -_raqm_itemize (raqm_t *rq) -{ - FriBidiParType par_type = FRIBIDI_PAR_ON; - FriBidiCharType *types; -#ifdef USE_FRIBIDI_EX_API - FriBidiBracketType *btypes; -#endif - FriBidiLevel *levels; - _raqm_bidi_run *runs = NULL; - raqm_run_t *last; - int max_level; - size_t run_count; - bool ok = true; - -#ifdef RAQM_TESTING - switch (rq->base_dir) - { - case RAQM_DIRECTION_RTL: - RAQM_TEST ("Direction is: RTL\n\n"); - break; - case RAQM_DIRECTION_LTR: - RAQM_TEST ("Direction is: LTR\n\n"); - break; - case RAQM_DIRECTION_TTB: - RAQM_TEST ("Direction is: TTB\n\n"); - break; - case RAQM_DIRECTION_DEFAULT: - default: - RAQM_TEST ("Direction is: DEFAULT\n\n"); - break; - } -#endif - - types = calloc (rq->text_len, sizeof (FriBidiCharType)); -#ifdef USE_FRIBIDI_EX_API - btypes = calloc (rq->text_len, sizeof (FriBidiBracketType)); -#endif - levels = calloc (rq->text_len, sizeof (FriBidiLevel)); - if (!types || !levels -#ifdef USE_FRIBIDI_EX_API - || !btypes -#endif - ) - { - ok = false; - goto done; - } - - if (rq->base_dir == RAQM_DIRECTION_RTL) - par_type = FRIBIDI_PAR_RTL; - else if (rq->base_dir == RAQM_DIRECTION_LTR) - par_type = FRIBIDI_PAR_LTR; - - if (rq->base_dir == RAQM_DIRECTION_TTB) - { - /* Treat every thing as LTR in vertical text */ - max_level = 1; - memset (types, FRIBIDI_TYPE_LTR, rq->text_len); - memset (levels, 0, rq->text_len); - rq->resolved_dir = RAQM_DIRECTION_LTR; - } - else - { - fribidi_get_bidi_types (rq->text, rq->text_len, types); -#ifdef USE_FRIBIDI_EX_API - fribidi_get_bracket_types (rq->text, rq->text_len, types, btypes); - max_level = fribidi_get_par_embedding_levels_ex (types, btypes, - rq->text_len, &par_type, - levels); -#else - max_level = fribidi_get_par_embedding_levels (types, rq->text_len, - &par_type, levels); -#endif - - if (par_type == FRIBIDI_PAR_LTR) - rq->resolved_dir = RAQM_DIRECTION_LTR; - else - rq->resolved_dir = RAQM_DIRECTION_RTL; - } - - if (max_level == 0) - { - ok = false; - goto done; - } - - if (!_raqm_resolve_scripts (rq)) - { - ok = false; - goto done; - } - - /* Get the number of bidi runs */ - runs = _raqm_reorder_runs (types, rq->text_len, par_type, levels, &run_count); - if (!runs) - { - ok = false; - goto done; - } - -#ifdef RAQM_TESTING - RAQM_TEST ("Number of runs before script itemization: %zu\n\n", run_count); - - RAQM_TEST ("Fribidi Runs:\n"); - for (size_t i = 0; i < run_count; i++) - { - RAQM_TEST ("run[%zu]:\t start: %zu\tlength: %zu\tlevel: %d\n", - i, runs[i].pos, runs[i].len, runs[i].level); - } - RAQM_TEST ("\n"); -#endif - - last = NULL; - for (size_t i = 0; i < run_count; i++) - { - raqm_run_t *run = calloc (1, sizeof (raqm_run_t)); - if (!run) - { - ok = false; - goto done; - } - - if (!rq->runs) - rq->runs = run; - - if (last) - last->next = run; - - run->direction = _raqm_hb_dir (rq, runs[i].level); - - if (HB_DIRECTION_IS_BACKWARD (run->direction)) - { - run->pos = runs[i].pos + runs[i].len - 1; - run->script = rq->text_info[run->pos].script; - run->font = _raqm_create_hb_font (rq, rq->text_info[run->pos].ftface); - for (int j = runs[i].len - 1; j >= 0; j--) - { - _raqm_text_info info = rq->text_info[runs[i].pos + j]; - if (!_raqm_compare_text_info (rq->text_info[run->pos], info)) - { - raqm_run_t *newrun = calloc (1, sizeof (raqm_run_t)); - if (!newrun) - { - ok = false; - goto done; - } - newrun->pos = runs[i].pos + j; - newrun->len = 1; - newrun->direction = _raqm_hb_dir (rq, runs[i].level); - newrun->script = info.script; - newrun->font = _raqm_create_hb_font (rq, info.ftface); - run->next = newrun; - run = newrun; - } - else - { - run->len++; - run->pos = runs[i].pos + j; - } - } - } - else - { - run->pos = runs[i].pos; - run->script = rq->text_info[run->pos].script; - run->font = _raqm_create_hb_font (rq, rq->text_info[run->pos].ftface); - for (size_t j = 0; j < runs[i].len; j++) - { - _raqm_text_info info = rq->text_info[runs[i].pos + j]; - if (!_raqm_compare_text_info (rq->text_info[run->pos], info)) - { - raqm_run_t *newrun = calloc (1, sizeof (raqm_run_t)); - if (!newrun) - { - ok = false; - goto done; - } - newrun->pos = runs[i].pos + j; - newrun->len = 1; - newrun->direction = _raqm_hb_dir (rq, runs[i].level); - newrun->script = info.script; - newrun->font = _raqm_create_hb_font (rq, info.ftface); - run->next = newrun; - run = newrun; - } - else - run->len++; - } - } - - last = run; - last->next = NULL; - } - -#ifdef RAQM_TESTING - run_count = 0; - for (raqm_run_t *run = rq->runs; run != NULL; run = run->next) - run_count++; - RAQM_TEST ("Number of runs after script itemization: %zu\n\n", run_count); - - run_count = 0; - RAQM_TEST ("Final Runs:\n"); - for (raqm_run_t *run = rq->runs; run != NULL; run = run->next) - { - SCRIPT_TO_STRING (run->script); - RAQM_TEST ("run[%zu]:\t start: %d\tlength: %d\tdirection: %s\tscript: %s\tfont: %s\n", - run_count++, run->pos, run->len, - hb_direction_to_string (run->direction), buff, - rq->text_info[run->pos].ftface->family_name); - } - RAQM_TEST ("\n"); -#endif - -done: - free (runs); - free (types); -#ifdef USE_FRIBIDI_EX_API - free (btypes); -#endif - free (levels); - - return ok; -} - -/* Stack to handle script detection */ -typedef struct { - size_t capacity; - size_t size; - int *pair_index; - hb_script_t *script; -} _raqm_stack_t; - -/* Special paired characters for script detection */ -static size_t paired_len = 34; -static const FriBidiChar paired_chars[] = -{ - 0x0028, 0x0029, /* ascii paired punctuation */ - 0x003c, 0x003e, - 0x005b, 0x005d, - 0x007b, 0x007d, - 0x00ab, 0x00bb, /* guillemets */ - 0x2018, 0x2019, /* general punctuation */ - 0x201c, 0x201d, - 0x2039, 0x203a, - 0x3008, 0x3009, /* chinese paired punctuation */ - 0x300a, 0x300b, - 0x300c, 0x300d, - 0x300e, 0x300f, - 0x3010, 0x3011, - 0x3014, 0x3015, - 0x3016, 0x3017, - 0x3018, 0x3019, - 0x301a, 0x301b -}; - -static void -_raqm_stack_free (_raqm_stack_t *stack) -{ - free (stack->script); - free (stack->pair_index); - free (stack); -} - -/* Stack handling functions */ -static _raqm_stack_t * -_raqm_stack_new (size_t max) -{ - _raqm_stack_t *stack; - stack = calloc (1, sizeof (_raqm_stack_t)); - if (!stack) - return NULL; - - stack->script = malloc (sizeof (hb_script_t) * max); - if (!stack->script) - { - _raqm_stack_free (stack); - return NULL; - } - - stack->pair_index = malloc (sizeof (int) * max); - if (!stack->pair_index) - { - _raqm_stack_free (stack); - return NULL; - } - - stack->size = 0; - stack->capacity = max; - - return stack; -} - -static bool -_raqm_stack_pop (_raqm_stack_t *stack) -{ - if (!stack->size) - { - RAQM_DBG ("Stack is Empty\n"); - return false; - } - - stack->size--; - - return true; -} - -static hb_script_t -_raqm_stack_top (_raqm_stack_t *stack) -{ - if (!stack->size) - { - RAQM_DBG ("Stack is Empty\n"); - return HB_SCRIPT_INVALID; /* XXX: check this */ - } - - return stack->script[stack->size]; -} - -static bool -_raqm_stack_push (_raqm_stack_t *stack, - hb_script_t script, - int pair_index) -{ - if (stack->size == stack->capacity) - { - RAQM_DBG ("Stack is Full\n"); - return false; - } - - stack->size++; - stack->script[stack->size] = script; - stack->pair_index[stack->size] = pair_index; - - return true; -} - -static int -_get_pair_index (const FriBidiChar ch) -{ - int lower = 0; - int upper = paired_len - 1; - - while (lower <= upper) - { - int mid = (lower + upper) / 2; - if (ch < paired_chars[mid]) - upper = mid - 1; - else if (ch > paired_chars[mid]) - lower = mid + 1; - else - return mid; - } - - return -1; -} - -#define STACK_IS_EMPTY(script) ((script)->size <= 0) -#define IS_OPEN(pair_index) (((pair_index) & 1) == 0) - -/* Resolve the script for each character in the input string, if the character - * script is common or inherited it takes the script of the character before it - * except paired characters which we try to make them use the same script. We - * then split the BiDi runs, if necessary, on script boundaries. - */ -static bool -_raqm_resolve_scripts (raqm_t *rq) -{ - int last_script_index = -1; - int last_set_index = -1; - hb_script_t last_script = HB_SCRIPT_INVALID; - _raqm_stack_t *stack = NULL; - hb_unicode_funcs_t* unicode_funcs = hb_unicode_funcs_get_default (); - - for (size_t i = 0; i < rq->text_len; ++i) - rq->text_info[i].script = hb_unicode_script (unicode_funcs, rq->text[i]); - -#ifdef RAQM_TESTING - RAQM_TEST ("Before script detection:\n"); - for (size_t i = 0; i < rq->text_len; ++i) - { - SCRIPT_TO_STRING (rq->text_info[i].script); - RAQM_TEST ("script for ch[%zu]\t%s\n", i, buff); - } - RAQM_TEST ("\n"); -#endif - - stack = _raqm_stack_new (rq->text_len); - if (!stack) - return false; - - for (int i = 0; i < (int) rq->text_len; i++) - { - if (rq->text_info[i].script == HB_SCRIPT_COMMON && last_script_index != -1) - { - int pair_index = _get_pair_index (rq->text[i]); - if (pair_index >= 0) - { - if (IS_OPEN (pair_index)) - { - /* is a paired character */ - rq->text_info[i].script = last_script; - last_set_index = i; - _raqm_stack_push (stack, rq->text_info[i].script, pair_index); - } - else - { - /* is a close paired character */ - /* find matching opening (by getting the last even index for current - * odd index) */ - while (!STACK_IS_EMPTY (stack) && - stack->pair_index[stack->size] != (pair_index & ~1)) - { - _raqm_stack_pop (stack); - } - if (!STACK_IS_EMPTY (stack)) - { - rq->text_info[i].script = _raqm_stack_top (stack); - last_script = rq->text_info[i].script; - last_set_index = i; - } - else - { - rq->text_info[i].script = last_script; - last_set_index = i; - } - } - } - else - { - rq->text_info[i].script = last_script; - last_set_index = i; - } - } - else if (rq->text_info[i].script == HB_SCRIPT_INHERITED && - last_script_index != -1) - { - rq->text_info[i].script = last_script; - last_set_index = i; - } - else - { - for (int j = last_set_index + 1; j < i; ++j) - rq->text_info[j].script = rq->text_info[i].script; - last_script = rq->text_info[i].script; - last_script_index = i; - last_set_index = i; - } - } - - /* Loop backwards and change any remaining Common or Inherit characters to - * take the script if the next character. - * https://github.com/HOST-Oman/libraqm/issues/95 - */ - for (int i = rq->text_len - 2; i >= 0; --i) - { - if (rq->text_info[i].script == HB_SCRIPT_INHERITED || - rq->text_info[i].script == HB_SCRIPT_COMMON) - rq->text_info[i].script = rq->text_info[i + 1].script; - } - -#ifdef RAQM_TESTING - RAQM_TEST ("After script detection:\n"); - for (size_t i = 0; i < rq->text_len; ++i) - { - SCRIPT_TO_STRING (rq->text_info[i].script); - RAQM_TEST ("script for ch[%zu]\t%s\n", i, buff); - } - RAQM_TEST ("\n"); -#endif - - _raqm_stack_free (stack); - - return true; -} - -static bool -_raqm_shape (raqm_t *rq) -{ - hb_buffer_flags_t hb_buffer_flags = HB_BUFFER_FLAG_BOT | HB_BUFFER_FLAG_EOT; - -#if defined(HAVE_DECL_HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) && \ - HAVE_DECL_HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES - if (rq->invisible_glyph < 0) - hb_buffer_flags |= HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES; -#endif - - for (raqm_run_t *run = rq->runs; run != NULL; run = run->next) - { - run->buffer = hb_buffer_create (); - - hb_buffer_add_utf32 (run->buffer, rq->text, rq->text_len, - run->pos, run->len); - hb_buffer_set_script (run->buffer, run->script); - hb_buffer_set_language (run->buffer, rq->text_info[run->pos].lang); - hb_buffer_set_direction (run->buffer, run->direction); - hb_buffer_set_flags (run->buffer, hb_buffer_flags); - -#ifdef HAVE_HB_BUFFER_SET_INVISIBLE_GLYPH - if (rq->invisible_glyph > 0) - hb_buffer_set_invisible_glyph (run->buffer, rq->invisible_glyph); -#endif - - hb_shape_full (run->font, run->buffer, rq->features, rq->features_len, - NULL); - } - - return true; -} - -/* Convert index from UTF-32 to UTF-8 */ -static uint32_t -_raqm_u32_to_u8_index (raqm_t *rq, - uint32_t index) -{ - FriBidiStrIndex length; - char *output = malloc ((sizeof (char) * 4 * index) + 1); - - length = fribidi_unicode_to_charset (FRIBIDI_CHAR_SET_UTF8, - rq->text, - index, - output); - - free (output); - return length; -} - -/* Convert index from UTF-8 to UTF-32 */ -static uint32_t -_raqm_u8_to_u32_index (raqm_t *rq, - uint32_t index) -{ - FriBidiStrIndex length; - uint32_t *output = malloc (sizeof (uint32_t) * (index + 1)); - - length = fribidi_charset_to_unicode (FRIBIDI_CHAR_SET_UTF8, - rq->text_utf8, - index, - output); - - free (output); - return length; -} - -static bool -_raqm_allowed_grapheme_boundary (hb_codepoint_t l_char, - hb_codepoint_t r_char); - -static bool -_raqm_in_hangul_syllable (hb_codepoint_t ch); - -/** - * raqm_index_to_position: - * @rq: a #raqm_t. - * @index: (inout): character index. - * @x: (out): output x position. - * @y: (out): output y position. - * - * Calculates the cursor position after the character at @index. If the character - * is right-to-left, then the cursor will be at the left of it, whereas if the - * character is left-to-right, then the cursor will be at the right of it. - * - * Return value: - * %true if the process was successful, %false otherwise. - * - * Since: 0.2 - */ -bool -raqm_index_to_position (raqm_t *rq, - size_t *index, - int *x, - int *y) -{ - /* We don't currently support multiline, so y is always 0 */ - *y = 0; - *x = 0; - - if (rq == NULL) - return false; - - if (rq->flags & RAQM_FLAG_UTF8) - *index = _raqm_u8_to_u32_index (rq, *index); - - if (*index >= rq->text_len) - return false; - - RAQM_TEST ("\n"); - - while (*index < rq->text_len) - { - if (_raqm_allowed_grapheme_boundary (rq->text[*index], rq->text[*index + 1])) - break; - - ++*index; - } - - for (raqm_run_t *run = rq->runs; run != NULL; run = run->next) - { - size_t len; - hb_glyph_info_t *info; - hb_glyph_position_t *position; - len = hb_buffer_get_length (run->buffer); - info = hb_buffer_get_glyph_infos (run->buffer, NULL); - position = hb_buffer_get_glyph_positions (run->buffer, NULL); - - for (size_t i = 0; i < len; i++) - { - uint32_t curr_cluster = info[i].cluster; - uint32_t next_cluster = curr_cluster; - *x += position[i].x_advance; - - if (run->direction == HB_DIRECTION_LTR) - { - for (size_t j = i + 1; j < len && next_cluster == curr_cluster; j++) - next_cluster = info[j].cluster; - } - else - { - for (int j = i - 1; i != 0 && j >= 0 && next_cluster == curr_cluster; - j--) - next_cluster = info[j].cluster; - } - - if (next_cluster == curr_cluster) - next_cluster = run->pos + run->len; - - if (*index < next_cluster && *index >= curr_cluster) - { - if (run->direction == HB_DIRECTION_RTL) - *x -= position[i].x_advance; - *index = curr_cluster; - goto found; - } - } - } - -found: - if (rq->flags & RAQM_FLAG_UTF8) - *index = _raqm_u32_to_u8_index (rq, *index); - RAQM_TEST ("The position is %d at index %zu\n",*x ,*index); - return true; -} - -/** - * raqm_position_to_index: - * @rq: a #raqm_t. - * @x: x position. - * @y: y position. - * @index: (out): output character index. - * - * Returns the @index of the character at @x and @y position within text. - * If the position is outside the text, the last character is chosen as - * @index. - * - * Return value: - * %true if the process was successful, %false in case of error. - * - * Since: 0.2 - */ -bool -raqm_position_to_index (raqm_t *rq, - int x, - int y, - size_t *index) -{ - int delta_x = 0, current_x = 0; - (void)y; - - if (rq == NULL) - return false; - - if (x < 0) /* Get leftmost index */ - { - if (rq->resolved_dir == RAQM_DIRECTION_RTL) - *index = rq->text_len; - else - *index = 0; - return true; - } - - RAQM_TEST ("\n"); - - for (raqm_run_t *run = rq->runs; run != NULL; run = run->next) - { - size_t len; - hb_glyph_info_t *info; - hb_glyph_position_t *position; - len = hb_buffer_get_length (run->buffer); - info = hb_buffer_get_glyph_infos (run->buffer, NULL); - position = hb_buffer_get_glyph_positions (run->buffer, NULL); - - for (size_t i = 0; i < len; i++) - { - delta_x = position[i].x_advance; - if (x < (current_x + delta_x)) - { - bool before = false; - if (run->direction == HB_DIRECTION_LTR) - before = (x < current_x + (delta_x / 2)); - else - before = (x > current_x + (delta_x / 2)); - - if (before) - *index = info[i].cluster; - else - { - uint32_t curr_cluster = info[i].cluster; - uint32_t next_cluster = curr_cluster; - if (run->direction == HB_DIRECTION_LTR) - for (size_t j = i + 1; j < len && next_cluster == curr_cluster; j++) - next_cluster = info[j].cluster; - else - for (int j = i - 1; i != 0 && j >= 0 && next_cluster == curr_cluster; - j--) - next_cluster = info[j].cluster; - - if (next_cluster == curr_cluster) - next_cluster = run->pos + run->len; - - *index = next_cluster; - } - if (_raqm_allowed_grapheme_boundary (rq->text[*index],rq->text[*index + 1])) - { - RAQM_TEST ("The start-index is %zu at position %d \n", *index, x); - return true; - } - - while (*index < (unsigned)run->pos + run->len) - { - if (_raqm_allowed_grapheme_boundary (rq->text[*index], - rq->text[*index + 1])) - { - *index += 1; - break; - } - *index += 1; - } - RAQM_TEST ("The start-index is %zu at position %d \n", *index, x); - return true; - } - else - current_x += delta_x; - } - } - - /* Get rightmost index*/ - if (rq->resolved_dir == RAQM_DIRECTION_RTL) - *index = 0; - else - *index = rq->text_len; - - RAQM_TEST ("The start-index is %zu at position %d \n", *index, x); - - return true; -} - -typedef enum -{ - RAQM_GRAPHEM_CR, - RAQM_GRAPHEM_LF, - RAQM_GRAPHEM_CONTROL, - RAQM_GRAPHEM_EXTEND, - RAQM_GRAPHEM_REGIONAL_INDICATOR, - RAQM_GRAPHEM_PREPEND, - RAQM_GRAPHEM_SPACING_MARK, - RAQM_GRAPHEM_HANGUL_SYLLABLE, - RAQM_GRAPHEM_OTHER -} _raqm_grapheme_t; - -static _raqm_grapheme_t -_raqm_get_grapheme_break (hb_codepoint_t ch, - hb_unicode_general_category_t category); - -static bool -_raqm_allowed_grapheme_boundary (hb_codepoint_t l_char, - hb_codepoint_t r_char) -{ - hb_unicode_general_category_t l_category; - hb_unicode_general_category_t r_category; - _raqm_grapheme_t l_grapheme, r_grapheme; - hb_unicode_funcs_t* unicode_funcs = hb_unicode_funcs_get_default (); - - l_category = hb_unicode_general_category (unicode_funcs, l_char); - r_category = hb_unicode_general_category (unicode_funcs, r_char); - l_grapheme = _raqm_get_grapheme_break (l_char, l_category); - r_grapheme = _raqm_get_grapheme_break (r_char, r_category); - - if (l_grapheme == RAQM_GRAPHEM_CR && r_grapheme == RAQM_GRAPHEM_LF) - return false; /*Do not break between a CR and LF GB3*/ - if (l_grapheme == RAQM_GRAPHEM_CONTROL || l_grapheme == RAQM_GRAPHEM_CR || - l_grapheme == RAQM_GRAPHEM_LF || r_grapheme == RAQM_GRAPHEM_CONTROL || - r_grapheme == RAQM_GRAPHEM_CR || r_grapheme == RAQM_GRAPHEM_LF) - return true; /*Break before and after CONTROL GB4, GB5*/ - if (r_grapheme == RAQM_GRAPHEM_HANGUL_SYLLABLE) - return false; /*Do not break Hangul syllable sequences. GB6, GB7, GB8*/ - if (l_grapheme == RAQM_GRAPHEM_REGIONAL_INDICATOR && - r_grapheme == RAQM_GRAPHEM_REGIONAL_INDICATOR) - return false; /*Do not break between regional indicator symbols. GB8a*/ - if (r_grapheme == RAQM_GRAPHEM_EXTEND) - return false; /*Do not break before extending characters. GB9*/ - /*Do not break before SpacingMarks, or after Prepend characters.GB9a, GB9b*/ - if (l_grapheme == RAQM_GRAPHEM_PREPEND) - return false; - if (r_grapheme == RAQM_GRAPHEM_SPACING_MARK) - return false; - return true; /*Otherwise, break everywhere. GB1, GB2, GB10*/ -} - -static _raqm_grapheme_t -_raqm_get_grapheme_break (hb_codepoint_t ch, - hb_unicode_general_category_t category) -{ - _raqm_grapheme_t gb_type; - - gb_type = RAQM_GRAPHEM_OTHER; - switch ((int)category) - { - case HB_UNICODE_GENERAL_CATEGORY_FORMAT: - if (ch == 0x200C || ch == 0x200D) - gb_type = RAQM_GRAPHEM_EXTEND; - else - gb_type = RAQM_GRAPHEM_CONTROL; - break; - - case HB_UNICODE_GENERAL_CATEGORY_CONTROL: - if (ch == 0x000D) - gb_type = RAQM_GRAPHEM_CR; - else if (ch == 0x000A) - gb_type = RAQM_GRAPHEM_LF; - else - gb_type = RAQM_GRAPHEM_CONTROL; - break; - - case HB_UNICODE_GENERAL_CATEGORY_SURROGATE: - case HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR: - case HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR: - case HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED: - if ((ch >= 0xFFF0 && ch <= 0xFFF8) || - (ch >= 0xE0000 && ch <= 0xE0FFF)) - gb_type = RAQM_GRAPHEM_CONTROL; - break; - - case HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK: - case HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK: - case HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK: - if (ch != 0x102B || ch != 0x102C || ch != 0x1038 || - (ch <= 0x1062 && ch >= 0x1064) || (ch <= 0x1067 && ch >= 0x106D) || - ch != 0x1083 || (ch <= 0x1087 && ch >= 0x108C) || ch != 0x108F || - (ch <= 0x109A && ch >= 0x109C) || ch != 0x1A61 || ch != 0x1A63 || - ch != 0x1A64 || ch != 0xAA7B || ch != 0xAA70 || ch != 0x11720 || - ch != 0x11721) /**/ - gb_type = RAQM_GRAPHEM_SPACING_MARK; - - else if (ch == 0x09BE || ch == 0x09D7 || - ch == 0x0B3E || ch == 0x0B57 || ch == 0x0BBE || ch == 0x0BD7 || - ch == 0x0CC2 || ch == 0x0CD5 || ch == 0x0CD6 || - ch == 0x0D3E || ch == 0x0D57 || ch == 0x0DCF || ch == 0x0DDF || - ch == 0x1D165 || (ch >= 0x1D16E && ch <= 0x1D172)) - gb_type = RAQM_GRAPHEM_EXTEND; - break; - - case HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER: - if (ch == 0x0E33 || ch == 0x0EB3) - gb_type = RAQM_GRAPHEM_SPACING_MARK; - break; - - case HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL: - if (ch >= 0x1F1E6 && ch <= 0x1F1FF) - gb_type = RAQM_GRAPHEM_REGIONAL_INDICATOR; - break; - - default: - gb_type = RAQM_GRAPHEM_OTHER; - break; - } - - if (_raqm_in_hangul_syllable (ch)) - gb_type = RAQM_GRAPHEM_HANGUL_SYLLABLE; - - return gb_type; -} - -static bool -_raqm_in_hangul_syllable (hb_codepoint_t ch) -{ - (void)ch; - return false; -} - -/** - * raqm_version: - * @major: (out): Library major version component. - * @minor: (out): Library minor version component. - * @micro: (out): Library micro version component. - * - * Returns library version as three integer components. - * - * Since: 0.7 - **/ -void -raqm_version (unsigned int *major, - unsigned int *minor, - unsigned int *micro) -{ - *major = RAQM_VERSION_MAJOR; - *minor = RAQM_VERSION_MINOR; - *micro = RAQM_VERSION_MICRO; -} - -/** - * raqm_version_string: - * - * Returns library version as a string with three components. - * - * Return value: library version string. - * - * Since: 0.7 - **/ -const char * -raqm_version_string (void) -{ - return RAQM_VERSION_STRING; -} - -/** - * raqm_version_atleast: - * @major: Library major version component. - * @minor: Library minor version component. - * @micro: Library micro version component. - * - * Checks if library version is less than or equal the specified version. - * - * Return value: - * %true if library version is less than or equal the specfied version, %false - * otherwise. - * - * Since: 0.7 - **/ -bool -raqm_version_atleast (unsigned int major, - unsigned int minor, - unsigned int micro) -{ - return RAQM_VERSION_ATLEAST (major, minor, micro); -} - -/** - * RAQM_VERSION_ATLEAST: - * @major: Library major version component. - * @minor: Library minor version component. - * @micro: Library micro version component. - * - * Checks if library version is less than or equal the specified version. - * - * Return value: - * %true if library version is less than or equal the specfied version, %false - * otherwise. - * - * Since: 0.7 - **/ - -/** - * RAQM_VERSION_STRING: - * - * Library version as a string with three components. - * - * Since: 0.7 - **/ - -/** - * RAQM_VERSION_MAJOR: - * - * Library major version component. - * - * Since: 0.7 - **/ - -/** - * RAQM_VERSION_MINOR: - * - * Library minor version component. - * - * Since: 0.7 - **/ - -/** - * RAQM_VERSION_MICRO: - * - * Library micro version component. - * - * Since: 0.7 - **/ diff --git a/lib/libraqm/raqm.h b/lib/libraqm/raqm.h deleted file mode 100644 index 1a33fe8ba..000000000 --- a/lib/libraqm/raqm.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright © 2015 Information Technology Authority (ITA) - * Copyright © 2016 Khaled Hosny - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -#ifndef _RAQM_H_ -#define _RAQM_H_ -#define _RAQM_H_IN_ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include FT_FREETYPE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "raqm-version.h" - -/** - * raqm_t: - * - * This is the main object holding all state of the currently processed text as - * well as its output. - * - * Since: 0.1 - */ -typedef struct _raqm raqm_t; - -/** - * raqm_direction_t: - * @RAQM_DIRECTION_DEFAULT: Detect paragraph direction automatically. - * @RAQM_DIRECTION_RTL: Paragraph is mainly right-to-left text. - * @RAQM_DIRECTION_LTR: Paragraph is mainly left-to-right text. - * @RAQM_DIRECTION_TTB: Paragraph is mainly vertical top-to-bottom text. - * - * Base paragraph direction, see raqm_set_par_direction(). - * - * Since: 0.1 - */ -typedef enum -{ - RAQM_DIRECTION_DEFAULT, - RAQM_DIRECTION_RTL, - RAQM_DIRECTION_LTR, - RAQM_DIRECTION_TTB -} raqm_direction_t; - -/** - * raqm_glyph_t: - * @index: the index of the glyph in the font file. - * @x_advance: the glyph advance width in horizontal text. - * @y_advance: the glyph advance width in vertical text. - * @x_offset: the horizontal movement of the glyph from the current point. - * @y_offset: the vertical movement of the glyph from the current point. - * @cluster: the index of original character in input text. - * @ftface: the @FT_Face of the glyph. - * - * The structure that holds information about output glyphs, returned from - * raqm_get_glyphs(). - */ -typedef struct raqm_glyph_t { - unsigned int index; - int x_advance; - int y_advance; - int x_offset; - int y_offset; - uint32_t cluster; - FT_Face ftface; -} raqm_glyph_t; - -raqm_t * -raqm_create (void); - -raqm_t * -raqm_reference (raqm_t *rq); - -void -raqm_destroy (raqm_t *rq); - -bool -raqm_set_text (raqm_t *rq, - const uint32_t *text, - size_t len); - -bool -raqm_set_text_utf8 (raqm_t *rq, - const char *text, - size_t len); - -bool -raqm_set_par_direction (raqm_t *rq, - raqm_direction_t dir); - -bool -raqm_set_language (raqm_t *rq, - const char *lang, - size_t start, - size_t len); - -bool -raqm_add_font_feature (raqm_t *rq, - const char *feature, - int len); - -bool -raqm_set_freetype_face (raqm_t *rq, - FT_Face face); - -bool -raqm_set_freetype_face_range (raqm_t *rq, - FT_Face face, - size_t start, - size_t len); - -bool -raqm_set_freetype_load_flags (raqm_t *rq, - int flags); - -bool -raqm_set_invisible_glyph (raqm_t *rq, - int gid); - -bool -raqm_layout (raqm_t *rq); - -raqm_glyph_t * -raqm_get_glyphs (raqm_t *rq, - size_t *length); - -bool -raqm_index_to_position (raqm_t *rq, - size_t *index, - int *x, - int *y); - -bool -raqm_position_to_index (raqm_t *rq, - int x, - int y, - size_t *index); - -void -raqm_version (unsigned int *major, - unsigned int *minor, - unsigned int *micro); - -const char * -raqm_version_string (void); - -bool -raqm_version_atleast (unsigned int major, - unsigned int minor, - unsigned int micro); - - -#ifdef __cplusplus -} -#endif -#undef _RAQM_H_IN_ -#endif /* _RAQM_H_ */ diff --git a/tools/linux_builder.sh b/tools/linux_builder.sh index 398dfec4e..dff861482 100755 --- a/tools/linux_builder.sh +++ b/tools/linux_builder.sh @@ -168,20 +168,6 @@ build_stk() touch "$DEPENDENCIES_DIR/libpng.stamp" fi - # Fribidi - if [ ! -f "$DEPENDENCIES_DIR/fribidi.stamp" ]; then - echo "Compiling fribidi" - mkdir -p "$DEPENDENCIES_DIR/fribidi" - cp -a -f "$DEPENDENCIES_DIR/../lib/fribidi/"* "$DEPENDENCIES_DIR/fribidi" - - cd "$DEPENDENCIES_DIR/fribidi" - ./configure --prefix="$INSTALL_DIR" && - make -j$THREADS_NUMBER && - make install - check_error - touch "$DEPENDENCIES_DIR/fribidi.stamp" - fi - # Freetype bootstrap if [ ! -f "$DEPENDENCIES_DIR/freetype_bootstrap.stamp" ]; then echo "Compiling freetype"