├── .github └── workflows │ └── main.yml ├── .gitignore ├── .gitmodules ├── COPYRIGHT ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── clippy.toml ├── harfbuzz-sys ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── build.rs ├── src │ ├── bindings.rs │ ├── coretext.rs │ ├── directwrite.rs │ ├── freetype.rs │ └── lib.rs ├── update.sh └── wrapper.h ├── harfbuzz-traits ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ ├── lib.rs │ └── unicode_funcs_traits.rs └── harfbuzz ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src ├── blob.rs ├── buffer.rs ├── direction.rs ├── language.rs ├── lib.rs ├── unicode_funcs.rs └── version.rs /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [auto] 6 | pull_request: 7 | workflow_dispatch: 8 | merge_group: 9 | types: [checks_requested] 10 | 11 | 12 | jobs: 13 | linux-ci-shared: 14 | name: stable, Linux, shared library 15 | runs-on: ubuntu-24.04 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | submodules: true 20 | 21 | - name: Install harfbuzz from apt 22 | run: | 23 | sudo apt update 24 | sudo apt install libharfbuzz-dev libfreetype-dev 25 | 26 | - name: Install stable toolchain 27 | uses: dtolnay/rust-toolchain@stable 28 | 29 | - name: Cargo build 30 | run: cargo build --workspace 31 | 32 | - name: Cargo test 33 | run: cargo test --workspace 34 | env: 35 | RUST_BACKTRACE: 1 36 | 37 | - name: Cargo check no-default-features 38 | run: cargo check --no-default-features 39 | env: 40 | RUST_BACKTRACE: 1 41 | 42 | linux-ci-static: 43 | name: stable, Linux, static linking, no pkg-config 44 | runs-on: ubuntu-latest 45 | steps: 46 | - uses: actions/checkout@v4 47 | with: 48 | submodules: true 49 | 50 | - name: Install stable toolchain 51 | uses: dtolnay/rust-toolchain@stable 52 | 53 | # Test the harfbuzz-sys package build to check the 'exclude's. We should 54 | # do this where the embedded harfbuzz is statically linked, but we don't 55 | # need to do it for every environment. 56 | - name: Cargo package 57 | run: cargo package --manifest-path=harfbuzz-sys/Cargo.toml --features "freetype-sys/bundled bundled" 58 | 59 | - name: Cargo build 60 | run: cargo build --workspace --features "freetype-sys/bundled bundled" 61 | 62 | - name: Cargo clippy 63 | run: cargo clippy --workspace --features "freetype-sys/bundled bundled" -- -D warnings 64 | 65 | - name: Cargo test 66 | run: cargo test --workspace --features "freetype-sys/bundled bundled" 67 | env: 68 | RUST_BACKTRACE: 1 69 | 70 | mac-ci-shared: 71 | name: stable, macOS, shared library 72 | runs-on: macos-latest 73 | 74 | steps: 75 | - uses: actions/checkout@v4 76 | with: 77 | submodules: true 78 | 79 | - name: install harfbuzz from homebrew 80 | run: | 81 | brew install harfbuzz 82 | 83 | - name: Install stable toolchain 84 | uses: dtolnay/rust-toolchain@stable 85 | with: 86 | components: rustfmt 87 | 88 | - name: Cargo fmt 89 | run: cargo fmt --all -- --check 90 | 91 | - name: Cargo build 92 | run: cargo build --workspace 93 | 94 | - name: Cargo test 95 | run: cargo test --workspace 96 | env: 97 | RUST_BACKTRACE: 1 98 | 99 | mac-ci-static: 100 | name: stable, macOS, static library 101 | runs-on: macos-latest 102 | 103 | steps: 104 | - uses: actions/checkout@v4 105 | with: 106 | submodules: true 107 | 108 | - name: Install stable toolchain 109 | uses: dtolnay/rust-toolchain@stable 110 | with: 111 | components: rustfmt 112 | 113 | - name: Cargo fmt 114 | run: cargo fmt --all -- --check 115 | 116 | - name: Cargo build 117 | run: cargo build --workspace --features bundled 118 | 119 | - name: Cargo test 120 | run: cargo test --workspace --features bundled 121 | env: 122 | RUST_BACKTRACE: 1 123 | 124 | windows-ci: 125 | name: stable, Windows, static library 126 | runs-on: windows-latest 127 | 128 | steps: 129 | - uses: actions/checkout@v4 130 | with: 131 | submodules: true 132 | 133 | - name: Install stable toolchain 134 | uses: dtolnay/rust-toolchain@stable 135 | 136 | - name: Cargo build 137 | run: cargo build --workspace --features "freetype-sys/bundled bundled" 138 | 139 | - name: Cargo test 140 | run: cargo test --workspace --features "freetype-sys/bundled bundled" 141 | env: 142 | RUST_BACKTRACE: 1 143 | 144 | wasm32-emscripten-ci: 145 | name: stable, Emscripten, static library 146 | runs-on: ubuntu-latest 147 | 148 | steps: 149 | - uses: actions/checkout@v4 150 | with: 151 | submodules: true 152 | 153 | - uses: mymindstorm/setup-emsdk@v14 154 | with: 155 | version: "3.1.44" 156 | 157 | - name: Install stable toolchain 158 | uses: dtolnay/rust-toolchain@stable 159 | with: 160 | target: wasm32-unknown-emscripten 161 | 162 | - name: Cargo build 163 | run: cargo build --target wasm32-unknown-emscripten --workspace --no-default-features --features bundled 164 | 165 | ios-ci-static: 166 | name: stable, iOS, static library 167 | runs-on: macos-latest 168 | 169 | steps: 170 | - uses: actions/checkout@v4 171 | with: 172 | submodules: true 173 | 174 | - name: Install stable toolchain 175 | uses: dtolnay/rust-toolchain@stable 176 | with: 177 | target: aarch64-apple-ios 178 | 179 | - name: Cargo build 180 | run: cargo build --target aarch64-apple-ios --workspace --no-default-features --features "bundled, coretext" 181 | 182 | build_result: 183 | name: Result 184 | runs-on: ubuntu-latest 185 | needs: 186 | - "ios-ci-static" 187 | - "linux-ci-static" 188 | - "linux-ci-shared" 189 | - "mac-ci-shared" 190 | - "mac-ci-static" 191 | - "wasm32-emscripten-ci" 192 | - "windows-ci" 193 | 194 | steps: 195 | - name: Mark the job as successful 196 | run: exit 0 197 | if: success() 198 | - name: Mark the job as unsuccessful 199 | run: exit 1 200 | if: "!success()" 201 | 202 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *# 3 | *.o 4 | *.a 5 | *.so 6 | *.dylib 7 | *.dSYM 8 | *.dll 9 | *.dummy 10 | /doc 11 | /target 12 | /Cargo.lock 13 | 14 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "harfbuzz-sys/harfbuzz"] 2 | path = harfbuzz-sys/harfbuzz 3 | url = https://github.com/harfbuzz/harfbuzz 4 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Licensed under the Apache License, Version 2.0 or the MIT license 3 | , at your 4 | option. All files in the project carrying such notice may not be 5 | copied, modified, or distributed except according to those terms. 6 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = ["harfbuzz", "harfbuzz-sys", "harfbuzz-traits"] 4 | 5 | [workspace.package] 6 | edition = "2021" 7 | authors = ["The Servo Project Developers"] 8 | license = "MIT OR Apache-2.0" 9 | documentation = "https://docs.rs/harfbuzz/" 10 | keywords = ["opentype", "font", "text", "unicode", "shaping"] 11 | categories = ["text-processing"] 12 | repository = "https://github.com/servo/rust-harfbuzz" 13 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2013 Mozilla Foundation 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rust-harfbuzz 2 | 3 | [![Build Status](https://github.com/servo/rust-harfbuzz/actions/workflows/main.yml/badge.svg)](https://github.com/servo/rust-harfbuzz/actions) 4 | 5 | [Documentation](https://docs.rs/harfbuzz-sys) 6 | 7 | Bindings to the HarfBuzz text shaping engine. 8 | 9 | ## Vendored Harfbuzz Sources 10 | 11 | This repository contains a vendored copy of the `harfbuzz` sources 12 | as a git submodule. If building with the `bundled` feature, be sure 13 | to initialize submodules: 14 | 15 | ``` 16 | git clone --recursive https://github.com/servo/rust-harfbuzz.git 17 | ``` 18 | 19 | Or, after a clone: 20 | 21 | ``` 22 | git submodule update --init 23 | ``` 24 | 25 | ## FreeType Support 26 | 27 | The `freetype` feature is enabled by default. If your system does not have FreeType 28 | or FreeType development packages, which is typically the case for Windows, you can 29 | either disable default features or enable the `freetype-sys/bundled` feature. 30 | -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | doc-valid-idents = ["CoreText", "DirectWrite", "FreeType", "HarfBuzz", "OpenType", ".."] 2 | -------------------------------------------------------------------------------- /harfbuzz-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "harfbuzz-sys" 3 | version = "0.6.1" 4 | readme = "README.md" 5 | categories = ["external-ffi-bindings", "internationalization", "text-processing"] 6 | description = "Rust bindings to the HarfBuzz text shaping engine" 7 | 8 | authors = { workspace = true } 9 | documentation = { workspace = true } 10 | edition = { workspace = true } 11 | keywords = { workspace = true } 12 | license = { workspace = true } 13 | repository = { workspace = true } 14 | 15 | exclude = [ 16 | "harfbuzz/docs/*", 17 | "harfbuzz/subprojects/benchmark-1.5.2/*", 18 | "harfbuzz/test/*", 19 | "update.sh", 20 | ] 21 | 22 | links = "harfbuzz" 23 | build = "build.rs" 24 | 25 | [build-dependencies] 26 | pkg-config = { version = "0.3" } 27 | cc = { version = "1" } 28 | 29 | [target.'cfg(target_vendor = "apple")'.dependencies] 30 | core-graphics = { version = "0.23", optional = true } 31 | core-text = { version = "20", optional = true } 32 | foreign-types = { version = "0.5", optional = true } 33 | 34 | [target.'cfg(target_family = "windows")'.dependencies.windows] 35 | version = "0.59" 36 | optional = true 37 | features = ["Win32_Graphics_DirectWrite"] 38 | 39 | [dependencies.freetype-sys] 40 | version = "0.21.0" 41 | optional = true 42 | 43 | [features] 44 | default = ["coretext", "directwrite", "freetype"] 45 | bundled = [] 46 | coretext = ["dep:core-graphics", "dep:core-text", "dep:foreign-types"] 47 | directwrite = ["dep:windows"] 48 | freetype = ["dep:freetype-sys"] 49 | -------------------------------------------------------------------------------- /harfbuzz-sys/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /harfbuzz-sys/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2013 Mozilla Foundation 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /harfbuzz-sys/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # harfbuzz-sys 4 | 5 | [![Build Status](https://github.com/servo/rust-harfbuzz/actions/workflows/main.yml/badge.svg)](https://github.com/servo/rust-harfbuzz/actions) 6 | [![Crates.io](https://img.shields.io/crates/v/harfbuzz-sys.svg)](https://crates.io/crates/harfbuzz-sys) 7 | [![Docs](https://docs.rs/harfbuzz-sys/badge.svg)](https://docs.rs/harfbuzz-sys) 8 | 9 |
10 | 11 | [HarfBuzz](https://harfbuzz.github.io/) is a text shaping engine. It 12 | solves the problem of selecting and positioning glyphs from a font 13 | given a Unicode string. 14 | 15 | This crate provides low-level bindings to the C API. 16 | 17 | ## Features 18 | 19 | - `freetype` - Enables bindings to the FreeType font engine. (Enabled by default.) 20 | - `coretext` - Enables bindings to the CoreText font engine. (Apple platforms only) (Enabled by default.) 21 | - `directwrite` - Enables bindings to the DirectWrite font engine. (Windows only) (Enabled by default.) 22 | 23 | - `bundled` - Use the bundled copy of the harfbuzz library rather than one installed on the system. 24 | 25 | ## License 26 | 27 | Licensed under either of 28 | 29 | - Apache License, Version 2.0 30 | ([LICENSE-APACHE](LICENSE-APACHE) or ) 31 | - MIT license 32 | ([LICENSE-MIT](LICENSE-MIT) or ) 33 | 34 | at your option. 35 | 36 | ## Contribution 37 | 38 | Contributions are welcome by pull request. 39 | 40 | Unless you explicitly state otherwise, any contribution intentionally submitted 41 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 42 | dual licensed as above, without any additional terms or conditions. -------------------------------------------------------------------------------- /harfbuzz-sys/build.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | fn build_harfbuzz() { 11 | use std::env; 12 | use std::path::PathBuf; 13 | 14 | let target = env::var("TARGET").unwrap(); 15 | 16 | let mut cfg = cc::Build::new(); 17 | cfg.cpp(true) 18 | .flag_if_supported("-std=c++11") // for unix 19 | .warnings(false) 20 | .file("harfbuzz/src/harfbuzz.cc"); 21 | 22 | if !target.contains("windows") { 23 | cfg.define("HAVE_PTHREAD", "1"); 24 | } 25 | 26 | if target.contains("apple") && cfg!(feature = "coretext") { 27 | cfg.define("HAVE_CORETEXT", "1"); 28 | } 29 | 30 | if target.contains("windows") && cfg!(feature = "directwrite") { 31 | cfg.define("HAVE_DIRECTWRITE", "1"); 32 | } 33 | 34 | if target.contains("windows-gnu") { 35 | cfg.flag("-Wa,-mbig-obj"); 36 | } 37 | 38 | cfg.compile("embedded_harfbuzz"); 39 | 40 | let out_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); 41 | 42 | println!( 43 | "cargo:include={}", 44 | out_dir.join("harfbuzz").join("src").display() 45 | ); 46 | } 47 | 48 | fn main() { 49 | if cfg!(feature = "bundled") { 50 | build_harfbuzz(); 51 | } else { 52 | // Use the pre-installed harfbuzz. 53 | pkg_config::probe_library("harfbuzz").unwrap(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /harfbuzz-sys/src/coretext.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | use crate::{hb_face_t, hb_font_t}; 11 | 12 | use core_graphics::font::CGFont; 13 | use core_text::font::CTFontRef; 14 | use foreign_types::ForeignType; 15 | 16 | type CGFontRef = *mut ::CType; 17 | 18 | extern "C" { 19 | /// This requires that the `coretext` feature is enabled. 20 | pub fn hb_coretext_face_create(cg_font: CGFontRef) -> *mut hb_face_t; 21 | /// This requires that the `coretext` feature is enabled. 22 | pub fn hb_coretext_font_create(ct_font: CTFontRef) -> *mut hb_font_t; 23 | /// This requires that the `coretext` feature is enabled. 24 | pub fn hb_coretext_face_get_cg_font(face: *mut hb_face_t) -> CGFontRef; 25 | /// This requires that the `coretext` feature is enabled. 26 | pub fn hb_coretext_font_get_ct_font(font: *mut hb_font_t) -> CTFontRef; 27 | } 28 | -------------------------------------------------------------------------------- /harfbuzz-sys/src/directwrite.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | use crate::hb_face_t; 11 | 12 | use windows::Win32::Graphics::DirectWrite::IDWriteFontFace; 13 | 14 | extern "C" { 15 | /// This requires that the `directwrite` feature is enabled. 16 | pub fn hb_directwrite_face_create(font_face: *mut IDWriteFontFace) -> *mut hb_face_t; 17 | } 18 | -------------------------------------------------------------------------------- /harfbuzz-sys/src/freetype.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | use crate::hb_font_t; 11 | 12 | extern "C" { 13 | /// This requires that the `freetype` feature is enabled. 14 | pub fn hb_ft_font_create_referenced(face: freetype_sys::FT_Face) -> *mut hb_font_t; 15 | } 16 | -------------------------------------------------------------------------------- /harfbuzz-sys/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | //! # harfbuzz-sys 11 | //! 12 | //! This crate provides raw bindings to the [HarfBuzz](https://harfbuzz.github.io/) 13 | //! text shaping library. 14 | //! 15 | //! ## Features 16 | //! 17 | //! - `freetype` - Enables bindings to the FreeType font engine. (Enabled by default.) 18 | //! - `coretext` - Enables bindings to the CoreText font engine. (Apple platforms only) (Enabled by default.) 19 | //! - `directwrite` - Enables bindings to the DirectWrite font engine. (Windows only) (Enabled by default.) 20 | //! 21 | //! - `bundled` - Use the bundled copy of the harfbuzz library rather than one installed on the system. 22 | 23 | #![no_std] 24 | #![warn(clippy::doc_markdown)] 25 | 26 | #[cfg(all(target_vendor = "apple", feature = "coretext"))] 27 | pub mod coretext; 28 | 29 | #[cfg(all(target_family = "windows", feature = "directwrite"))] 30 | pub mod directwrite; 31 | 32 | #[cfg(feature = "freetype")] 33 | pub mod freetype; 34 | 35 | #[allow(non_camel_case_types)] 36 | #[allow(non_snake_case)] 37 | #[allow(non_upper_case_globals)] 38 | #[allow(clippy::unreadable_literal)] 39 | #[allow(rustdoc::bare_urls)] 40 | #[allow(rustdoc::broken_intra_doc_links)] 41 | mod bindings; 42 | 43 | pub use crate::bindings::*; 44 | -------------------------------------------------------------------------------- /harfbuzz-sys/update.sh: -------------------------------------------------------------------------------- 1 | wget https://github.com/harfbuzz/harfbuzz/releases/download/2.7.4/harfbuzz-2.7.4.tar.xz 2 | rm -rf harfbuzz 3 | tar xvf harfbuzz-2.7.4.tar.xz 4 | rm harfbuzz-2.7.4.tar.xz 5 | mv harfbuzz-2.7.4 harfbuzz 6 | bindgen --use-core --no-prepend-enum-name --allowlist-function hb_.\* --allowlist-type hb_.\* wrapper.h | sed 's/ f32/ ::core::ffi::c_float/' | sed 's/u32_/u32/' | sed 's/i32_/i32/' | sed 's/u16_/u16/' | sed 's/i16_/i16/' | sed 's/u8_/u8/' | sed 's/i8_/i8/' >src/bindings.rs 7 | -------------------------------------------------------------------------------- /harfbuzz-sys/wrapper.h: -------------------------------------------------------------------------------- 1 | #include "harfbuzz/src/hb.h" 2 | #include "harfbuzz/src/hb-ot.h" 3 | #include "harfbuzz/src/hb-aat.h" 4 | -------------------------------------------------------------------------------- /harfbuzz-traits/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "harfbuzz-traits" 3 | version = "0.6.0" 4 | description = "Rust traits for the HarfBuzz text shaping engine bindings" 5 | 6 | authors = { workspace = true } 7 | categories = { workspace = true } 8 | documentation = { workspace = true } 9 | edition = { workspace = true } 10 | keywords = { workspace = true } 11 | license = { workspace = true } 12 | repository = { workspace = true } 13 | -------------------------------------------------------------------------------- /harfbuzz-traits/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /harfbuzz-traits/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2013 Mozilla Foundation 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /harfbuzz-traits/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # harfbuzz-traits 4 | 5 | [![Build Status](https://github.com/servo/rust-harfbuzz/actions/workflows/main.yml/badge.svg)](https://github.com/servo/rust-harfbuzz/actions) 6 | [![Crates.io](https://img.shields.io/crates/v/harfbuzz-traits.svg)](https://crates.io/crates/harfbuzz-traits) 7 | [![Docs](https://docs.rs/harfbuzz-traits/badge.svg)](https://docs.rs/harfbuzz-traits) 8 | 9 |
10 | 11 | [HarfBuzz](https://harfbuzz.github.io/) is a text shaping engine. It 12 | solves the problem of selecting and positioning glyphs from a font 13 | given a Unicode string. 14 | 15 | This crate provides high-level Rust traits that can be implemented without 16 | depending on HarfBuzz itself. 17 | 18 | ## License 19 | 20 | Licensed under either of 21 | 22 | - Apache License, Version 2.0 23 | ([LICENSE-APACHE](LICENSE-APACHE) or ) 24 | - MIT license 25 | ([LICENSE-MIT](LICENSE-MIT) or ) 26 | 27 | at your option. 28 | 29 | ## Contribution 30 | 31 | Contributions are welcome by pull request. 32 | 33 | Unless you explicitly state otherwise, any contribution intentionally submitted 34 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 35 | dual licensed as above, without any additional terms or conditions. -------------------------------------------------------------------------------- /harfbuzz-traits/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | //! # harfbuzz-traits 11 | //! 12 | //! This crate provides traits for the `harfbuzz` crate that can be implemented without 13 | //! depending on [HarfBuzz](https://harfbuzz.github.io/) itself. 14 | 15 | #![no_std] 16 | 17 | mod unicode_funcs_traits; 18 | 19 | pub use unicode_funcs_traits::*; 20 | -------------------------------------------------------------------------------- /harfbuzz-traits/src/unicode_funcs_traits.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | /// A general category value. Equivalent to [`hb_unicode_general_category_t`]. 11 | /// 12 | /// [`hb_unicode_general_category_t`]: crate::sys::hb_unicode_general_category_t 13 | #[repr(u8)] 14 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] 15 | #[allow(non_camel_case_types)] // the names are defined by Unicode 16 | #[allow(missing_docs)] // the categories are defined by Unicode 17 | pub enum GeneralCategory { 18 | Control = 0, 19 | Format = 1, 20 | Unassigned = 2, 21 | PrivateUse = 3, 22 | Surrogate = 4, 23 | LowercaseLetter = 5, 24 | ModifierLetter = 6, 25 | OtherLetter = 7, 26 | TitlecaseLetter = 8, 27 | UppercaseLetter = 9, 28 | SpacingMark = 10, 29 | EnclosingMark = 11, 30 | NonSpacingMark = 12, 31 | DecimalNumber = 13, 32 | LetterNumber = 14, 33 | OtherNumber = 15, 34 | ConnectPunctuation = 16, 35 | DashPunctuation = 17, 36 | ClosePunctuation = 18, 37 | FinalPunctuation = 19, 38 | InitialPunctuation = 20, 39 | OtherPunctuation = 21, 40 | OpenPunctuation = 22, 41 | CurrencySymbol = 23, 42 | ModifierSymbol = 24, 43 | MathSymbol = 25, 44 | OtherSymbol = 26, 45 | LineSeparator = 27, 46 | ParagraphSeparator = 28, 47 | SpaceSeparator = 29, 48 | } 49 | 50 | /// An object to map from code points to general category properties. 51 | pub trait GeneralCategoryFunc { 52 | /// Given a code point, return the general category as a [`GeneralCategory`]. 53 | fn general_category(&self, ch: char) -> GeneralCategory; 54 | } 55 | 56 | /// An object to map from code points to combining classes. 57 | pub trait CombiningClassFunc { 58 | /// Given a code point, return the combining class as a `u8` corresponding to a 59 | /// [`hb_unicode_combining_class_t`]. Note that the 60 | /// [Unicode stability policy](https://www.unicode.org/policies/stability_policy.html) 61 | /// guarantees that Canonical Combining Class numeric values fit in a `u8`. 62 | /// 63 | /// [`hb_unicode_combining_class_t`]: crate::sys::hb_unicode_combining_class_t 64 | fn combining_class(&self, ch: char) -> u8; 65 | } 66 | 67 | /// An object to map from code points to mirrored code points. 68 | pub trait MirroringFunc { 69 | /// Given a code point, return the mirrored code point. 70 | fn mirroring(&self, ch: char) -> char; 71 | } 72 | 73 | /// An object to map from code points to script names. 74 | pub trait ScriptFunc { 75 | /// Given a code point, return the script as a 4-byte script name. 76 | fn script(&self, ch: char) -> [u8; 4]; 77 | } 78 | 79 | /// An object to compose two characters. 80 | pub trait ComposeFunc { 81 | /// Given two code points, return the composed code point. 82 | fn compose(&self, a: char, b: char) -> Option; 83 | } 84 | 85 | /// An object to decompose a character. 86 | pub trait DecomposeFunc { 87 | /// Given a code point, return the two decomposed code points. 88 | fn decompose(&self, ab: char) -> Option<(char, char)>; 89 | } 90 | -------------------------------------------------------------------------------- /harfbuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "harfbuzz" 3 | version = "0.6.0" 4 | readme = "README.md" 5 | description = "High-level Rust bindings to the HarfBuzz text shaping engine" 6 | 7 | authors = { workspace = true } 8 | categories = { workspace = true } 9 | documentation = { workspace = true } 10 | edition = { workspace = true } 11 | keywords = { workspace = true } 12 | license = { workspace = true } 13 | repository = { workspace = true } 14 | 15 | [dependencies.harfbuzz-sys] 16 | path = "../harfbuzz-sys" 17 | version = "0.6.1" 18 | default-features = false 19 | 20 | [dependencies.harfbuzz-traits] 21 | path = "../harfbuzz-traits" 22 | version = "0.6.0" 23 | default-features = false 24 | 25 | [features] 26 | default = ["coretext", "directwrite", "freetype", "std"] 27 | bundled = ["harfbuzz-sys/bundled"] 28 | coretext = ["harfbuzz-sys/coretext"] 29 | directwrite = ["harfbuzz-sys/directwrite"] 30 | freetype = ["harfbuzz-sys/freetype"] 31 | std = [] 32 | -------------------------------------------------------------------------------- /harfbuzz/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /harfbuzz/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2013 Mozilla Foundation 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /harfbuzz/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # harfbuzz 4 | 5 | [![Build Status](https://github.com/servo/rust-harfbuzz/actions/workflows/main.yml/badge.svg)](https://github.com/servo/rust-harfbuzz/actions) 6 | [![Crates.io](https://img.shields.io/crates/v/harfbuzz.svg)](https://crates.io/crates/harfbuzz) 7 | [![Docs](https://docs.rs/harfbuzz/badge.svg)](https://docs.rs/harfbuzz) 8 | 9 |
10 | 11 | [HarfBuzz](https://harfbuzz.github.io/) is a text shaping engine. It 12 | solves the problem of selecting and positioning glyphs from a font 13 | given a Unicode string. 14 | 15 | This crate provides a higher level API (than the 16 | [raw C bindings](https://crates.io/crates/harfbuzz-sys)). 17 | 18 | ## Features 19 | 20 | - `freetype` - Enables bindings to the FreeType font engine. (Enabled by default.) 21 | - `coretext` - Enables bindings to the CoreText font engine. (Apple platforms only) (Enabled by default.) 22 | - `directwrite` - Enables bindings to the DirectWrite font engine. (Windows only) (Enabled by default.) 23 | 24 | - `bundled` - Use the bundled copy of the harfbuzz library rather than one installed on the system. 25 | 26 | ## License 27 | 28 | Licensed under either of 29 | 30 | - Apache License, Version 2.0 31 | ([LICENSE-APACHE](LICENSE-APACHE) or ) 32 | - MIT license 33 | ([LICENSE-MIT](LICENSE-MIT) or ) 34 | 35 | at your option. 36 | 37 | ## Contribution 38 | 39 | Contributions are welcome by pull request. 40 | 41 | Unless you explicitly state otherwise, any contribution intentionally submitted 42 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 43 | dual licensed as above, without any additional terms or conditions. -------------------------------------------------------------------------------- /harfbuzz/src/blob.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | use crate::sys; 11 | use core::ffi::{c_char, c_uint}; 12 | use core::marker::PhantomData; 13 | use core::{mem, ops, ptr, slice}; 14 | 15 | #[cfg(feature = "std")] 16 | use std::{ffi::c_void, sync::Arc, vec::Vec}; 17 | 18 | /// Blobs wrap a chunk of binary data to handle lifecycle management of data 19 | /// while it is passed between client and HarfBuzz. 20 | /// 21 | /// Blobs are primarily used to create font faces, but also to access font face 22 | /// tables, as well as pass around other binary data. 23 | pub struct Blob<'a> { 24 | raw: *mut sys::hb_blob_t, 25 | phantom: PhantomData<&'a [u8]>, 26 | } 27 | 28 | impl<'a> Blob<'a> { 29 | /// Create a new read-only blob. 30 | /// 31 | /// The data is not copied, so it must outlive the 32 | /// `Blob`. 33 | /// 34 | /// ``` 35 | /// # use harfbuzz::Blob; 36 | /// let data = vec![1; 256]; 37 | /// let blob = Blob::new_read_only(&data); 38 | /// assert_eq!(blob.len(), 256); 39 | /// assert!(!blob.is_empty()); 40 | /// ``` 41 | pub fn new_read_only(data: &'a [u8]) -> Blob<'a> { 42 | assert!(data.len() <= c_uint::MAX as usize); 43 | unsafe { 44 | Blob::from_raw(sys::hb_blob_create( 45 | data.as_ptr() as *const c_char, 46 | data.len() as c_uint, 47 | sys::HB_MEMORY_MODE_READONLY, 48 | ptr::null_mut(), // user data 49 | None, // destroy callback 50 | )) 51 | } 52 | } 53 | 54 | /// Create a blob wrapping an `Arc>`. 55 | /// 56 | /// This method allows creation of a blob without copying, where the 57 | /// data may be shared by Rust code and the blob. The `Vec` is freed 58 | /// when all references are dropped. 59 | /// 60 | /// ✨ *Enabled with the `std` Cargo feature.* 61 | /// 62 | /// ``` 63 | /// # use std::sync::Arc; 64 | /// # use harfbuzz::Blob; 65 | /// let data = vec![1; 256]; 66 | /// let blob = Blob::new_from_arc_vec(Arc::new(data)); 67 | /// assert_eq!(blob.len(), 256); 68 | /// assert!(!blob.is_empty()); 69 | /// ``` 70 | #[cfg(feature = "std")] 71 | pub fn new_from_arc_vec(data: Arc>) -> Blob<'static> { 72 | let len = data.len(); 73 | assert!(len <= c_uint::MAX as usize); 74 | unsafe { 75 | let data_ptr = data.as_ptr(); 76 | let ptr = Arc::into_raw(data); 77 | 78 | // This has type hb_destroy_func_t 79 | unsafe extern "C" fn arc_vec_blob_destroy(user_data: *mut c_void) { 80 | drop(Arc::from_raw(user_data as *const Vec)); 81 | } 82 | 83 | let hb_blob = sys::hb_blob_create( 84 | data_ptr as *const c_char, 85 | len as c_uint, 86 | sys::HB_MEMORY_MODE_READONLY, 87 | ptr as *mut c_void, 88 | Some(arc_vec_blob_destroy), 89 | ); 90 | Blob::from_raw(hb_blob) 91 | } 92 | } 93 | 94 | /// Construct a `Blob` from a raw pointer. Takes ownership of the blob. 95 | /// 96 | /// # Safety 97 | /// 98 | /// The pointer must be valid and must not be used after this function is called. 99 | pub unsafe fn from_raw(raw: *mut sys::hb_blob_t) -> Self { 100 | Blob { 101 | raw, 102 | phantom: PhantomData, 103 | } 104 | } 105 | 106 | /// Returns the size of the blob in bytes. 107 | pub fn len(&self) -> usize { 108 | unsafe { sys::hb_blob_get_length(self.raw) as usize } 109 | } 110 | 111 | /// Returns true if the length is zero. 112 | pub fn is_empty(&self) -> bool { 113 | self.len() == 0 114 | } 115 | 116 | /// Make this blob immutable. 117 | pub fn make_immutable(&mut self) { 118 | unsafe { 119 | sys::hb_blob_make_immutable(self.raw); 120 | } 121 | } 122 | 123 | /// Returns true if the blob is immutable. 124 | pub fn is_immutable(&self) -> bool { 125 | unsafe { sys::hb_blob_is_immutable(self.raw) != 0 } 126 | } 127 | 128 | /// Borrows a raw pointer to the blob. 129 | pub fn as_raw(&self) -> *mut sys::hb_blob_t { 130 | self.raw 131 | } 132 | 133 | /// Gives up ownership and returns a raw pointer to the blob. 134 | pub fn into_raw(self) -> *mut sys::hb_blob_t { 135 | let raw = self.raw; 136 | mem::forget(self); 137 | raw 138 | } 139 | } 140 | 141 | impl ops::Deref for Blob<'_> { 142 | type Target = [u8]; 143 | 144 | fn deref(&self) -> &[u8] { 145 | unsafe { 146 | let mut len = 0; 147 | let ptr = sys::hb_blob_get_data(self.raw, &mut len); 148 | assert!(!ptr.is_null(), "hb_blob_get_data failed"); 149 | slice::from_raw_parts(ptr as *const u8, len as usize) 150 | } 151 | } 152 | } 153 | 154 | impl ops::DerefMut for Blob<'_> { 155 | fn deref_mut(&mut self) -> &mut [u8] { 156 | unsafe { 157 | let mut len = 0; 158 | let ptr = sys::hb_blob_get_data_writable(self.raw, &mut len); 159 | assert!(!ptr.is_null(), "hb_blob_get_data_writable failed"); 160 | slice::from_raw_parts_mut(ptr as *mut u8, len as usize) 161 | } 162 | } 163 | } 164 | 165 | impl Drop for Blob<'_> { 166 | /// Decrement the reference count, and destroy the blob if the reference count is zero. 167 | fn drop(&mut self) { 168 | unsafe { 169 | sys::hb_blob_destroy(self.raw); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /harfbuzz/src/buffer.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | use crate::sys; 11 | use crate::UnicodeFuncs; 12 | use crate::{Direction, Language}; 13 | 14 | /// A series of Unicode characters. 15 | /// 16 | /// ## Adding Text 17 | /// 18 | /// Since in Rust, a value of type `&str` must contain valid UTF-8 19 | /// text, adding text to a `Buffer` is simple: 20 | /// 21 | /// ``` 22 | /// # use harfbuzz::Buffer; 23 | /// let mut b = Buffer::new(); 24 | /// b.add_str("Hello World"); 25 | /// assert_eq!(b.is_empty(), false); 26 | /// ``` 27 | /// 28 | /// or, more simply: 29 | /// 30 | /// ``` 31 | /// # use harfbuzz::Buffer; 32 | /// let b = Buffer::with("Hello World"); 33 | /// assert_eq!(b.is_empty(), false); 34 | /// ``` 35 | /// 36 | /// ## Segment Properties 37 | /// 38 | /// In addition to the text itself, there are three important properties 39 | /// that influence how a piece of text is shaped: 40 | /// 41 | /// * Direction: The direction in which the output glyphs flow. This is 42 | /// typically left to right or right to left. This is controlled via 43 | /// the [`Buffer::set_direction()`] method. 44 | /// * Script: Script is crucial for choosing the proper shaping behaviour 45 | /// for scripts that require it (e.g. Arabic) and the which OpenType 46 | /// features defined in the font to be applied. This is controlled via 47 | /// the [`Buffer::set_script()`] method. 48 | /// * Language: Languages are crucial for selecting which OpenType feature 49 | /// to apply to the buffer which can result in applying language-specific 50 | /// behaviour. Languages are orthogonal to the scripts, and though they 51 | /// are related, they are different concepts and should not be confused 52 | /// with each other. This is controlled via the [`Buffer::set_language()`] 53 | /// method. 54 | /// 55 | /// Additionally, Harfbuzz can attempt to infer the values for these 56 | /// properties using the [`Buffer::guess_segment_properties()`] method: 57 | /// 58 | /// ``` 59 | /// # use harfbuzz::{Buffer, Direction, sys}; 60 | /// let mut b = Buffer::with("مساء الخير"); 61 | /// b.guess_segment_properties(); 62 | /// assert_eq!(b.get_direction(), Direction::RTL); 63 | /// assert_eq!(b.get_script(), sys::HB_SCRIPT_ARABIC); 64 | /// ``` 65 | pub struct Buffer { 66 | /// The underlying `hb_buffer_t` from the `harfbuzz-sys` crate. 67 | /// 68 | /// This isn't commonly needed unless interfacing directly with 69 | /// functions from the `harfbuzz-sys` crate that haven't been 70 | /// safely exposed. 71 | raw: *mut sys::hb_buffer_t, 72 | } 73 | 74 | impl Buffer { 75 | /// Create a new, empty buffer. 76 | /// 77 | /// ``` 78 | /// # use harfbuzz::Buffer; 79 | /// let b = Buffer::new(); 80 | /// assert!(b.is_empty()); 81 | /// ``` 82 | pub fn new() -> Self { 83 | Buffer::default() 84 | } 85 | 86 | /// Construct a `Buffer` from a raw pointer. Takes ownership of the buffer. 87 | /// 88 | /// # Safety 89 | /// 90 | /// The pointer must be valid and must not be used after this function is called. 91 | pub unsafe fn from_raw(raw: *mut sys::hb_buffer_t) -> Self { 92 | Buffer { raw } 93 | } 94 | 95 | /// Borrows a raw pointer to the buffer. 96 | pub fn as_ptr(&self) -> *mut sys::hb_buffer_t { 97 | self.raw 98 | } 99 | 100 | /// Gives up ownership and returns a raw pointer to the buffer. 101 | pub fn into_raw(self) -> *mut sys::hb_buffer_t { 102 | let raw = self.raw; 103 | core::mem::forget(self); 104 | raw 105 | } 106 | 107 | /// Create a new buffer with the given text. 108 | pub fn with(text: &str) -> Self { 109 | let mut b = Buffer::new(); 110 | b.add_str(text); 111 | b 112 | } 113 | 114 | /// Create a new, empty buffer with the specified capacity. 115 | pub fn with_capacity(capacity: usize) -> Self { 116 | let mut b = Buffer::default(); 117 | b.reserve(capacity); 118 | b 119 | } 120 | 121 | /// Sets a [`UnicodeFuncs`] instance to use with this buffer. 122 | /// 123 | /// Note: `unicode_funcs` is reference counted by HarfBuzz. 124 | pub fn set_unicode_funcs(&mut self, unicode_funcs: &UnicodeFuncs) { 125 | unsafe { sys::hb_buffer_set_unicode_funcs(self.raw, unicode_funcs.as_ptr()) } 126 | } 127 | 128 | /// Add UTF-8 encoded text to the buffer. 129 | pub fn add_str(&mut self, text: &str) { 130 | unsafe { 131 | sys::hb_buffer_add_utf8( 132 | self.raw, 133 | text.as_ptr() as *const core::ffi::c_char, 134 | text.len() as core::ffi::c_int, 135 | 0, 136 | text.len() as core::ffi::c_int, 137 | ); 138 | }; 139 | } 140 | 141 | /// Append part of the contents of another buffer to this one. 142 | /// 143 | /// ``` 144 | /// # use harfbuzz::Buffer; 145 | /// let mut b1 = Buffer::with("butter"); 146 | /// let b2 = Buffer::with("fly"); 147 | /// b1.append(&b2, 0, 3); 148 | /// assert_eq!(b1.len(), "butterfly".len()); 149 | /// ``` 150 | pub fn append(&mut self, other: &Buffer, start: usize, end: usize) { 151 | unsafe { 152 | sys::hb_buffer_append( 153 | self.raw, 154 | other.raw, 155 | start as core::ffi::c_uint, 156 | end as core::ffi::c_uint, 157 | ); 158 | }; 159 | } 160 | 161 | /// Throw away text stored in the buffer, but maintain the 162 | /// currently configured Unicode functions and flags. 163 | /// 164 | /// Text, glyph info, and segment properties will be discarded. 165 | pub fn clear_contents(&mut self) { 166 | unsafe { sys::hb_buffer_clear_contents(self.raw) }; 167 | } 168 | 169 | /// Throw away all data stored in the buffer as well as configuration 170 | /// parameters like Unicode functions, flags, and segment properties. 171 | pub fn reset(&mut self) { 172 | unsafe { sys::hb_buffer_reset(self.raw) }; 173 | } 174 | 175 | /// Preallocate space to fit at least *size* number of items. 176 | /// 177 | /// FIXME: Does this correctly match the expected semantics? 178 | pub fn reserve(&mut self, size: usize) { 179 | unsafe { sys::hb_buffer_pre_allocate(self.raw, size as u32) }; 180 | } 181 | 182 | /// Returns the number of elements in the buffer, also referred to as its 'length'. 183 | pub fn len(&self) -> usize { 184 | unsafe { sys::hb_buffer_get_length(self.raw) as usize } 185 | } 186 | 187 | /// Returns `true` if the buffer contains no data. 188 | pub fn is_empty(&self) -> bool { 189 | self.len() == 0 190 | } 191 | 192 | /// Sets unset buffer segment properties based on buffer Unicode 193 | /// contents. 194 | /// 195 | /// If buffer is not empty, it must have content type 196 | /// `HB_BUFFER_CONTENT_TYPE_UNICODE`. 197 | /// 198 | /// If buffer script is not set (ie. is `HB_SCRIPT_INVALID`), it will 199 | /// be set to the Unicode script of the first character in the buffer 200 | /// that has a script other than `HB_SCRIPT_COMMON`, 201 | /// `HB_SCRIPT_INHERITED`, and `HB_SCRIPT_UNKNOWN`. 202 | /// 203 | /// Next, if buffer direction is not set (ie. is [`Direction::Invalid`]), 204 | /// it will be set to the natural horizontal direction of the buffer 205 | /// script as returned by `hb_script_get_horizontal_direction()`. 206 | /// 207 | /// Finally, if buffer language is not set (ie. is `HB_LANGUAGE_INVALID`), 208 | /// it will be set to the process's default language as returned by 209 | /// [`Language::get_process_default()`]. This may change in the future by 210 | /// taking buffer script into consideration when choosing a language. 211 | /// 212 | /// ``` 213 | /// # use harfbuzz::{Buffer, Direction, sys}; 214 | /// let mut b = Buffer::with("Hello, world!"); 215 | /// b.guess_segment_properties(); 216 | /// assert_eq!(b.get_direction(), Direction::LTR); 217 | /// assert_eq!(b.get_script(), sys::HB_SCRIPT_LATIN); 218 | /// ``` 219 | /// 220 | /// See also: 221 | /// 222 | /// * [`Buffer::get_direction`] 223 | /// * [`Buffer::set_direction`] 224 | /// * [`Buffer::get_script`] 225 | /// * [`Buffer::set_script`] 226 | /// * [`Buffer::get_language`] 227 | /// * [`Buffer::set_language`] 228 | pub fn guess_segment_properties(&mut self) { 229 | unsafe { sys::hb_buffer_guess_segment_properties(self.raw) }; 230 | } 231 | 232 | /// Set the text flow direction of the buffer. 233 | /// 234 | /// No shaping can happen without setting buffer direction, and 235 | /// it controls the visual direction for the output glyphs; for 236 | /// RTL direction the glyphs will be reversed. Many layout features 237 | /// depend on the proper setting of the direction, for example, 238 | /// reversing RTL text before shaping, then shaping with LTR direction 239 | /// is not the same as keeping the text in logical order and shaping 240 | /// with RTL direction. 241 | /// 242 | /// See also: 243 | /// 244 | /// * [`Buffer::get_direction()`] 245 | /// * [`Buffer::guess_segment_properties()`] 246 | pub fn set_direction(&mut self, direction: Direction) { 247 | unsafe { sys::hb_buffer_set_direction(self.raw, direction.into()) }; 248 | } 249 | 250 | /// Get the text flow direction for the buffer. 251 | /// 252 | /// See also: 253 | /// 254 | /// * [`Buffer::set_direction()`] 255 | pub fn get_direction(&self) -> Direction { 256 | (unsafe { sys::hb_buffer_get_direction(self.raw) }).into() 257 | } 258 | 259 | /// Sets the script of buffer to *script*. 260 | /// 261 | /// Script is crucial for choosing the proper shaping behaviour 262 | /// for scripts that require it (e.g. Arabic) and the which 263 | /// OpenType features defined in the font to be applied. 264 | /// 265 | /// See also: 266 | /// 267 | /// * [`Buffer::get_script()`] 268 | /// * [`Buffer::guess_segment_properties()`] 269 | pub fn set_script(&mut self, script: sys::hb_script_t) { 270 | unsafe { sys::hb_buffer_set_script(self.raw, script) }; 271 | } 272 | 273 | /// Get the script for the buffer. 274 | /// 275 | /// See also: 276 | /// 277 | /// * [`Buffer::set_script()`] 278 | pub fn get_script(&self) -> sys::hb_script_t { 279 | unsafe { sys::hb_buffer_get_script(self.raw) } 280 | } 281 | 282 | /// Sets the language of buffer to *language*. 283 | /// 284 | /// Languages are crucial for selecting which OpenType feature 285 | /// to apply to the buffer which can result in applying 286 | /// language-specific behaviour. Languages are orthogonal to 287 | /// the scripts, and though they are related, they are different 288 | /// concepts and should not be confused with each other. 289 | /// 290 | /// See also: 291 | /// 292 | /// * [`Buffer::get_language()`] 293 | /// * [`Buffer::guess_segment_properties()`] 294 | pub fn set_language(&mut self, language: Language) { 295 | unsafe { sys::hb_buffer_set_language(self.raw, language.as_raw()) }; 296 | } 297 | 298 | /// Get the language for the buffer. 299 | /// 300 | /// See also: 301 | /// 302 | /// * [`Buffer::set_language()`] 303 | pub fn get_language(&self) -> Language { 304 | unsafe { Language::from_raw(sys::hb_buffer_get_language(self.raw)) } 305 | } 306 | } 307 | 308 | impl core::fmt::Debug for Buffer { 309 | fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { 310 | fmt.debug_struct("Buffer") 311 | .field("direction", &self.get_direction()) 312 | .field("script", &self.get_script()) 313 | .field("language", &self.get_language()) 314 | .finish() 315 | } 316 | } 317 | 318 | impl Default for Buffer { 319 | /// Create a new, empty buffer. 320 | fn default() -> Self { 321 | Buffer { 322 | raw: unsafe { sys::hb_buffer_create() }, 323 | } 324 | } 325 | } 326 | 327 | impl Drop for Buffer { 328 | fn drop(&mut self) { 329 | unsafe { sys::hb_buffer_destroy(self.raw) } 330 | } 331 | } 332 | -------------------------------------------------------------------------------- /harfbuzz/src/direction.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | use crate::sys; 11 | 12 | /// Direction of text flow during layout. 13 | /// 14 | /// This maps to the [`hb_direction_t`](crate::sys::hb_direction_t) from 15 | /// [`harfbuzz-sys`](crate::sys). It can be converted to 16 | /// or from `hb_direction_t` using the [`From`] 17 | /// and [`Into`] traits: 18 | /// 19 | /// ``` 20 | /// # use harfbuzz::{Direction, sys}; 21 | /// assert_eq!(Direction::from(sys::HB_DIRECTION_LTR), Direction::LTR); 22 | /// assert_eq!(sys::hb_direction_t::from(Direction::BTT), sys::HB_DIRECTION_BTT); 23 | /// 24 | /// let hb_dir: sys::hb_direction_t = Direction::LTR.into(); 25 | /// assert_eq!(hb_dir, sys::HB_DIRECTION_LTR); 26 | /// 27 | /// let dir: Direction = sys::HB_DIRECTION_TTB.into(); 28 | /// assert_eq!(dir, Direction::TTB); 29 | /// ``` 30 | #[derive(Copy, Clone, Debug, PartialEq, PartialOrd)] 31 | pub enum Direction { 32 | /// Initial, unset direction. 33 | /// 34 | /// This corresponds to [`HB_DIRECTION_INVALID`](crate::sys::HB_DIRECTION_INVALID). 35 | Invalid, 36 | /// Text is set horizontally from left to right. 37 | /// 38 | /// This corresponds to [`HB_DIRECTION_LTR`](crate::sys::HB_DIRECTION_LTR). 39 | LTR, 40 | /// Text is set horizontally from right to left. 41 | /// 42 | /// This corresponds to [`HB_DIRECTION_RTL`](crate::sys::HB_DIRECTION_RTL). 43 | RTL, 44 | /// Text is set vertically from top to bottom. 45 | /// 46 | /// This corresponds to [`HB_DIRECTION_TTB`](crate::sys::HB_DIRECTION_TTB). 47 | TTB, 48 | /// Text is set vertically from bottom to top. 49 | /// 50 | /// This corresponds to [`HB_DIRECTION_BTT`](crate::sys::HB_DIRECTION_BTT). 51 | BTT, 52 | } 53 | 54 | impl From for Direction { 55 | fn from(s: sys::hb_direction_t) -> Self { 56 | match s { 57 | sys::HB_DIRECTION_INVALID => Direction::Invalid, 58 | sys::HB_DIRECTION_LTR => Direction::LTR, 59 | sys::HB_DIRECTION_RTL => Direction::RTL, 60 | sys::HB_DIRECTION_TTB => Direction::TTB, 61 | sys::HB_DIRECTION_BTT => Direction::BTT, 62 | _ => Direction::Invalid, 63 | } 64 | } 65 | } 66 | 67 | impl From for sys::hb_direction_t { 68 | fn from(s: Direction) -> Self { 69 | match s { 70 | Direction::Invalid => sys::HB_DIRECTION_INVALID, 71 | Direction::LTR => sys::HB_DIRECTION_LTR, 72 | Direction::RTL => sys::HB_DIRECTION_RTL, 73 | Direction::TTB => sys::HB_DIRECTION_TTB, 74 | Direction::BTT => sys::HB_DIRECTION_BTT, 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /harfbuzz/src/language.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | use crate::sys; 11 | 12 | /// A language tag. 13 | /// 14 | /// This corresponds to a [BCP 47] language tag. 15 | /// 16 | /// This is a wrapper around the [`hb_language_t`] type from the 17 | /// [`harfbuzz-sys`](crate::sys) crate. 18 | /// 19 | /// [`hb_language_t`]: crate::sys::hb_language_t 20 | /// [BCP 47]: https://tools.ietf.org/html/bcp47 21 | #[derive(Copy, Clone, PartialEq, PartialOrd)] 22 | pub struct Language { 23 | /// The underlying `hb_language_t` from the `harfbuzz-sys` crate. 24 | /// 25 | /// This isn't commonly needed unless interfacing directly with 26 | /// functions from the `harfbuzz-sys` crate that haven't been 27 | /// safely exposed. 28 | raw: sys::hb_language_t, 29 | } 30 | 31 | impl Language { 32 | /// Construct a `Language` from a string. 33 | /// 34 | /// The string should be a [BCP 47] language tag. 35 | /// 36 | /// Example: 37 | /// 38 | /// ``` 39 | /// let lang = harfbuzz::Language::from_string("en-US"); 40 | /// assert!(lang.is_valid()); 41 | /// let lang = harfbuzz::Language::from_string("ja"); 42 | /// assert!(lang.is_valid()); 43 | /// let lang = harfbuzz::Language::from_string("zh-Hant"); 44 | /// assert!(lang.is_valid()); 45 | /// let lang = harfbuzz::Language::from_string("sr-Latn-RS"); 46 | /// assert!(lang.is_valid()); 47 | /// let lang = harfbuzz::Language::from_string(""); 48 | /// assert!(!lang.is_valid()); 49 | /// ``` 50 | /// 51 | /// [BCP 47]: https://tools.ietf.org/html/bcp47 52 | pub fn from_string(lang: &str) -> Self { 53 | Language { 54 | raw: unsafe { 55 | sys::hb_language_from_string( 56 | lang.as_ptr() as *const core::ffi::c_char, 57 | lang.len() as core::ffi::c_int, 58 | ) 59 | }, 60 | } 61 | } 62 | 63 | /// Converts the language to a string. 64 | /// 65 | /// Example: 66 | /// ``` 67 | /// let lang = harfbuzz::Language::from_string("en-US"); 68 | /// assert_eq!(lang.to_string(), "en-us"); 69 | /// ``` 70 | pub fn to_string(&self) -> &str { 71 | unsafe { core::ffi::CStr::from_ptr(sys::hb_language_to_string(self.raw)) } 72 | .to_str() 73 | .unwrap() 74 | } 75 | 76 | /// Construct a `Language` from a raw pointer. 77 | /// 78 | /// # Safety 79 | /// 80 | /// The pointer must be a valid pointer. 81 | pub unsafe fn from_raw(raw: sys::hb_language_t) -> Self { 82 | Language { raw } 83 | } 84 | 85 | /// Convert the `Language` to a raw pointer. 86 | /// 87 | /// This is useful for interfacing with functions from the 88 | /// [`harfbuzz-sys`](crate::sys) crate that haven't been safely exposed. 89 | pub fn as_raw(self) -> sys::hb_language_t { 90 | self.raw 91 | } 92 | 93 | /// Returns the default language for the process locale. 94 | /// 95 | /// See [`hb_language_get_default()`] for more information. 96 | /// 97 | /// Example: 98 | /// 99 | /// ``` 100 | /// let lang = harfbuzz::Language::get_process_default(); 101 | /// assert!(lang.is_valid()); 102 | /// ``` 103 | /// 104 | /// [`hb_language_get_default()`]: https://harfbuzz.github.io/harfbuzz-hb-common.html#hb-language-get-default 105 | pub fn get_process_default() -> Self { 106 | Language { 107 | raw: unsafe { sys::hb_language_get_default() }, 108 | } 109 | } 110 | 111 | /// Returns whether or not the language is valid. 112 | /// 113 | /// TODO: This should go away and the constructor should 114 | /// return an `Option`. 115 | pub fn is_valid(self) -> bool { 116 | !self.raw.is_null() 117 | } 118 | } 119 | 120 | impl core::fmt::Debug for Language { 121 | fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { 122 | fmt.write_str(self.to_string()) 123 | } 124 | } 125 | 126 | #[cfg(test)] 127 | mod tests { 128 | use super::Language; 129 | 130 | #[test] 131 | fn test_lookup() { 132 | let en = Language::from_string("en_US"); 133 | assert!(en.is_valid()); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /harfbuzz/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | //! HarfBuzz is a text shaping engine. It solves the problem of selecting 11 | //! and positioning glyphs from a font given a Unicode string. 12 | //! 13 | //! ## Features 14 | //! 15 | //! - `freetype` - Enables bindings to the FreeType font engine. (Enabled by default.) 16 | //! - `coretext` - Enables bindings to the CoreText font engine. (Apple platforms only) (Enabled by default.) 17 | //! - `directwrite` - Enables bindings to the DirectWrite font engine. (Windows only) (Enabled by default.) 18 | //! - `std` - Enable certain functions that require the standard library. (Enabled by default.) 19 | //! 20 | //! - `bundled` - Use the bundled copy of the harfbuzz library rather than one installed on the system. 21 | 22 | #![no_std] 23 | #![warn(clippy::doc_markdown, missing_docs)] 24 | #![deny( 25 | trivial_numeric_casts, 26 | unstable_features, 27 | unused_import_braces, 28 | unused_qualifications 29 | )] 30 | 31 | extern crate alloc; 32 | 33 | #[cfg(feature = "std")] 34 | extern crate std; 35 | 36 | pub use harfbuzz_sys as sys; 37 | pub use harfbuzz_traits as traits; 38 | 39 | /// An error type for this crate 40 | #[derive(Debug)] 41 | pub enum HarfBuzzError { 42 | /// Allocation failed within HarfBuzz itself 43 | Alloc, 44 | } 45 | pub use HarfBuzzError as Error; 46 | 47 | mod buffer; 48 | pub use self::buffer::Buffer; 49 | 50 | mod direction; 51 | pub use self::direction::Direction; 52 | 53 | mod language; 54 | pub use self::language::Language; 55 | 56 | mod blob; 57 | pub use self::blob::Blob; 58 | 59 | mod unicode_funcs; 60 | pub use self::unicode_funcs::{UnicodeFuncs, UnicodeFuncsBuilder}; 61 | 62 | mod version; 63 | pub use self::version::{version, version_atleast, version_string}; 64 | -------------------------------------------------------------------------------- /harfbuzz/src/unicode_funcs.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | use crate::sys::*; 11 | use crate::traits::*; 12 | use crate::Error; 13 | use alloc::boxed::Box; 14 | use core::ffi::c_void; 15 | 16 | /// Converts from `hb_codepoint_t`, assumed to be valid, to `char`. 17 | #[inline] 18 | fn hb_codepoint_t_to_char(input: hb_codepoint_t) -> char { 19 | unsafe { char::from_u32_unchecked(input) } 20 | } 21 | 22 | /// A builder for [`UnicodeFuncs`]. 23 | /// 24 | /// Not all of the functions need to be provided. If a function is missing, 25 | /// the one from the parent will be called, either empty (returning invalid 26 | /// placeholder data) or default (using the built-in Harfbuzz properties). 27 | #[non_exhaustive] 28 | #[derive(Debug)] 29 | pub struct UnicodeFuncsBuilder { 30 | raw: *mut hb_unicode_funcs_t, 31 | } 32 | 33 | impl UnicodeFuncsBuilder { 34 | /// Creates a new, empty builder. 35 | pub fn new_with_empty_parent() -> Result { 36 | let parent = unsafe { hb_unicode_funcs_get_empty() }; 37 | // The HarfBuzz refcounting convention is that "create" 38 | // sets refcount to one, not zero. 39 | // https://harfbuzz.github.io/object-model-lifecycle.html 40 | let ufuncs = unsafe { hb_unicode_funcs_create(parent) }; 41 | if core::ptr::eq(ufuncs, parent) { 42 | return Err(Error::Alloc); 43 | } 44 | Ok(Self { raw: ufuncs }) 45 | } 46 | 47 | /// Creates a new builder with the parent set to the HarfBuzz default. 48 | pub fn new_with_harfbuzz_default_parent() -> Result { 49 | let parent = unsafe { hb_unicode_funcs_get_default() }; 50 | // The HarfBuzz refcounting convention is that "create" 51 | // sets refcount to one, not zero. 52 | // https://harfbuzz.github.io/object-model-lifecycle.html 53 | let ufuncs = unsafe { hb_unicode_funcs_create(parent) }; 54 | if core::ptr::eq(ufuncs, parent) { 55 | return Err(Error::Alloc); 56 | } 57 | Ok(Self { raw: ufuncs }) 58 | } 59 | 60 | /// Sets an implementation of [`hb_unicode_general_category_func_t`]. 61 | pub fn set_general_category_func(&mut self, f: Box) { 62 | let general_category_ptr: *mut F = Box::into_raw(f); 63 | extern "C" fn impl_general_category( 64 | _ufuncs: *mut hb_unicode_funcs_t, 65 | unicode: hb_codepoint_t, 66 | user_data: *mut c_void, 67 | ) -> hb_unicode_general_category_t { 68 | unsafe { &*(user_data as *mut F) }.general_category(hb_codepoint_t_to_char(unicode)) 69 | as hb_unicode_general_category_t 70 | } 71 | extern "C" fn destroy_general_category(user_data: *mut c_void) { 72 | let _ = unsafe { Box::from_raw(user_data as *mut F) }; 73 | } 74 | unsafe { 75 | hb_unicode_funcs_set_general_category_func( 76 | self.raw, 77 | Some(impl_general_category::), 78 | general_category_ptr as *mut c_void, 79 | Some(destroy_general_category::), 80 | ); 81 | } 82 | } 83 | 84 | /// Sets an implementation of [`hb_unicode_combining_class_func_t`]. 85 | pub fn set_combining_class_func(&mut self, f: Box) { 86 | let combining_class_ptr: *mut F = Box::into_raw(f); 87 | extern "C" fn impl_combining_class( 88 | _ufuncs: *mut hb_unicode_funcs_t, 89 | unicode: hb_codepoint_t, 90 | user_data: *mut c_void, 91 | ) -> hb_unicode_combining_class_t { 92 | unsafe { &*(user_data as *mut F) }.combining_class(hb_codepoint_t_to_char(unicode)) 93 | as hb_unicode_combining_class_t 94 | } 95 | extern "C" fn destroy_combining_class(user_data: *mut c_void) { 96 | let _ = unsafe { Box::from_raw(user_data as *mut F) }; 97 | } 98 | unsafe { 99 | hb_unicode_funcs_set_combining_class_func( 100 | self.raw, 101 | Some(impl_combining_class::), 102 | combining_class_ptr as *mut c_void, 103 | Some(destroy_combining_class::), 104 | ); 105 | } 106 | } 107 | 108 | /// Sets an implementation of [`hb_unicode_mirroring_func_t`]. 109 | pub fn set_mirroring_func(&mut self, f: Box) { 110 | let mirroring_ptr: *mut F = Box::into_raw(f); 111 | extern "C" fn impl_mirroring( 112 | _ufuncs: *mut hb_unicode_funcs_t, 113 | unicode: hb_codepoint_t, 114 | user_data: *mut c_void, 115 | ) -> hb_codepoint_t { 116 | unsafe { &*(user_data as *mut F) }.mirroring(hb_codepoint_t_to_char(unicode)) 117 | as hb_codepoint_t 118 | } 119 | extern "C" fn destroy_mirroring(user_data: *mut c_void) { 120 | let _ = unsafe { Box::from_raw(user_data as *mut F) }; 121 | } 122 | unsafe { 123 | hb_unicode_funcs_set_mirroring_func( 124 | self.raw, 125 | Some(impl_mirroring::), 126 | mirroring_ptr as *mut c_void, 127 | Some(destroy_mirroring::), 128 | ); 129 | } 130 | } 131 | 132 | /// Sets an implementation of [`hb_unicode_script_func_t`]. 133 | pub fn set_script_func(&mut self, f: Box) { 134 | let script_ptr: *mut F = Box::into_raw(f); 135 | extern "C" fn impl_script( 136 | _ufuncs: *mut hb_unicode_funcs_t, 137 | unicode: hb_codepoint_t, 138 | user_data: *mut c_void, 139 | ) -> hb_codepoint_t { 140 | let code = unsafe { &*(user_data as *mut F) }.script(hb_codepoint_t_to_char(unicode)); 141 | unsafe { hb_script_from_string(code.as_ptr() as *const i8, 4) } 142 | } 143 | extern "C" fn destroy_script(user_data: *mut c_void) { 144 | let _ = unsafe { Box::from_raw(user_data as *mut F) }; 145 | } 146 | unsafe { 147 | hb_unicode_funcs_set_script_func( 148 | self.raw, 149 | Some(impl_script::), 150 | script_ptr as *mut c_void, 151 | Some(destroy_script::), 152 | ); 153 | } 154 | } 155 | 156 | /// Sets an implementation of [`hb_unicode_compose_func_t`]. 157 | pub fn set_compose_func(&mut self, f: Box) { 158 | let compose_ptr: *mut F = Box::into_raw(f); 159 | extern "C" fn impl_compose( 160 | _ufuncs: *mut hb_unicode_funcs_t, 161 | a: hb_codepoint_t, 162 | b: hb_codepoint_t, 163 | ab: *mut hb_codepoint_t, 164 | user_data: *mut c_void, 165 | ) -> hb_bool_t { 166 | let result = unsafe { &*(user_data as *mut F) } 167 | .compose(hb_codepoint_t_to_char(a), hb_codepoint_t_to_char(b)); 168 | match result { 169 | Some(ab_x) => { 170 | unsafe { *ab = ab_x as hb_codepoint_t }; 171 | true as hb_bool_t 172 | } 173 | None => false as hb_bool_t, 174 | } 175 | } 176 | extern "C" fn destroy_compose(user_data: *mut c_void) { 177 | let _ = unsafe { Box::from_raw(user_data as *mut F) }; 178 | } 179 | unsafe { 180 | hb_unicode_funcs_set_compose_func( 181 | self.raw, 182 | Some(impl_compose::), 183 | compose_ptr as *mut c_void, 184 | Some(destroy_compose::), 185 | ); 186 | } 187 | } 188 | 189 | /// Sets an implementation of [`hb_unicode_decompose_func_t`]. 190 | pub fn set_decompose_func(&mut self, f: Box) { 191 | let decompose_ptr: *mut F = Box::into_raw(f); 192 | extern "C" fn impl_decompose( 193 | _ufuncs: *mut hb_unicode_funcs_t, 194 | ab: hb_codepoint_t, 195 | a: *mut hb_codepoint_t, 196 | b: *mut hb_codepoint_t, 197 | user_data: *mut c_void, 198 | ) -> hb_bool_t { 199 | let result = unsafe { &*(user_data as *mut F) }.decompose(hb_codepoint_t_to_char(ab)); 200 | match result { 201 | Some((a_x, b_x)) => { 202 | unsafe { *a = a_x as hb_codepoint_t }; 203 | unsafe { *b = b_x as hb_codepoint_t }; 204 | true as hb_bool_t 205 | } 206 | None => false as hb_bool_t, 207 | } 208 | } 209 | extern "C" fn destroy_decompose(user_data: *mut c_void) { 210 | let _ = unsafe { Box::from_raw(user_data as *mut F) }; 211 | } 212 | unsafe { 213 | hb_unicode_funcs_set_decompose_func( 214 | self.raw, 215 | Some(impl_decompose::), 216 | decompose_ptr as *mut c_void, 217 | Some(destroy_decompose::), 218 | ); 219 | } 220 | } 221 | 222 | /// Creates a [`UnicodeFuncs`] based on this builder. 223 | pub fn build(self) -> UnicodeFuncs { 224 | let raw = self.raw; 225 | unsafe { 226 | hb_unicode_funcs_make_immutable(raw); 227 | } 228 | core::mem::forget(self); 229 | // Safety: Ownership is being transferred 230 | unsafe { UnicodeFuncs::from_raw(raw) } 231 | } 232 | 233 | /// Takes ownership of a `*mut hb_unicode_funcs_t` without incrementing 234 | /// the refcount. 235 | /// 236 | /// # Safety 237 | /// 238 | /// After the call, the previous owner must not call 239 | /// `hb_unicode_funcs_destroy()`, since `UnicodeFuncs` will now 240 | /// take care of it. 241 | pub unsafe fn from_raw(raw: *mut hb_unicode_funcs_t) -> Self { 242 | Self { raw } 243 | } 244 | 245 | /// Transfers the ownership of the wrapped pointer to the caller. 246 | /// The caller is responsible for calling `hb_unicode_funcs_destroy()`; 247 | /// `UnicodeFuncs` will no longer take care of it. 248 | pub fn into_raw(self) -> *mut hb_unicode_funcs_t { 249 | let ret = self.raw; 250 | core::mem::forget(self); 251 | ret 252 | } 253 | } 254 | 255 | impl Drop for UnicodeFuncsBuilder { 256 | fn drop(&mut self) { 257 | unsafe { 258 | hb_unicode_funcs_destroy(self.raw); 259 | } 260 | } 261 | } 262 | 263 | /// A collection of functions to run Unicode algorithms required by HarfBuzz. 264 | /// 265 | /// Create one of these using a [`UnicodeFuncsBuilder`]. 266 | /// 267 | /// # Example 268 | /// 269 | /// Implementing a custom properties provider for HarfBuzz: 270 | /// 271 | /// ``` 272 | /// # use harfbuzz::{Buffer, Direction, UnicodeFuncsBuilder, sys}; 273 | /// struct PropertyProvider; 274 | /// 275 | /// impl harfbuzz::traits::GeneralCategoryFunc for PropertyProvider { 276 | /// fn general_category(&self, ch: char) -> harfbuzz::traits::GeneralCategory { 277 | /// todo!("GeneralCategoryFunc") 278 | /// } 279 | /// } 280 | /// 281 | /// impl harfbuzz::traits::CombiningClassFunc for PropertyProvider { 282 | /// fn combining_class(&self, ch: char) -> u8 { 283 | /// todo!("CombiningClassFunc") 284 | /// } 285 | /// } 286 | /// 287 | /// impl harfbuzz::traits::MirroringFunc for PropertyProvider { 288 | /// fn mirroring(&self, ch: char) -> char { 289 | /// todo!("MirroringFunc") 290 | /// } 291 | /// } 292 | /// 293 | /// impl harfbuzz::traits::ScriptFunc for PropertyProvider { 294 | /// fn script(&self, ch: char) -> [u8; 4] { 295 | /// debug_assert!(ch as u32 >= 0x0600 && ch as u32 <= 0x06FF); // Arab code points 296 | /// *b"Arab" 297 | /// } 298 | /// } 299 | /// 300 | /// impl harfbuzz::traits::ComposeFunc for PropertyProvider { 301 | /// fn compose(&self, a: char, b:char) -> Option { 302 | /// todo!("ComposeFunc") 303 | /// } 304 | /// } 305 | /// 306 | /// impl harfbuzz::traits::DecomposeFunc for PropertyProvider { 307 | /// fn decompose(&self, ab: char) -> Option<(char, char)> { 308 | /// todo!("DecomposeFunc") 309 | /// } 310 | /// } 311 | /// 312 | /// let mut unicode_funcs = UnicodeFuncsBuilder::new_with_empty_parent().unwrap(); 313 | /// unicode_funcs.set_general_category_func(Box::new(PropertyProvider)); 314 | /// unicode_funcs.set_combining_class_func(Box::new(PropertyProvider)); 315 | /// unicode_funcs.set_mirroring_func(Box::new(PropertyProvider)); 316 | /// unicode_funcs.set_script_func(Box::new(PropertyProvider)); 317 | /// unicode_funcs.set_compose_func(Box::new(PropertyProvider)); 318 | /// unicode_funcs.set_decompose_func(Box::new(PropertyProvider)); 319 | /// let unicode_funcs = unicode_funcs.build(); 320 | /// 321 | /// let mut b = Buffer::with("مساء الخير"); 322 | /// b.set_unicode_funcs(&unicode_funcs); 323 | /// b.guess_segment_properties(); 324 | /// assert_eq!(b.get_direction(), Direction::RTL); 325 | /// assert_eq!(b.get_script(), sys::HB_SCRIPT_ARABIC); 326 | /// ``` 327 | /// 328 | /// Without the provider, the results are unexpected: 329 | /// 330 | /// ``` 331 | /// # use harfbuzz::{Buffer, Direction, UnicodeFuncsBuilder, sys}; 332 | /// 333 | /// let mut unicode_funcs = UnicodeFuncsBuilder::new_with_empty_parent().unwrap(); 334 | /// let unicode_funcs = unicode_funcs.build(); 335 | /// 336 | /// let mut b = Buffer::with("مساء الخير"); 337 | /// b.set_unicode_funcs(&unicode_funcs); 338 | /// b.guess_segment_properties(); 339 | /// assert_eq!(b.get_direction(), Direction::LTR); // WRONG! 340 | /// assert_eq!(b.get_script(), sys::HB_SCRIPT_INVALID); // WRONG! 341 | /// ``` 342 | pub struct UnicodeFuncs { 343 | raw: *mut hb_unicode_funcs_t, 344 | } 345 | 346 | impl UnicodeFuncs { 347 | /// Takes ownership of a `*mut hb_unicode_funcs_t` without incrementing 348 | /// the refcount. 349 | /// 350 | /// # Safety 351 | /// 352 | /// After the call, the previous owner must not call 353 | /// `hb_unicode_funcs_destroy()`, since `UnicodeFuncs` will now 354 | /// take care of it. 355 | pub unsafe fn from_raw(raw: *mut hb_unicode_funcs_t) -> Self { 356 | Self { raw } 357 | } 358 | 359 | /// Transfers the ownership of the wrapped pointer to the caller. 360 | /// The caller is responsible for calling `hb_unicode_funcs_destroy()`; 361 | /// `UnicodeFuncs` will no longer take care of it. 362 | pub fn into_raw(self) -> *mut hb_unicode_funcs_t { 363 | let ret = self.raw; 364 | core::mem::forget(self); 365 | ret 366 | } 367 | 368 | /// Borrows the wrapped raw pointer without transferring ownership 369 | /// and without affecting the refcount. 370 | pub fn as_ptr(&self) -> *mut hb_unicode_funcs_t { 371 | self.raw 372 | } 373 | } 374 | 375 | impl Drop for UnicodeFuncs { 376 | fn drop(&mut self) { 377 | unsafe { 378 | hb_unicode_funcs_destroy(self.raw); 379 | } 380 | } 381 | } 382 | -------------------------------------------------------------------------------- /harfbuzz/src/version.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Servo Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | use crate::sys::{hb_version, hb_version_atleast, hb_version_string}; 11 | 12 | /// Returns the HarfBuzz library version. 13 | /// 14 | /// # Example: 15 | /// 16 | /// ``` 17 | /// let (major, minor, patch) = harfbuzz::version(); 18 | /// println!("HarfBuzz version {}.{}.{}", major, minor, patch); 19 | /// ``` 20 | pub fn version() -> (u32, u32, u32) { 21 | let mut major: u32 = 0; 22 | let mut minor: u32 = 0; 23 | let mut patch: u32 = 0; 24 | unsafe { 25 | hb_version(&mut major, &mut minor, &mut patch); 26 | } 27 | (major, minor, patch) 28 | } 29 | 30 | /// Returns true if the HarfBuzz library version is at least the given version. 31 | /// 32 | /// # Example: 33 | /// 34 | /// ``` 35 | /// assert!(harfbuzz::version_atleast(2, 0, 0)); 36 | /// ``` 37 | pub fn version_atleast(major: u32, minor: u32, patch: u32) -> bool { 38 | unsafe { hb_version_atleast(major, minor, patch) != 0 } 39 | } 40 | 41 | /// Returns the HarfBuzz library version as a string. 42 | /// 43 | /// # Example: 44 | /// 45 | /// ``` 46 | /// println!("HarfBuzz version {}", harfbuzz::version_string()); 47 | /// ``` 48 | pub fn version_string() -> &'static str { 49 | unsafe { core::ffi::CStr::from_ptr(hb_version_string()) } 50 | .to_str() 51 | .unwrap() 52 | } 53 | --------------------------------------------------------------------------------