├── CMakeLists.txt ├── README ├── cmake ├── FindGraphite2.cmake └── FindUniscribe.cmake ├── gl3.h ├── gltext.cpp ├── gltext.hpp ├── harfbuzz ├── AUTHORS ├── COPYING ├── hb-blob.cc ├── hb-blob.h ├── hb-buffer-private.hh ├── hb-buffer.cc ├── hb-buffer.h ├── hb-common.cc ├── hb-common.h ├── hb-fallback-shape-private.hh ├── hb-fallback-shape.cc ├── hb-font-private.hh ├── hb-font.cc ├── hb-font.h ├── hb-ft.cc ├── hb-ft.h ├── hb-glib.cc ├── hb-glib.h ├── hb-gobject-structs.cc ├── hb-gobject.h ├── hb-graphite2.cc ├── hb-graphite2.h ├── hb-icu.cc ├── hb-icu.h ├── hb-mutex-private.hh ├── hb-object-private.hh ├── hb-open-file-private.hh ├── hb-open-type-private.hh ├── hb-ot-head-table.hh ├── hb-ot-hhea-table.hh ├── hb-ot-hmtx-table.hh ├── hb-ot-layout-common-private.hh ├── hb-ot-layout-gdef-table.hh ├── hb-ot-layout-gpos-table.hh ├── hb-ot-layout-gsub-table.hh ├── hb-ot-layout-gsubgpos-private.hh ├── hb-ot-layout-private.hh ├── hb-ot-layout.cc ├── hb-ot-layout.h ├── hb-ot-map-private.hh ├── hb-ot-map.cc ├── hb-ot-maxp-table.hh ├── hb-ot-name-table.hh ├── hb-ot-shape-complex-arabic-table.hh ├── hb-ot-shape-complex-arabic.cc ├── hb-ot-shape-complex-indic-machine.hh ├── hb-ot-shape-complex-indic-table.hh ├── hb-ot-shape-complex-indic.cc ├── hb-ot-shape-complex-misc.cc ├── hb-ot-shape-complex-private.hh ├── hb-ot-shape-normalize.cc ├── hb-ot-shape-private.hh ├── hb-ot-shape.cc ├── hb-ot-shape.h ├── hb-ot-tag.cc ├── hb-ot-tag.h ├── hb-ot.h ├── hb-private.hh ├── hb-shape.cc ├── hb-shape.h ├── hb-unicode-private.hh ├── hb-unicode.cc ├── hb-unicode.h ├── hb-uniscribe.cc ├── hb-uniscribe.h ├── hb-version.h ├── hb.h ├── main.cc └── test.cc └── test.cpp /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(gltext) 2 | cmake_minimum_required(VERSION 2.8) 3 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${gltext_SOURCE_DIR}/cmake/") 4 | 5 | set(HB_SOURCES 6 | harfbuzz/hb-blob.cc 7 | harfbuzz/hb-buffer-private.hh 8 | harfbuzz/hb-buffer.cc 9 | harfbuzz/hb-common.cc 10 | harfbuzz/hb-fallback-shape-private.hh 11 | harfbuzz/hb-fallback-shape.cc 12 | harfbuzz/hb-font-private.hh 13 | harfbuzz/hb-font.cc 14 | harfbuzz/hb-ft.cc 15 | harfbuzz/hb-mutex-private.hh 16 | harfbuzz/hb-object-private.hh 17 | harfbuzz/hb-open-file-private.hh 18 | harfbuzz/hb-open-type-private.hh 19 | harfbuzz/hb-ot-head-table.hh 20 | harfbuzz/hb-ot-hhea-table.hh 21 | harfbuzz/hb-ot-hmtx-table.hh 22 | harfbuzz/hb-ot-layout-common-private.hh 23 | harfbuzz/hb-ot-layout-gpos-table.hh 24 | harfbuzz/hb-ot-layout-gsub-table.hh 25 | harfbuzz/hb-ot-layout-gsubgpos-private.hh 26 | harfbuzz/hb-ot-layout-private.hh 27 | harfbuzz/hb-ot-layout.cc 28 | harfbuzz/hb-ot-map-private.hh 29 | harfbuzz/hb-ot-map.cc 30 | harfbuzz/hb-ot-maxp-table.hh 31 | harfbuzz/hb-ot-name-table.hh 32 | harfbuzz/hb-ot-shape-complex-arabic-table.hh 33 | harfbuzz/hb-ot-shape-complex-arabic.cc 34 | harfbuzz/hb-ot-shape-complex-indic-table.hh 35 | harfbuzz/hb-ot-shape-complex-indic.cc 36 | harfbuzz/hb-ot-shape-complex-misc.cc 37 | harfbuzz/hb-ot-shape-complex-private.hh 38 | harfbuzz/hb-ot-shape-normalize.cc 39 | harfbuzz/hb-ot-shape.cc 40 | harfbuzz/hb-ot-tag.cc 41 | harfbuzz/hb-private.hh 42 | harfbuzz/hb-shape.cc 43 | harfbuzz/hb-unicode-private.hh 44 | harfbuzz/hb-unicode.cc 45 | 46 | harfbuzz/hb.h 47 | harfbuzz/hb-blob.h 48 | harfbuzz/hb-buffer.h 49 | harfbuzz/hb-common.h 50 | harfbuzz/hb-font.h 51 | harfbuzz/hb-ft.h 52 | harfbuzz/hb-ot-layout.h 53 | harfbuzz/hb-ot-shape.h 54 | harfbuzz/hb-ot-tag.h 55 | harfbuzz/hb-ot.h 56 | harfbuzz/hb-shape.h 57 | harfbuzz/hb-unicode.h 58 | harfbuzz/hb-version.h 59 | ) 60 | 61 | set(GLTEXT_SOURCES 62 | gltext.cpp 63 | ) 64 | 65 | set(GLTEXT_HEADERS 66 | gltext.hpp 67 | ) 68 | 69 | find_package(Graphite2) 70 | find_package(Uniscribe) 71 | find_package(GLUT) 72 | find_package(OpenGL REQUIRED) 73 | find_package(Freetype REQUIRED) 74 | 75 | include_directories(${FREETYPE_INCLUDE_DIRS}) 76 | 77 | add_definitions(-DHAVE_OT=1) 78 | 79 | if(GRAPHITE2_FOUND) 80 | set(HB_SOURCES ${HB_SOURCES} 81 | harfbuzz/hb-graphite2.cc 82 | 83 | harfbuzz/hb-graphite2.h 84 | ) 85 | set(HB_EXTRA_LIBS ${GRAPHITE2_LIBRARY}) 86 | add_definitions(-DHAVE_GRAPHITE=1) 87 | endif() 88 | 89 | if(UNISCRIBE_FOUND) 90 | option(GLTEXT_USE_UNISCRIBE "Enable uniscribe. This will cause gltext and your application to require Windows Vista or newer" FALSE) 91 | if(GLTEXT_USE_UNISCRIBE) 92 | set(HB_SOURCES ${HB_SOURCES} 93 | harfbuzz/hb-uniscribe.cc 94 | 95 | harfbuzz/hb-uniscribe.h 96 | ) 97 | set(HB_EXTRA_LIBS ${UNISCRIBE_LIBRARY}) 98 | add_definitions(-DHAVE_UNISCRIBE=1) 99 | endif() 100 | endif() 101 | 102 | add_library(gltext ${GLTEXT_SOURCES} ${GLTEXT_HEADERS} ${HB_SOURCES}) 103 | 104 | if(GLUT_FOUND) 105 | option(GLTEXT_BUILD_DEMO_TEST "Build the demo 'test' program" FALSE) 106 | if(GLTEXT_BUILD_DEMO_TEST) 107 | add_executable(test test.cpp) 108 | target_link_libraries(test ${FREETYPE_LIBRARY} ${HB_EXTRA_LIBS} ${OPENGL_gl_LIBRARY} ${GLUT_LIBRARIES} gltext ) 109 | endif() 110 | endif() 111 | 112 | if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) 113 | option(GLTEXT_DO_INSTALL "Add install targets for gltext libraries" TRUE) 114 | else() 115 | option(GLTEXT_DO_INSTALL "Add install targets for gltext libraries" FALSE) 116 | set(GLTEXT_LIBRARIES gltext ${FREETYPE_LIBRARY} ${HB_EXTRA_LIBS} ${OPENGL_gl_LIBRARY} PARENT_SCOPE) 117 | endif() 118 | 119 | if(GLTEXT_DO_INSTALL) 120 | install(TARGETS gltext DESTINATION lib) 121 | install(FILES ${GLTEXT_HEADERS} DESTINATION include) 122 | endif() 123 | 124 | source_group("harbuzz" FILES ${HB_SOURCES}) -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | gltext provides a text-rendering library compatible with modern (core profile) OpenGL implementations. 2 | 3 | CMAKE NOTES: 4 | 5 | gltext can be built as a standalone library, or integrated into your own CMake project as a subdirectory. If you use it as a subdirectory, the CMake variable GLTEXT_LIBRARIES will include gltext and its dependency libraries, and is intended to be used in your application's TARGET_LINK_LIBRARIES() command. 6 | 7 | If built as a subdirectory, gltext will disable its 'make install' targets. If you would like gltext to be installed during 'make install' (for example, if your umbrella project is a bundle of libraries, not an appication), you can set the CMake variable GLTEXT_DO_INSTALL to ON. 8 | 9 | OPENGL NOTES: 10 | 11 | gltext makes some changes to the GL state as it renders. In most applications, these states will probably be overwritten by your code anyway. There may be issues if you generate a single VAO and treat it like the default VAO of older OpenGL versions. You should assume that after any gltext::Font function is called, including the constructor, that any and all of these states have changed to the following values: 12 | 13 | * VERTEX_ARRAY_BINDING is set to the VAO for the given font 14 | * CURRENT_PROGRAM is set to the shared text-drawing shader program 15 | * ACTIVE_TEXTURE is set to TEXTURE0 16 | * TEXTURE_BINDING_2D is set to the Font's cache texture 17 | * SAMPLER_BINDING is set to 0 for TEXTURE0 (OpenGL 3.3 and higher) 18 | * UNPACK_ALIGNMENT is set to 1 19 | * UNPACK_ROW_LENGTH is set to an arbitrary value 20 | 21 | TODO: 22 | * Add some sort of line-splitting algorithm 23 | * Expose language and script settings from HarfBuzz -------------------------------------------------------------------------------- /cmake/FindGraphite2.cmake: -------------------------------------------------------------------------------- 1 | find_path(GRAPHITE2_INCLUDE_DIR graphite2/Font.h) 2 | find_library(GRAPHITE2_LIBRARY graphite2) 3 | 4 | include(FindPackageHandleStandardArgs) 5 | 6 | find_package_handle_standard_args(GRAPHITE2 GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY) -------------------------------------------------------------------------------- /cmake/FindUniscribe.cmake: -------------------------------------------------------------------------------- 1 | find_path(UNISCRIBE_INCLUDE_DIR usp10.h) 2 | find_library(UNISCRIBE_LIBRARY usp10) 3 | 4 | include(FindPackageHandleStandardArgs) 5 | 6 | find_package_handle_standard_args(UNISCRIBE UNISCRIBE_INCLUDE_DIR UNISCRIBE_LIBRARY) -------------------------------------------------------------------------------- /gltext.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Branan Purvine-Riley 3 | * 4 | * This is part of gltext, a text-rendering library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | */ 24 | 25 | #ifndef GLTEXT_FONT_HPP 26 | #define GLTEXT_FONT_HPP 27 | 28 | #include 29 | #include 30 | 31 | #define GLTEXT_CACHE_TEXTURE_SIZE 256 32 | 33 | namespace gltext { 34 | 35 | /// The base class for all gltext exceptions 36 | class Exception : public std::runtime_error { 37 | public: 38 | Exception(std::string str) : std::runtime_error(str) {} 39 | }; 40 | 41 | /// Thrown when an error occurs in Freetype. 42 | class FtException : public Exception { 43 | public: 44 | FtException() : Exception("Freetype error occured") {} 45 | }; 46 | 47 | /// Thrown when there is no more room in the glyph cache, but a non-cached glyph is required 48 | class CacheOverflowException : public Exception { 49 | public: 50 | CacheOverflowException() : Exception("Overflow in glyph cache") {} 51 | }; 52 | 53 | /// Thrown when certain operations are attempted on an un-initialized Font object 54 | class EmptyFontException : public Exception { 55 | public: 56 | EmptyFontException() : Exception("The request operation is not permitted on an empty Font") {} 57 | }; 58 | 59 | /// Thrown when Freetype gives us a glyph that is not in 8-bit luminance format 60 | class BadFontFormatException : public Exception { 61 | public: 62 | BadFontFormatException() : Exception("The font glyphs are not in an appropriate bitmap format") {} 63 | }; 64 | 65 | /// Internal structure for the Font class 66 | struct FontPimpl; 67 | 68 | /** 69 | * @brief Font loading and rendering 70 | * 71 | * The Font class provides capabilities to load and render any font supported by Freetype. It uses an advanced 72 | * text layout system, to provide the correct glyph selection and positioning for internationalized text. 73 | * 74 | * If the display size is set correctly, this class can provide pixel-perfect rendering. Setting the display size to 75 | * other values will not give correct results. 76 | * 77 | * When drawing, this class will output pixels with pre-multiplied alpha. To blend them properly, set the blend mode to (GL_ONE, GL_SRC_ALPHA) 78 | */ 79 | class Font { 80 | public: 81 | /** 82 | * @brief Create a new fully initialized font 83 | * 84 | * If any exceptions are thrown, the new Font object will be placed in the empty state, as if it were built with the default constructor. 85 | * @param[in] font_file The path to the requrested font file 86 | * @param[in] size The vertical size of the font, in pixels 87 | * @param[in] cache_w The width of the cache texture, in pixels 88 | * @param[in] cache_h The height of the cache texture, in pixels 89 | */ 90 | Font(std::string font_file, unsigned size, unsigned cache_w = GLTEXT_CACHE_TEXTURE_SIZE, unsigned cache_h = GLTEXT_CACHE_TEXTURE_SIZE); 91 | /** 92 | * @brief Create an empty font 93 | */ 94 | Font(); 95 | /** 96 | * @brief Copy constructor 97 | * 98 | * This provides a deep copy. A new font object is initialized from scatch, copying over only basic parameters from the source. 99 | * Importantly, a new cache buffer and texture are created for the new object. They are not shared with the source Font. 100 | */ 101 | Font(const Font&); 102 | /** 103 | * @brief deep assignment 104 | * 105 | * This will clean up the corrent font if needed, then perform a new initialization based on basic parameters from the source. 106 | * Importantly, a new cache buffer and texture are created for this object. They are not shared with the source Font. 107 | */ 108 | Font& operator=(const Font&); 109 | 110 | /** 111 | * @brief cleanup 112 | * 113 | * Deletes all buffers, textures, and Freetype objects associated with this font 114 | */ 115 | ~Font(); 116 | 117 | /** 118 | * @brief Set the size of the display 119 | * 120 | * In order to provide pixel-perfect rendering, you must pass the actual size of the OpenGL viewport here. 121 | * @param[in] w The width of the OpenGL viewport, in pixels 122 | * @param[in] h The height of the OpenGL viewport, in pixels 123 | */ 124 | void setDisplaySize(unsigned w, unsigned h); 125 | 126 | /** 127 | * @brief Set the drawing position 128 | * 129 | * This is in OpenGL coordinates: 0,0 is the bottom-left corner 130 | * @param[in] x The horizontal drawing position 131 | * @param[in] y The vertical drawing position 132 | */ 133 | void setPenPosition(unsigned x, unsigned y); 134 | 135 | /** 136 | * @brief Set the drawing color 137 | */ 138 | void setPenColor(float r, float g, float b); 139 | 140 | /** 141 | * @brief change the font size 142 | * This function will cause the font cache to be cleared. 143 | * @param[in] size The new font size 144 | */ 145 | void setPointSize(unsigned size); 146 | 147 | /** 148 | * @brief load some characters into the cache 149 | * 150 | * This function allows you to pre-load the cache with a set of common characters. When this is done, 151 | * there will not be any need to render those characters at runtime. 152 | * 153 | * There is no requirement to call this function. Any character not found in the cache will be rendered 154 | * as-needed. 155 | * 156 | * Note that depending on the script, the order of the characters in this string might cause different glyphs 157 | * to be selectd for caching. This is especially of concern in indic and arabic scripts. If you want to cache 158 | * the correct glyphs in those scripts, you may have to pass your actual strings to this function, instead of 159 | * a dummy list of characters. 160 | * 161 | * @param[in] chars The characters to place in the cache. 162 | */ 163 | void cacheCharacters(std::string chars); 164 | 165 | /** 166 | * @brief draw a line of text 167 | * 168 | * This function draws a single line of text. No line-splitting is performed - it is up to the application to provide that functionality if needed. 169 | * @param[in] text The string to draw 170 | */ 171 | void draw(std::string text); 172 | private: 173 | FontPimpl* self; 174 | }; 175 | 176 | } 177 | 178 | /** 179 | * @mainpage gltext documentation 180 | * 181 | * This is the documentation for the gltext library. The capabilities of this library are exposed through the gltext::Font class. 182 | */ 183 | 184 | #endif // GLTEXT_FONT_HPP -------------------------------------------------------------------------------- /harfbuzz/AUTHORS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/branan/gltext/f1ad62b04687013378a186643ca3e8889fa3729d/harfbuzz/AUTHORS -------------------------------------------------------------------------------- /harfbuzz/COPYING: -------------------------------------------------------------------------------- 1 | HarfBuzz is licensed under the so-called "Old MIT" license. Details follow. 2 | 3 | Copyright © 2011 Codethink Limited 4 | Copyright © 2010,2011 Google, Inc. 5 | Copyright © 2006 Behdad Esfahbod 6 | Copyright © 2009 Keith Stribley 7 | Copyright © 2009 Martin Hosken and SIL International 8 | Copyright © 2007 Chris Wilson 9 | Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc. 10 | Copyright © 1998-2004 David Turner and Werner Lemberg 11 | 12 | For full copyright notices consult the individual files in the package. 13 | 14 | 15 | Permission is hereby granted, without written agreement and without 16 | license or royalty fees, to use, copy, modify, and distribute this 17 | software and its documentation for any purpose, provided that the 18 | above copyright notice and the following two paragraphs appear in 19 | all copies of this software. 20 | 21 | IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 22 | DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 23 | ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 24 | IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 25 | DAMAGE. 26 | 27 | THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 28 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 29 | FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 30 | ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 31 | PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 32 | -------------------------------------------------------------------------------- /harfbuzz/hb-blob.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #include "hb-private.hh" 28 | 29 | #include "hb-blob.h" 30 | #include "hb-object-private.hh" 31 | 32 | #ifdef HAVE_SYS_MMAN_H 33 | #ifdef HAVE_UNISTD_H 34 | #include 35 | #endif /* HAVE_UNISTD_H */ 36 | #include 37 | #endif /* HAVE_SYS_MMAN_H */ 38 | 39 | #include 40 | #include 41 | 42 | 43 | 44 | #ifndef HB_DEBUG_BLOB 45 | #define HB_DEBUG_BLOB (HB_DEBUG+0) 46 | #endif 47 | 48 | 49 | struct _hb_blob_t { 50 | hb_object_header_t header; 51 | 52 | bool immutable; 53 | 54 | const char *data; 55 | unsigned int length; 56 | hb_memory_mode_t mode; 57 | 58 | void *user_data; 59 | hb_destroy_func_t destroy; 60 | }; 61 | 62 | static hb_blob_t _hb_blob_nil = { 63 | HB_OBJECT_HEADER_STATIC, 64 | 65 | TRUE, /* immutable */ 66 | 67 | NULL, /* data */ 68 | 0, /* length */ 69 | HB_MEMORY_MODE_READONLY, /* mode */ 70 | 71 | NULL, /* user_data */ 72 | NULL /* destroy */ 73 | }; 74 | 75 | 76 | static bool _try_writable (hb_blob_t *blob); 77 | 78 | static void 79 | _hb_blob_destroy_user_data (hb_blob_t *blob) 80 | { 81 | if (blob->destroy) { 82 | blob->destroy (blob->user_data); 83 | blob->user_data = NULL; 84 | blob->destroy = NULL; 85 | } 86 | } 87 | 88 | hb_blob_t * 89 | hb_blob_create (const char *data, 90 | unsigned int length, 91 | hb_memory_mode_t mode, 92 | void *user_data, 93 | hb_destroy_func_t destroy) 94 | { 95 | hb_blob_t *blob; 96 | 97 | if (!length || !(blob = hb_object_create ())) { 98 | if (destroy) 99 | destroy (user_data); 100 | return &_hb_blob_nil; 101 | } 102 | 103 | blob->data = data; 104 | blob->length = length; 105 | blob->mode = mode; 106 | 107 | blob->user_data = user_data; 108 | blob->destroy = destroy; 109 | 110 | if (blob->mode == HB_MEMORY_MODE_DUPLICATE) { 111 | blob->mode = HB_MEMORY_MODE_READONLY; 112 | if (!_try_writable (blob)) { 113 | hb_blob_destroy (blob); 114 | return &_hb_blob_nil; 115 | } 116 | } 117 | 118 | return blob; 119 | } 120 | 121 | hb_blob_t * 122 | hb_blob_create_sub_blob (hb_blob_t *parent, 123 | unsigned int offset, 124 | unsigned int length) 125 | { 126 | hb_blob_t *blob; 127 | 128 | if (!length || offset >= parent->length) 129 | return &_hb_blob_nil; 130 | 131 | hb_blob_make_immutable (parent); 132 | 133 | blob = hb_blob_create (parent->data + offset, 134 | MIN (length, parent->length - offset), 135 | parent->mode, 136 | hb_blob_reference (parent), 137 | (hb_destroy_func_t) hb_blob_destroy); 138 | 139 | return blob; 140 | } 141 | 142 | hb_blob_t * 143 | hb_blob_get_empty (void) 144 | { 145 | return &_hb_blob_nil; 146 | } 147 | 148 | hb_blob_t * 149 | hb_blob_reference (hb_blob_t *blob) 150 | { 151 | return hb_object_reference (blob); 152 | } 153 | 154 | void 155 | hb_blob_destroy (hb_blob_t *blob) 156 | { 157 | if (!hb_object_destroy (blob)) return; 158 | 159 | _hb_blob_destroy_user_data (blob); 160 | 161 | free (blob); 162 | } 163 | 164 | hb_bool_t 165 | hb_blob_set_user_data (hb_blob_t *blob, 166 | hb_user_data_key_t *key, 167 | void * data, 168 | hb_destroy_func_t destroy, 169 | hb_bool_t replace) 170 | { 171 | return hb_object_set_user_data (blob, key, data, destroy, replace); 172 | } 173 | 174 | void * 175 | hb_blob_get_user_data (hb_blob_t *blob, 176 | hb_user_data_key_t *key) 177 | { 178 | return hb_object_get_user_data (blob, key); 179 | } 180 | 181 | 182 | void 183 | hb_blob_make_immutable (hb_blob_t *blob) 184 | { 185 | if (hb_object_is_inert (blob)) 186 | return; 187 | 188 | blob->immutable = TRUE; 189 | } 190 | 191 | hb_bool_t 192 | hb_blob_is_immutable (hb_blob_t *blob) 193 | { 194 | return blob->immutable; 195 | } 196 | 197 | 198 | unsigned int 199 | hb_blob_get_length (hb_blob_t *blob) 200 | { 201 | return blob->length; 202 | } 203 | 204 | const char * 205 | hb_blob_get_data (hb_blob_t *blob, unsigned int *length) 206 | { 207 | if (length) 208 | *length = blob->length; 209 | 210 | return blob->data; 211 | } 212 | 213 | char * 214 | hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length) 215 | { 216 | if (!_try_writable (blob)) { 217 | if (length) 218 | *length = 0; 219 | 220 | return NULL; 221 | } 222 | 223 | if (length) 224 | *length = blob->length; 225 | 226 | return const_cast (blob->data); 227 | } 228 | 229 | 230 | static hb_bool_t 231 | _try_make_writable_inplace_unix (hb_blob_t *blob) 232 | { 233 | #if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT) 234 | uintptr_t pagesize = -1, mask, length; 235 | const char *addr; 236 | 237 | #if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) 238 | pagesize = (uintptr_t) sysconf (_SC_PAGE_SIZE); 239 | #elif defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) 240 | pagesize = (uintptr_t) sysconf (_SC_PAGESIZE); 241 | #elif defined(HAVE_GETPAGESIZE) 242 | pagesize = (uintptr_t) getpagesize (); 243 | #endif 244 | 245 | if ((uintptr_t) -1L == pagesize) { 246 | DEBUG_MSG_FUNC (BLOB, blob, "failed to get pagesize: %s", strerror (errno)); 247 | return FALSE; 248 | } 249 | DEBUG_MSG_FUNC (BLOB, blob, "pagesize is %lu", (unsigned long) pagesize); 250 | 251 | mask = ~(pagesize-1); 252 | addr = (const char *) (((uintptr_t) blob->data) & mask); 253 | length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask) - addr; 254 | DEBUG_MSG_FUNC (BLOB, blob, 255 | "calling mprotect on [%p..%p] (%lu bytes)", 256 | addr, addr+length, (unsigned long) length); 257 | if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) { 258 | DEBUG_MSG_FUNC (BLOB, blob, "mprotect failed: %s", strerror (errno)); 259 | return FALSE; 260 | } 261 | 262 | blob->mode = HB_MEMORY_MODE_WRITABLE; 263 | 264 | DEBUG_MSG_FUNC (BLOB, blob, 265 | "successfully made [%p..%p] (%lu bytes) writable\n", 266 | addr, addr+length, (unsigned long) length); 267 | return TRUE; 268 | #else 269 | return FALSE; 270 | #endif 271 | } 272 | 273 | static bool 274 | _try_writable_inplace (hb_blob_t *blob) 275 | { 276 | DEBUG_MSG_FUNC (BLOB, blob, "making writable inplace\n"); 277 | 278 | if (_try_make_writable_inplace_unix (blob)) 279 | return TRUE; 280 | 281 | DEBUG_MSG_FUNC (BLOB, blob, "making writable -> FAILED\n"); 282 | 283 | /* Failed to make writable inplace, mark that */ 284 | blob->mode = HB_MEMORY_MODE_READONLY; 285 | return FALSE; 286 | } 287 | 288 | static bool 289 | _try_writable (hb_blob_t *blob) 290 | { 291 | if (blob->immutable) 292 | return FALSE; 293 | 294 | if (blob->mode == HB_MEMORY_MODE_WRITABLE) 295 | return TRUE; 296 | 297 | if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && _try_writable_inplace (blob)) 298 | return TRUE; 299 | 300 | if (blob->mode == HB_MEMORY_MODE_WRITABLE) 301 | return TRUE; 302 | 303 | 304 | DEBUG_MSG_FUNC (BLOB, blob, "currect data is -> %p\n", blob->data); 305 | 306 | char *new_data; 307 | 308 | new_data = (char *) malloc (blob->length); 309 | if (unlikely (!new_data)) 310 | return FALSE; 311 | 312 | DEBUG_MSG_FUNC (BLOB, blob, "dupped successfully -> %p\n", blob->data); 313 | 314 | memcpy (new_data, blob->data, blob->length); 315 | _hb_blob_destroy_user_data (blob); 316 | blob->mode = HB_MEMORY_MODE_WRITABLE; 317 | blob->data = new_data; 318 | blob->user_data = new_data; 319 | blob->destroy = free; 320 | 321 | return TRUE; 322 | } 323 | 324 | 325 | -------------------------------------------------------------------------------- /harfbuzz/hb-blob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_BLOB_H 28 | #define HB_BLOB_H 29 | 30 | #include "hb-common.h" 31 | 32 | HB_BEGIN_DECLS 33 | 34 | 35 | typedef enum { 36 | HB_MEMORY_MODE_DUPLICATE, 37 | HB_MEMORY_MODE_READONLY, 38 | HB_MEMORY_MODE_WRITABLE, 39 | HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE 40 | } hb_memory_mode_t; 41 | 42 | typedef struct _hb_blob_t hb_blob_t; 43 | 44 | hb_blob_t * 45 | hb_blob_create (const char *data, 46 | unsigned int length, 47 | hb_memory_mode_t mode, 48 | void *user_data, 49 | hb_destroy_func_t destroy); 50 | 51 | hb_blob_t * 52 | hb_blob_create_sub_blob (hb_blob_t *parent, 53 | unsigned int offset, 54 | unsigned int length); 55 | 56 | hb_blob_t * 57 | hb_blob_get_empty (void); 58 | 59 | hb_blob_t * 60 | hb_blob_reference (hb_blob_t *blob); 61 | 62 | void 63 | hb_blob_destroy (hb_blob_t *blob); 64 | 65 | hb_bool_t 66 | hb_blob_set_user_data (hb_blob_t *blob, 67 | hb_user_data_key_t *key, 68 | void * data, 69 | hb_destroy_func_t destroy, 70 | hb_bool_t replace); 71 | 72 | 73 | void * 74 | hb_blob_get_user_data (hb_blob_t *blob, 75 | hb_user_data_key_t *key); 76 | 77 | 78 | void 79 | hb_blob_make_immutable (hb_blob_t *blob); 80 | 81 | hb_bool_t 82 | hb_blob_is_immutable (hb_blob_t *blob); 83 | 84 | 85 | unsigned int 86 | hb_blob_get_length (hb_blob_t *blob); 87 | 88 | const char * 89 | hb_blob_get_data (hb_blob_t *blob, unsigned int *length); 90 | 91 | char * 92 | hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length); 93 | 94 | 95 | HB_END_DECLS 96 | 97 | #endif /* HB_BLOB_H */ 98 | -------------------------------------------------------------------------------- /harfbuzz/hb-buffer-private.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 1998-2004 David Turner and Werner Lemberg 3 | * Copyright © 2004,2007,2009,2010 Red Hat, Inc. 4 | * Copyright © 2011 Google, Inc. 5 | * 6 | * This is part of HarfBuzz, a text shaping library. 7 | * 8 | * Permission is hereby granted, without written agreement and without 9 | * license or royalty fees, to use, copy, modify, and distribute this 10 | * software and its documentation for any purpose, provided that the 11 | * above copyright notice and the following two paragraphs appear in 12 | * all copies of this software. 13 | * 14 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18 | * DAMAGE. 19 | * 20 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | * 26 | * Red Hat Author(s): Owen Taylor, Behdad Esfahbod 27 | * Google Author(s): Behdad Esfahbod 28 | */ 29 | 30 | #ifndef HB_BUFFER_PRIVATE_HH 31 | #define HB_BUFFER_PRIVATE_HH 32 | 33 | #include "hb-private.hh" 34 | #include "hb-buffer.h" 35 | #include "hb-object-private.hh" 36 | #include "hb-unicode-private.hh" 37 | 38 | 39 | 40 | ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20); 41 | ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)); 42 | 43 | typedef struct _hb_segment_properties_t { 44 | hb_direction_t direction; 45 | hb_script_t script; 46 | hb_language_t language; 47 | } hb_segment_properties_t; 48 | 49 | 50 | struct _hb_buffer_t { 51 | hb_object_header_t header; 52 | 53 | /* Information about how the text in the buffer should be treated */ 54 | 55 | hb_unicode_funcs_t *unicode; /* Unicode functions */ 56 | hb_segment_properties_t props; /* Script, language, direction */ 57 | 58 | /* Buffer contents */ 59 | 60 | bool in_error; /* Allocation failed */ 61 | bool have_output; /* Whether we have an output buffer going on */ 62 | bool have_positions; /* Whether we have positions */ 63 | 64 | unsigned int idx; /* Cursor into ->info and ->pos arrays */ 65 | unsigned int len; /* Length of ->info and ->pos arrays */ 66 | unsigned int out_len; /* Length of ->out array if have_output */ 67 | 68 | unsigned int allocated; /* Length of allocated arrays */ 69 | hb_glyph_info_t *info; 70 | hb_glyph_info_t *out_info; 71 | hb_glyph_position_t *pos; 72 | 73 | unsigned int serial; 74 | uint8_t allocated_var_bytes[8]; 75 | const char *allocated_var_owner[8]; 76 | 77 | 78 | /* Methods */ 79 | 80 | HB_INTERNAL void reset (void); 81 | 82 | inline unsigned int backtrack_len (void) const 83 | { return have_output? out_len : idx; } 84 | inline unsigned int next_serial (void) { return serial++; } 85 | 86 | HB_INTERNAL void allocate_var (unsigned int byte_i, unsigned int count, const char *owner); 87 | HB_INTERNAL void deallocate_var (unsigned int byte_i, unsigned int count, const char *owner); 88 | HB_INTERNAL void deallocate_var_all (void); 89 | 90 | HB_INTERNAL void add (hb_codepoint_t codepoint, 91 | hb_mask_t mask, 92 | unsigned int cluster); 93 | 94 | HB_INTERNAL void reverse_range (unsigned int start, unsigned int end); 95 | HB_INTERNAL void reverse (void); 96 | HB_INTERNAL void reverse_clusters (void); 97 | HB_INTERNAL void guess_properties (void); 98 | 99 | HB_INTERNAL void swap_buffers (void); 100 | HB_INTERNAL void clear_output (void); 101 | HB_INTERNAL void clear_positions (void); 102 | HB_INTERNAL void replace_glyphs_be16 (unsigned int num_in, 103 | unsigned int num_out, 104 | const uint16_t *glyph_data_be); 105 | HB_INTERNAL void replace_glyphs (unsigned int num_in, 106 | unsigned int num_out, 107 | const uint16_t *glyph_data); 108 | HB_INTERNAL void replace_glyph (hb_codepoint_t glyph_index); 109 | /* Makes a copy of the glyph at idx to output and replace glyph_index */ 110 | HB_INTERNAL void output_glyph (hb_codepoint_t glyph_index); 111 | /* Copies glyph at idx to output but doesn't advance idx */ 112 | HB_INTERNAL void copy_glyph (void); 113 | /* Copies glyph at idx to output and advance idx. 114 | * If there's no output, just advance idx. */ 115 | HB_INTERNAL void next_glyph (void); 116 | /* Advance idx without copying to output. */ 117 | inline void skip_glyph (void) { idx++; } 118 | 119 | inline void reset_masks (hb_mask_t mask) 120 | { 121 | for (unsigned int j = 0; j < len; j++) 122 | info[j].mask = mask; 123 | } 124 | inline void add_masks (hb_mask_t mask) 125 | { 126 | for (unsigned int j = 0; j < len; j++) 127 | info[j].mask |= mask; 128 | } 129 | HB_INTERNAL void set_masks (hb_mask_t value, 130 | hb_mask_t mask, 131 | unsigned int cluster_start, 132 | unsigned int cluster_end); 133 | 134 | /* Internal methods */ 135 | HB_INTERNAL bool enlarge (unsigned int size); 136 | 137 | inline bool ensure (unsigned int size) 138 | { return likely (size <= allocated) ? TRUE : enlarge (size); } 139 | 140 | HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out); 141 | 142 | HB_INTERNAL void *get_scratch_buffer (unsigned int *size); 143 | }; 144 | 145 | 146 | #define HB_BUFFER_XALLOCATE_VAR(b, func, var, owner) \ 147 | b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \ 148 | sizeof (b->info[0].var), owner) 149 | #define HB_BUFFER_ALLOCATE_VAR(b, var) \ 150 | HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var (), #var) 151 | #define HB_BUFFER_DEALLOCATE_VAR(b, var) \ 152 | HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var (), #var) 153 | 154 | 155 | 156 | #endif /* HB_BUFFER_PRIVATE_HH */ 157 | -------------------------------------------------------------------------------- /harfbuzz/hb-buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 1998-2004 David Turner and Werner Lemberg 3 | * Copyright © 2004,2007,2009 Red Hat, Inc. 4 | * Copyright © 2011 Google, Inc. 5 | * 6 | * This is part of HarfBuzz, a text shaping library. 7 | * 8 | * Permission is hereby granted, without written agreement and without 9 | * license or royalty fees, to use, copy, modify, and distribute this 10 | * software and its documentation for any purpose, provided that the 11 | * above copyright notice and the following two paragraphs appear in 12 | * all copies of this software. 13 | * 14 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18 | * DAMAGE. 19 | * 20 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | * 26 | * Red Hat Author(s): Owen Taylor, Behdad Esfahbod 27 | * Google Author(s): Behdad Esfahbod 28 | */ 29 | 30 | #ifndef HB_BUFFER_H 31 | #define HB_BUFFER_H 32 | 33 | #include "hb-common.h" 34 | #include "hb-unicode.h" 35 | 36 | HB_BEGIN_DECLS 37 | 38 | 39 | typedef struct _hb_buffer_t hb_buffer_t; 40 | 41 | typedef struct _hb_glyph_info_t { 42 | hb_codepoint_t codepoint; 43 | hb_mask_t mask; 44 | uint32_t cluster; 45 | 46 | /*< private >*/ 47 | hb_var_int_t var1; 48 | hb_var_int_t var2; 49 | } hb_glyph_info_t; 50 | 51 | typedef struct _hb_glyph_position_t { 52 | hb_position_t x_advance; 53 | hb_position_t y_advance; 54 | hb_position_t x_offset; 55 | hb_position_t y_offset; 56 | 57 | /*< private >*/ 58 | hb_var_int_t var; 59 | } hb_glyph_position_t; 60 | 61 | 62 | hb_buffer_t * 63 | hb_buffer_create (void); 64 | 65 | hb_buffer_t * 66 | hb_buffer_get_empty (void); 67 | 68 | hb_buffer_t * 69 | hb_buffer_reference (hb_buffer_t *buffer); 70 | 71 | void 72 | hb_buffer_destroy (hb_buffer_t *buffer); 73 | 74 | hb_bool_t 75 | hb_buffer_set_user_data (hb_buffer_t *buffer, 76 | hb_user_data_key_t *key, 77 | void * data, 78 | hb_destroy_func_t destroy, 79 | hb_bool_t replace); 80 | 81 | void * 82 | hb_buffer_get_user_data (hb_buffer_t *buffer, 83 | hb_user_data_key_t *key); 84 | 85 | 86 | void 87 | hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, 88 | hb_unicode_funcs_t *unicode_funcs); 89 | 90 | hb_unicode_funcs_t * 91 | hb_buffer_get_unicode_funcs (hb_buffer_t *buffer); 92 | 93 | void 94 | hb_buffer_set_direction (hb_buffer_t *buffer, 95 | hb_direction_t direction); 96 | 97 | hb_direction_t 98 | hb_buffer_get_direction (hb_buffer_t *buffer); 99 | 100 | void 101 | hb_buffer_set_script (hb_buffer_t *buffer, 102 | hb_script_t script); 103 | 104 | hb_script_t 105 | hb_buffer_get_script (hb_buffer_t *buffer); 106 | 107 | void 108 | hb_buffer_set_language (hb_buffer_t *buffer, 109 | hb_language_t language); 110 | 111 | hb_language_t 112 | hb_buffer_get_language (hb_buffer_t *buffer); 113 | 114 | 115 | /* Resets the buffer. Afterwards it's as if it was just created, 116 | * except that it has a larger buffer allocated perhaps... */ 117 | void 118 | hb_buffer_reset (hb_buffer_t *buffer); 119 | 120 | /* Returns FALSE if allocation failed */ 121 | hb_bool_t 122 | hb_buffer_pre_allocate (hb_buffer_t *buffer, 123 | unsigned int size); 124 | 125 | 126 | /* Returns FALSE if allocation has failed before */ 127 | hb_bool_t 128 | hb_buffer_allocation_successful (hb_buffer_t *buffer); 129 | 130 | void 131 | hb_buffer_reverse (hb_buffer_t *buffer); 132 | 133 | void 134 | hb_buffer_reverse_clusters (hb_buffer_t *buffer); 135 | 136 | void 137 | hb_buffer_guess_properties (hb_buffer_t *buffer); 138 | 139 | 140 | /* Filling the buffer in */ 141 | 142 | void 143 | hb_buffer_add (hb_buffer_t *buffer, 144 | hb_codepoint_t codepoint, 145 | hb_mask_t mask, 146 | unsigned int cluster); 147 | 148 | void 149 | hb_buffer_add_utf8 (hb_buffer_t *buffer, 150 | const char *text, 151 | int text_length, 152 | unsigned int item_offset, 153 | int item_length); 154 | 155 | void 156 | hb_buffer_add_utf16 (hb_buffer_t *buffer, 157 | const uint16_t *text, 158 | int text_length, 159 | unsigned int item_offset, 160 | int item_length); 161 | 162 | void 163 | hb_buffer_add_utf32 (hb_buffer_t *buffer, 164 | const uint32_t *text, 165 | int text_length, 166 | unsigned int item_offset, 167 | int item_length); 168 | 169 | 170 | /* Clears any new items added at the end */ 171 | hb_bool_t 172 | hb_buffer_set_length (hb_buffer_t *buffer, 173 | unsigned int length); 174 | 175 | /* Return value valid as long as buffer not modified */ 176 | unsigned int 177 | hb_buffer_get_length (hb_buffer_t *buffer); 178 | 179 | /* Getting glyphs out of the buffer */ 180 | 181 | /* Return value valid as long as buffer not modified */ 182 | hb_glyph_info_t * 183 | hb_buffer_get_glyph_infos (hb_buffer_t *buffer, 184 | unsigned int *length); 185 | 186 | /* Return value valid as long as buffer not modified */ 187 | hb_glyph_position_t * 188 | hb_buffer_get_glyph_positions (hb_buffer_t *buffer, 189 | unsigned int *length); 190 | 191 | 192 | HB_END_DECLS 193 | 194 | #endif /* HB_BUFFER_H */ 195 | -------------------------------------------------------------------------------- /harfbuzz/hb-fallback-shape-private.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_FALLBACK_SHAPE_PRIVATE_HH 28 | #define HB_FALLBACK_SHAPE_PRIVATE_HH 29 | 30 | #include "hb-private.hh" 31 | 32 | #include "hb-shape.h" 33 | 34 | 35 | HB_BEGIN_DECLS 36 | 37 | 38 | HB_INTERNAL hb_bool_t 39 | hb_fallback_shape (hb_font_t *font, 40 | hb_buffer_t *buffer, 41 | const hb_feature_t *features, 42 | unsigned int num_features, 43 | const char * const *shaper_options); 44 | 45 | 46 | HB_END_DECLS 47 | 48 | #endif /* HB_FALLBACK_SHAPE_PRIVATE_HH */ 49 | -------------------------------------------------------------------------------- /harfbuzz/hb-fallback-shape.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #include "hb-fallback-shape-private.hh" 28 | 29 | #include "hb-buffer-private.hh" 30 | 31 | hb_bool_t 32 | hb_fallback_shape (hb_font_t *font, 33 | hb_buffer_t *buffer, 34 | const hb_feature_t *features, 35 | unsigned int num_features, 36 | const char * const *shaper_options) 37 | { 38 | buffer->guess_properties (); 39 | 40 | unsigned int count = buffer->len; 41 | 42 | for (unsigned int i = 0; i < count; i++) 43 | hb_font_get_glyph (font, buffer->info[i].codepoint, 0, &buffer->info[i].codepoint); 44 | 45 | buffer->clear_positions (); 46 | 47 | for (unsigned int i = 0; i < count; i++) { 48 | hb_font_get_glyph_advance_for_direction (font, buffer->info[i].codepoint, 49 | buffer->props.direction, 50 | &buffer->pos[i].x_advance, 51 | &buffer->pos[i].y_advance); 52 | hb_font_subtract_glyph_origin_for_direction (font, buffer->info[i].codepoint, 53 | buffer->props.direction, 54 | &buffer->pos[i].x_offset, 55 | &buffer->pos[i].y_offset); 56 | } 57 | 58 | if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) 59 | hb_buffer_reverse (buffer); 60 | 61 | return TRUE; 62 | } 63 | -------------------------------------------------------------------------------- /harfbuzz/hb-font-private.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * Copyright © 2011 Google, Inc. 4 | * 5 | * This is part of HarfBuzz, a text shaping library. 6 | * 7 | * Permission is hereby granted, without written agreement and without 8 | * license or royalty fees, to use, copy, modify, and distribute this 9 | * software and its documentation for any purpose, provided that the 10 | * above copyright notice and the following two paragraphs appear in 11 | * all copies of this software. 12 | * 13 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17 | * DAMAGE. 18 | * 19 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24 | * 25 | * Red Hat Author(s): Behdad Esfahbod 26 | * Google Author(s): Behdad Esfahbod 27 | */ 28 | 29 | #ifndef HB_FONT_PRIVATE_HH 30 | #define HB_FONT_PRIVATE_HH 31 | 32 | #include "hb-private.hh" 33 | 34 | #include "hb-font.h" 35 | #include "hb-object-private.hh" 36 | 37 | 38 | 39 | /* 40 | * hb_font_funcs_t 41 | */ 42 | 43 | #define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \ 44 | HB_FONT_FUNC_IMPLEMENT (glyph) \ 45 | HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \ 46 | HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \ 47 | HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \ 48 | HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \ 49 | HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \ 50 | HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \ 51 | HB_FONT_FUNC_IMPLEMENT (glyph_extents) \ 52 | HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \ 53 | /* ^--- Add new callbacks here */ 54 | 55 | struct _hb_font_funcs_t { 56 | hb_object_header_t header; 57 | 58 | hb_bool_t immutable; 59 | 60 | /* Don't access these directly. Call hb_font_get_*() instead. */ 61 | 62 | struct { 63 | #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name; 64 | HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 65 | #undef HB_FONT_FUNC_IMPLEMENT 66 | } get; 67 | 68 | struct { 69 | #define HB_FONT_FUNC_IMPLEMENT(name) void *name; 70 | HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 71 | #undef HB_FONT_FUNC_IMPLEMENT 72 | } user_data; 73 | 74 | struct { 75 | #define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name; 76 | HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 77 | #undef HB_FONT_FUNC_IMPLEMENT 78 | } destroy; 79 | }; 80 | 81 | 82 | /* 83 | * hb_face_t 84 | */ 85 | 86 | struct _hb_face_t { 87 | hb_object_header_t header; 88 | 89 | hb_bool_t immutable; 90 | 91 | hb_reference_table_func_t reference_table; 92 | void *user_data; 93 | hb_destroy_func_t destroy; 94 | 95 | struct hb_ot_layout_t *ot_layout; 96 | 97 | unsigned int index; 98 | unsigned int upem; 99 | }; 100 | 101 | 102 | /* 103 | * hb_font_t 104 | */ 105 | 106 | struct _hb_font_t { 107 | hb_object_header_t header; 108 | 109 | hb_bool_t immutable; 110 | 111 | hb_font_t *parent; 112 | hb_face_t *face; 113 | 114 | int x_scale; 115 | int y_scale; 116 | 117 | unsigned int x_ppem; 118 | unsigned int y_ppem; 119 | 120 | hb_font_funcs_t *klass; 121 | void *user_data; 122 | hb_destroy_func_t destroy; 123 | 124 | 125 | /* Convert from font-space to user-space */ 126 | inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scale); } 127 | inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, this->y_scale); } 128 | 129 | /* Convert from parent-font user-space to our user-space */ 130 | inline hb_position_t parent_scale_x_distance (hb_position_t v) { 131 | if (unlikely (parent && parent->x_scale != x_scale)) 132 | return v * (int64_t) this->x_scale / this->parent->x_scale; 133 | return v; 134 | } 135 | inline hb_position_t parent_scale_y_distance (hb_position_t v) { 136 | if (unlikely (parent && parent->y_scale != y_scale)) 137 | return v * (int64_t) this->y_scale / this->parent->y_scale; 138 | return v; 139 | } 140 | inline hb_position_t parent_scale_x_position (hb_position_t v) { 141 | return parent_scale_x_distance (v); 142 | } 143 | inline hb_position_t parent_scale_y_position (hb_position_t v) { 144 | return parent_scale_y_distance (v); 145 | } 146 | 147 | inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) { 148 | *x = parent_scale_x_distance (*x); 149 | *y = parent_scale_y_distance (*y); 150 | } 151 | inline void parent_scale_position (hb_position_t *x, hb_position_t *y) { 152 | *x = parent_scale_x_position (*x); 153 | *y = parent_scale_y_position (*y); 154 | } 155 | 156 | 157 | private: 158 | inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) scale / hb_face_get_upem (this->face); } 159 | }; 160 | 161 | 162 | 163 | #endif /* HB_FONT_PRIVATE_HH */ 164 | -------------------------------------------------------------------------------- /harfbuzz/hb-ft.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_FT_H 28 | #define HB_FT_H 29 | 30 | #include "hb.h" 31 | 32 | #include "hb-font.h" 33 | 34 | #include 35 | #include FT_FREETYPE_H 36 | 37 | HB_BEGIN_DECLS 38 | 39 | /* Note: FreeType is not thread-safe. Hence, these functions are not either. */ 40 | 41 | hb_face_t * 42 | hb_ft_face_create (FT_Face ft_face, 43 | hb_destroy_func_t destroy); 44 | 45 | hb_face_t * 46 | hb_ft_face_create_cached (FT_Face ft_face); 47 | 48 | hb_font_t * 49 | hb_ft_font_create (FT_Face ft_face, 50 | hb_destroy_func_t destroy); 51 | 52 | 53 | 54 | /* Makes an hb_font_t use FreeType internally to implement font functions. */ 55 | void 56 | hb_ft_font_set_funcs (hb_font_t *font); 57 | 58 | FT_Face 59 | hb_ft_font_get_face (hb_font_t *font); 60 | 61 | 62 | HB_END_DECLS 63 | 64 | #endif /* HB_FT_H */ 65 | -------------------------------------------------------------------------------- /harfbuzz/hb-glib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * Copyright © 2011 Google, Inc. 4 | * 5 | * This is part of HarfBuzz, a text shaping library. 6 | * 7 | * Permission is hereby granted, without written agreement and without 8 | * license or royalty fees, to use, copy, modify, and distribute this 9 | * software and its documentation for any purpose, provided that the 10 | * above copyright notice and the following two paragraphs appear in 11 | * all copies of this software. 12 | * 13 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17 | * DAMAGE. 18 | * 19 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24 | * 25 | * Red Hat Author(s): Behdad Esfahbod 26 | * Google Author(s): Behdad Esfahbod 27 | */ 28 | 29 | #ifndef HB_GLIB_H 30 | #define HB_GLIB_H 31 | 32 | #include "hb.h" 33 | #include 34 | 35 | HB_BEGIN_DECLS 36 | 37 | 38 | hb_script_t 39 | hb_glib_script_to_script (GUnicodeScript script); 40 | 41 | GUnicodeScript 42 | hb_glib_script_from_script (hb_script_t script); 43 | 44 | 45 | hb_unicode_funcs_t * 46 | hb_glib_get_unicode_funcs (void); 47 | 48 | 49 | HB_END_DECLS 50 | 51 | #endif /* HB_GLIB_H */ 52 | -------------------------------------------------------------------------------- /harfbuzz/hb-gobject-structs.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #include "hb-private.hh" 28 | 29 | /* g++ didn't like older gtype.h gcc-only code path. */ 30 | #include 31 | #if !GLIB_CHECK_VERSION(2,29,16) 32 | #undef __GNUC__ 33 | #undef __GNUC_MINOR__ 34 | #define __GNUC__ 2 35 | #define __GNUC_MINOR__ 6 36 | #endif 37 | 38 | #include "hb-gobject.h" 39 | 40 | #define _HB_DEFINE_BOXED_TYPE(Name,underscore_name,copy_func,free_func) \ 41 | GType \ 42 | underscore_name##_get_type (void) \ 43 | { \ 44 | static volatile gsize type = 0; \ 45 | if (g_once_init_enter (&type)) { \ 46 | GType t = g_boxed_type_register_static (g_intern_static_string (#Name), \ 47 | (GBoxedCopyFunc) copy_func, \ 48 | (GBoxedFreeFunc) free_func); \ 49 | g_once_init_leave (&type, t); \ 50 | } \ 51 | return type; \ 52 | } 53 | 54 | #define HB_DEFINE_BOXED_TYPE(name) \ 55 | _HB_DEFINE_BOXED_TYPE (hb_##name, hb_gobject_##name, hb_##name##_reference, hb_##name##_destroy); 56 | 57 | HB_DEFINE_BOXED_TYPE (buffer) 58 | HB_DEFINE_BOXED_TYPE (blob) 59 | HB_DEFINE_BOXED_TYPE (face) 60 | HB_DEFINE_BOXED_TYPE (font) 61 | HB_DEFINE_BOXED_TYPE (font_funcs) 62 | HB_DEFINE_BOXED_TYPE (unicode_funcs) 63 | 64 | -------------------------------------------------------------------------------- /harfbuzz/hb-gobject.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_GOBJECT_H 28 | #define HB_GOBJECT_H 29 | 30 | #include "hb.h" 31 | #include 32 | 33 | HB_BEGIN_DECLS 34 | 35 | 36 | /* Objects */ 37 | 38 | #define HB_GOBJECT_TYPE_BLOB hb_gobject_blob_get_type () 39 | GType 40 | hb_gobject_blob_get_type (void); 41 | 42 | #define HB_GOBJECT_TYPE_BUFFER hb_gobject_buffer_get_type () 43 | GType 44 | hb_gobject_buffer_get_type (void); 45 | 46 | #define HB_GOBJECT_TYPE_FACE hb_gobject_face_get_type () 47 | GType 48 | hb_gobject_face_get_type (void); 49 | 50 | #define HB_GOBJECT_TYPE_FONT hb_gobject_font_get_type () 51 | GType 52 | hb_gobject_font_get_type (void); 53 | 54 | #define HB_GOBJECT_TYPE_FONT_FUNCS hb_gobject_font_funcs_get_type () 55 | GType 56 | hb_gobject_font_funcs_get_type (void); 57 | 58 | #define HB_GOBJECT_TYPE_UNICODE_FUNCS hb_gobject_unicode_funcs_get_type () 59 | GType 60 | hb_gobject_unicode_funcs_get_type (void); 61 | 62 | 63 | /* Enums */ 64 | 65 | 66 | HB_END_DECLS 67 | 68 | #endif /* HB_GOBJECT_H */ 69 | -------------------------------------------------------------------------------- /harfbuzz/hb-graphite2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Martin Hosken 3 | * Copyright (C) 2011 SIL International 4 | * 5 | * This is part of HarfBuzz, a text shaping library. 6 | * 7 | * Permission is hereby granted, without written agreement and without 8 | * license or royalty fees, to use, copy, modify, and distribute this 9 | * software and its documentation for any purpose, provided that the 10 | * above copyright notice and the following two paragraphs appear in 11 | * all copies of this software. 12 | * 13 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17 | * DAMAGE. 18 | * 19 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24 | */ 25 | 26 | #ifndef HB_GRAPHITE2_H 27 | #define HB_GRAPHITE2_H 28 | 29 | #include "hb-common.h" 30 | #include "hb-shape.h" 31 | 32 | HB_BEGIN_DECLS 33 | 34 | 35 | #define HB_GRAPHITE_TAG_Silf HB_TAG('S','i','l','f') 36 | 37 | hb_bool_t 38 | hb_graphite_shape (hb_font_t *font, 39 | hb_buffer_t *buffer, 40 | const hb_feature_t *features, 41 | unsigned int num_features, 42 | const char * const *shaper_options); 43 | 44 | HB_END_DECLS 45 | 46 | #endif /* HB_GRAPHITE2_H */ 47 | -------------------------------------------------------------------------------- /harfbuzz/hb-icu.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * Copyright © 2009 Keith Stribley 4 | * Copyright © 2011 Google, Inc. 5 | * 6 | * This is part of HarfBuzz, a text shaping library. 7 | * 8 | * Permission is hereby granted, without written agreement and without 9 | * license or royalty fees, to use, copy, modify, and distribute this 10 | * software and its documentation for any purpose, provided that the 11 | * above copyright notice and the following two paragraphs appear in 12 | * all copies of this software. 13 | * 14 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18 | * DAMAGE. 19 | * 20 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | * 26 | * Red Hat Author(s): Behdad Esfahbod 27 | * Google Author(s): Behdad Esfahbod 28 | */ 29 | 30 | #include "hb-private.hh" 31 | 32 | #include "hb-icu.h" 33 | 34 | #include "hb-unicode-private.hh" 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | 42 | 43 | hb_script_t 44 | hb_icu_script_to_script (UScriptCode script) 45 | { 46 | if (unlikely (script == USCRIPT_INVALID_CODE)) 47 | return HB_SCRIPT_INVALID; 48 | 49 | return hb_script_from_string (uscript_getShortName (script), -1); 50 | } 51 | 52 | UScriptCode 53 | hb_icu_script_from_script (hb_script_t script) 54 | { 55 | if (unlikely (script == HB_SCRIPT_INVALID)) 56 | return USCRIPT_INVALID_CODE; 57 | 58 | for (unsigned int i = 0; i < USCRIPT_CODE_LIMIT; i++) 59 | if (unlikely (hb_icu_script_to_script ((UScriptCode) i) == script)) 60 | return (UScriptCode) i; 61 | 62 | return USCRIPT_UNKNOWN; 63 | } 64 | 65 | 66 | static unsigned int 67 | hb_icu_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED, 68 | hb_codepoint_t unicode, 69 | void *user_data HB_UNUSED) 70 | 71 | { 72 | return u_getCombiningClass (unicode); 73 | } 74 | 75 | static unsigned int 76 | hb_icu_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED, 77 | hb_codepoint_t unicode, 78 | void *user_data HB_UNUSED) 79 | { 80 | switch (u_getIntPropertyValue(unicode, UCHAR_EAST_ASIAN_WIDTH)) 81 | { 82 | case U_EA_WIDE: 83 | case U_EA_FULLWIDTH: 84 | return 2; 85 | case U_EA_NEUTRAL: 86 | case U_EA_AMBIGUOUS: 87 | case U_EA_HALFWIDTH: 88 | case U_EA_NARROW: 89 | return 1; 90 | } 91 | return 1; 92 | } 93 | 94 | static hb_unicode_general_category_t 95 | hb_icu_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED, 96 | hb_codepoint_t unicode, 97 | void *user_data HB_UNUSED) 98 | { 99 | switch (u_getIntPropertyValue(unicode, UCHAR_GENERAL_CATEGORY)) 100 | { 101 | case U_UNASSIGNED: return HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED; 102 | 103 | case U_UPPERCASE_LETTER: return HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER; 104 | case U_LOWERCASE_LETTER: return HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER; 105 | case U_TITLECASE_LETTER: return HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER; 106 | case U_MODIFIER_LETTER: return HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER; 107 | case U_OTHER_LETTER: return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER; 108 | 109 | case U_NON_SPACING_MARK: return HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK; 110 | case U_ENCLOSING_MARK: return HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK; 111 | case U_COMBINING_SPACING_MARK: return HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK; 112 | 113 | case U_DECIMAL_DIGIT_NUMBER: return HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER; 114 | case U_LETTER_NUMBER: return HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER; 115 | case U_OTHER_NUMBER: return HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER; 116 | 117 | case U_SPACE_SEPARATOR: return HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR; 118 | case U_LINE_SEPARATOR: return HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR; 119 | case U_PARAGRAPH_SEPARATOR: return HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR; 120 | 121 | case U_CONTROL_CHAR: return HB_UNICODE_GENERAL_CATEGORY_CONTROL; 122 | case U_FORMAT_CHAR: return HB_UNICODE_GENERAL_CATEGORY_FORMAT; 123 | case U_PRIVATE_USE_CHAR: return HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE; 124 | case U_SURROGATE: return HB_UNICODE_GENERAL_CATEGORY_SURROGATE; 125 | 126 | 127 | case U_DASH_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION; 128 | case U_START_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION; 129 | case U_END_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION; 130 | case U_CONNECTOR_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION; 131 | case U_OTHER_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION; 132 | 133 | case U_MATH_SYMBOL: return HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL; 134 | case U_CURRENCY_SYMBOL: return HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL; 135 | case U_MODIFIER_SYMBOL: return HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL; 136 | case U_OTHER_SYMBOL: return HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL; 137 | 138 | case U_INITIAL_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION; 139 | case U_FINAL_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION; 140 | } 141 | 142 | return HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED; 143 | } 144 | 145 | static hb_codepoint_t 146 | hb_icu_unicode_mirroring (hb_unicode_funcs_t *ufuncs HB_UNUSED, 147 | hb_codepoint_t unicode, 148 | void *user_data HB_UNUSED) 149 | { 150 | return u_charMirror(unicode); 151 | } 152 | 153 | static hb_script_t 154 | hb_icu_unicode_script (hb_unicode_funcs_t *ufuncs HB_UNUSED, 155 | hb_codepoint_t unicode, 156 | void *user_data HB_UNUSED) 157 | { 158 | UErrorCode status = U_ZERO_ERROR; 159 | UScriptCode scriptCode = uscript_getScript(unicode, &status); 160 | 161 | if (unlikely (status != U_ZERO_ERROR)) 162 | return HB_SCRIPT_UNKNOWN; 163 | 164 | return hb_icu_script_to_script (scriptCode); 165 | } 166 | 167 | static hb_bool_t 168 | hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED, 169 | hb_codepoint_t a, 170 | hb_codepoint_t b, 171 | hb_codepoint_t *ab, 172 | void *user_data HB_UNUSED) 173 | { 174 | if (!a || !b) 175 | return FALSE; 176 | 177 | UChar utf16[4], normalized[5]; 178 | gint len; 179 | hb_bool_t ret, err; 180 | UErrorCode icu_err; 181 | 182 | len = 0; 183 | err = FALSE; 184 | U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), a, err); 185 | if (err) return FALSE; 186 | U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), b, err); 187 | if (err) return FALSE; 188 | 189 | icu_err = U_ZERO_ERROR; 190 | len = unorm_normalize (utf16, len, UNORM_NFC, 0, normalized, ARRAY_LENGTH (normalized), &icu_err); 191 | if (icu_err) 192 | return FALSE; 193 | normalized[len] = 0; 194 | if (u_strlen (normalized) == 1) { 195 | U16_GET_UNSAFE (normalized, 0, *ab); 196 | ret = TRUE; 197 | } else { 198 | ret = FALSE; 199 | } 200 | 201 | return ret; 202 | } 203 | 204 | static hb_bool_t 205 | hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, 206 | hb_codepoint_t ab, 207 | hb_codepoint_t *a, 208 | hb_codepoint_t *b, 209 | void *user_data HB_UNUSED) 210 | { 211 | UChar utf16[2], normalized[20]; 212 | gint len; 213 | hb_bool_t ret, err; 214 | UErrorCode icu_err; 215 | 216 | /* This function is a monster! Maybe it wasn't a good idea adding a 217 | * pairwise decompose API... */ 218 | /* Watchout for the dragons. Err, watchout for macros changing len. */ 219 | 220 | len = 0; 221 | err = FALSE; 222 | U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), ab, err); 223 | if (err) return FALSE; 224 | 225 | icu_err = U_ZERO_ERROR; 226 | len = unorm_normalize (utf16, len, UNORM_NFD, 0, normalized, ARRAY_LENGTH (normalized), &icu_err); 227 | if (icu_err) 228 | return FALSE; 229 | 230 | normalized[len] = 0; 231 | len = u_strlen (normalized); 232 | 233 | if (len == 1) { 234 | U16_GET_UNSAFE (normalized, 0, *a); 235 | *b = 0; 236 | ret = *a != ab; 237 | } else if (len == 2) { 238 | len =0; 239 | U16_NEXT_UNSAFE (normalized, len, *a); 240 | U16_NEXT_UNSAFE (normalized, len, *b); 241 | 242 | /* Here's the ugly part: if ab decomposes to a single character and 243 | * that character decomposes again, we have to detect that and undo 244 | * the second part :-(. */ 245 | UChar recomposed[20]; 246 | icu_err = U_ZERO_ERROR; 247 | unorm_normalize (normalized, len, UNORM_NFC, 0, recomposed, ARRAY_LENGTH (recomposed), &icu_err); 248 | if (icu_err) 249 | return FALSE; 250 | hb_codepoint_t c; 251 | U16_GET_UNSAFE (recomposed, 0, c); 252 | if (c != *a && c != ab) { 253 | *a = c; 254 | *b = 0; 255 | } 256 | ret = TRUE; 257 | } else { 258 | /* If decomposed to more than two characters, take the last one, 259 | * and recompose the rest to get the first component. */ 260 | U16_PREV_UNSAFE (normalized, len, *b); 261 | UChar recomposed[20]; 262 | icu_err = U_ZERO_ERROR; 263 | len = unorm_normalize (normalized, len, UNORM_NFC, 0, recomposed, ARRAY_LENGTH (recomposed), &icu_err); 264 | if (icu_err) 265 | return FALSE; 266 | /* We expect that recomposed has exactly one character now. */ 267 | U16_GET_UNSAFE (recomposed, 0, *a); 268 | ret = TRUE; 269 | } 270 | 271 | return ret; 272 | } 273 | 274 | extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_icu; 275 | hb_unicode_funcs_t _hb_icu_unicode_funcs = { 276 | HB_OBJECT_HEADER_STATIC, 277 | 278 | NULL, /* parent */ 279 | TRUE, /* immutable */ 280 | { 281 | #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_icu_unicode_##name, 282 | HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS 283 | #undef HB_UNICODE_FUNC_IMPLEMENT 284 | } 285 | }; 286 | 287 | hb_unicode_funcs_t * 288 | hb_icu_get_unicode_funcs (void) 289 | { 290 | return &_hb_icu_unicode_funcs; 291 | } 292 | 293 | 294 | -------------------------------------------------------------------------------- /harfbuzz/hb-icu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * Copyright © 2011 Google, Inc. 4 | * 5 | * This is part of HarfBuzz, a text shaping library. 6 | * 7 | * Permission is hereby granted, without written agreement and without 8 | * license or royalty fees, to use, copy, modify, and distribute this 9 | * software and its documentation for any purpose, provided that the 10 | * above copyright notice and the following two paragraphs appear in 11 | * all copies of this software. 12 | * 13 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17 | * DAMAGE. 18 | * 19 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24 | * 25 | * Red Hat Author(s): Behdad Esfahbod 26 | * Google Author(s): Behdad Esfahbod 27 | */ 28 | 29 | #ifndef HB_ICU_H 30 | #define HB_ICU_H 31 | 32 | #include "hb.h" 33 | #include 34 | 35 | 36 | HB_BEGIN_DECLS 37 | 38 | 39 | hb_script_t 40 | hb_icu_script_to_script (UScriptCode script); 41 | 42 | UScriptCode 43 | hb_icu_script_from_script (hb_script_t script); 44 | 45 | 46 | hb_unicode_funcs_t * 47 | hb_icu_get_unicode_funcs (void); 48 | 49 | 50 | HB_END_DECLS 51 | 52 | #endif /* HB_ICU_H */ 53 | -------------------------------------------------------------------------------- /harfbuzz/hb-mutex-private.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2007 Chris Wilson 3 | * Copyright © 2009,2010 Red Hat, Inc. 4 | * Copyright © 2011 Google, Inc. 5 | * 6 | * This is part of HarfBuzz, a text shaping library. 7 | * 8 | * Permission is hereby granted, without written agreement and without 9 | * license or royalty fees, to use, copy, modify, and distribute this 10 | * software and its documentation for any purpose, provided that the 11 | * above copyright notice and the following two paragraphs appear in 12 | * all copies of this software. 13 | * 14 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18 | * DAMAGE. 19 | * 20 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | * 26 | * Contributor(s): 27 | * Chris Wilson 28 | * Red Hat Author(s): Behdad Esfahbod 29 | * Google Author(s): Behdad Esfahbod 30 | */ 31 | 32 | #ifndef HB_MUTEX_PRIVATE_HH 33 | #define HB_MUTEX_PRIVATE_HH 34 | 35 | #include "hb-private.hh" 36 | 37 | 38 | 39 | /* mutex */ 40 | 41 | /* We need external help for these */ 42 | 43 | #ifdef HAVE_GLIB 44 | 45 | #include 46 | 47 | typedef GStaticMutex hb_mutex_impl_t; 48 | #define HB_MUTEX_IMPL_INIT G_STATIC_MUTEX_INIT 49 | #define hb_mutex_impl_init(M) g_static_mutex_init (M) 50 | #define hb_mutex_impl_lock(M) g_static_mutex_lock (M) 51 | #define hb_mutex_impl_unlock(M) g_static_mutex_unlock (M) 52 | #define hb_mutex_impl_free(M) g_static_mutex_free (M) 53 | 54 | 55 | #elif defined(_MSC_VER) || defined(__MINGW32__) 56 | 57 | #include 58 | 59 | typedef CRITICAL_SECTION hb_mutex_impl_t; 60 | #define HB_MUTEX_IMPL_INIT { NULL, 0, 0, NULL, NULL, 0 } 61 | #define hb_mutex_impl_init(M) InitializeCriticalSection (M) 62 | #define hb_mutex_impl_lock(M) EnterCriticalSection (M) 63 | #define hb_mutex_impl_unlock(M) LeaveCriticalSection (M) 64 | #define hb_mutex_impl_free(M) DeleteCriticalSection (M) 65 | 66 | 67 | #else 68 | 69 | #warning "Could not find any system to define platform macros, library will NOT be thread-safe" 70 | 71 | typedef volatile int hb_mutex_impl_t; 72 | #define HB_MUTEX_IMPL_INIT 0 73 | #define hb_mutex_impl_init(M) ((void) (*(M) = 0)) 74 | #define hb_mutex_impl_lock(M) ((void) (*(M) = 1)) 75 | #define hb_mutex_impl_unlock(M) ((void) (*(M) = 0)) 76 | #define hb_mutex_impl_free(M) ((void) (*(M) = 2)) 77 | 78 | 79 | #endif 80 | 81 | 82 | struct hb_mutex_t 83 | { 84 | hb_mutex_impl_t m; 85 | 86 | inline void init (void) { hb_mutex_impl_init (&m); } 87 | inline void lock (void) { hb_mutex_impl_lock (&m); } 88 | inline void unlock (void) { hb_mutex_impl_unlock (&m); } 89 | inline void free (void) { hb_mutex_impl_free (&m); } 90 | }; 91 | 92 | #define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT} 93 | #define hb_mutex_init(M) (M)->init () 94 | #define hb_mutex_lock(M) (M)->lock () 95 | #define hb_mutex_unlock(M) (M)->unlock () 96 | #define hb_mutex_free(M) (M)->free () 97 | 98 | 99 | struct hb_static_mutex_t : hb_mutex_t 100 | { 101 | hb_static_mutex_t (void) { this->init (); } 102 | ~hb_static_mutex_t (void) { this->free (); } 103 | 104 | private: 105 | NO_COPY (hb_static_mutex_t); 106 | }; 107 | 108 | 109 | 110 | #endif /* HB_MUTEX_PRIVATE_HH */ 111 | -------------------------------------------------------------------------------- /harfbuzz/hb-object-private.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2007 Chris Wilson 3 | * Copyright © 2009,2010 Red Hat, Inc. 4 | * Copyright © 2011 Google, Inc. 5 | * 6 | * This is part of HarfBuzz, a text shaping library. 7 | * 8 | * Permission is hereby granted, without written agreement and without 9 | * license or royalty fees, to use, copy, modify, and distribute this 10 | * software and its documentation for any purpose, provided that the 11 | * above copyright notice and the following two paragraphs appear in 12 | * all copies of this software. 13 | * 14 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18 | * DAMAGE. 19 | * 20 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | * 26 | * Contributor(s): 27 | * Chris Wilson 28 | * Red Hat Author(s): Behdad Esfahbod 29 | * Google Author(s): Behdad Esfahbod 30 | */ 31 | 32 | #ifndef HB_OBJECT_PRIVATE_HH 33 | #define HB_OBJECT_PRIVATE_HH 34 | 35 | #include "hb-private.hh" 36 | 37 | #include "hb-mutex-private.hh" 38 | 39 | 40 | 41 | /* Debug */ 42 | 43 | #ifndef HB_DEBUG_OBJECT 44 | #define HB_DEBUG_OBJECT (HB_DEBUG+0) 45 | #endif 46 | 47 | 48 | /* atomic_int */ 49 | 50 | /* We need external help for these */ 51 | 52 | #ifdef HAVE_GLIB 53 | 54 | #include 55 | 56 | typedef volatile int hb_atomic_int_t; 57 | #if GLIB_CHECK_VERSION(2,29,5) 58 | #define hb_atomic_int_add(AI, V) g_atomic_int_add (&(AI), V) 59 | #else 60 | #define hb_atomic_int_add(AI, V) g_atomic_int_exchange_and_add (&(AI), V) 61 | #endif 62 | #define hb_atomic_int_get(AI) g_atomic_int_get (&(AI)) 63 | #define hb_atomic_int_set(AI, V) g_atomic_int_set (&(AI), V) 64 | 65 | 66 | #elif _MSC_VER >= 1600 67 | 68 | #include 69 | 70 | typedef long hb_atomic_int_t; 71 | #define hb_atomic_int_add(AI, V) _InterlockedExchangeAdd (&(AI), V) 72 | #define hb_atomic_int_get(AI) (_ReadBarrier (), (AI)) 73 | #define hb_atomic_int_set(AI, V) ((void) _InterlockedExchange (&(AI), (V))) 74 | 75 | 76 | #else 77 | 78 | #ifdef _MSC_VER 79 | #pragma message("Could not find any system to define atomic_int macros, library will NOT be thread-safe") 80 | #else 81 | #warning "Could not find any system to define atomic_int macros, library will NOT be thread-safe" 82 | #endif 83 | 84 | typedef volatile int hb_atomic_int_t; 85 | #define hb_atomic_int_add(AI, V) ((AI) += (V), (AI) - (V)) 86 | #define hb_atomic_int_get(AI) (AI) 87 | #define hb_atomic_int_set(AI, V) ((void) ((AI) = (V))) 88 | 89 | 90 | #endif 91 | 92 | 93 | 94 | 95 | /* reference_count */ 96 | 97 | typedef struct { 98 | hb_atomic_int_t ref_count; 99 | 100 | #define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1) 101 | #define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE} 102 | 103 | inline void init (int v) { ref_count = v; /* non-atomic is fine */ } 104 | inline int inc (void) { return hb_atomic_int_add (ref_count, 1); } 105 | inline int dec (void) { return hb_atomic_int_add (ref_count, -1); } 106 | inline void set (int v) { hb_atomic_int_set (ref_count, v); } 107 | 108 | inline int get (void) const { return hb_atomic_int_get (ref_count); } 109 | inline bool is_invalid (void) const { return get () == HB_REFERENCE_COUNT_INVALID_VALUE; } 110 | 111 | } hb_reference_count_t; 112 | 113 | 114 | /* user_data */ 115 | 116 | struct hb_user_data_array_t { 117 | 118 | struct hb_user_data_item_t { 119 | hb_user_data_key_t *key; 120 | void *data; 121 | hb_destroy_func_t destroy; 122 | 123 | inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; } 124 | inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; } 125 | 126 | void finish (void) { if (destroy) destroy (data); } 127 | }; 128 | 129 | hb_lockable_set_t items; 130 | 131 | HB_INTERNAL bool set (hb_user_data_key_t *key, 132 | void * data, 133 | hb_destroy_func_t destroy, 134 | hb_bool_t replace); 135 | 136 | HB_INTERNAL void *get (hb_user_data_key_t *key); 137 | 138 | HB_INTERNAL void finish (void); 139 | }; 140 | 141 | 142 | /* object_header */ 143 | 144 | typedef struct _hb_object_header_t hb_object_header_t; 145 | 146 | struct _hb_object_header_t { 147 | hb_reference_count_t ref_count; 148 | hb_user_data_array_t user_data; 149 | 150 | #define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID} 151 | 152 | static inline void *create (unsigned int size) { 153 | hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size); 154 | 155 | if (likely (obj)) 156 | obj->init (); 157 | 158 | return obj; 159 | } 160 | 161 | inline void init (void) { 162 | ref_count.init (1); 163 | } 164 | 165 | inline bool is_inert (void) const { 166 | return unlikely (ref_count.is_invalid ()); 167 | } 168 | 169 | inline void reference (void) { 170 | if (unlikely (!this || this->is_inert ())) 171 | return; 172 | ref_count.inc (); 173 | } 174 | 175 | inline bool destroy (void) { 176 | if (unlikely (!this || this->is_inert ())) 177 | return false; 178 | if (ref_count.dec () != 1) 179 | return false; 180 | 181 | ref_count.init (HB_REFERENCE_COUNT_INVALID_VALUE); 182 | 183 | user_data.finish (); 184 | 185 | return true; 186 | } 187 | 188 | inline bool set_user_data (hb_user_data_key_t *key, 189 | void * data, 190 | hb_destroy_func_t destroy_func, 191 | hb_bool_t replace) { 192 | if (unlikely (!this || this->is_inert ())) 193 | return false; 194 | 195 | return user_data.set (key, data, destroy_func, replace); 196 | } 197 | 198 | inline void *get_user_data (hb_user_data_key_t *key) { 199 | return user_data.get (key); 200 | } 201 | 202 | inline void trace (const char *function) const { 203 | DEBUG_MSG (OBJECT, (void *) this, 204 | "refcount=%d %s", 205 | this ? ref_count.get () : 0, 206 | function); 207 | } 208 | 209 | }; 210 | 211 | 212 | 213 | 214 | /* object */ 215 | 216 | template 217 | static inline void hb_object_trace (const Type *obj, const char *function) 218 | { 219 | obj->header.trace (function); 220 | } 221 | template 222 | static inline Type *hb_object_create (void) 223 | { 224 | Type *obj = (Type *) hb_object_header_t::create (sizeof (Type)); 225 | hb_object_trace (obj, HB_FUNC); 226 | return obj; 227 | } 228 | template 229 | static inline bool hb_object_is_inert (const Type *obj) 230 | { 231 | return unlikely (obj->header.is_inert ()); 232 | } 233 | template 234 | static inline Type *hb_object_reference (Type *obj) 235 | { 236 | hb_object_trace (obj, HB_FUNC); 237 | obj->header.reference (); 238 | return obj; 239 | } 240 | template 241 | static inline bool hb_object_destroy (Type *obj) 242 | { 243 | hb_object_trace (obj, HB_FUNC); 244 | return obj->header.destroy (); 245 | } 246 | template 247 | static inline bool hb_object_set_user_data (Type *obj, 248 | hb_user_data_key_t *key, 249 | void * data, 250 | hb_destroy_func_t destroy, 251 | hb_bool_t replace) 252 | { 253 | return obj->header.set_user_data (key, data, destroy, replace); 254 | } 255 | 256 | template 257 | static inline void *hb_object_get_user_data (Type *obj, 258 | hb_user_data_key_t *key) 259 | { 260 | return obj->header.get_user_data (key); 261 | } 262 | 263 | 264 | 265 | 266 | 267 | #endif /* HB_OBJECT_PRIVATE_HH */ 268 | -------------------------------------------------------------------------------- /harfbuzz/hb-open-file-private.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2007,2008,2009 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OPEN_FILE_PRIVATE_HH 28 | #define HB_OPEN_FILE_PRIVATE_HH 29 | 30 | #include "hb-open-type-private.hh" 31 | 32 | 33 | 34 | /* 35 | * 36 | * The OpenType Font File 37 | * 38 | */ 39 | 40 | 41 | /* 42 | * Organization of an OpenType Font 43 | */ 44 | 45 | struct OpenTypeFontFile; 46 | struct OffsetTable; 47 | struct TTCHeader; 48 | 49 | 50 | typedef struct TableRecord 51 | { 52 | inline bool sanitize (hb_sanitize_context_t *c) { 53 | TRACE_SANITIZE (); 54 | return c->check_struct (this); 55 | } 56 | 57 | Tag tag; /* 4-byte identifier. */ 58 | CheckSum checkSum; /* CheckSum for this table. */ 59 | ULONG offset; /* Offset from beginning of TrueType font 60 | * file. */ 61 | ULONG length; /* Length of this table. */ 62 | public: 63 | DEFINE_SIZE_STATIC (16); 64 | } OpenTypeTable; 65 | 66 | typedef struct OffsetTable 67 | { 68 | friend struct OpenTypeFontFile; 69 | 70 | inline unsigned int get_table_count (void) const 71 | { return numTables; } 72 | inline const TableRecord& get_table (unsigned int i) const 73 | { 74 | if (unlikely (i >= numTables)) return Null(TableRecord); 75 | return tables[i]; 76 | } 77 | inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const 78 | { 79 | Tag t; 80 | t.set (tag); 81 | unsigned int count = numTables; 82 | for (unsigned int i = 0; i < count; i++) 83 | { 84 | if (t == tables[i].tag) 85 | { 86 | if (table_index) *table_index = i; 87 | return true; 88 | } 89 | } 90 | if (table_index) *table_index = Index::NOT_FOUND_INDEX; 91 | return false; 92 | } 93 | inline const TableRecord& get_table_by_tag (hb_tag_t tag) const 94 | { 95 | unsigned int table_index; 96 | find_table_index (tag, &table_index); 97 | return get_table (table_index); 98 | } 99 | 100 | public: 101 | inline bool sanitize (hb_sanitize_context_t *c) { 102 | TRACE_SANITIZE (); 103 | return c->check_struct (this) 104 | && c->check_array (tables, TableRecord::static_size, numTables); 105 | } 106 | 107 | private: 108 | Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */ 109 | USHORT numTables; /* Number of tables. */ 110 | USHORT searchRange; /* (Maximum power of 2 <= numTables) x 16 */ 111 | USHORT entrySelector; /* Log2(maximum power of 2 <= numTables). */ 112 | USHORT rangeShift; /* NumTables x 16-searchRange. */ 113 | TableRecord tables[VAR]; /* TableRecord entries. numTables items */ 114 | public: 115 | DEFINE_SIZE_ARRAY (12, tables); 116 | } OpenTypeFontFace; 117 | 118 | 119 | /* 120 | * TrueType Collections 121 | */ 122 | 123 | struct TTCHeaderVersion1 124 | { 125 | friend struct TTCHeader; 126 | 127 | inline unsigned int get_face_count (void) const { return table.len; } 128 | inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; } 129 | 130 | inline bool sanitize (hb_sanitize_context_t *c) { 131 | TRACE_SANITIZE (); 132 | return table.sanitize (c, this); 133 | } 134 | 135 | private: 136 | Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ 137 | FixedVersion version; /* Version of the TTC Header (1.0), 138 | * 0x00010000 */ 139 | LongOffsetLongArrayOf 140 | table; /* Array of offsets to the OffsetTable for each font 141 | * from the beginning of the file */ 142 | public: 143 | DEFINE_SIZE_ARRAY (12, table); 144 | }; 145 | 146 | struct TTCHeader 147 | { 148 | friend struct OpenTypeFontFile; 149 | 150 | private: 151 | 152 | inline unsigned int get_face_count (void) const 153 | { 154 | switch (u.header.version.major) { 155 | case 2: /* version 2 is compatible with version 1 */ 156 | case 1: return u.version1.get_face_count (); 157 | default:return 0; 158 | } 159 | } 160 | inline const OpenTypeFontFace& get_face (unsigned int i) const 161 | { 162 | switch (u.header.version.major) { 163 | case 2: /* version 2 is compatible with version 1 */ 164 | case 1: return u.version1.get_face (i); 165 | default:return Null(OpenTypeFontFace); 166 | } 167 | } 168 | 169 | inline bool sanitize (hb_sanitize_context_t *c) { 170 | TRACE_SANITIZE (); 171 | if (unlikely (!u.header.version.sanitize (c))) return false; 172 | switch (u.header.version.major) { 173 | case 2: /* version 2 is compatible with version 1 */ 174 | case 1: return u.version1.sanitize (c); 175 | default:return true; 176 | } 177 | } 178 | 179 | private: 180 | union { 181 | struct { 182 | Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ 183 | FixedVersion version; /* Version of the TTC Header (1.0 or 2.0), 184 | * 0x00010000 or 0x00020000 */ 185 | } header; 186 | TTCHeaderVersion1 version1; 187 | } u; 188 | }; 189 | 190 | 191 | /* 192 | * OpenType Font File 193 | */ 194 | 195 | struct OpenTypeFontFile 196 | { 197 | static const hb_tag_t CFFTag = HB_TAG ('O','T','T','O'); /* OpenType with Postscript outlines */ 198 | static const hb_tag_t TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ); /* OpenType with TrueType outlines */ 199 | static const hb_tag_t TTCTag = HB_TAG ('t','t','c','f'); /* TrueType Collection */ 200 | static const hb_tag_t TrueTag = HB_TAG ('t','r','u','e'); /* Obsolete Apple TrueType */ 201 | static const hb_tag_t Typ1Tag = HB_TAG ('t','y','p','1'); /* Obsolete Apple Type1 font in SFNT container */ 202 | 203 | inline hb_tag_t get_tag (void) const { return u.tag; } 204 | 205 | inline unsigned int get_face_count (void) const 206 | { 207 | switch (u.tag) { 208 | case CFFTag: /* All the non-collection tags */ 209 | case TrueTag: 210 | case Typ1Tag: 211 | case TrueTypeTag: return 1; 212 | case TTCTag: return u.ttcHeader.get_face_count (); 213 | default: return 0; 214 | } 215 | } 216 | inline const OpenTypeFontFace& get_face (unsigned int i) const 217 | { 218 | switch (u.tag) { 219 | /* Note: for non-collection SFNT data we ignore index. This is because 220 | * Apple dfont container is a container of SFNT's. So each SFNT is a 221 | * non-TTC, but the index is more than zero. */ 222 | case CFFTag: /* All the non-collection tags */ 223 | case TrueTag: 224 | case Typ1Tag: 225 | case TrueTypeTag: return u.fontFace; 226 | case TTCTag: return u.ttcHeader.get_face (i); 227 | default: return Null(OpenTypeFontFace); 228 | } 229 | } 230 | 231 | inline bool sanitize (hb_sanitize_context_t *c) { 232 | TRACE_SANITIZE (); 233 | if (unlikely (!u.tag.sanitize (c))) return false; 234 | switch (u.tag) { 235 | case CFFTag: /* All the non-collection tags */ 236 | case TrueTag: 237 | case Typ1Tag: 238 | case TrueTypeTag: return u.fontFace.sanitize (c); 239 | case TTCTag: return u.ttcHeader.sanitize (c); 240 | default: return true; 241 | } 242 | } 243 | 244 | private: 245 | union { 246 | Tag tag; /* 4-byte identifier. */ 247 | OpenTypeFontFace fontFace; 248 | TTCHeader ttcHeader; 249 | } u; 250 | public: 251 | DEFINE_SIZE_UNION (4, tag); 252 | }; 253 | 254 | 255 | 256 | #endif /* HB_OPEN_FILE_PRIVATE_HH */ 257 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-head-table.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OT_HEAD_TABLE_HH 28 | #define HB_OT_HEAD_TABLE_HH 29 | 30 | #include "hb-open-type-private.hh" 31 | 32 | 33 | 34 | /* 35 | * head -- Font Header 36 | */ 37 | 38 | #define HB_OT_TAG_head HB_TAG('h','e','a','d') 39 | 40 | struct head 41 | { 42 | static const hb_tag_t Tag = HB_OT_TAG_head; 43 | 44 | inline unsigned int get_upem (void) const { 45 | unsigned int upem = unitsPerEm; 46 | /* If no valid head table found, assume 1000, which matches typicaly Type1 usage. */ 47 | return 16 <= upem && upem <= 16384 ? upem : 1000; 48 | } 49 | 50 | inline bool sanitize (hb_sanitize_context_t *c) { 51 | TRACE_SANITIZE (); 52 | return c->check_struct (this) && likely (version.major == 1); 53 | } 54 | 55 | private: 56 | FixedVersion version; /* Version of the head table--currently 57 | * 0x00010000 for version 1.0. */ 58 | FixedVersion fontRevision; /* Set by font manufacturer. */ 59 | ULONG checkSumAdjustment; /* To compute: set it to 0, sum the 60 | * entire font as ULONG, then store 61 | * 0xB1B0AFBA - sum. */ 62 | ULONG magicNumber; /* Set to 0x5F0F3CF5. */ 63 | USHORT flags; /* Bit 0: Baseline for font at y=0; 64 | * Bit 1: Left sidebearing point at x=0; 65 | * Bit 2: Instructions may depend on point size; 66 | * Bit 3: Force ppem to integer values for all 67 | * internal scaler math; may use fractional 68 | * ppem sizes if this bit is clear; 69 | * Bit 4: Instructions may alter advance width 70 | * (the advance widths might not scale linearly); 71 | 72 | * Bits 5-10: These should be set according to 73 | * Apple's specification. However, they are not 74 | * implemented in OpenType. 75 | * Bit 5: This bit should be set in fonts that are 76 | * intended to e laid out vertically, and in 77 | * which the glyphs have been drawn such that an 78 | * x-coordinate of 0 corresponds to the desired 79 | * vertical baseline. 80 | * Bit 6: This bit must be set to zero. 81 | * Bit 7: This bit should be set if the font 82 | * requires layout for correct linguistic 83 | * rendering (e.g. Arabic fonts). 84 | * Bit 8: This bit should be set for a GX font 85 | * which has one or more metamorphosis effects 86 | * designated as happening by default. 87 | * Bit 9: This bit should be set if the font 88 | * contains any strong right-to-left glyphs. 89 | * Bit 10: This bit should be set if the font 90 | * contains Indic-style rearrangement effects. 91 | 92 | * Bit 11: Font data is 'lossless,' as a result 93 | * of having been compressed and decompressed 94 | * with the Agfa MicroType Express engine. 95 | * Bit 12: Font converted (produce compatible metrics) 96 | * Bit 13: Font optimized for ClearType™. 97 | * Note, fonts that rely on embedded bitmaps (EBDT) 98 | * for rendering should not be considered optimized 99 | * for ClearType, and therefore should keep this bit 100 | * cleared. 101 | * Bit 14: Last Resort font. If set, indicates that 102 | * the glyphs encoded in the cmap subtables are simply 103 | * generic symbolic representations of code point 104 | * ranges and don’t truly represent support for those 105 | * code points. If unset, indicates that the glyphs 106 | * encoded in the cmap subtables represent proper 107 | * support for those code points. 108 | * Bit 15: Reserved, set to 0. */ 109 | USHORT unitsPerEm; /* Valid range is from 16 to 16384. This value 110 | * should be a power of 2 for fonts that have 111 | * TrueType outlines. */ 112 | LONGDATETIME created; /* Number of seconds since 12:00 midnight, 113 | January 1, 1904. 64-bit integer */ 114 | LONGDATETIME modified; /* Number of seconds since 12:00 midnight, 115 | January 1, 1904. 64-bit integer */ 116 | SHORT xMin; /* For all glyph bounding boxes. */ 117 | SHORT yMin; /* For all glyph bounding boxes. */ 118 | SHORT xMax; /* For all glyph bounding boxes. */ 119 | SHORT yMax; /* For all glyph bounding boxes. */ 120 | USHORT macStyle; /* Bit 0: Bold (if set to 1); 121 | * Bit 1: Italic (if set to 1) 122 | * Bit 2: Underline (if set to 1) 123 | * Bit 3: Outline (if set to 1) 124 | * Bit 4: Shadow (if set to 1) 125 | * Bit 5: Condensed (if set to 1) 126 | * Bit 6: Extended (if set to 1) 127 | * Bits 7-15: Reserved (set to 0). */ 128 | USHORT lowestRecPPEM; /* Smallest readable size in pixels. */ 129 | SHORT fontDirectionHint; /* Deprecated (Set to 2). 130 | * 0: Fully mixed directional glyphs; 131 | * 1: Only strongly left to right; 132 | * 2: Like 1 but also contains neutrals; 133 | * -1: Only strongly right to left; 134 | * -2: Like -1 but also contains neutrals. */ 135 | SHORT indexToLocFormat; /* 0 for short offsets, 1 for long. */ 136 | SHORT glyphDataFormat; /* 0 for current format. */ 137 | public: 138 | DEFINE_SIZE_STATIC (54); 139 | }; 140 | 141 | 142 | 143 | #endif /* HB_OT_HEAD_TABLE_HH */ 144 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-hhea-table.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OT_HHEA_TABLE_HH 28 | #define HB_OT_HHEA_TABLE_HH 29 | 30 | #include "hb-open-type-private.hh" 31 | 32 | 33 | 34 | /* 35 | * hhea -- The Horizontal Header Table 36 | */ 37 | 38 | #define HB_OT_TAG_hhea HB_TAG('h','h','e','a') 39 | 40 | 41 | struct hhea 42 | { 43 | static const hb_tag_t Tag = HB_OT_TAG_hhea; 44 | 45 | inline bool sanitize (hb_sanitize_context_t *c) { 46 | TRACE_SANITIZE (); 47 | return c->check_struct (this) && likely (version.major == 1); 48 | } 49 | 50 | private: 51 | FixedVersion version; /* 0x00010000 for version 1.0. */ 52 | FWORD ascender; /* Typographic ascent. 54 | * (Distance from baseline of highest 55 | * ascender) */ 56 | FWORD descender; /* Typographic descent. 58 | * (Distance from baseline of lowest 59 | * descender) */ 60 | FWORD lineGap; /* Typographic line gap. Negative 61 | * LineGap values are treated as zero 62 | * in Windows 3.1, System 6, and 63 | * System 7. */ 64 | UFWORD advanceWidthMax; /* Maximum advance width value in 65 | * 'hmtx' table. */ 66 | FWORD minLeftSideBearing; /* Minimum left sidebearing value in 67 | * 'hmtx' table. */ 68 | FWORD minRightSideBearing; /* Minimum right sidebearing value; 69 | * calculated as Min(aw - lsb - 70 | * (xMax - xMin)). */ 71 | FWORD xMaxExtent; /* Max(lsb + (xMax - xMin)). */ 72 | SHORT caretSlopeRise; /* Used to calculate the slope of the 73 | * cursor (rise/run); 1 for vertical. */ 74 | SHORT caretSlopeRun; /* 0 for vertical. */ 75 | SHORT caretOffset; /* The amount by which a slanted 76 | * highlight on a glyph needs 77 | * to be shifted to produce the 78 | * best appearance. Set to 0 for 79 | * non--slanted fonts */ 80 | SHORT reserved1; /* set to 0 */ 81 | SHORT reserved2; /* set to 0 */ 82 | SHORT reserved3; /* set to 0 */ 83 | SHORT reserved4; /* set to 0 */ 84 | SHORT metricDataFormat; /* 0 for current format. */ 85 | USHORT numberOfHMetrics; /* Number of hMetric entries in 'hmtx' 86 | * table */ 87 | public: 88 | DEFINE_SIZE_STATIC (36); 89 | }; 90 | 91 | 92 | #endif /* HB_OT_HHEA_TABLE_HH */ 93 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-hmtx-table.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OT_HMTX_TABLE_HH 28 | #define HB_OT_HMTX_TABLE_HH 29 | 30 | #include "hb-open-type-private.hh" 31 | 32 | 33 | 34 | /* 35 | * hmtx -- The Horizontal Metrics Table 36 | */ 37 | 38 | #define HB_OT_TAG_hmtx HB_TAG('h','m','t','x') 39 | 40 | 41 | struct LongHorMetric 42 | { 43 | USHORT advanceWidth; 44 | SHORT lsb; 45 | public: 46 | DEFINE_SIZE_STATIC (4); 47 | }; 48 | 49 | struct hmtx 50 | { 51 | static const hb_tag_t Tag = HB_OT_TAG_hmtx; 52 | 53 | inline bool sanitize (hb_sanitize_context_t *c) { 54 | TRACE_SANITIZE (); 55 | /* We don't check for anything specific here. The users of the 56 | * struct do all the hard work... */ 57 | return true; 58 | } 59 | 60 | private: 61 | LongHorMetric longHorMetric[VAR]; /* Paired advance width and left side 62 | * bearing values for each glyph. The 63 | * value numOfHMetrics comes from 64 | * the 'hhea' table. If the font is 65 | * monospaced, only one entry need 66 | * be in the array, but that entry is 67 | * required. The last entry applies to 68 | * all subsequent glyphs. */ 69 | SHORT leftSideBearingX[VAR]; /* Here the advanceWidth is assumed 70 | * to be the same as the advanceWidth 71 | * for the last entry above. The 72 | * number of entries in this array is 73 | * derived from numGlyphs (from 'maxp' 74 | * table) minus numberOfHMetrics. This 75 | * generally is used with a run of 76 | * monospaced glyphs (e.g., Kanji 77 | * fonts or Courier fonts). Only one 78 | * run is allowed and it must be at 79 | * the end. This allows a monospaced 80 | * font to vary the left side bearing 81 | * values for each glyph. */ 82 | public: 83 | DEFINE_SIZE_ARRAY2 (0, longHorMetric, leftSideBearingX); 84 | }; 85 | 86 | #endif /* HB_OT_HMTX_TABLE_HH */ 87 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-layout-private.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2007,2008,2009 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OT_LAYOUT_PRIVATE_HH 28 | #define HB_OT_LAYOUT_PRIVATE_HH 29 | 30 | #include "hb-private.hh" 31 | 32 | #include "hb-ot-layout.h" 33 | 34 | #include "hb-font-private.hh" 35 | #include "hb-buffer-private.hh" 36 | 37 | 38 | 39 | /* 40 | * GDEF 41 | */ 42 | 43 | /* buffer var allocations */ 44 | #define props_cache() var1.u16[1] /* glyph_props cache */ 45 | 46 | /* XXX cleanup */ 47 | typedef enum { 48 | HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0x0001, 49 | HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 0x0002, 50 | HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE = 0x0004, 51 | HB_OT_LAYOUT_GLYPH_CLASS_MARK = 0x0008, 52 | HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 0x0010 53 | } hb_ot_layout_glyph_class_t; 54 | 55 | 56 | HB_INTERNAL unsigned int 57 | _hb_ot_layout_get_glyph_property (hb_face_t *face, 58 | hb_glyph_info_t *info); 59 | 60 | HB_INTERNAL hb_bool_t 61 | _hb_ot_layout_check_glyph_property (hb_face_t *face, 62 | hb_glyph_info_t *ginfo, 63 | unsigned int lookup_props, 64 | unsigned int *property_out); 65 | 66 | HB_INTERNAL hb_bool_t 67 | _hb_ot_layout_skip_mark (hb_face_t *face, 68 | hb_glyph_info_t *ginfo, 69 | unsigned int lookup_props, 70 | unsigned int *property_out); 71 | 72 | 73 | 74 | /* 75 | * hb_ot_layout_t 76 | */ 77 | 78 | struct hb_ot_layout_t 79 | { 80 | hb_blob_t *gdef_blob; 81 | hb_blob_t *gsub_blob; 82 | hb_blob_t *gpos_blob; 83 | 84 | const struct GDEF *gdef; 85 | const struct GSUB *gsub; 86 | const struct GPOS *gpos; 87 | }; 88 | 89 | 90 | HB_INTERNAL hb_ot_layout_t * 91 | _hb_ot_layout_create (hb_face_t *face); 92 | 93 | HB_INTERNAL void 94 | _hb_ot_layout_destroy (hb_ot_layout_t *layout); 95 | 96 | 97 | 98 | #endif /* HB_OT_LAYOUT_PRIVATE_HH */ 99 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-layout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2007,2008,2009 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OT_LAYOUT_H 28 | #define HB_OT_LAYOUT_H 29 | 30 | #include "hb-common.h" 31 | #include "hb-buffer.h" 32 | #include "hb-font.h" 33 | 34 | #include "hb-ot-tag.h" 35 | 36 | HB_BEGIN_DECLS 37 | 38 | 39 | #define HB_OT_TAG_GDEF HB_TAG('G','D','E','F') 40 | #define HB_OT_TAG_GSUB HB_TAG('G','S','U','B') 41 | #define HB_OT_TAG_GPOS HB_TAG('G','P','O','S') 42 | 43 | /* 44 | * GDEF 45 | */ 46 | 47 | hb_bool_t 48 | hb_ot_layout_has_glyph_classes (hb_face_t *face); 49 | 50 | /* Not that useful. Provides list of attach points for a glyph that a 51 | * client may want to cache */ 52 | unsigned int 53 | hb_ot_layout_get_attach_points (hb_face_t *face, 54 | hb_codepoint_t glyph, 55 | unsigned int start_offset, 56 | unsigned int *point_count /* IN/OUT */, 57 | unsigned int *point_array /* OUT */); 58 | 59 | /* Ligature caret positions */ 60 | unsigned int 61 | hb_ot_layout_get_ligature_carets (hb_font_t *font, 62 | hb_direction_t direction, 63 | hb_codepoint_t glyph, 64 | unsigned int start_offset, 65 | unsigned int *caret_count /* IN/OUT */, 66 | hb_position_t *caret_array /* OUT */); 67 | 68 | 69 | /* 70 | * GSUB/GPOS feature query and enumeration interface 71 | */ 72 | 73 | #define HB_OT_LAYOUT_NO_SCRIPT_INDEX ((unsigned int) 0xFFFF) 74 | #define HB_OT_LAYOUT_NO_FEATURE_INDEX ((unsigned int) 0xFFFF) 75 | #define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX ((unsigned int) 0xFFFF) 76 | 77 | unsigned int 78 | hb_ot_layout_table_get_script_tags (hb_face_t *face, 79 | hb_tag_t table_tag, 80 | unsigned int start_offset, 81 | unsigned int *script_count /* IN/OUT */, 82 | hb_tag_t *script_tags /* OUT */); 83 | 84 | hb_bool_t 85 | hb_ot_layout_table_find_script (hb_face_t *face, 86 | hb_tag_t table_tag, 87 | hb_tag_t script_tag, 88 | unsigned int *script_index); 89 | 90 | /* Like find_script, but takes zero-terminated array of scripts to test */ 91 | hb_bool_t 92 | hb_ot_layout_table_choose_script (hb_face_t *face, 93 | hb_tag_t table_tag, 94 | const hb_tag_t *script_tags, 95 | unsigned int *script_index, 96 | hb_tag_t *chosen_script); 97 | 98 | unsigned int 99 | hb_ot_layout_table_get_feature_tags (hb_face_t *face, 100 | hb_tag_t table_tag, 101 | unsigned int start_offset, 102 | unsigned int *feature_count /* IN/OUT */, 103 | hb_tag_t *feature_tags /* OUT */); 104 | 105 | unsigned int 106 | hb_ot_layout_script_get_language_tags (hb_face_t *face, 107 | hb_tag_t table_tag, 108 | unsigned int script_index, 109 | unsigned int start_offset, 110 | unsigned int *language_count /* IN/OUT */, 111 | hb_tag_t *language_tags /* OUT */); 112 | 113 | hb_bool_t 114 | hb_ot_layout_script_find_language (hb_face_t *face, 115 | hb_tag_t table_tag, 116 | unsigned int script_index, 117 | hb_tag_t language_tag, 118 | unsigned int *language_index); 119 | 120 | hb_bool_t 121 | hb_ot_layout_language_get_required_feature_index (hb_face_t *face, 122 | hb_tag_t table_tag, 123 | unsigned int script_index, 124 | unsigned int language_index, 125 | unsigned int *feature_index); 126 | 127 | unsigned int 128 | hb_ot_layout_language_get_feature_indexes (hb_face_t *face, 129 | hb_tag_t table_tag, 130 | unsigned int script_index, 131 | unsigned int language_index, 132 | unsigned int start_offset, 133 | unsigned int *feature_count /* IN/OUT */, 134 | unsigned int *feature_indexes /* OUT */); 135 | 136 | unsigned int 137 | hb_ot_layout_language_get_feature_tags (hb_face_t *face, 138 | hb_tag_t table_tag, 139 | unsigned int script_index, 140 | unsigned int language_index, 141 | unsigned int start_offset, 142 | unsigned int *feature_count /* IN/OUT */, 143 | hb_tag_t *feature_tags /* OUT */); 144 | 145 | hb_bool_t 146 | hb_ot_layout_language_find_feature (hb_face_t *face, 147 | hb_tag_t table_tag, 148 | unsigned int script_index, 149 | unsigned int language_index, 150 | hb_tag_t feature_tag, 151 | unsigned int *feature_index); 152 | 153 | unsigned int 154 | hb_ot_layout_feature_get_lookup_indexes (hb_face_t *face, 155 | hb_tag_t table_tag, 156 | unsigned int feature_index, 157 | unsigned int start_offset, 158 | unsigned int *lookup_count /* IN/OUT */, 159 | unsigned int *lookup_indexes /* OUT */); 160 | 161 | 162 | /* 163 | * GSUB 164 | */ 165 | 166 | hb_bool_t 167 | hb_ot_layout_has_substitution (hb_face_t *face); 168 | 169 | /* Should be called before all the substitute_lookup's are done. */ 170 | void 171 | hb_ot_layout_substitute_start (hb_buffer_t *buffer); 172 | 173 | hb_bool_t 174 | hb_ot_layout_substitute_lookup (hb_face_t *face, 175 | hb_buffer_t *buffer, 176 | unsigned int lookup_index, 177 | hb_mask_t mask); 178 | 179 | /* Should be called after all the substitute_lookup's are done */ 180 | void 181 | hb_ot_layout_substitute_finish (hb_buffer_t *buffer); 182 | 183 | /* 184 | * GPOS 185 | */ 186 | 187 | hb_bool_t 188 | hb_ot_layout_has_positioning (hb_face_t *face); 189 | 190 | /* Should be called before all the position_lookup's are done. Resets positions to zero. */ 191 | void 192 | hb_ot_layout_position_start (hb_buffer_t *buffer); 193 | 194 | hb_bool_t 195 | hb_ot_layout_position_lookup (hb_font_t *font, 196 | hb_buffer_t *buffer, 197 | unsigned int lookup_index, 198 | hb_mask_t mask); 199 | 200 | /* Should be called after all the position_lookup's are done */ 201 | void 202 | hb_ot_layout_position_finish (hb_buffer_t *buffer); 203 | 204 | 205 | HB_END_DECLS 206 | 207 | #endif /* HB_OT_LAYOUT_H */ 208 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-map-private.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009,2010 Red Hat, Inc. 3 | * Copyright © 2010,2011 Google, Inc. 4 | * 5 | * This is part of HarfBuzz, a text shaping library. 6 | * 7 | * Permission is hereby granted, without written agreement and without 8 | * license or royalty fees, to use, copy, modify, and distribute this 9 | * software and its documentation for any purpose, provided that the 10 | * above copyright notice and the following two paragraphs appear in 11 | * all copies of this software. 12 | * 13 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17 | * DAMAGE. 18 | * 19 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24 | * 25 | * Red Hat Author(s): Behdad Esfahbod 26 | * Google Author(s): Behdad Esfahbod 27 | */ 28 | 29 | #ifndef HB_OT_MAP_PRIVATE_HH 30 | #define HB_OT_MAP_PRIVATE_HH 31 | 32 | #include "hb-buffer-private.hh" 33 | 34 | #include "hb-ot-layout.h" 35 | 36 | 37 | 38 | static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS}; 39 | 40 | struct hb_ot_map_t 41 | { 42 | friend struct hb_ot_map_builder_t; 43 | 44 | public: 45 | 46 | hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); } 47 | 48 | typedef void (*gsub_pause_func_t) (const hb_ot_map_t *map, hb_face_t *face, hb_buffer_t *buffer, void *user_data); 49 | typedef void (*gpos_pause_func_t) (const hb_ot_map_t *map, hb_font_t *font, hb_buffer_t *buffer, void *user_data); 50 | 51 | inline hb_mask_t get_global_mask (void) const { return global_mask; } 52 | 53 | inline hb_mask_t get_mask (hb_tag_t tag, unsigned int *shift = NULL) const { 54 | const feature_map_t *map = features.bsearch (&tag); 55 | if (shift) *shift = map ? map->shift : 0; 56 | return map ? map->mask : 0; 57 | } 58 | 59 | inline hb_mask_t get_1_mask (hb_tag_t tag) const { 60 | const feature_map_t *map = features.bsearch (&tag); 61 | return map ? map->_1_mask : 0; 62 | } 63 | 64 | inline hb_tag_t get_chosen_script (unsigned int table_index) const 65 | { return chosen_script[table_index]; } 66 | 67 | inline void substitute (hb_face_t *face, hb_buffer_t *buffer) const 68 | { apply (0, (hb_ot_map_t::apply_lookup_func_t) hb_ot_layout_substitute_lookup, face, buffer); } 69 | inline void position (hb_font_t *font, hb_buffer_t *buffer) const 70 | { apply (1, (hb_ot_map_t::apply_lookup_func_t) hb_ot_layout_position_lookup, font, buffer); } 71 | 72 | inline void finish (void) { 73 | features.finish (); 74 | lookups[0].finish (); 75 | lookups[1].finish (); 76 | pauses[0].finish (); 77 | pauses[1].finish (); 78 | } 79 | 80 | private: 81 | 82 | struct feature_map_t { 83 | hb_tag_t tag; /* should be first for our bsearch to work */ 84 | unsigned int index[2]; /* GSUB/GPOS */ 85 | unsigned int stage[2]; /* GSUB/GPOS */ 86 | unsigned int shift; 87 | hb_mask_t mask; 88 | hb_mask_t _1_mask; /* mask for value=1, for quick access */ 89 | 90 | static int cmp (const feature_map_t *a, const feature_map_t *b) 91 | { return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; } 92 | }; 93 | 94 | struct lookup_map_t { 95 | unsigned int index; 96 | hb_mask_t mask; 97 | 98 | static int cmp (const lookup_map_t *a, const lookup_map_t *b) 99 | { return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; } 100 | }; 101 | 102 | typedef void (*pause_func_t) (const hb_ot_map_t *map, void *face_or_font, hb_buffer_t *buffer, void *user_data); 103 | typedef struct { 104 | pause_func_t func; 105 | void *user_data; 106 | } pause_callback_t; 107 | 108 | struct pause_map_t { 109 | unsigned int num_lookups; /* Cumulative */ 110 | pause_callback_t callback; 111 | }; 112 | 113 | typedef hb_bool_t (*apply_lookup_func_t) (void *face_or_font, 114 | hb_buffer_t *buffer, 115 | unsigned int lookup_index, 116 | hb_mask_t mask); 117 | 118 | HB_INTERNAL void add_lookups (hb_face_t *face, 119 | unsigned int table_index, 120 | unsigned int feature_index, 121 | hb_mask_t mask); 122 | 123 | HB_INTERNAL void apply (unsigned int table_index, 124 | hb_ot_map_t::apply_lookup_func_t apply_lookup_func, 125 | void *face_or_font, 126 | hb_buffer_t *buffer) const; 127 | 128 | hb_mask_t global_mask; 129 | 130 | hb_tag_t chosen_script[2]; 131 | hb_prealloced_array_t features; 132 | hb_prealloced_array_t lookups[2]; /* GSUB/GPOS */ 133 | hb_prealloced_array_t pauses[2]; /* GSUB/GPOS */ 134 | }; 135 | 136 | 137 | struct hb_ot_map_builder_t 138 | { 139 | public: 140 | 141 | hb_ot_map_builder_t (void) { memset (this, 0, sizeof (*this)); } 142 | 143 | HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value, bool global); 144 | 145 | inline void add_bool_feature (hb_tag_t tag, bool global = true) 146 | { add_feature (tag, 1, global); } 147 | 148 | inline void add_gsub_pause (hb_ot_map_t::gsub_pause_func_t pause_func, void *user_data) 149 | { add_pause (0, (hb_ot_map_t::pause_func_t) pause_func, user_data); } 150 | inline void add_gpos_pause (hb_ot_map_t::gpos_pause_func_t pause_func, void *user_data) 151 | { add_pause (1, (hb_ot_map_t::pause_func_t) pause_func, user_data); } 152 | 153 | HB_INTERNAL void compile (hb_face_t *face, 154 | const hb_segment_properties_t *props, 155 | struct hb_ot_map_t &m); 156 | 157 | inline void finish (void) { 158 | feature_infos.finish (); 159 | pauses[0].finish (); 160 | pauses[1].finish (); 161 | } 162 | 163 | private: 164 | 165 | struct feature_info_t { 166 | hb_tag_t tag; 167 | unsigned int seq; /* sequence#, used for stable sorting only */ 168 | unsigned int max_value; 169 | bool global; /* whether the feature applies value to every glyph in the buffer */ 170 | unsigned int default_value; /* for non-global features, what should the unset glyphs take */ 171 | unsigned int stage[2]; /* GSUB/GPOS */ 172 | 173 | static int cmp (const feature_info_t *a, const feature_info_t *b) 174 | { return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) : (a->seq < b->seq ? -1 : 1); } 175 | }; 176 | 177 | struct pause_info_t { 178 | unsigned int stage; 179 | hb_ot_map_t::pause_callback_t callback; 180 | }; 181 | 182 | HB_INTERNAL void add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func, void *user_data); 183 | 184 | unsigned int current_stage[2]; /* GSUB/GPOS */ 185 | hb_prealloced_array_t feature_infos; 186 | hb_prealloced_array_t pauses[2]; /* GSUB/GPOS */ 187 | }; 188 | 189 | 190 | 191 | #endif /* HB_OT_MAP_PRIVATE_HH */ 192 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-map.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009,2010 Red Hat, Inc. 3 | * Copyright © 2010,2011 Google, Inc. 4 | * 5 | * This is part of HarfBuzz, a text shaping library. 6 | * 7 | * Permission is hereby granted, without written agreement and without 8 | * license or royalty fees, to use, copy, modify, and distribute this 9 | * software and its documentation for any purpose, provided that the 10 | * above copyright notice and the following two paragraphs appear in 11 | * all copies of this software. 12 | * 13 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17 | * DAMAGE. 18 | * 19 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24 | * 25 | * Red Hat Author(s): Behdad Esfahbod 26 | * Google Author(s): Behdad Esfahbod 27 | */ 28 | 29 | #include "hb-ot-map-private.hh" 30 | 31 | #include "hb-ot-shape-private.hh" 32 | 33 | 34 | 35 | void 36 | hb_ot_map_t::add_lookups (hb_face_t *face, 37 | unsigned int table_index, 38 | unsigned int feature_index, 39 | hb_mask_t mask) 40 | { 41 | unsigned int lookup_indices[32]; 42 | unsigned int offset, len; 43 | 44 | offset = 0; 45 | do { 46 | len = ARRAY_LENGTH (lookup_indices); 47 | hb_ot_layout_feature_get_lookup_indexes (face, 48 | table_tags[table_index], 49 | feature_index, 50 | offset, &len, 51 | lookup_indices); 52 | 53 | for (unsigned int i = 0; i < len; i++) { 54 | hb_ot_map_t::lookup_map_t *lookup = lookups[table_index].push (); 55 | if (unlikely (!lookup)) 56 | return; 57 | lookup->mask = mask; 58 | lookup->index = lookup_indices[i]; 59 | } 60 | 61 | offset += len; 62 | } while (len == ARRAY_LENGTH (lookup_indices)); 63 | } 64 | 65 | 66 | void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, bool global) 67 | { 68 | feature_info_t *info = feature_infos.push(); 69 | if (unlikely (!info)) return; 70 | info->tag = tag; 71 | info->seq = feature_infos.len; 72 | info->max_value = value; 73 | info->global = global; 74 | info->default_value = global ? value : 0; 75 | info->stage[0] = current_stage[0]; 76 | info->stage[1] = current_stage[1]; 77 | } 78 | 79 | void hb_ot_map_t::apply (unsigned int table_index, 80 | hb_ot_map_t::apply_lookup_func_t apply_lookup_func, 81 | void *face_or_font, 82 | hb_buffer_t *buffer) const 83 | { 84 | unsigned int i = 0; 85 | 86 | for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; pause_index++) { 87 | const pause_map_t *pause = &pauses[table_index][pause_index]; 88 | for (; i < pause->num_lookups; i++) 89 | apply_lookup_func (face_or_font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); 90 | 91 | pause->callback.func (this, face_or_font, buffer, pause->callback.user_data); 92 | } 93 | 94 | for (; i < lookups[table_index].len; i++) 95 | apply_lookup_func (face_or_font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); 96 | } 97 | 98 | 99 | void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func, void *user_data) 100 | { 101 | if (pause_func) { 102 | pause_info_t *p = pauses[table_index].push (); 103 | if (likely (p)) { 104 | p->stage = current_stage[table_index]; 105 | p->callback.func = pause_func; 106 | p->callback.user_data = user_data; 107 | } 108 | } 109 | 110 | current_stage[table_index]++; 111 | } 112 | 113 | void 114 | hb_ot_map_builder_t::compile (hb_face_t *face, 115 | const hb_segment_properties_t *props, 116 | hb_ot_map_t &m) 117 | { 118 | m.global_mask = 1; 119 | 120 | if (!feature_infos.len) 121 | return; 122 | 123 | 124 | /* Fetch script/language indices for GSUB/GPOS. We need these later to skip 125 | * features not available in either table and not waste precious bits for them. */ 126 | 127 | hb_tag_t script_tags[3] = {HB_TAG_NONE}; 128 | hb_tag_t language_tag; 129 | 130 | hb_ot_tags_from_script (props->script, &script_tags[0], &script_tags[1]); 131 | language_tag = hb_ot_tag_from_language (props->language); 132 | 133 | unsigned int script_index[2], language_index[2]; 134 | for (unsigned int table_index = 0; table_index < 2; table_index++) { 135 | hb_tag_t table_tag = table_tags[table_index]; 136 | hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &m.chosen_script[table_index]); 137 | hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]); 138 | } 139 | 140 | 141 | /* Sort features and merge duplicates */ 142 | { 143 | feature_infos.sort (); 144 | unsigned int j = 0; 145 | for (unsigned int i = 1; i < feature_infos.len; i++) 146 | if (feature_infos[i].tag != feature_infos[j].tag) 147 | feature_infos[++j] = feature_infos[i]; 148 | else { 149 | if (feature_infos[i].global) { 150 | feature_infos[j].global = true; 151 | feature_infos[j].max_value = feature_infos[i].max_value; 152 | feature_infos[j].default_value = feature_infos[i].default_value; 153 | } else { 154 | feature_infos[j].global = false; 155 | feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value); 156 | } 157 | feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]); 158 | feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]); 159 | /* Inherit default_value from j */ 160 | } 161 | feature_infos.shrink (j + 1); 162 | } 163 | 164 | 165 | /* Allocate bits now */ 166 | unsigned int next_bit = 1; 167 | for (unsigned int i = 0; i < feature_infos.len; i++) { 168 | const feature_info_t *info = &feature_infos[i]; 169 | 170 | unsigned int bits_needed; 171 | 172 | if (info->global && info->max_value == 1) 173 | /* Uses the global bit */ 174 | bits_needed = 0; 175 | else 176 | bits_needed = _hb_bit_storage (info->max_value); 177 | 178 | if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t)) 179 | continue; /* Feature disabled, or not enough bits. */ 180 | 181 | 182 | bool found = false; 183 | unsigned int feature_index[2]; 184 | for (unsigned int table_index = 0; table_index < 2; table_index++) 185 | found |= hb_ot_layout_language_find_feature (face, 186 | table_tags[table_index], 187 | script_index[table_index], 188 | language_index[table_index], 189 | info->tag, 190 | &feature_index[table_index]); 191 | if (!found) 192 | continue; 193 | 194 | 195 | hb_ot_map_t::feature_map_t *map = m.features.push (); 196 | if (unlikely (!map)) 197 | break; 198 | 199 | map->tag = info->tag; 200 | map->index[0] = feature_index[0]; 201 | map->index[1] = feature_index[1]; 202 | map->stage[0] = info->stage[0]; 203 | map->stage[1] = info->stage[1]; 204 | if (info->global && info->max_value == 1) { 205 | /* Uses the global bit */ 206 | map->shift = 0; 207 | map->mask = 1; 208 | } else { 209 | map->shift = next_bit; 210 | map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit); 211 | next_bit += bits_needed; 212 | if (info->global) 213 | m.global_mask |= (info->default_value << map->shift) & map->mask; 214 | } 215 | map->_1_mask = (1 << map->shift) & map->mask; 216 | 217 | } 218 | feature_infos.shrink (0); /* Done with these */ 219 | 220 | 221 | add_gsub_pause (NULL, NULL); 222 | add_gpos_pause (NULL, NULL); 223 | 224 | for (unsigned int table_index = 0; table_index < 2; table_index++) { 225 | hb_tag_t table_tag = table_tags[table_index]; 226 | 227 | /* Collect lookup indices for features */ 228 | 229 | unsigned int required_feature_index; 230 | if (hb_ot_layout_language_get_required_feature_index (face, 231 | table_tag, 232 | script_index[table_index], 233 | language_index[table_index], 234 | &required_feature_index)) 235 | m.add_lookups (face, table_index, required_feature_index, 1); 236 | 237 | unsigned int pause_index = 0; 238 | unsigned int last_num_lookups = 0; 239 | for (unsigned stage = 0; stage < current_stage[table_index]; stage++) 240 | { 241 | for (unsigned i = 0; i < m.features.len; i++) 242 | if (m.features[i].stage[table_index] == stage) 243 | m.add_lookups (face, table_index, m.features[i].index[table_index], m.features[i].mask); 244 | 245 | /* Sort lookups and merge duplicates */ 246 | if (last_num_lookups < m.lookups[table_index].len) 247 | { 248 | m.lookups[table_index].sort (last_num_lookups, m.lookups[table_index].len); 249 | 250 | unsigned int j = last_num_lookups; 251 | for (unsigned int i = j + 1; i < m.lookups[table_index].len; i++) 252 | if (m.lookups[table_index][i].index != m.lookups[table_index][j].index) 253 | m.lookups[table_index][++j] = m.lookups[table_index][i]; 254 | else 255 | m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask; 256 | m.lookups[table_index].shrink (j + 1); 257 | } 258 | 259 | last_num_lookups = m.lookups[table_index].len; 260 | 261 | if (pause_index < pauses[table_index].len && pauses[table_index][pause_index].stage == stage) { 262 | hb_ot_map_t::pause_map_t *pause_map = m.pauses[table_index].push (); 263 | if (likely (pause_map)) { 264 | pause_map->num_lookups = last_num_lookups; 265 | pause_map->callback = pauses[table_index][pause_index].callback; 266 | } 267 | 268 | pause_index++; 269 | } 270 | } 271 | } 272 | } 273 | 274 | 275 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-maxp-table.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OT_MAXP_TABLE_HH 28 | #define HB_OT_MAXP_TABLE_HH 29 | 30 | #include "hb-open-type-private.hh" 31 | 32 | 33 | 34 | /* 35 | * maxp -- The Maximum Profile Table 36 | */ 37 | 38 | #define HB_OT_TAG_maxp HB_TAG('m','a','x','p') 39 | 40 | struct maxp 41 | { 42 | static const hb_tag_t Tag = HB_OT_TAG_maxp; 43 | 44 | inline unsigned int get_num_glyphs (void) const { 45 | return numGlyphs; 46 | } 47 | 48 | inline bool sanitize (hb_sanitize_context_t *c) { 49 | TRACE_SANITIZE (); 50 | return c->check_struct (this) && 51 | likely (version.major == 1 || 52 | (version.major == 0 && version.minor == 0x5000)); 53 | } 54 | 55 | /* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */ 56 | private: 57 | FixedVersion version; /* Version of the maxp table (0.5 or 1.0), 58 | * 0x00005000 or 0x00010000. */ 59 | USHORT numGlyphs; /* The number of glyphs in the font. */ 60 | public: 61 | DEFINE_SIZE_STATIC (6); 62 | }; 63 | 64 | 65 | 66 | #endif /* HB_OT_MAXP_TABLE_HH */ 67 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-name-table.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OT_NAME_TABLE_HH 28 | #define HB_OT_NAME_TABLE_HH 29 | 30 | #include "hb-open-type-private.hh" 31 | 32 | 33 | 34 | /* 35 | * name -- The Naming Table 36 | */ 37 | 38 | #define HB_OT_TAG_name HB_TAG('n','a','m','e') 39 | 40 | 41 | struct NameRecord 42 | { 43 | static int cmp (const NameRecord *a, const NameRecord *b) 44 | { 45 | int ret; 46 | ret = b->platformID.cmp (a->platformID); 47 | if (ret) return ret; 48 | ret = b->encodingID.cmp (a->encodingID); 49 | if (ret) return ret; 50 | ret = b->languageID.cmp (a->languageID); 51 | if (ret) return ret; 52 | ret = b->nameID.cmp (a->nameID); 53 | if (ret) return ret; 54 | return 0; 55 | } 56 | 57 | inline bool sanitize (hb_sanitize_context_t *c, void *base) { 58 | TRACE_SANITIZE (); 59 | /* We can check from base all the way up to the end of string... */ 60 | return c->check_struct (this) && 61 | c->check_range ((char *) base, (unsigned int) length + offset); 62 | } 63 | 64 | USHORT platformID; /* Platform ID. */ 65 | USHORT encodingID; /* Platform-specific encoding ID. */ 66 | USHORT languageID; /* Language ID. */ 67 | USHORT nameID; /* Name ID. */ 68 | USHORT length; /* String length (in bytes). */ 69 | USHORT offset; /* String offset from start of storage area (in bytes). */ 70 | public: 71 | DEFINE_SIZE_STATIC (12); 72 | }; 73 | 74 | struct name 75 | { 76 | static const hb_tag_t Tag = HB_OT_TAG_name; 77 | 78 | inline unsigned int get_name (unsigned int platform_id, 79 | unsigned int encoding_id, 80 | unsigned int language_id, 81 | unsigned int name_id, 82 | void *buffer, 83 | unsigned int buffer_length) const 84 | { 85 | NameRecord key; 86 | key.platformID.set (platform_id); 87 | key.encodingID.set (encoding_id); 88 | key.languageID.set (language_id); 89 | key.nameID.set (name_id); 90 | NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), (hb_compare_func_t) NameRecord::cmp); 91 | 92 | if (!match) 93 | return 0; 94 | 95 | unsigned int length = MIN (buffer_length, (unsigned int) match->length); 96 | memcpy (buffer, (char *) this + stringOffset + match->offset, length); 97 | return length; 98 | } 99 | 100 | inline bool sanitize_records (hb_sanitize_context_t *c) { 101 | TRACE_SANITIZE (); 102 | char *string_pool = (char *) this + stringOffset; 103 | unsigned int _count = count; 104 | for (unsigned int i = 0; i < _count; i++) 105 | if (!nameRecord[i].sanitize (c, string_pool)) return false; 106 | return true; 107 | } 108 | 109 | inline bool sanitize (hb_sanitize_context_t *c) { 110 | TRACE_SANITIZE (); 111 | return c->check_struct (this) && 112 | likely (format == 0 || format == 1) && 113 | c->check_array (nameRecord, nameRecord[0].static_size, count) && 114 | sanitize_records (c); 115 | } 116 | 117 | /* We only implement format 0 for now. */ 118 | private: 119 | USHORT format; /* Format selector (=0/1). */ 120 | USHORT count; /* Number of name records. */ 121 | Offset stringOffset; /* Offset to start of string storage (from start of table). */ 122 | NameRecord nameRecord[VAR]; /* The name records where count is the number of records. */ 123 | public: 124 | DEFINE_SIZE_ARRAY (6, nameRecord); 125 | }; 126 | 127 | 128 | 129 | #endif /* HB_OT_NAME_TABLE_HH */ 130 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-shape-complex-arabic.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #include "hb-ot-shape-complex-private.hh" 28 | 29 | 30 | 31 | /* buffer var allocations */ 32 | #define arabic_shaping_action() complex_var_temporary_u16() /* arabic shaping action */ 33 | 34 | 35 | /* 36 | * Bits used in the joining tables 37 | */ 38 | enum { 39 | JOINING_TYPE_U = 0, 40 | JOINING_TYPE_R = 1, 41 | JOINING_TYPE_D = 2, 42 | JOINING_TYPE_C = JOINING_TYPE_D, 43 | JOINING_GROUP_ALAPH = 3, 44 | JOINING_GROUP_DALATH_RISH = 4, 45 | NUM_STATE_MACHINE_COLS = 5, 46 | 47 | /* We deliberately don't have a JOINING_TYPE_L since that's unused in Unicode. */ 48 | 49 | JOINING_TYPE_T = 6, 50 | JOINING_TYPE_X = 7 /* means: use general-category to choose between U or T. */ 51 | }; 52 | 53 | /* 54 | * Joining types: 55 | */ 56 | 57 | #include "hb-ot-shape-complex-arabic-table.hh" 58 | 59 | static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat) 60 | { 61 | /* TODO Macroize the magic bit operations */ 62 | 63 | if (likely (hb_in_range (u, JOINING_TABLE_FIRST, JOINING_TABLE_LAST))) { 64 | unsigned int j_type = joining_table[u - JOINING_TABLE_FIRST]; 65 | if (likely (j_type != JOINING_TYPE_X)) 66 | return j_type; 67 | } 68 | 69 | /* Mongolian joining data is not in ArabicJoining.txt yet */ 70 | if (unlikely (hb_in_range (u, 0x1800, 0x18AF))) 71 | { 72 | /* All letters, SIBE SYLLABLE BOUNDARY MARKER, and NIRUGU are D */ 73 | if (gen_cat == HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER || u == 0x1807 || u == 0x180A) 74 | return JOINING_TYPE_D; 75 | } 76 | 77 | if (unlikely (hb_in_range (u, 0x200C, 0x200D))) { 78 | return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C; 79 | } 80 | 81 | return (FLAG(gen_cat) & (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT))) ? 82 | JOINING_TYPE_T : JOINING_TYPE_U; 83 | } 84 | 85 | 86 | 87 | static const hb_tag_t arabic_syriac_features[] = 88 | { 89 | HB_TAG('i','n','i','t'), 90 | HB_TAG('m','e','d','i'), 91 | HB_TAG('f','i','n','a'), 92 | HB_TAG('i','s','o','l'), 93 | /* Syriac */ 94 | HB_TAG('m','e','d','2'), 95 | HB_TAG('f','i','n','2'), 96 | HB_TAG('f','i','n','3'), 97 | HB_TAG_NONE 98 | }; 99 | 100 | 101 | /* Same order as the feature array */ 102 | enum { 103 | INIT, 104 | MEDI, 105 | FINA, 106 | ISOL, 107 | 108 | /* Syriac */ 109 | MED2, 110 | FIN2, 111 | FIN3, 112 | 113 | NONE, 114 | 115 | COMMON_NUM_FEATURES = 4, 116 | SYRIAC_NUM_FEATURES = 7, 117 | TOTAL_NUM_FEATURES = NONE 118 | }; 119 | 120 | static const struct arabic_state_table_entry { 121 | uint8_t prev_action; 122 | uint8_t curr_action; 123 | uint16_t next_state; 124 | } arabic_state_table[][NUM_STATE_MACHINE_COLS] = 125 | { 126 | /* jt_U, jt_R, jt_D, jg_ALAPH, jg_DALATH_RISH */ 127 | 128 | /* State 0: prev was U, not willing to join. */ 129 | { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, }, 130 | 131 | /* State 1: prev was R or ISOL/ALAPH, not willing to join. */ 132 | { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, }, 133 | 134 | /* State 2: prev was D/ISOL, willing to join. */ 135 | { {NONE,NONE,0}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, }, 136 | 137 | /* State 3: prev was D/FINA, willing to join. */ 138 | { {NONE,NONE,0}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, }, 139 | 140 | /* State 4: prev was FINA ALAPH, not willing to join. */ 141 | { {NONE,NONE,0}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, }, 142 | 143 | /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */ 144 | { {NONE,NONE,0}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, }, 145 | 146 | /* State 6: prev was DALATH/RISH, not willing to join. */ 147 | { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, } 148 | }; 149 | 150 | 151 | 152 | void 153 | _hb_ot_shape_complex_collect_features_arabic (hb_ot_map_builder_t *map, const hb_segment_properties_t *props) 154 | { 155 | /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init together, 156 | * then rlig and calt each in their own stage. This makes IranNastaliq's ALLAH 157 | * ligature work correctly. It's unfortunate though... 158 | * 159 | * This also makes Arial Bold in Windows7 work. See: 160 | * https://bugzilla.mozilla.org/show_bug.cgi?id=644184 161 | * 162 | * TODO: Add test cases for these two. 163 | */ 164 | 165 | map->add_bool_feature (HB_TAG('c','c','m','p')); 166 | map->add_bool_feature (HB_TAG('l','o','c','l')); 167 | 168 | map->add_gsub_pause (NULL, NULL); 169 | 170 | unsigned int num_features = props->script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES; 171 | for (unsigned int i = 0; i < num_features; i++) 172 | map->add_bool_feature (arabic_syriac_features[i], false); 173 | 174 | map->add_gsub_pause (NULL, NULL); 175 | 176 | map->add_bool_feature (HB_TAG('r','l','i','g')); 177 | map->add_gsub_pause (NULL, NULL); 178 | 179 | map->add_bool_feature (HB_TAG('c','a','l','t')); 180 | map->add_gsub_pause (NULL, NULL); 181 | 182 | /* ArabicOT spec enables 'cswh' for Arabic where as for basic shaper it's disabled by default. */ 183 | map->add_bool_feature (HB_TAG('c','s','w','h')); 184 | } 185 | 186 | bool 187 | _hb_ot_shape_complex_prefer_decomposed_arabic (void) 188 | { 189 | return FALSE; 190 | } 191 | 192 | void 193 | _hb_ot_shape_complex_setup_masks_arabic (hb_ot_map_t *map, hb_buffer_t *buffer) 194 | { 195 | unsigned int count = buffer->len; 196 | unsigned int prev = 0, state = 0; 197 | 198 | HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action); 199 | 200 | for (unsigned int i = 0; i < count; i++) 201 | { 202 | unsigned int this_type = get_joining_type (buffer->info[i].codepoint, (hb_unicode_general_category_t) buffer->info[i].general_category()); 203 | 204 | if (unlikely (this_type == JOINING_TYPE_T)) { 205 | buffer->info[i].arabic_shaping_action() = NONE; 206 | continue; 207 | } 208 | 209 | const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; 210 | 211 | if (entry->prev_action != NONE) 212 | buffer->info[prev].arabic_shaping_action() = entry->prev_action; 213 | 214 | buffer->info[i].arabic_shaping_action() = entry->curr_action; 215 | 216 | prev = i; 217 | state = entry->next_state; 218 | } 219 | 220 | hb_mask_t mask_array[TOTAL_NUM_FEATURES + 1] = {0}; 221 | unsigned int num_masks = buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES; 222 | for (unsigned int i = 0; i < num_masks; i++) 223 | mask_array[i] = map->get_1_mask (arabic_syriac_features[i]); 224 | 225 | for (unsigned int i = 0; i < count; i++) 226 | buffer->info[i].mask |= mask_array[buffer->info[i].arabic_shaping_action()]; 227 | 228 | HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); 229 | } 230 | 231 | 232 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-shape-complex-indic-machine.hh: -------------------------------------------------------------------------------- 1 | 2 | #line 1 "hb-ot-shape-complex-indic-machine.rl" 3 | /* 4 | * Copyright © 2011 Google, Inc. 5 | * 6 | * This is part of HarfBuzz, a text shaping library. 7 | * 8 | * Permission is hereby granted, without written agreement and without 9 | * license or royalty fees, to use, copy, modify, and distribute this 10 | * software and its documentation for any purpose, provided that the 11 | * above copyright notice and the following two paragraphs appear in 12 | * all copies of this software. 13 | * 14 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18 | * DAMAGE. 19 | * 20 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | * 26 | * Google Author(s): Behdad Esfahbod 27 | */ 28 | 29 | #ifndef HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH 30 | #define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH 31 | 32 | #include "hb-private.hh" 33 | 34 | HB_BEGIN_DECLS 35 | 36 | 37 | #line 38 "hb-ot-shape-complex-indic-machine.hh.tmp" 38 | static const unsigned char _indic_syllable_machine_trans_keys[] = { 39 | 0u, 0u, 5u, 5u, 1u, 2u, 1u, 2u, 5u, 5u, 1u, 5u, 5u, 5u, 1u, 2u, 40 | 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 41 | 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 42 | 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 43 | 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, 44 | 0u, 12u, 0 45 | }; 46 | 47 | static const char _indic_syllable_machine_key_spans[] = { 48 | 0, 1, 2, 2, 1, 5, 1, 2, 49 | 13, 13, 13, 13, 13, 13, 13, 13, 50 | 13, 13, 13, 13, 13, 13, 13, 13, 51 | 13, 13, 13, 13, 13, 13, 13, 13, 52 | 13, 13, 13, 13, 13, 13, 13, 13, 53 | 13 54 | }; 55 | 56 | static const short _indic_syllable_machine_index_offsets[] = { 57 | 0, 0, 2, 5, 8, 10, 16, 18, 58 | 21, 35, 49, 63, 77, 91, 105, 119, 59 | 133, 147, 161, 175, 189, 203, 217, 231, 60 | 245, 259, 273, 287, 301, 315, 329, 343, 61 | 357, 371, 385, 399, 413, 427, 441, 455, 62 | 469 63 | }; 64 | 65 | static const char _indic_syllable_machine_indicies[] = { 66 | 0, 1, 2, 2, 1, 3, 3, 67 | 1, 4, 1, 2, 2, 1, 1, 0, 68 | 1, 5, 1, 6, 6, 1, 7, 6, 69 | 8, 9, 1, 1, 1, 1, 1, 1, 70 | 1, 1, 10, 1, 11, 12, 13, 14, 71 | 1, 1, 1, 1, 1, 1, 1, 1, 72 | 15, 1, 16, 17, 18, 19, 20, 21, 73 | 22, 22, 23, 24, 25, 26, 27, 1, 74 | 16, 17, 18, 19, 20, 28, 22, 22, 75 | 23, 24, 25, 26, 27, 1, 29, 30, 76 | 31, 32, 33, 1, 34, 35, 36, 37, 77 | 38, 1, 39, 1, 29, 30, 31, 32, 78 | 1, 1, 34, 35, 36, 37, 38, 1, 79 | 39, 1, 29, 30, 31, 32, 1, 1, 80 | 1, 1, 36, 37, 38, 1, 39, 1, 81 | 29, 30, 31, 32, 40, 2, 1, 1, 82 | 36, 37, 38, 1, 39, 1, 29, 30, 83 | 31, 32, 1, 2, 1, 1, 36, 37, 84 | 38, 1, 39, 1, 29, 30, 31, 32, 85 | 1, 1, 1, 1, 1, 1, 38, 1, 86 | 39, 1, 29, 30, 31, 32, 1, 1, 87 | 1, 1, 1, 1, 41, 1, 39, 1, 88 | 29, 30, 31, 32, 1, 1, 1, 1, 89 | 1, 1, 1, 1, 39, 1, 42, 43, 90 | 44, 45, 46, 4, 47, 47, 48, 49, 91 | 50, 1, 51, 1, 42, 43, 44, 45, 92 | 1, 4, 47, 47, 48, 49, 50, 1, 93 | 51, 1, 42, 43, 44, 45, 1, 1, 94 | 1, 1, 48, 49, 50, 1, 51, 1, 95 | 42, 43, 44, 45, 52, 3, 1, 1, 96 | 48, 49, 50, 1, 51, 1, 42, 43, 97 | 44, 45, 1, 3, 1, 1, 48, 49, 98 | 50, 1, 51, 1, 42, 43, 44, 45, 99 | 1, 1, 1, 1, 1, 1, 50, 1, 100 | 51, 1, 42, 43, 44, 45, 1, 1, 101 | 1, 1, 1, 1, 53, 1, 51, 1, 102 | 42, 43, 44, 45, 1, 1, 1, 1, 103 | 1, 1, 1, 1, 51, 1, 16, 17, 104 | 18, 19, 1, 21, 22, 22, 23, 24, 105 | 25, 26, 27, 1, 16, 6, 6, 19, 106 | 1, 1, 54, 54, 1, 24, 25, 1, 107 | 27, 1, 16, 6, 6, 19, 1, 1, 108 | 1, 1, 1, 24, 25, 1, 27, 1, 109 | 16, 17, 18, 19, 1, 1, 1, 1, 110 | 1, 1, 25, 1, 27, 1, 16, 17, 111 | 18, 19, 1, 1, 1, 1, 1, 1, 112 | 55, 1, 27, 1, 16, 17, 18, 19, 113 | 1, 1, 1, 1, 1, 1, 1, 1, 114 | 27, 1, 16, 17, 18, 19, 56, 57, 115 | 1, 1, 23, 24, 25, 1, 27, 1, 116 | 16, 17, 18, 19, 1, 57, 1, 1, 117 | 23, 24, 25, 1, 27, 1, 16, 17, 118 | 18, 19, 1, 1, 1, 1, 23, 24, 119 | 25, 1, 27, 1, 16, 17, 18, 19, 120 | 1, 58, 1, 1, 23, 24, 25, 1, 121 | 27, 1, 16, 17, 18, 19, 1, 1, 122 | 59, 59, 1, 24, 25, 1, 27, 1, 123 | 16, 17, 18, 19, 1, 1, 1, 1, 124 | 1, 24, 25, 1, 27, 1, 16, 6, 125 | 6, 9, 1, 1, 54, 54, 1, 24, 126 | 25, 1, 10, 1, 0 127 | }; 128 | 129 | static const char _indic_syllable_machine_trans_targs[] = { 130 | 2, 0, 14, 22, 3, 7, 10, 9, 131 | 11, 12, 20, 9, 10, 11, 12, 20, 132 | 9, 10, 11, 12, 28, 29, 6, 34, 133 | 31, 32, 37, 20, 40, 9, 10, 11, 134 | 12, 13, 1, 5, 15, 17, 18, 20, 135 | 16, 19, 9, 10, 11, 12, 21, 4, 136 | 23, 25, 26, 20, 24, 27, 30, 33, 137 | 35, 36, 38, 39 138 | }; 139 | 140 | static const char _indic_syllable_machine_trans_actions[] = { 141 | 0, 0, 0, 0, 0, 0, 0, 0, 142 | 0, 0, 0, 1, 1, 1, 1, 1, 143 | 2, 2, 2, 2, 0, 0, 0, 0, 144 | 0, 0, 0, 2, 0, 3, 3, 3, 145 | 3, 0, 0, 0, 0, 0, 0, 3, 146 | 0, 0, 4, 4, 4, 4, 0, 0, 147 | 0, 0, 0, 4, 0, 0, 0, 0, 148 | 0, 0, 0, 0 149 | }; 150 | 151 | static const char _indic_syllable_machine_eof_actions[] = { 152 | 0, 0, 0, 0, 0, 0, 0, 0, 153 | 0, 1, 2, 2, 3, 3, 3, 3, 154 | 3, 3, 3, 3, 4, 4, 4, 4, 155 | 4, 4, 4, 4, 2, 2, 2, 2, 156 | 2, 2, 2, 2, 2, 2, 2, 2, 157 | 2 158 | }; 159 | 160 | static const int indic_syllable_machine_start = 8; 161 | static const int indic_syllable_machine_first_final = 8; 162 | static const int indic_syllable_machine_error = 0; 163 | 164 | static const int indic_syllable_machine_en_main = 8; 165 | 166 | 167 | #line 38 "hb-ot-shape-complex-indic-machine.rl" 168 | 169 | 170 | 171 | #line 83 "hb-ot-shape-complex-indic-machine.rl" 172 | 173 | 174 | 175 | static void 176 | set_cluster (hb_buffer_t *buffer, 177 | unsigned int start, unsigned int end) 178 | { 179 | unsigned int cluster = buffer->info[start].cluster; 180 | 181 | for (unsigned int i = start + 1; i < end; i++) 182 | cluster = MIN (cluster, buffer->info[i].cluster); 183 | for (unsigned int i = start; i < end; i++) 184 | buffer->info[i].cluster = cluster; 185 | } 186 | 187 | static void 188 | find_syllables (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array) 189 | { 190 | unsigned int p, pe, eof; 191 | int cs; 192 | 193 | #line 194 "hb-ot-shape-complex-indic-machine.hh.tmp" 194 | { 195 | cs = indic_syllable_machine_start; 196 | } 197 | 198 | #line 106 "hb-ot-shape-complex-indic-machine.rl" 199 | 200 | 201 | p = 0; 202 | pe = eof = buffer->len; 203 | 204 | unsigned int last = 0; 205 | 206 | #line 207 "hb-ot-shape-complex-indic-machine.hh.tmp" 207 | { 208 | int _slen; 209 | int _trans; 210 | const unsigned char *_keys; 211 | const char *_inds; 212 | if ( p == pe ) 213 | goto _test_eof; 214 | if ( cs == 0 ) 215 | goto _out; 216 | _resume: 217 | _keys = _indic_syllable_machine_trans_keys + (cs<<1); 218 | _inds = _indic_syllable_machine_indicies + _indic_syllable_machine_index_offsets[cs]; 219 | 220 | _slen = _indic_syllable_machine_key_spans[cs]; 221 | _trans = _inds[ _slen > 0 && _keys[0] <=( buffer->info[p].indic_category()) && 222 | ( buffer->info[p].indic_category()) <= _keys[1] ? 223 | ( buffer->info[p].indic_category()) - _keys[0] : _slen ]; 224 | 225 | cs = _indic_syllable_machine_trans_targs[_trans]; 226 | 227 | if ( _indic_syllable_machine_trans_actions[_trans] == 0 ) 228 | goto _again; 229 | 230 | switch ( _indic_syllable_machine_trans_actions[_trans] ) { 231 | case 2: 232 | #line 62 "hb-ot-shape-complex-indic-machine.rl" 233 | { found_consonant_syllable (map, buffer, mask_array, last, p); } 234 | #line 67 "hb-ot-shape-complex-indic-machine.rl" 235 | { set_cluster (buffer, p, last); last = p; } 236 | break; 237 | case 3: 238 | #line 63 "hb-ot-shape-complex-indic-machine.rl" 239 | { found_vowel_syllable (map, buffer, mask_array, last, p); } 240 | #line 67 "hb-ot-shape-complex-indic-machine.rl" 241 | { set_cluster (buffer, p, last); last = p; } 242 | break; 243 | case 4: 244 | #line 64 "hb-ot-shape-complex-indic-machine.rl" 245 | { found_standalone_cluster (map, buffer, mask_array, last, p); } 246 | #line 67 "hb-ot-shape-complex-indic-machine.rl" 247 | { set_cluster (buffer, p, last); last = p; } 248 | break; 249 | case 1: 250 | #line 65 "hb-ot-shape-complex-indic-machine.rl" 251 | { found_non_indic (map, buffer, mask_array, last, p); } 252 | #line 67 "hb-ot-shape-complex-indic-machine.rl" 253 | { set_cluster (buffer, p, last); last = p; } 254 | break; 255 | #line 256 "hb-ot-shape-complex-indic-machine.hh.tmp" 256 | } 257 | 258 | _again: 259 | if ( cs == 0 ) 260 | goto _out; 261 | if ( ++p != pe ) 262 | goto _resume; 263 | _test_eof: {} 264 | if ( p == eof ) 265 | { 266 | switch ( _indic_syllable_machine_eof_actions[cs] ) { 267 | case 2: 268 | #line 62 "hb-ot-shape-complex-indic-machine.rl" 269 | { found_consonant_syllable (map, buffer, mask_array, last, p); } 270 | #line 67 "hb-ot-shape-complex-indic-machine.rl" 271 | { set_cluster (buffer, p, last); last = p; } 272 | break; 273 | case 3: 274 | #line 63 "hb-ot-shape-complex-indic-machine.rl" 275 | { found_vowel_syllable (map, buffer, mask_array, last, p); } 276 | #line 67 "hb-ot-shape-complex-indic-machine.rl" 277 | { set_cluster (buffer, p, last); last = p; } 278 | break; 279 | case 4: 280 | #line 64 "hb-ot-shape-complex-indic-machine.rl" 281 | { found_standalone_cluster (map, buffer, mask_array, last, p); } 282 | #line 67 "hb-ot-shape-complex-indic-machine.rl" 283 | { set_cluster (buffer, p, last); last = p; } 284 | break; 285 | case 1: 286 | #line 65 "hb-ot-shape-complex-indic-machine.rl" 287 | { found_non_indic (map, buffer, mask_array, last, p); } 288 | #line 67 "hb-ot-shape-complex-indic-machine.rl" 289 | { set_cluster (buffer, p, last); last = p; } 290 | break; 291 | #line 292 "hb-ot-shape-complex-indic-machine.hh.tmp" 292 | } 293 | } 294 | 295 | _out: {} 296 | } 297 | 298 | #line 114 "hb-ot-shape-complex-indic-machine.rl" 299 | 300 | } 301 | 302 | HB_END_DECLS 303 | 304 | #endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */ 305 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-shape-complex-misc.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #include "hb-ot-shape-complex-private.hh" 28 | 29 | 30 | /* TODO Add kana, hangul, and other small sahpers here */ 31 | 32 | /* When adding trivial shapers, eg. kana, hangul, etc, we can either 33 | * add a full shaper enum value for them, or switch on the script in 34 | * the default complex shaper. The former is faster, so I think that's 35 | * what we would do, and hence the default complex shaper shall remain 36 | * empty. 37 | */ 38 | 39 | void 40 | _hb_ot_shape_complex_collect_features_default (hb_ot_map_builder_t *map, const hb_segment_properties_t *props) 41 | { 42 | } 43 | 44 | bool 45 | _hb_ot_shape_complex_prefer_decomposed_default (void) 46 | { 47 | return FALSE; 48 | } 49 | 50 | void 51 | _hb_ot_shape_complex_setup_masks_default (hb_ot_map_t *map, hb_buffer_t *buffer) 52 | { 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-shape-complex-private.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010,2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OT_SHAPE_COMPLEX_PRIVATE_HH 28 | #define HB_OT_SHAPE_COMPLEX_PRIVATE_HH 29 | 30 | #include "hb-private.hh" 31 | 32 | #include "hb-ot-map-private.hh" 33 | 34 | 35 | 36 | /* buffer var allocations, used during the entire shaping process */ 37 | #define general_category() var1.u8[0] /* unicode general_category (hb_unicode_general_category_t) */ 38 | #define combining_class() var1.u8[1] /* unicode combining_class (uint8_t) */ 39 | 40 | /* buffer var allocations, used by complex shapers */ 41 | #define complex_var_persistent_u8_0() var2.u8[0] 42 | #define complex_var_persistent_u8_1() var2.u8[1] 43 | #define complex_var_persistent_u16() var2.u16[0] 44 | #define complex_var_temporary_u8_0() var2.u8[2] 45 | #define complex_var_temporary_u8_1() var2.u8[3] 46 | #define complex_var_temporary_u16() var2.u16[1] 47 | 48 | 49 | #define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \ 50 | HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \ 51 | HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \ 52 | HB_COMPLEX_SHAPER_IMPLEMENT (indic) \ 53 | /* ^--- Add new shapers here */ 54 | 55 | enum hb_ot_complex_shaper_t { 56 | #define HB_COMPLEX_SHAPER_IMPLEMENT(name) hb_ot_complex_shaper_##name, 57 | HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS 58 | #undef HB_COMPLEX_SHAPER_IMPLEMENT 59 | }; 60 | 61 | static inline hb_ot_complex_shaper_t 62 | hb_ot_shape_complex_categorize (const hb_segment_properties_t *props) 63 | { 64 | switch ((int) props->script) 65 | { 66 | default: 67 | return hb_ot_complex_shaper_default; 68 | 69 | case HB_SCRIPT_ARABIC: 70 | case HB_SCRIPT_MANDAIC: 71 | case HB_SCRIPT_MONGOLIAN: 72 | case HB_SCRIPT_NKO: 73 | case HB_SCRIPT_SYRIAC: 74 | return hb_ot_complex_shaper_arabic; 75 | 76 | #if 0 77 | /* Note: 78 | * 79 | * These disabled scripts are listed in ucd/IndicSyllabicCategory.txt, but according 80 | * to Martin Hosken do not require complex shaping. 81 | * 82 | * TODO We currently keep data for these scripts in our indic table. Need to fix the 83 | * generator to not do that. 84 | */ 85 | 86 | /* Simple? */ 87 | case HB_SCRIPT_BATAK: 88 | case HB_SCRIPT_BRAHMI: 89 | case HB_SCRIPT_HANUNOO: 90 | case HB_SCRIPT_MEETEI_MAYEK: 91 | case HB_SCRIPT_SAURASHTRA: 92 | 93 | /* Simple */ 94 | case HB_SCRIPT_KAYAH_LI: 95 | case HB_SCRIPT_LAO: 96 | case HB_SCRIPT_LIMBU: 97 | case HB_SCRIPT_PHAGS_PA: 98 | case HB_SCRIPT_SYLOTI_NAGRI: 99 | case HB_SCRIPT_TAGALOG: 100 | case HB_SCRIPT_TAGBANWA: 101 | case HB_SCRIPT_TAI_LE: 102 | case HB_SCRIPT_TAI_VIET: 103 | case HB_SCRIPT_THAI: 104 | case HB_SCRIPT_TIBETAN: 105 | 106 | /* May need Indic treatment in the future? */ 107 | case HB_SCRIPT_MYANMAR: 108 | #endif 109 | 110 | case HB_SCRIPT_BALINESE: 111 | case HB_SCRIPT_BENGALI: 112 | case HB_SCRIPT_BUGINESE: 113 | case HB_SCRIPT_BUHID: 114 | case HB_SCRIPT_CHAM: 115 | case HB_SCRIPT_DEVANAGARI: 116 | case HB_SCRIPT_GUJARATI: 117 | case HB_SCRIPT_GURMUKHI: 118 | case HB_SCRIPT_JAVANESE: 119 | case HB_SCRIPT_KAITHI: 120 | case HB_SCRIPT_KANNADA: 121 | case HB_SCRIPT_KHAROSHTHI: 122 | case HB_SCRIPT_KHMER: 123 | case HB_SCRIPT_LEPCHA: 124 | case HB_SCRIPT_MALAYALAM: 125 | case HB_SCRIPT_NEW_TAI_LUE: 126 | case HB_SCRIPT_ORIYA: case HB_SCRIPT_REJANG: 127 | case HB_SCRIPT_SINHALA: 128 | case HB_SCRIPT_SUNDANESE: 129 | case HB_SCRIPT_TAI_THAM: 130 | case HB_SCRIPT_TAMIL: 131 | case HB_SCRIPT_TELUGU: 132 | return hb_ot_complex_shaper_indic; 133 | 134 | /* ^--- Add new shapers here */ 135 | } 136 | } 137 | 138 | 139 | 140 | /* 141 | * collect_features() 142 | * 143 | * Called during shape_plan(). 144 | * 145 | * Shapers should use map to add their features and callbacks. 146 | */ 147 | 148 | typedef void hb_ot_shape_complex_collect_features_func_t (hb_ot_map_builder_t *map, const hb_segment_properties_t *props); 149 | #define HB_COMPLEX_SHAPER_IMPLEMENT(name) \ 150 | HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_##name; 151 | HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS 152 | #undef HB_COMPLEX_SHAPER_IMPLEMENT 153 | 154 | static inline void 155 | hb_ot_shape_complex_collect_features (hb_ot_complex_shaper_t shaper, 156 | hb_ot_map_builder_t *map, 157 | const hb_segment_properties_t *props) 158 | { 159 | switch (shaper) { 160 | default: 161 | #define HB_COMPLEX_SHAPER_IMPLEMENT(name) \ 162 | case hb_ot_complex_shaper_##name: _hb_ot_shape_complex_collect_features_##name (map, props); return; 163 | HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS 164 | #undef HB_COMPLEX_SHAPER_IMPLEMENT 165 | } 166 | } 167 | 168 | 169 | /* 170 | * prefer_decomposed() 171 | * 172 | * Called during shape_execute(). 173 | * 174 | * Shapers should return TRUE if it prefers decomposed (NFD) input rather than precomposed (NFC). 175 | */ 176 | 177 | typedef bool hb_ot_shape_complex_prefer_decomposed_func_t (void); 178 | #define HB_COMPLEX_SHAPER_IMPLEMENT(name) \ 179 | HB_INTERNAL hb_ot_shape_complex_prefer_decomposed_func_t _hb_ot_shape_complex_prefer_decomposed_##name; 180 | HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS 181 | #undef HB_COMPLEX_SHAPER_IMPLEMENT 182 | 183 | static inline bool 184 | hb_ot_shape_complex_prefer_decomposed (hb_ot_complex_shaper_t shaper) 185 | { 186 | switch (shaper) { 187 | default: 188 | #define HB_COMPLEX_SHAPER_IMPLEMENT(name) \ 189 | case hb_ot_complex_shaper_##name: return _hb_ot_shape_complex_prefer_decomposed_##name (); 190 | HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS 191 | #undef HB_COMPLEX_SHAPER_IMPLEMENT 192 | } 193 | } 194 | 195 | 196 | /* setup_masks() 197 | * 198 | * Called during shape_execute(). 199 | * 200 | * Shapers should use map to get feature masks and set on buffer. 201 | */ 202 | 203 | typedef void hb_ot_shape_complex_setup_masks_func_t (hb_ot_map_t *map, hb_buffer_t *buffer); 204 | #define HB_COMPLEX_SHAPER_IMPLEMENT(name) \ 205 | HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_##name; 206 | HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS 207 | #undef HB_COMPLEX_SHAPER_IMPLEMENT 208 | 209 | static inline void 210 | hb_ot_shape_complex_setup_masks (hb_ot_complex_shaper_t shaper, 211 | hb_ot_map_t *map, 212 | hb_buffer_t *buffer) 213 | { 214 | switch (shaper) { 215 | default: 216 | #define HB_COMPLEX_SHAPER_IMPLEMENT(name) \ 217 | case hb_ot_complex_shaper_##name: _hb_ot_shape_complex_setup_masks_##name (map, buffer); return; 218 | HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS 219 | #undef HB_COMPLEX_SHAPER_IMPLEMENT 220 | } 221 | } 222 | 223 | 224 | 225 | #endif /* HB_OT_SHAPE_COMPLEX_PRIVATE_HH */ 226 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-shape-normalize.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #include "hb-ot-shape-private.hh" 28 | #include "hb-ot-shape-complex-private.hh" 29 | 30 | 31 | /* 32 | * HIGHLEVEL DESIGN: 33 | * 34 | * This file exports one main function: _hb_ot_shape_normalize(). 35 | * 36 | * This function closely reflects the Unicode Normalization Algorithm, 37 | * yet it's different. The shaper an either prefer decomposed (NFD) or 38 | * composed (NFC). 39 | * 40 | * In general what happens is that: each grapheme is decomposed in a chain 41 | * of 1:2 decompositions, marks reordered, and then recomposed if desired, 42 | * so far it's like Unicode Normalization. However, the decomposition and 43 | * recomposition only happens if the font supports the resulting characters. 44 | * 45 | * The goals are: 46 | * 47 | * - Try to render all canonically equivalent strings similarly. To really 48 | * achieve this we have to always do the full decomposition and then 49 | * selectively recompose from there. It's kinda too expensive though, so 50 | * we skip some cases. For example, if composed is desired, we simply 51 | * don't touch 1-character clusters that are supported by the font, even 52 | * though their NFC may be different. 53 | * 54 | * - When a font has a precomposed character for a sequence but the 'ccmp' 55 | * feature in the font is not adequate, use the precomposed character 56 | * which typically has better mark positioning. 57 | * 58 | * - When a font does not support a combining mark, but supports it precomposed 59 | * with previous base. This needs the itemizer to have this knowledge too. 60 | * We need ot provide assistance to the itemizer. 61 | * 62 | * - When a font does not support a character but supports its decomposition, 63 | * well, use the decomposition. 64 | * 65 | * - The Indic shaper requests decomposed output. This will handle splitting 66 | * matra for the Indic shaper. 67 | */ 68 | 69 | static void 70 | output_glyph (hb_ot_shape_context_t *c, 71 | hb_codepoint_t glyph) 72 | { 73 | hb_buffer_t *buffer = c->buffer; 74 | 75 | buffer->output_glyph (glyph); 76 | hb_glyph_info_set_unicode_props (&buffer->out_info[buffer->out_len - 1], buffer->unicode); 77 | } 78 | 79 | static bool 80 | decompose (hb_ot_shape_context_t *c, 81 | bool shortest, 82 | hb_codepoint_t ab) 83 | { 84 | hb_codepoint_t a, b, glyph; 85 | 86 | if (!hb_unicode_decompose (c->buffer->unicode, ab, &a, &b) || 87 | (b && !hb_font_get_glyph (c->font, b, 0, &glyph))) 88 | return FALSE; 89 | 90 | bool has_a = hb_font_get_glyph (c->font, a, 0, &glyph); 91 | if (shortest && has_a) { 92 | /* Output a and b */ 93 | output_glyph (c, a); 94 | if (b) 95 | output_glyph (c, b); 96 | return TRUE; 97 | } 98 | 99 | if (decompose (c, shortest, a)) { 100 | if (b) 101 | output_glyph (c, b); 102 | return TRUE; 103 | } 104 | 105 | if (has_a) { 106 | output_glyph (c, a); 107 | if (b) 108 | output_glyph (c, b); 109 | return TRUE; 110 | } 111 | 112 | return FALSE; 113 | } 114 | 115 | static void 116 | decompose_current_glyph (hb_ot_shape_context_t *c, 117 | bool shortest) 118 | { 119 | if (decompose (c, shortest, c->buffer->info[c->buffer->idx].codepoint)) 120 | c->buffer->skip_glyph (); 121 | else 122 | c->buffer->next_glyph (); 123 | } 124 | 125 | static void 126 | decompose_single_char_cluster (hb_ot_shape_context_t *c, 127 | bool will_recompose) 128 | { 129 | hb_codepoint_t glyph; 130 | 131 | /* If recomposing and font supports this, we're good to go */ 132 | if (will_recompose && hb_font_get_glyph (c->font, c->buffer->info[c->buffer->idx].codepoint, 0, &glyph)) { 133 | c->buffer->next_glyph (); 134 | return; 135 | } 136 | 137 | decompose_current_glyph (c, will_recompose); 138 | } 139 | 140 | static void 141 | decompose_multi_char_cluster (hb_ot_shape_context_t *c, 142 | unsigned int end) 143 | { 144 | /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */ 145 | for (unsigned int i = c->buffer->idx; i < end; i++) 146 | if (unlikely (is_variation_selector (c->buffer->info[i].codepoint))) { 147 | while (c->buffer->idx < end) 148 | c->buffer->next_glyph (); 149 | return; 150 | } 151 | 152 | while (c->buffer->idx < end) 153 | decompose_current_glyph (c, FALSE); 154 | } 155 | 156 | static int 157 | compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) 158 | { 159 | unsigned int a = pa->combining_class(); 160 | unsigned int b = pb->combining_class(); 161 | 162 | return a < b ? -1 : a == b ? 0 : +1; 163 | } 164 | 165 | void 166 | _hb_ot_shape_normalize (hb_ot_shape_context_t *c) 167 | { 168 | hb_buffer_t *buffer = c->buffer; 169 | bool recompose = !hb_ot_shape_complex_prefer_decomposed (c->plan->shaper); 170 | bool has_multichar_clusters = FALSE; 171 | unsigned int count; 172 | 173 | /* We do a fairly straightforward yet custom normalization process in three 174 | * separate rounds: decompose, reorder, recompose (if desired). Currently 175 | * this makes two buffer swaps. We can make it faster by moving the last 176 | * two rounds into the inner loop for the first round, but it's more readable 177 | * this way. */ 178 | 179 | 180 | /* First round, decompose */ 181 | 182 | buffer->clear_output (); 183 | count = buffer->len; 184 | for (buffer->idx = 0; buffer->idx < count;) 185 | { 186 | unsigned int end; 187 | for (end = buffer->idx + 1; end < count; end++) 188 | if (buffer->info[buffer->idx].cluster != buffer->info[end].cluster) 189 | break; 190 | 191 | if (buffer->idx + 1 == end) 192 | decompose_single_char_cluster (c, recompose); 193 | else { 194 | decompose_multi_char_cluster (c, end); 195 | has_multichar_clusters = TRUE; 196 | } 197 | } 198 | buffer->swap_buffers (); 199 | 200 | 201 | /* Technically speaking, two characters with ccc=0 may combine. But all 202 | * those cases are in languages that the indic module handles (which expects 203 | * decomposed), or in Hangul jamo, which again, we want decomposed anyway. 204 | * So we don't bother combining across cluster boundaries. This is a huge 205 | * performance saver if the compose() callback is slow. 206 | * 207 | * TODO: Am I right about Hangul? If I am, we should add a Hangul module 208 | * that requests decomposed. If for Hangul we end up wanting composed, we 209 | * can do that in the Hangul module. 210 | */ 211 | 212 | if (!has_multichar_clusters) 213 | return; /* Done! */ 214 | 215 | 216 | /* Second round, reorder (inplace) */ 217 | 218 | count = buffer->len; 219 | for (unsigned int i = 0; i < count; i++) 220 | { 221 | if (buffer->info[i].combining_class() == 0) 222 | continue; 223 | 224 | unsigned int end; 225 | for (end = i + 1; end < count; end++) 226 | if (buffer->info[end].combining_class() == 0) 227 | break; 228 | 229 | /* We are going to do a bubble-sort. Only do this if the 230 | * sequence is short. Doing it on long sequences can result 231 | * in an O(n^2) DoS. */ 232 | if (end - i > 10) { 233 | i = end; 234 | continue; 235 | } 236 | 237 | hb_bubble_sort (buffer->info + i, end - i, compare_combining_class); 238 | 239 | i = end; 240 | } 241 | 242 | 243 | if (!recompose) 244 | return; 245 | 246 | /* Third round, recompose */ 247 | 248 | /* As noted in the comment earlier, we don't try to combine 249 | * ccc=0 chars with their previous Starter. */ 250 | 251 | buffer->clear_output (); 252 | count = buffer->len; 253 | unsigned int starter = 0; 254 | buffer->next_glyph (); 255 | while (buffer->idx < count) 256 | { 257 | if (buffer->info[buffer->idx].combining_class() == 0) { 258 | starter = buffer->out_len; 259 | buffer->next_glyph (); 260 | continue; 261 | } 262 | 263 | hb_codepoint_t composed, glyph; 264 | if ((buffer->out_info[buffer->out_len - 1].combining_class() >= 265 | buffer->info[buffer->idx].combining_class()) || 266 | !hb_unicode_compose (c->buffer->unicode, 267 | buffer->out_info[starter].codepoint, 268 | buffer->info[buffer->idx].codepoint, 269 | &composed) || 270 | !hb_font_get_glyph (c->font, composed, 0, &glyph)) 271 | { 272 | /* Blocked, or doesn't compose. */ 273 | buffer->next_glyph (); 274 | continue; 275 | } 276 | 277 | /* Composes. Modify starter and carry on. */ 278 | buffer->out_info[starter].codepoint = composed; 279 | hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer->unicode); 280 | 281 | buffer->skip_glyph (); 282 | } 283 | buffer->swap_buffers (); 284 | 285 | } 286 | 287 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-shape-private.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OT_SHAPE_PRIVATE_HH 28 | #define HB_OT_SHAPE_PRIVATE_HH 29 | 30 | #include "hb-private.hh" 31 | 32 | #include "hb-ot-shape.h" 33 | 34 | #include "hb-ot-map-private.hh" 35 | #include "hb-ot-shape-complex-private.hh" 36 | 37 | 38 | 39 | enum hb_ot_complex_shaper_t; 40 | 41 | struct hb_ot_shape_plan_t 42 | { 43 | friend struct hb_ot_shape_planner_t; 44 | 45 | hb_ot_map_t map; 46 | hb_ot_complex_shaper_t shaper; 47 | 48 | hb_ot_shape_plan_t (void) : map () {} 49 | ~hb_ot_shape_plan_t (void) { map.finish (); } 50 | 51 | private: 52 | NO_COPY (hb_ot_shape_plan_t); 53 | }; 54 | 55 | struct hb_ot_shape_planner_t 56 | { 57 | hb_ot_map_builder_t map; 58 | hb_ot_complex_shaper_t shaper; 59 | 60 | hb_ot_shape_planner_t (void) : map () {} 61 | ~hb_ot_shape_planner_t (void) { map.finish (); } 62 | 63 | inline void compile (hb_face_t *face, 64 | const hb_segment_properties_t *props, 65 | struct hb_ot_shape_plan_t &plan) 66 | { 67 | plan.shaper = shaper; 68 | map.compile (face, props, plan.map); 69 | } 70 | 71 | private: 72 | NO_COPY (hb_ot_shape_planner_t); 73 | }; 74 | 75 | 76 | struct hb_ot_shape_context_t 77 | { 78 | /* Input to hb_ot_shape_execute() */ 79 | hb_ot_shape_plan_t *plan; 80 | hb_font_t *font; 81 | hb_face_t *face; 82 | hb_buffer_t *buffer; 83 | const hb_feature_t *user_features; 84 | unsigned int num_user_features; 85 | 86 | /* Transient stuff */ 87 | hb_direction_t target_direction; 88 | hb_bool_t applied_substitute_complex; 89 | hb_bool_t applied_position_complex; 90 | }; 91 | 92 | 93 | static inline hb_bool_t 94 | is_variation_selector (hb_codepoint_t unicode) 95 | { 96 | return unlikely ((unicode >= 0x180B && unicode <= 0x180D) || /* MONGOLIAN FREE VARIATION SELECTOR ONE..THREE */ 97 | (unicode >= 0xFE00 && unicode <= 0xFE0F) || /* VARIATION SELECTOR-1..16 */ 98 | (unicode >= 0xE0100 && unicode <= 0xE01EF)); /* VARIATION SELECTOR-17..256 */ 99 | } 100 | 101 | static inline unsigned int 102 | _hb_unicode_modified_combining_class (hb_unicode_funcs_t *ufuncs, 103 | hb_codepoint_t unicode) 104 | { 105 | int c = hb_unicode_combining_class (ufuncs, unicode); 106 | 107 | /* Modify the combining-class to suit Arabic better. See: 108 | * http://unicode.org/faq/normalization.html#8 109 | * http://unicode.org/faq/normalization.html#9 110 | */ 111 | if (unlikely (hb_in_range (c, 27, 33))) 112 | c = c == 33 ? 27 : c + 1; 113 | 114 | return c; 115 | } 116 | 117 | static inline void 118 | hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode) 119 | { 120 | info->general_category() = hb_unicode_general_category (unicode, info->codepoint); 121 | info->combining_class() = _hb_unicode_modified_combining_class (unicode, info->codepoint); 122 | } 123 | 124 | HB_INTERNAL void _hb_set_unicode_props (hb_buffer_t *buffer); 125 | 126 | HB_INTERNAL void _hb_ot_shape_normalize (hb_ot_shape_context_t *c); 127 | 128 | 129 | #endif /* HB_OT_SHAPE_PRIVATE_HH */ 130 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-shape.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OT_SHAPE_H 28 | #define HB_OT_SHAPE_H 29 | 30 | #include "hb-common.h" 31 | #include "hb-shape.h" 32 | 33 | 34 | HB_BEGIN_DECLS 35 | 36 | 37 | hb_bool_t 38 | hb_ot_shape (hb_font_t *font, 39 | hb_buffer_t *buffer, 40 | const hb_feature_t *features, 41 | unsigned int num_features, 42 | const char * const *shaper_options); 43 | 44 | 45 | HB_END_DECLS 46 | 47 | #endif /* HB_OT_SHAPE_H */ 48 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot-tag.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OT_TAG_H 28 | #define HB_OT_TAG_H 29 | 30 | #include "hb-common.h" 31 | 32 | HB_BEGIN_DECLS 33 | 34 | 35 | #define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T') 36 | #define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't') 37 | 38 | void 39 | hb_ot_tags_from_script (hb_script_t script, 40 | hb_tag_t *script_tag_1, 41 | hb_tag_t *script_tag_2); 42 | 43 | hb_script_t 44 | hb_ot_tag_to_script (hb_tag_t tag); 45 | 46 | hb_tag_t 47 | hb_ot_tag_from_language (hb_language_t language); 48 | 49 | hb_language_t 50 | hb_ot_tag_to_language (hb_tag_t tag); 51 | 52 | 53 | HB_END_DECLS 54 | 55 | #endif /* HB_OT_TAG_H */ 56 | -------------------------------------------------------------------------------- /harfbuzz/hb-ot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_OT_H 28 | #define HB_OT_H 29 | 30 | #include "hb.h" 31 | 32 | #include "hb-ot-layout.h" 33 | #include "hb-ot-shape.h" 34 | #include "hb-ot-tag.h" 35 | 36 | HB_BEGIN_DECLS 37 | HB_END_DECLS 38 | 39 | #endif /* HB_OT_H */ 40 | -------------------------------------------------------------------------------- /harfbuzz/hb-shape.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #include "hb-private.hh" 28 | 29 | #include "hb-shape.h" 30 | 31 | #include "hb-buffer-private.hh" 32 | 33 | #ifdef HAVE_GRAPHITE 34 | #include "hb-graphite2.h" 35 | #endif 36 | #ifdef HAVE_UNISCRIBE 37 | # include "hb-uniscribe.h" 38 | #endif 39 | #ifdef HAVE_OT 40 | # include "hb-ot-shape.h" 41 | #endif 42 | #include "hb-fallback-shape-private.hh" 43 | 44 | typedef hb_bool_t (*hb_shape_func_t) (hb_font_t *font, 45 | hb_buffer_t *buffer, 46 | const hb_feature_t *features, 47 | unsigned int num_features, 48 | const char * const *shaper_options); 49 | 50 | #define HB_SHAPER_IMPLEMENT(name) {#name, hb_##name##_shape} 51 | static struct hb_shaper_pair_t { 52 | char name[16]; 53 | hb_shape_func_t func; 54 | } shapers[] = { 55 | /* v--- Add new shapers in the right place here */ 56 | #ifdef HAVE_GRAPHITE 57 | HB_SHAPER_IMPLEMENT (graphite), 58 | #endif 59 | #ifdef HAVE_UNISCRIBE 60 | HB_SHAPER_IMPLEMENT (uniscribe), 61 | #endif 62 | #ifdef HAVE_OT 63 | HB_SHAPER_IMPLEMENT (ot), 64 | #endif 65 | HB_SHAPER_IMPLEMENT (fallback) /* should be last */ 66 | }; 67 | #undef HB_SHAPER_IMPLEMENT 68 | 69 | static struct static_shaper_list_t 70 | { 71 | static_shaper_list_t (void) 72 | { 73 | char *env = getenv ("HB_SHAPER_LIST"); 74 | if (env && *env) 75 | { 76 | /* Reorder shaper list to prefer requested shaper list. */ 77 | unsigned int i = 0; 78 | char *end, *p = env; 79 | for (;;) { 80 | end = strchr (p, ','); 81 | if (!end) 82 | end = p + strlen (p); 83 | 84 | for (unsigned int j = i; j < ARRAY_LENGTH (shapers); j++) 85 | if (end - p == (int) strlen (shapers[j].name) && 86 | 0 == strncmp (shapers[j].name, p, end - p)) 87 | { 88 | /* Reorder this shaper to position i */ 89 | struct hb_shaper_pair_t t = shapers[j]; 90 | memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i)); 91 | shapers[i] = t; 92 | i++; 93 | } 94 | 95 | if (!*end) 96 | break; 97 | else 98 | p = end + 1; 99 | } 100 | } 101 | 102 | ASSERT_STATIC ((ARRAY_LENGTH (shapers) + 1) * sizeof (*shaper_list) <= sizeof (shaper_list)); 103 | unsigned int i; 104 | for (i = 0; i < ARRAY_LENGTH (shapers); i++) 105 | shaper_list[i] = shapers[i].name; 106 | shaper_list[i] = NULL; 107 | } 108 | 109 | const char *shaper_list[ARRAY_LENGTH (shapers) + 1]; 110 | } static_shaper_list; 111 | 112 | const char ** 113 | hb_shape_list_shapers (void) 114 | { 115 | return static_shaper_list.shaper_list; 116 | } 117 | 118 | hb_bool_t 119 | hb_shape_full (hb_font_t *font, 120 | hb_buffer_t *buffer, 121 | const hb_feature_t *features, 122 | unsigned int num_features, 123 | const char * const *shaper_options, 124 | const char * const *shaper_list) 125 | { 126 | if (likely (!shaper_list)) { 127 | for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++) 128 | if (likely (shapers[i].func (font, buffer, 129 | features, num_features, 130 | shaper_options))) 131 | return TRUE; 132 | } else { 133 | while (*shaper_list) { 134 | for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++) 135 | if (0 == strcmp (*shaper_list, shapers[i].name)) { 136 | if (likely (shapers[i].func (font, buffer, 137 | features, num_features, 138 | shaper_options))) 139 | return TRUE; 140 | break; 141 | } 142 | shaper_list++; 143 | } 144 | } 145 | return FALSE; 146 | } 147 | 148 | void 149 | hb_shape (hb_font_t *font, 150 | hb_buffer_t *buffer, 151 | const hb_feature_t *features, 152 | unsigned int num_features) 153 | { 154 | hb_shape_full (font, buffer, features, num_features, NULL, NULL); 155 | } 156 | -------------------------------------------------------------------------------- /harfbuzz/hb-shape.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_SHAPE_H 28 | #define HB_SHAPE_H 29 | 30 | #include "hb-common.h" 31 | #include "hb-buffer.h" 32 | #include "hb-font.h" 33 | 34 | HB_BEGIN_DECLS 35 | 36 | 37 | typedef struct _hb_feature_t { 38 | hb_tag_t tag; 39 | uint32_t value; 40 | unsigned int start; 41 | unsigned int end; 42 | } hb_feature_t; 43 | 44 | 45 | void 46 | hb_shape (hb_font_t *font, 47 | hb_buffer_t *buffer, 48 | const hb_feature_t *features, 49 | unsigned int num_features); 50 | 51 | hb_bool_t 52 | hb_shape_full (hb_font_t *font, 53 | hb_buffer_t *buffer, 54 | const hb_feature_t *features, 55 | unsigned int num_features, 56 | const char * const *shaper_options, 57 | const char * const *shaper_list); 58 | 59 | const char ** 60 | hb_shape_list_shapers (void); 61 | 62 | 63 | HB_END_DECLS 64 | 65 | #endif /* HB_SHAPE_H */ 66 | -------------------------------------------------------------------------------- /harfbuzz/hb-unicode-private.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * Copyright © 2011 Codethink Limited 4 | * Copyright © 2010,2011 Google, Inc. 5 | * 6 | * This is part of HarfBuzz, a text shaping library. 7 | * 8 | * Permission is hereby granted, without written agreement and without 9 | * license or royalty fees, to use, copy, modify, and distribute this 10 | * software and its documentation for any purpose, provided that the 11 | * above copyright notice and the following two paragraphs appear in 12 | * all copies of this software. 13 | * 14 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18 | * DAMAGE. 19 | * 20 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | * 26 | * Red Hat Author(s): Behdad Esfahbod 27 | * Codethink Author(s): Ryan Lortie 28 | * Google Author(s): Behdad Esfahbod 29 | */ 30 | 31 | #ifndef HB_UNICODE_PRIVATE_HH 32 | #define HB_UNICODE_PRIVATE_HH 33 | 34 | #include "hb-private.hh" 35 | 36 | #include "hb-unicode.h" 37 | #include "hb-object-private.hh" 38 | 39 | 40 | 41 | /* 42 | * hb_unicode_funcs_t 43 | */ 44 | 45 | #define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS \ 46 | HB_UNICODE_FUNC_IMPLEMENT (combining_class) \ 47 | HB_UNICODE_FUNC_IMPLEMENT (eastasian_width) \ 48 | HB_UNICODE_FUNC_IMPLEMENT (general_category) \ 49 | HB_UNICODE_FUNC_IMPLEMENT (mirroring) \ 50 | HB_UNICODE_FUNC_IMPLEMENT (script) \ 51 | HB_UNICODE_FUNC_IMPLEMENT (compose) \ 52 | HB_UNICODE_FUNC_IMPLEMENT (decompose) \ 53 | /* ^--- Add new callbacks here */ 54 | 55 | /* Simple callbacks are those taking a hb_codepoint_t and returning a hb_codepoint_t */ 56 | #define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE \ 57 | HB_UNICODE_FUNC_IMPLEMENT (unsigned int, combining_class) \ 58 | HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width) \ 59 | HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_general_category_t, general_category) \ 60 | HB_UNICODE_FUNC_IMPLEMENT (hb_codepoint_t, mirroring) \ 61 | HB_UNICODE_FUNC_IMPLEMENT (hb_script_t, script) \ 62 | /* ^--- Add new simple callbacks here */ 63 | 64 | struct _hb_unicode_funcs_t { 65 | hb_object_header_t header; 66 | 67 | hb_unicode_funcs_t *parent; 68 | 69 | bool immutable; 70 | 71 | /* Don't access these directly. Call hb_unicode_*() instead. */ 72 | 73 | struct { 74 | #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name; 75 | HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS 76 | #undef HB_UNICODE_FUNC_IMPLEMENT 77 | } func; 78 | 79 | struct { 80 | #define HB_UNICODE_FUNC_IMPLEMENT(name) void *name; 81 | HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS 82 | #undef HB_UNICODE_FUNC_IMPLEMENT 83 | } user_data; 84 | 85 | struct { 86 | #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_destroy_func_t name; 87 | HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS 88 | #undef HB_UNICODE_FUNC_IMPLEMENT 89 | } destroy; 90 | }; 91 | 92 | 93 | #ifdef HAVE_GLIB 94 | extern HB_INTERNAL hb_unicode_funcs_t _hb_glib_unicode_funcs; 95 | #define _hb_unicode_funcs_default _hb_glib_unicode_funcs 96 | #elif defined(HAVE_ICU) 97 | extern HB_INTERNAL hb_unicode_funcs_t _hb_icu_unicode_funcs; 98 | #define _hb_unicode_funcs_default _hb_icu_unicode_funcs 99 | #else 100 | extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_nil; 101 | #define _hb_unicode_funcs_default _hb_unicode_funcs_nil 102 | #endif 103 | 104 | 105 | 106 | 107 | #endif /* HB_UNICODE_PRIVATE_HH */ 108 | -------------------------------------------------------------------------------- /harfbuzz/hb-unicode.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * Copyright © 2011 Codethink Limited 4 | * Copyright © 2010,2011 Google, Inc. 5 | * 6 | * This is part of HarfBuzz, a text shaping library. 7 | * 8 | * Permission is hereby granted, without written agreement and without 9 | * license or royalty fees, to use, copy, modify, and distribute this 10 | * software and its documentation for any purpose, provided that the 11 | * above copyright notice and the following two paragraphs appear in 12 | * all copies of this software. 13 | * 14 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18 | * DAMAGE. 19 | * 20 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | * 26 | * Red Hat Author(s): Behdad Esfahbod 27 | * Codethink Author(s): Ryan Lortie 28 | * Google Author(s): Behdad Esfahbod 29 | */ 30 | 31 | #include "hb-private.hh" 32 | 33 | #include "hb-unicode-private.hh" 34 | 35 | 36 | 37 | /* 38 | * hb_unicode_funcs_t 39 | */ 40 | 41 | static unsigned int 42 | hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 43 | hb_codepoint_t unicode HB_UNUSED, 44 | void *user_data HB_UNUSED) 45 | { 46 | return 0; 47 | } 48 | 49 | static unsigned int 50 | hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 51 | hb_codepoint_t unicode HB_UNUSED, 52 | void *user_data HB_UNUSED) 53 | { 54 | return 1; 55 | } 56 | 57 | static hb_unicode_general_category_t 58 | hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 59 | hb_codepoint_t unicode HB_UNUSED, 60 | void *user_data HB_UNUSED) 61 | { 62 | return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER; 63 | } 64 | 65 | static hb_codepoint_t 66 | hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 67 | hb_codepoint_t unicode HB_UNUSED, 68 | void *user_data HB_UNUSED) 69 | { 70 | return unicode; 71 | } 72 | 73 | static hb_script_t 74 | hb_unicode_script_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 75 | hb_codepoint_t unicode HB_UNUSED, 76 | void *user_data HB_UNUSED) 77 | { 78 | return HB_SCRIPT_UNKNOWN; 79 | } 80 | 81 | static hb_bool_t 82 | hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 83 | hb_codepoint_t a HB_UNUSED, 84 | hb_codepoint_t b HB_UNUSED, 85 | hb_codepoint_t *ab HB_UNUSED, 86 | void *user_data HB_UNUSED) 87 | { 88 | /* TODO handle Hangul jamo here? */ 89 | return FALSE; 90 | } 91 | 92 | static hb_bool_t 93 | hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 94 | hb_codepoint_t ab HB_UNUSED, 95 | hb_codepoint_t *a HB_UNUSED, 96 | hb_codepoint_t *b HB_UNUSED, 97 | void *user_data HB_UNUSED) 98 | { 99 | /* TODO handle Hangul jamo here? */ 100 | return FALSE; 101 | } 102 | 103 | 104 | hb_unicode_funcs_t _hb_unicode_funcs_nil = { 105 | HB_OBJECT_HEADER_STATIC, 106 | 107 | NULL, /* parent */ 108 | TRUE, /* immutable */ 109 | { 110 | #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil, 111 | HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS 112 | #undef HB_UNICODE_FUNC_IMPLEMENT 113 | } 114 | }; 115 | 116 | 117 | hb_unicode_funcs_t * 118 | hb_unicode_funcs_get_default (void) 119 | { 120 | return &_hb_unicode_funcs_default; 121 | } 122 | 123 | hb_unicode_funcs_t * 124 | hb_unicode_funcs_create (hb_unicode_funcs_t *parent) 125 | { 126 | hb_unicode_funcs_t *ufuncs; 127 | 128 | if (!(ufuncs = hb_object_create ())) 129 | return &_hb_unicode_funcs_nil; 130 | 131 | if (!parent) 132 | parent = &_hb_unicode_funcs_nil; 133 | 134 | hb_unicode_funcs_make_immutable (parent); 135 | ufuncs->parent = hb_unicode_funcs_reference (parent); 136 | 137 | ufuncs->func = parent->func; 138 | 139 | /* We can safely copy user_data from parent since we hold a reference 140 | * onto it and it's immutable. We should not copy the destroy notifiers 141 | * though. */ 142 | ufuncs->user_data = parent->user_data; 143 | 144 | return ufuncs; 145 | } 146 | 147 | hb_unicode_funcs_t * 148 | hb_unicode_funcs_get_empty (void) 149 | { 150 | return &_hb_unicode_funcs_nil; 151 | } 152 | 153 | hb_unicode_funcs_t * 154 | hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs) 155 | { 156 | return hb_object_reference (ufuncs); 157 | } 158 | 159 | void 160 | hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs) 161 | { 162 | if (!hb_object_destroy (ufuncs)) return; 163 | 164 | #define HB_UNICODE_FUNC_IMPLEMENT(name) \ 165 | if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name); 166 | HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS 167 | #undef HB_UNICODE_FUNC_IMPLEMENT 168 | 169 | hb_unicode_funcs_destroy (ufuncs->parent); 170 | 171 | free (ufuncs); 172 | } 173 | 174 | hb_bool_t 175 | hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, 176 | hb_user_data_key_t *key, 177 | void * data, 178 | hb_destroy_func_t destroy, 179 | hb_bool_t replace) 180 | { 181 | return hb_object_set_user_data (ufuncs, key, data, destroy, replace); 182 | } 183 | 184 | void * 185 | hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, 186 | hb_user_data_key_t *key) 187 | { 188 | return hb_object_get_user_data (ufuncs, key); 189 | } 190 | 191 | 192 | void 193 | hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) 194 | { 195 | if (hb_object_is_inert (ufuncs)) 196 | return; 197 | 198 | ufuncs->immutable = TRUE; 199 | } 200 | 201 | hb_bool_t 202 | hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs) 203 | { 204 | return ufuncs->immutable; 205 | } 206 | 207 | hb_unicode_funcs_t * 208 | hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs) 209 | { 210 | return ufuncs->parent ? ufuncs->parent : &_hb_unicode_funcs_nil; 211 | } 212 | 213 | 214 | #define HB_UNICODE_FUNC_IMPLEMENT(name) \ 215 | \ 216 | void \ 217 | hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \ 218 | hb_unicode_##name##_func_t func, \ 219 | void *user_data, \ 220 | hb_destroy_func_t destroy) \ 221 | { \ 222 | if (ufuncs->immutable) \ 223 | return; \ 224 | \ 225 | if (ufuncs->destroy.name) \ 226 | ufuncs->destroy.name (ufuncs->user_data.name); \ 227 | \ 228 | if (func) { \ 229 | ufuncs->func.name = func; \ 230 | ufuncs->user_data.name = user_data; \ 231 | ufuncs->destroy.name = destroy; \ 232 | } else { \ 233 | ufuncs->func.name = ufuncs->parent->func.name; \ 234 | ufuncs->user_data.name = ufuncs->parent->user_data.name; \ 235 | ufuncs->destroy.name = NULL; \ 236 | } \ 237 | } 238 | 239 | HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS 240 | #undef HB_UNICODE_FUNC_IMPLEMENT 241 | 242 | 243 | #define HB_UNICODE_FUNC_IMPLEMENT(return_type, name) \ 244 | \ 245 | return_type \ 246 | hb_unicode_##name (hb_unicode_funcs_t *ufuncs, \ 247 | hb_codepoint_t unicode) \ 248 | { \ 249 | return ufuncs->func.name (ufuncs, unicode, ufuncs->user_data.name); \ 250 | } 251 | HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE 252 | #undef HB_UNICODE_FUNC_IMPLEMENT 253 | 254 | hb_bool_t 255 | hb_unicode_compose (hb_unicode_funcs_t *ufuncs, 256 | hb_codepoint_t a, 257 | hb_codepoint_t b, 258 | hb_codepoint_t *ab) 259 | { 260 | *ab = 0; 261 | return ufuncs->func.compose (ufuncs, a, b, ab, ufuncs->user_data.compose); 262 | } 263 | 264 | hb_bool_t 265 | hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, 266 | hb_codepoint_t ab, 267 | hb_codepoint_t *a, 268 | hb_codepoint_t *b) 269 | { 270 | *a = ab; *b = 0; 271 | return ufuncs->func.decompose (ufuncs, ab, a, b, ufuncs->user_data.decompose); 272 | } 273 | 274 | -------------------------------------------------------------------------------- /harfbuzz/hb-unicode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * Copyright © 2011 Codethink Limited 4 | * Copyright © 2011 Google, Inc. 5 | * 6 | * This is part of HarfBuzz, a text shaping library. 7 | * 8 | * Permission is hereby granted, without written agreement and without 9 | * license or royalty fees, to use, copy, modify, and distribute this 10 | * software and its documentation for any purpose, provided that the 11 | * above copyright notice and the following two paragraphs appear in 12 | * all copies of this software. 13 | * 14 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18 | * DAMAGE. 19 | * 20 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | * 26 | * Red Hat Author(s): Behdad Esfahbod 27 | * Codethink Author(s): Ryan Lortie 28 | * Google Author(s): Behdad Esfahbod 29 | */ 30 | 31 | #ifndef HB_UNICODE_H 32 | #define HB_UNICODE_H 33 | 34 | #include "hb-common.h" 35 | 36 | HB_BEGIN_DECLS 37 | 38 | 39 | /* 40 | * hb_unicode_funcs_t 41 | */ 42 | 43 | typedef struct _hb_unicode_funcs_t hb_unicode_funcs_t; 44 | 45 | 46 | /* 47 | * just give me the best implementation you've got there. 48 | */ 49 | hb_unicode_funcs_t * 50 | hb_unicode_funcs_get_default (void); 51 | 52 | 53 | hb_unicode_funcs_t * 54 | hb_unicode_funcs_create (hb_unicode_funcs_t *parent); 55 | 56 | hb_unicode_funcs_t * 57 | hb_unicode_funcs_get_empty (void); 58 | 59 | hb_unicode_funcs_t * 60 | hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs); 61 | 62 | void 63 | hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs); 64 | 65 | hb_bool_t 66 | hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, 67 | hb_user_data_key_t *key, 68 | void * data, 69 | hb_destroy_func_t destroy, 70 | hb_bool_t replace); 71 | 72 | 73 | void * 74 | hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, 75 | hb_user_data_key_t *key); 76 | 77 | 78 | void 79 | hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs); 80 | 81 | hb_bool_t 82 | hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs); 83 | 84 | hb_unicode_funcs_t * 85 | hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs); 86 | 87 | 88 | /* 89 | * funcs 90 | */ 91 | 92 | /* typedefs */ 93 | 94 | typedef unsigned int (*hb_unicode_combining_class_func_t) (hb_unicode_funcs_t *ufuncs, 95 | hb_codepoint_t unicode, 96 | void *user_data); 97 | typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs, 98 | hb_codepoint_t unicode, 99 | void *user_data); 100 | typedef hb_unicode_general_category_t (*hb_unicode_general_category_func_t) (hb_unicode_funcs_t *ufuncs, 101 | hb_codepoint_t unicode, 102 | void *user_data); 103 | typedef hb_codepoint_t (*hb_unicode_mirroring_func_t) (hb_unicode_funcs_t *ufuncs, 104 | hb_codepoint_t unicode, 105 | void *user_data); 106 | typedef hb_script_t (*hb_unicode_script_func_t) (hb_unicode_funcs_t *ufuncs, 107 | hb_codepoint_t unicode, 108 | void *user_data); 109 | 110 | typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs, 111 | hb_codepoint_t a, 112 | hb_codepoint_t b, 113 | hb_codepoint_t *ab, 114 | void *user_data); 115 | typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs, 116 | hb_codepoint_t ab, 117 | hb_codepoint_t *a, 118 | hb_codepoint_t *b, 119 | void *user_data); 120 | 121 | /* setters */ 122 | 123 | void 124 | hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs, 125 | hb_unicode_combining_class_func_t combining_class_func, 126 | void *user_data, hb_destroy_func_t destroy); 127 | 128 | void 129 | hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, 130 | hb_unicode_eastasian_width_func_t eastasian_width_func, 131 | void *user_data, hb_destroy_func_t destroy); 132 | 133 | void 134 | hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs, 135 | hb_unicode_general_category_func_t general_category_func, 136 | void *user_data, hb_destroy_func_t destroy); 137 | 138 | void 139 | hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs, 140 | hb_unicode_mirroring_func_t mirroring_func, 141 | void *user_data, hb_destroy_func_t destroy); 142 | 143 | void 144 | hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs, 145 | hb_unicode_script_func_t script_func, 146 | void *user_data, hb_destroy_func_t destroy); 147 | 148 | void 149 | hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs, 150 | hb_unicode_compose_func_t compose_func, 151 | void *user_data, hb_destroy_func_t destroy); 152 | 153 | void 154 | hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs, 155 | hb_unicode_decompose_func_t decompose_func, 156 | void *user_data, hb_destroy_func_t destroy); 157 | 158 | 159 | /* accessors */ 160 | 161 | unsigned int 162 | hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs, 163 | hb_codepoint_t unicode); 164 | 165 | unsigned int 166 | hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, 167 | hb_codepoint_t unicode); 168 | 169 | hb_unicode_general_category_t 170 | hb_unicode_general_category (hb_unicode_funcs_t *ufuncs, 171 | hb_codepoint_t unicode); 172 | 173 | hb_codepoint_t 174 | hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs, 175 | hb_codepoint_t unicode); 176 | 177 | hb_script_t 178 | hb_unicode_script (hb_unicode_funcs_t *ufuncs, 179 | hb_codepoint_t unicode); 180 | 181 | hb_bool_t 182 | hb_unicode_compose (hb_unicode_funcs_t *ufuncs, 183 | hb_codepoint_t a, 184 | hb_codepoint_t b, 185 | hb_codepoint_t *ab); 186 | hb_bool_t 187 | hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, 188 | hb_codepoint_t ab, 189 | hb_codepoint_t *a, 190 | hb_codepoint_t *b); 191 | 192 | HB_END_DECLS 193 | 194 | #endif /* HB_UNICODE_H */ 195 | -------------------------------------------------------------------------------- /harfbuzz/hb-uniscribe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_UNISCRIBE_H 28 | #define HB_UNISCRIBE_H 29 | 30 | #include "hb-common.h" 31 | #include "hb-shape.h" 32 | 33 | #define _WIN32_WINNT 0x0600 34 | #include 35 | 36 | HB_BEGIN_DECLS 37 | 38 | 39 | hb_bool_t 40 | hb_uniscribe_shape (hb_font_t *font, 41 | hb_buffer_t *buffer, 42 | const hb_feature_t *features, 43 | unsigned int num_features, 44 | const char * const *shaper_options); 45 | 46 | LOGFONTW * 47 | hb_uniscribe_font_get_logfontw (hb_font_t *font); 48 | 49 | HFONT 50 | hb_uniscribe_font_get_hfont (hb_font_t *font); 51 | 52 | 53 | HB_END_DECLS 54 | 55 | #endif /* HB_UNISCRIBE_H */ 56 | -------------------------------------------------------------------------------- /harfbuzz/hb-version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_VERSION_H 28 | #define HB_VERSION_H 29 | 30 | #include "hb-common.h" 31 | 32 | HB_BEGIN_DECLS 33 | 34 | 35 | #define HB_VERSION_MAJOR 0 36 | #define HB_VERSION_MINOR 7 37 | #define HB_VERSION_MICRO 0 38 | 39 | #define HB_VERSION_STRING "0.7.0" 40 | 41 | #define HB_VERSION_CHECK(major,minor,micro) \ 42 | ((major)*10000+(minor)*100+(micro) >= \ 43 | HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO) 44 | 45 | 46 | void 47 | hb_version (unsigned int *major, 48 | unsigned int *minor, 49 | unsigned int *micro); 50 | 51 | const char * 52 | hb_version_string (void); 53 | 54 | hb_bool_t 55 | hb_version_check (unsigned int major, 56 | unsigned int minor, 57 | unsigned int micro); 58 | 59 | 60 | HB_END_DECLS 61 | 62 | #endif /* HB_VERSION_H */ 63 | -------------------------------------------------------------------------------- /harfbuzz/hb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifndef HB_H 28 | #define HB_H 29 | 30 | #include "hb-blob.h" 31 | #include "hb-buffer.h" 32 | #include "hb-common.h" 33 | #include "hb-font.h" 34 | #include "hb-shape.h" 35 | #include "hb-unicode.h" 36 | #include "hb-version.h" 37 | 38 | HB_BEGIN_DECLS 39 | HB_END_DECLS 40 | 41 | #endif /* HB_H */ 42 | -------------------------------------------------------------------------------- /harfbuzz/main.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2007,2008,2009 Red Hat, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Red Hat Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #include "hb-mutex-private.hh" 28 | #include "hb-open-file-private.hh" 29 | #include "hb-ot-layout-gdef-table.hh" 30 | #include "hb-ot-layout-gsubgpos-private.hh" 31 | 32 | #ifdef HAVE_GLIB 33 | #include 34 | #endif 35 | #include 36 | #include 37 | 38 | 39 | 40 | int 41 | main (int argc, char **argv) 42 | { 43 | if (argc != 2) { 44 | fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]); 45 | exit (1); 46 | } 47 | 48 | const char *font_data = NULL; 49 | int len = 0; 50 | 51 | #ifdef HAVE_GLIB 52 | GMappedFile *mf = g_mapped_file_new (argv[1], FALSE, NULL); 53 | font_data = g_mapped_file_get_contents (mf); 54 | len = g_mapped_file_get_length (mf); 55 | #else 56 | FILE *f = fopen (argv[1], "rb"); 57 | fseek (f, 0, SEEK_END); 58 | len = ftell (f); 59 | fseek (f, 0, SEEK_SET); 60 | font_data = (const char *) malloc (len); 61 | len = fread ((char *) font_data, 1, len, f); 62 | #endif 63 | 64 | printf ("Opened font file %s: %d bytes long\n", argv[1], len); 65 | 66 | const OpenTypeFontFile &ot = *CastP (font_data); 67 | 68 | switch (ot.get_tag ()) { 69 | case OpenTypeFontFile::TrueTypeTag: 70 | printf ("OpenType font with TrueType outlines\n"); 71 | break; 72 | case OpenTypeFontFile::CFFTag: 73 | printf ("OpenType font with CFF (Type1) outlines\n"); 74 | break; 75 | case OpenTypeFontFile::TTCTag: 76 | printf ("TrueType Collection of OpenType fonts\n"); 77 | break; 78 | case OpenTypeFontFile::TrueTag: 79 | printf ("Obsolete Apple TrueType font\n"); 80 | break; 81 | case OpenTypeFontFile::Typ1Tag: 82 | printf ("Obsolete Apple Type1 font in SFNT container\n"); 83 | break; 84 | default: 85 | printf ("Unknown font format\n"); 86 | break; 87 | } 88 | 89 | int num_fonts = ot.get_face_count (); 90 | printf ("%d font(s) found in file\n", num_fonts); 91 | for (int n_font = 0; n_font < num_fonts; n_font++) { 92 | const OpenTypeFontFace &font = ot.get_face (n_font); 93 | printf ("Font %d of %d:\n", n_font, num_fonts); 94 | 95 | int num_tables = font.get_table_count (); 96 | printf (" %d table(s) found in font\n", num_tables); 97 | for (int n_table = 0; n_table < num_tables; n_table++) { 98 | const OpenTypeTable &table = font.get_table (n_table); 99 | printf (" Table %2d of %2d: %.4s (0x%08x+0x%08x)\n", n_table, num_tables, 100 | (const char *)table.tag, 101 | (unsigned int) table.offset, 102 | (unsigned int) table.length); 103 | 104 | switch (table.tag) { 105 | 106 | case GSUBGPOS::GSUBTag: 107 | case GSUBGPOS::GPOSTag: 108 | { 109 | 110 | const GSUBGPOS &g = *CastP (font_data + table.offset); 111 | 112 | int num_scripts = g.get_script_count (); 113 | printf (" %d script(s) found in table\n", num_scripts); 114 | for (int n_script = 0; n_script < num_scripts; n_script++) { 115 | const Script &script = g.get_script (n_script); 116 | printf (" Script %2d of %2d: %.4s\n", n_script, num_scripts, 117 | (const char *)g.get_script_tag(n_script)); 118 | 119 | if (!script.has_default_lang_sys()) 120 | printf (" No default language system\n"); 121 | int num_langsys = script.get_lang_sys_count (); 122 | printf (" %d language system(s) found in script\n", num_langsys); 123 | for (int n_langsys = script.has_default_lang_sys() ? -1 : 0; n_langsys < num_langsys; n_langsys++) { 124 | const LangSys &langsys = n_langsys == -1 125 | ? script.get_default_lang_sys () 126 | : script.get_lang_sys (n_langsys); 127 | printf (n_langsys == -1 128 | ? " Default Language System\n" 129 | : " Language System %2d of %2d: %.4s\n", n_langsys, num_langsys, 130 | (const char *)script.get_lang_sys_tag (n_langsys)); 131 | if (langsys.get_required_feature_index () == Index::NOT_FOUND_INDEX) 132 | printf (" No required feature\n"); 133 | 134 | int num_features = langsys.get_feature_count (); 135 | printf (" %d feature(s) found in language system\n", num_features); 136 | for (int n_feature = 0; n_feature < num_features; n_feature++) { 137 | printf (" Feature index %2d of %2d: %d\n", n_feature, num_features, 138 | langsys.get_feature_index (n_feature)); 139 | } 140 | } 141 | } 142 | 143 | int num_features = g.get_feature_count (); 144 | printf (" %d feature(s) found in table\n", num_features); 145 | for (int n_feature = 0; n_feature < num_features; n_feature++) { 146 | const Feature &feature = g.get_feature (n_feature); 147 | printf (" Feature %2d of %2d: %.4s; %d lookup(s)\n", n_feature, num_features, 148 | (const char *)g.get_feature_tag(n_feature), 149 | feature.get_lookup_count()); 150 | 151 | int num_lookups = feature.get_lookup_count (); 152 | printf (" %d lookup(s) found in feature\n", num_lookups); 153 | for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) { 154 | printf (" Lookup index %2d of %2d: %d\n", n_lookup, num_lookups, 155 | feature.get_lookup_index (n_lookup)); 156 | } 157 | } 158 | 159 | int num_lookups = g.get_lookup_count (); 160 | printf (" %d lookup(s) found in table\n", num_lookups); 161 | for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) { 162 | const Lookup &lookup = g.get_lookup (n_lookup); 163 | printf (" Lookup %2d of %2d: type %d, props 0x%04X\n", n_lookup, num_lookups, 164 | lookup.get_type(), lookup.get_props()); 165 | } 166 | 167 | } 168 | break; 169 | 170 | case GDEF::Tag: 171 | { 172 | 173 | const GDEF &gdef = *CastP (font_data + table.offset); 174 | 175 | printf (" Has %sglyph classes\n", 176 | gdef.has_glyph_classes () ? "" : "no "); 177 | printf (" Has %smark attachment types\n", 178 | gdef.has_mark_attachment_types () ? "" : "no "); 179 | printf (" Has %sattach points\n", 180 | gdef.has_attach_points () ? "" : "no "); 181 | printf (" Has %slig carets\n", 182 | gdef.has_lig_carets () ? "" : "no "); 183 | printf (" Has %smark sets\n", 184 | gdef.has_mark_sets () ? "" : "no "); 185 | break; 186 | } 187 | } 188 | } 189 | } 190 | 191 | return 0; 192 | } 193 | 194 | 195 | -------------------------------------------------------------------------------- /harfbuzz/test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010,2011 Google, Inc. 3 | * 4 | * This is part of HarfBuzz, a text shaping library. 5 | * 6 | * Permission is hereby granted, without written agreement and without 7 | * license or royalty fees, to use, copy, modify, and distribute this 8 | * software and its documentation for any purpose, provided that the 9 | * above copyright notice and the following two paragraphs appear in 10 | * all copies of this software. 11 | * 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 | * DAMAGE. 17 | * 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 | * 24 | * Google Author(s): Behdad Esfahbod 25 | */ 26 | 27 | #ifdef HAVE_CONFIG_H 28 | #include "config.h" 29 | #endif 30 | 31 | #include "hb.h" 32 | 33 | #ifdef HAVE_GLIB 34 | #include 35 | #endif 36 | #include 37 | #include 38 | 39 | #ifdef HAVE_FREETYPE 40 | #include "hb-ft.h" 41 | #endif 42 | 43 | int 44 | main (int argc, char **argv) 45 | { 46 | hb_blob_t *blob = NULL; 47 | 48 | if (argc != 2) { 49 | fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]); 50 | exit (1); 51 | } 52 | 53 | /* Create the blob */ 54 | { 55 | const char *font_data; 56 | unsigned int len; 57 | hb_destroy_func_t destroy; 58 | void *user_data; 59 | hb_memory_mode_t mm; 60 | 61 | #ifdef HAVE_GLIB 62 | GMappedFile *mf = g_mapped_file_new (argv[1], FALSE, NULL); 63 | font_data = g_mapped_file_get_contents (mf); 64 | len = g_mapped_file_get_length (mf); 65 | destroy = (hb_destroy_func_t) g_mapped_file_unref; 66 | user_data = (void *) mf; 67 | mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE; 68 | #else 69 | FILE *f = fopen (argv[1], "rb"); 70 | fseek (f, 0, SEEK_END); 71 | len = ftell (f); 72 | fseek (f, 0, SEEK_SET); 73 | font_data = (const char *) malloc (len); 74 | if (!font_data) len = 0; 75 | len = fread ((char *) font_data, 1, len, f); 76 | destroy = free; 77 | user_data = (void *) font_data; 78 | fclose (f); 79 | mm = HB_MEMORY_MODE_WRITABLE; 80 | #endif 81 | 82 | blob = hb_blob_create (font_data, len, mm, user_data, destroy); 83 | } 84 | 85 | printf ("Opened font file %s: %u bytes long\n", argv[1], hb_blob_get_length (blob)); 86 | 87 | /* Create the face */ 88 | hb_face_t *face = hb_face_create (blob, 0 /* first face */); 89 | hb_blob_destroy (blob); 90 | blob = NULL; 91 | unsigned int upem = hb_face_get_upem (face); 92 | 93 | hb_font_t *font = hb_font_create (face); 94 | hb_font_set_scale (font, upem, upem); 95 | 96 | #ifdef HAVE_FREETYPE 97 | hb_ft_font_set_funcs (font); 98 | #endif 99 | 100 | hb_buffer_t *buffer = hb_buffer_create (); 101 | 102 | hb_buffer_add_utf8 (buffer, "\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x8d\xe0\xa4\x95", -1, 0, -1); 103 | 104 | hb_shape (font, buffer, NULL, 0); 105 | 106 | unsigned int count = hb_buffer_get_length (buffer); 107 | hb_glyph_info_t *infos = hb_buffer_get_glyph_infos (buffer, NULL); 108 | hb_glyph_position_t *positions = hb_buffer_get_glyph_positions (buffer, NULL); 109 | 110 | for (unsigned int i = 0; i < count; i++) 111 | { 112 | hb_glyph_info_t *info = &infos[i]; 113 | hb_glyph_position_t *pos = &positions[i]; 114 | 115 | printf ("cluster %d glyph 0x%x at (%d,%d)+(%d,%d)\n", 116 | info->cluster, 117 | info->codepoint, 118 | pos->x_offset, 119 | pos->x_offset, 120 | pos->x_advance, 121 | pos->y_advance); 122 | 123 | } 124 | 125 | hb_buffer_destroy (buffer); 126 | hb_font_destroy (font); 127 | hb_face_destroy (face); 128 | 129 | return 0; 130 | } 131 | 132 | 133 | -------------------------------------------------------------------------------- /test.cpp: -------------------------------------------------------------------------------- 1 | #include "gltext.hpp" 2 | 3 | #include 4 | 5 | gltext::Font font; 6 | 7 | void render(void) { 8 | glClear(GL_COLOR_BUFFER_BIT); 9 | 10 | font.setPenPosition(16, 32); 11 | font.setPenColor(1.0, 1.0, 1.0); 12 | font.setPointSize(32); 13 | font.draw("Hello, gltext!"); 14 | 15 | font.setPenPosition(16, 16); 16 | font.setPenColor(1.0, 0.0, 0.0); 17 | font.setPointSize(12); 18 | font.draw("Hello, RedText!"); 19 | 20 | glutSwapBuffers(); 21 | } 22 | 23 | int main(int argc, char** argv) { 24 | glutInit(&argc, argv); 25 | glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH); 26 | glutInitWindowPosition(0, 0); 27 | glutInitWindowSize(300, 300); 28 | glutCreateWindow("gltext demo"); 29 | glutDisplayFunc(render); 30 | 31 | font = gltext::Font("/home/branan/projects/coredump/vfx/droid.ttf", 16, 128); 32 | font.setDisplaySize(300, 300); 33 | font.cacheCharacters("1234567890!@#$%^&*()abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./;'[]\\<>?:\"{}|-=_+"); 34 | 35 | glutMainLoop(); 36 | } --------------------------------------------------------------------------------