diff --git a/core-text/.gitignore b/core-text/.gitignore new file mode 100644 index 0000000..c34fbd0 --- /dev/null +++ b/core-text/.gitignore @@ -0,0 +1,14 @@ +*~ +*# +*.o +*.a +*.so +*.dylib +*.dSYM +*.dll +*.dummy +cocoa-test +build +/target +/doc +/Cargo.lock diff --git a/core-text/.travis.yml b/core-text/.travis.yml new file mode 100644 index 0000000..ed3f5dd --- /dev/null +++ b/core-text/.travis.yml @@ -0,0 +1,8 @@ +language: rust +rust: + - nightly + - beta + - stable +os: osx +notifications: + webhooks: http://build.servo.org:54856/travis diff --git a/core-text/COPYRIGHT b/core-text/COPYRIGHT new file mode 100644 index 0000000..8b7291a --- /dev/null +++ b/core-text/COPYRIGHT @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 or the MIT license +, at your +option. All files in the project carrying such notice may not be +copied, modified, or distributed except according to those terms. diff --git a/core-text/Cargo.toml b/core-text/Cargo.toml new file mode 100644 index 0000000..a42bde0 --- /dev/null +++ b/core-text/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "core-text" +version = "9.1.0" +authors = ["The Servo Project Developers"] +description = "Bindings to the Core Text framework." +license = "MIT/Apache-2.0" +repository = "https://github.com/servo/core-text-rs" + +[features] +default = ["mountainlion"] +# For OS X 10.7 compat, exclude this feature. It will exclude some things from +# the exposed APIs in the crate. +mountainlion = [] + +[dependencies] +foreign-types = "0.3" +libc = "0.2" +core-foundation = "0.5" +core-graphics = "0.13" diff --git a/core-text/LICENSE-APACHE b/core-text/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/core-text/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/core-text/LICENSE-MIT b/core-text/LICENSE-MIT new file mode 100644 index 0000000..807526f --- /dev/null +++ b/core-text/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2012-2013 Mozilla Foundation + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/core-text/README.md b/core-text/README.md new file mode 100644 index 0000000..b72bf11 --- /dev/null +++ b/core-text/README.md @@ -0,0 +1,3 @@ +# core-text-rs + +[![Build Status](https://travis-ci.org/servo/core-text-rs.svg?branch=master)](https://travis-ci.org/servo/core-text-rs) diff --git a/core-text/src/font.rs b/core-text/src/font.rs new file mode 100644 index 0000000..79da411 --- /dev/null +++ b/core-text/src/font.rs @@ -0,0 +1,511 @@ +// Copyright 2013 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(non_upper_case_globals)] + +use font_descriptor::{CTFontDescriptor, CTFontDescriptorRef, CTFontOrientation}; +use font_descriptor::{CTFontSymbolicTraits, CTFontTraits, SymbolicTraitAccessors, TraitAccessors}; + +use core_foundation::array::{CFArray, CFArrayRef}; +use core_foundation::base::{CFIndex, CFOptionFlags, CFTypeID, CFTypeRef, TCFType}; +use core_foundation::data::{CFData, CFDataRef}; +use core_foundation::dictionary::CFDictionaryRef; +use core_foundation::string::{CFString, CFStringRef, UniChar}; +use core_foundation::url::{CFURL, CFURLRef}; +use core_graphics::base::CGFloat; +use core_graphics::context::CGContext; +use core_graphics::font::{CGGlyph, CGFont}; +use core_graphics::geometry::{CGAffineTransform, CGPoint, CGRect, CGSize}; +use core_graphics::path::CGPath; + +use foreign_types::ForeignType; +use libc::{self, size_t, c_void}; +use std::ptr; + +type CGContextRef = *mut ::CType; +type CGFontRef = *mut ::CType; +type CGPathRef = *mut ::CType; + +pub type CTFontUIFontType = u32; +// kCTFontNoFontType: CTFontUIFontType = -1; +pub const kCTFontUserFontType: CTFontUIFontType = 0; +pub const kCTFontUserFixedPitchFontType: CTFontUIFontType = 1; +pub const kCTFontSystemFontType: CTFontUIFontType = 2; +pub const kCTFontEmphasizedSystemFontType: CTFontUIFontType = 3; +pub const kCTFontSmallSystemFontType: CTFontUIFontType = 4; +pub const kCTFontSmallEmphasizedSystemFontType: CTFontUIFontType = 5; +pub const kCTFontMiniSystemFontType: CTFontUIFontType = 6; +pub const kCTFontMiniEmphasizedSystemFontType: CTFontUIFontType = 7; +pub const kCTFontViewsFontType: CTFontUIFontType = 8; +pub const kCTFontApplicationFontType: CTFontUIFontType = 9; +pub const kCTFontLabelFontType: CTFontUIFontType = 10; +pub const kCTFontMenuTitleFontType: CTFontUIFontType = 11; +pub const kCTFontMenuItemFontType: CTFontUIFontType = 12; +pub const kCTFontMenuItemMarkFontType: CTFontUIFontType = 13; +pub const kCTFontMenuItemCmdKeyFontType: CTFontUIFontType = 14; +pub const kCTFontWindowTitleFontType: CTFontUIFontType = 15; +pub const kCTFontPushButtonFontType: CTFontUIFontType = 16; +pub const kCTFontUtilityWindowTitleFontType: CTFontUIFontType = 17; +pub const kCTFontAlertHeaderFontType: CTFontUIFontType = 18; +pub const kCTFontSystemDetailFontType: CTFontUIFontType = 19; +pub const kCTFontEmphasizedSystemDetailFontType: CTFontUIFontType = 20; +pub const kCTFontToolbarFontType: CTFontUIFontType = 21; +pub const kCTFontSmallToolbarFontType: CTFontUIFontType = 22; +pub const kCTFontMessageFontType: CTFontUIFontType = 23; +pub const kCTFontPaletteFontType: CTFontUIFontType = 24; +pub const kCTFontToolTipFontType: CTFontUIFontType = 25; +pub const kCTFontControlContentFontType: CTFontUIFontType = 26; + +pub type CTFontTableTag = u32; +// TODO: create bindings for enum with 'chars' values + +pub type CTFontTableOptions = u32; +pub const kCTFontTableOptionsNoOptions: CTFontTableOptions = 0; +pub const kCTFontTableOptionsExcludeSynthetic: CTFontTableOptions = (1 << 0); + +pub type CTFontOptions = CFOptionFlags; +pub const kCTFontOptionsDefault: CTFontOptions = 0; +pub const kCTFontOptionsPreventAutoActivation: CTFontOptions = (1 << 0); +pub const kCTFontOptionsPreferSystemFont: CTFontOptions = (1 << 2); + +#[repr(C)] +pub struct __CTFont(c_void); + +pub type CTFontRef = *const __CTFont; + +declare_TCFType! { + CTFont, CTFontRef +} +impl_TCFType!(CTFont, CTFontRef, CTFontGetTypeID); +impl_CFTypeDescription!(CTFont); + +pub fn new_from_CGFont(cgfont: &CGFont, pt_size: f64) -> CTFont { + unsafe { + let font_ref = CTFontCreateWithGraphicsFont(cgfont.as_ptr() as *mut _, + pt_size as CGFloat, + ptr::null(), + ptr::null()); + CTFont::wrap_under_create_rule(font_ref) + } +} + +pub fn new_from_descriptor(desc: &CTFontDescriptor, pt_size: f64) -> CTFont { + unsafe { + let font_ref = CTFontCreateWithFontDescriptor(desc.as_concrete_TypeRef(), + pt_size as CGFloat, + ptr::null()); + CTFont::wrap_under_create_rule(font_ref) + } +} + +pub fn new_from_name(name: &str, pt_size: f64) -> Result { + unsafe { + let name: CFString = name.parse().unwrap(); + let font_ref = CTFontCreateWithName(name.as_concrete_TypeRef(), + pt_size as CGFloat, + ptr::null()); + if font_ref.is_null() { + Err(()) + } else { + Ok(CTFont::wrap_under_create_rule(font_ref)) + } + } +} + +impl CTFont { + // Properties + pub fn symbolic_traits(&self) -> CTFontSymbolicTraits { + unsafe { + CTFontGetSymbolicTraits(self.0) + } + } +} + +impl CTFont { + // Creation methods + pub fn copy_to_CGFont(&self) -> CGFont { + unsafe { + let cgfont_ref = CTFontCopyGraphicsFont(self.0, ptr::null_mut()); + CGFont::from_ptr(cgfont_ref as *mut _) + } + } + + pub fn clone_with_font_size(&self, size: f64) -> CTFont { + unsafe { + let font_ref = CTFontCreateCopyWithAttributes(self.0, + size as CGFloat, + ptr::null(), + ptr::null()); + CTFont::wrap_under_create_rule(font_ref) + } + } + + // Names + pub fn family_name(&self) -> String { + unsafe { + let value = get_string_by_name_key(self, kCTFontFamilyNameKey); + value.expect("Fonts should always have a family name.") + } + } + + pub fn face_name(&self) -> String { + unsafe { + let value = get_string_by_name_key(self, kCTFontSubFamilyNameKey); + value.expect("Fonts should always have a face name.") + } + } + + pub fn unique_name(&self) -> String { + unsafe { + let value = get_string_by_name_key(self, kCTFontUniqueNameKey); + value.expect("Fonts should always have a unique name.") + } + } + + pub fn postscript_name(&self) -> String { + unsafe { + let value = get_string_by_name_key(self, kCTFontPostScriptNameKey); + value.expect("Fonts should always have a PostScript name.") + } + } + + pub fn all_traits(&self) -> CTFontTraits { + unsafe { + CTFontTraits::wrap_under_create_rule(CTFontCopyTraits(self.0)) + } + } + + // Font metrics + pub fn ascent(&self) -> CGFloat { + unsafe { + CTFontGetAscent(self.0) + } + } + + pub fn descent(&self) -> CGFloat { + unsafe { + CTFontGetDescent(self.0) + } + } + + pub fn underline_thickness(&self) -> CGFloat { + unsafe { + CTFontGetUnderlineThickness(self.0) + } + } + + pub fn underline_position(&self) -> CGFloat { + unsafe { + CTFontGetUnderlinePosition(self.0) + } + } + + pub fn bounding_box(&self) -> CGRect { + unsafe { + CTFontGetBoundingBox(self.0) + } + } + + pub fn leading(&self) -> CGFloat { + unsafe { + CTFontGetLeading(self.0) + } + } + + pub fn units_per_em(&self) -> libc::c_uint { + unsafe { + CTFontGetUnitsPerEm(self.0) + } + } + + pub fn x_height(&self) -> CGFloat { + unsafe { + CTFontGetXHeight(self.0) + } + } + + pub fn pt_size(&self) -> CGFloat { + unsafe { + CTFontGetSize(self.0) + } + } + + pub fn get_glyphs_for_characters(&self, characters: *const UniChar, glyphs: *mut CGGlyph, count: CFIndex) + -> bool { + unsafe { + CTFontGetGlyphsForCharacters(self.0, characters, glyphs, count) + } + } + + pub fn get_advances_for_glyphs(&self, + orientation: CTFontOrientation, + glyphs: *const CGGlyph, + advances: *mut CGSize, + count: CFIndex) + -> f64 { + unsafe { + CTFontGetAdvancesForGlyphs(self.0, orientation, glyphs, advances, count) as f64 + } + } + + pub fn get_font_table(&self, tag: u32) -> Option { + unsafe { + let result = CTFontCopyTable(self.0, + tag as CTFontTableTag, + kCTFontTableOptionsExcludeSynthetic); + if result.is_null() { + None + } else { + Some(CFData::wrap_under_create_rule(result)) + } + } + } + + pub fn get_bounding_rects_for_glyphs(&self, orientation: CTFontOrientation, glyphs: &[CGGlyph]) + -> CGRect { + unsafe { + let result = CTFontGetBoundingRectsForGlyphs(self.as_concrete_TypeRef(), + orientation, + glyphs.as_ptr(), + ptr::null_mut(), + glyphs.len() as CFIndex); + result + } + } + + pub fn draw_glyphs(&self, glyphs: &[CGGlyph], positions: &[CGPoint], context: CGContext) { + assert!(glyphs.len() == positions.len()); + unsafe { + CTFontDrawGlyphs(self.as_concrete_TypeRef(), + glyphs.as_ptr(), + positions.as_ptr(), + glyphs.len() as size_t, + context.as_ptr()) + } + } + + pub fn url(&self) -> Option { + unsafe { + let result = CTFontCopyAttribute(self.0, kCTFontURLAttribute); + if result.is_null() { + None + } else { + Some(CFURL::wrap_under_create_rule(result as CFURLRef)) + } + } + } + + pub fn create_path_for_glyph(&self, glyph: CGGlyph, matrix: &CGAffineTransform) + -> Result { + unsafe { + let path = CTFontCreatePathForGlyph(self.0, glyph, matrix); + if path.is_null() { + Err(()) + } else { + Ok(CGPath::from_ptr(path)) + } + } + } +} + +// Helper methods +fn get_string_by_name_key(font: &CTFont, name_key: CFStringRef) -> Option { + unsafe { + let result = CTFontCopyName(font.as_concrete_TypeRef(), name_key); + if result.is_null() { + None + } else { + Some(CFString::wrap_under_create_rule(result).to_string()) + } + } +} + +pub fn debug_font_names(font: &CTFont) { + fn get_key(font: &CTFont, key: CFStringRef) -> String { + get_string_by_name_key(font, key).unwrap() + } + + unsafe { + println!("kCTFontFamilyNameKey: {}", get_key(font, kCTFontFamilyNameKey)); + println!("kCTFontSubFamilyNameKey: {}", get_key(font, kCTFontSubFamilyNameKey)); + println!("kCTFontStyleNameKey: {}", get_key(font, kCTFontStyleNameKey)); + println!("kCTFontUniqueNameKey: {}", get_key(font, kCTFontUniqueNameKey)); + println!("kCTFontFullNameKey: {}", get_key(font, kCTFontFullNameKey)); + println!("kCTFontPostScriptNameKey: {}", get_key(font, kCTFontPostScriptNameKey)); + } +} + +pub fn debug_font_traits(font: &CTFont) { + let sym = font.symbolic_traits(); + println!("kCTFontItalicTrait: {}", sym.is_italic()); + println!("kCTFontBoldTrait: {}", sym.is_bold()); + println!("kCTFontExpandedTrait: {}", sym.is_expanded()); + println!("kCTFontCondensedTrait: {}", sym.is_condensed()); + println!("kCTFontMonoSpaceTrait: {}", sym.is_monospace()); + + let traits = font.all_traits(); + println!("kCTFontWeightTrait: {}", traits.normalized_weight()); +// println!("kCTFontWidthTrait: {}", traits.normalized_width()); +// println!("kCTFontSlantTrait: {}", traits.normalized_slant()); +} + +#[cfg(feature = "mountainlion")] +pub fn cascade_list_for_languages(font: &CTFont, language_pref_list: &CFArray) -> CFArray { + unsafe { + let font_collection_ref = + CTFontCopyDefaultCascadeListForLanguages(font.as_concrete_TypeRef(), + language_pref_list.as_concrete_TypeRef()); + CFArray::wrap_under_create_rule(font_collection_ref) + } +} + +#[link(name = "CoreText", kind = "framework")] +extern { + /* + * CTFont.h + */ + + /* Name Specifier Constants */ + //static kCTFontCopyrightNameKey: CFStringRef; + static kCTFontFamilyNameKey: CFStringRef; + static kCTFontSubFamilyNameKey: CFStringRef; + static kCTFontStyleNameKey: CFStringRef; + static kCTFontUniqueNameKey: CFStringRef; + static kCTFontFullNameKey: CFStringRef; + //static kCTFontVersionNameKey: CFStringRef; + static kCTFontPostScriptNameKey: CFStringRef; + //static kCTFontTrademarkNameKey: CFStringRef; + //static kCTFontManufacturerNameKey: CFStringRef; + //static kCTFontDesignerNameKey: CFStringRef; + //static kCTFontDescriptionNameKey: CFStringRef; + //static kCTFontVendorURLNameKey: CFStringRef; + //static kCTFontDesignerURLNameKey: CFStringRef; + //static kCTFontLicenseNameKey: CFStringRef; + //static kCTFontLicenseURLNameKey: CFStringRef; + //static kCTFontSampleTextNameKey: CFStringRef; + //static kCTFontPostScriptCIDNameKey: CFStringRef; + + //static kCTFontVariationAxisIdentifierKey: CFStringRef; + //static kCTFontVariationAxisMinimumValueKey: CFStringRef; + //static kCTFontVariationAxisMaximumValueKey: CFStringRef; + //static kCTFontVariationAxisDefaultValueKey: CFStringRef; + //static kCTFontVariationAxisNameKey: CFStringRef; + + //static kCTFontFeatureTypeIdentifierKey: CFStringRef; + //static kCTFontFeatureTypeNameKey: CFStringRef; + //static kCTFontFeatureTypeExclusiveKey: CFStringRef; + //static kCTFontFeatureTypeSelectorsKey: CFStringRef; + //static kCTFontFeatureSelectorIdentifierKey: CFStringRef; + //static kCTFontFeatureSelectorNameKey: CFStringRef; + //static kCTFontFeatureSelectorDefaultKey: CFStringRef; + //static kCTFontFeatureSelectorSettingKey: CFStringRef; + + static kCTFontURLAttribute: CFStringRef; + + // N.B. Unlike most Cocoa bindings, this extern block is organized according + // to the documentation's Functions By Task listing, because there so many functions. + + /* Creating Fonts */ + fn CTFontCreateWithName(name: CFStringRef, size: CGFloat, matrix: *const CGAffineTransform) -> CTFontRef; + //fn CTFontCreateWithNameAndOptions + fn CTFontCreateWithFontDescriptor(descriptor: CTFontDescriptorRef, size: CGFloat, + matrix: *const CGAffineTransform) -> CTFontRef; + //fn CTFontCreateWithFontDescriptorAndOptions + //fn CTFontCreateUIFontForLanguage + fn CTFontCreateCopyWithAttributes(font: CTFontRef, size: CGFloat, matrix: *const CGAffineTransform, + attributes: CTFontDescriptorRef) -> CTFontRef; + //fn CTFontCreateCopyWithSymbolicTraits + //fn CTFontCreateCopyWithFamily + //fn CTFontCreateForString + + /* Getting Font Data */ + //fn CTFontCopyFontDescriptor(font: CTFontRef) -> CTFontDescriptorRef; + fn CTFontCopyAttribute(font: CTFontRef, attribute: CFStringRef) -> CFTypeRef; + fn CTFontGetSize(font: CTFontRef) -> CGFloat; + //fn CTFontGetMatrix + fn CTFontGetSymbolicTraits(font: CTFontRef) -> CTFontSymbolicTraits; + fn CTFontCopyTraits(font: CTFontRef) -> CFDictionaryRef; + + /* Getting Font Names */ + //fn CTFontCopyPostScriptName(font: CTFontRef) -> CFStringRef; + //fn CTFontCopyFamilyName(font: CTFontRef) -> CFStringRef; + //fn CTFontCopyFullName(font: CTFontRef) -> CFStringRef; + //fn CTFontCopyDisplayName(font: CTFontRef) -> CFStringRef; + fn CTFontCopyName(font: CTFontRef, nameKey: CFStringRef) -> CFStringRef; + //fn CTFontCopyLocalizedName(font: CTFontRef, nameKey: CFStringRef, + // language: *CFStringRef) -> CFStringRef; + #[cfg(feature = "mountainlion")] + fn CTFontCopyDefaultCascadeListForLanguages(font: CTFontRef, languagePrefList: CFArrayRef) -> CFArrayRef; + + + /* Working With Encoding */ + //fn CTFontCopyCharacterSet + //fn CTFontGetStringEncoding + //fn CTFontCopySupportedLanguages + + /* Getting Font Metrics */ + fn CTFontGetAscent(font: CTFontRef) -> CGFloat; + fn CTFontGetDescent(font: CTFontRef) -> CGFloat; + fn CTFontGetLeading(font: CTFontRef) -> CGFloat; + fn CTFontGetUnitsPerEm(font: CTFontRef) -> libc::c_uint; + //fn CTFontGetGlyphCount + fn CTFontGetBoundingBox(font: CTFontRef) -> CGRect; + fn CTFontGetUnderlinePosition(font: CTFontRef) -> CGFloat; + fn CTFontGetUnderlineThickness(font: CTFontRef) -> CGFloat; + //fn CTFontGetSlantAngle + //fn CTFontGetCapHeight + fn CTFontGetXHeight(font: CTFontRef) -> CGFloat; + + /* Getting Glyph Data */ + fn CTFontCreatePathForGlyph(font: CTFontRef, glyph: CGGlyph, matrix: *const CGAffineTransform) + -> CGPathRef; + //fn CTFontGetGlyphWithName + fn CTFontGetBoundingRectsForGlyphs(font: CTFontRef, + orientation: CTFontOrientation, + glyphs: *const CGGlyph, + boundingRects: *mut CGRect, + count: CFIndex) + -> CGRect; + fn CTFontGetAdvancesForGlyphs(font: CTFontRef, orientation: CTFontOrientation, glyphs: *const CGGlyph, advances: *mut CGSize, count: CFIndex) -> libc::c_double; + //fn CTFontGetVerticalTranslationsForGlyphs + + /* Working With Font Variations */ + //fn CTFontCopyVariationAxes + //fn CTFontCopyVariation + + /* Getting Font Features */ + //fn CTFontCopyFeatures + //fn CTFontCopyFeatureSettings + + /* Working with Glyphs */ + fn CTFontGetGlyphsForCharacters(font: CTFontRef, characters: *const UniChar, glyphs: *mut CGGlyph, count: CFIndex) -> bool; + fn CTFontDrawGlyphs(font: CTFontRef, + glyphs: *const CGGlyph, + positions: *const CGPoint, + count: size_t, + context: CGContextRef); + //fn CTFontGetLigatureCaretPositions + + /* Converting Fonts */ + fn CTFontCopyGraphicsFont(font: CTFontRef, attributes: *mut CTFontDescriptorRef) + -> CGFontRef; + fn CTFontCreateWithGraphicsFont(graphicsFont: CGFontRef, size: CGFloat, + matrix: *const CGAffineTransform, + attributes: CTFontDescriptorRef) -> CTFontRef; + //fn CTFontGetPlatformFont + //fn CTFontCreateWithPlatformFont + //fn CTFontCreateWithQuickdrawInstance + + /* Getting Font Table Data */ + //fn CTFontCopyAvailableTables(font: CTFontRef, options: CTFontTableOptions) -> CFArrayRef; + fn CTFontCopyTable(font: CTFontRef, table: CTFontTableTag, options: CTFontTableOptions) -> CFDataRef; + + fn CTFontGetTypeID() -> CFTypeID; +} + diff --git a/core-text/src/font_collection.rs b/core-text/src/font_collection.rs new file mode 100644 index 0000000..e1c550e --- /dev/null +++ b/core-text/src/font_collection.rs @@ -0,0 +1,120 @@ +// Copyright 2013 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use font_descriptor; +use font_descriptor::{CTFontDescriptor, CTFontDescriptorCreateMatchingFontDescriptors}; +use font_manager::CTFontManagerCopyAvailableFontFamilyNames; + +use core_foundation::array::{CFArray, CFArrayRef}; +use core_foundation::base::{CFTypeID, TCFType}; +use core_foundation::dictionary::{CFDictionary, CFDictionaryRef}; +use core_foundation::number::CFNumber; +use core_foundation::set::CFSet; +use core_foundation::string::{CFString, CFStringRef}; + +use libc::c_void; +use std::ptr; + +#[repr(C)] +pub struct __CTFontCollection(c_void); + +pub type CTFontCollectionRef = *const __CTFontCollection; + +declare_TCFType! { + CTFontCollection, CTFontCollectionRef +} +impl_TCFType!(CTFontCollection, CTFontCollectionRef, CTFontCollectionGetTypeID); +impl_CFTypeDescription!(CTFontCollection); + + +impl CTFontCollection { + pub fn get_descriptors(&self) -> CFArray { + // surprise! this function follows the Get rule, despite being named *Create*. + // So we have to addRef it to avoid CTFontCollection from double freeing it later. + unsafe { + CFArray::wrap_under_get_rule(CTFontCollectionCreateMatchingFontDescriptors(self.0)) + } + } +} + +pub fn new_from_descriptors(descs: &CFArray) -> CTFontCollection { + unsafe { + let key = CFString::wrap_under_get_rule(kCTFontCollectionRemoveDuplicatesOption); + let value = CFNumber::from(1i64); + let options = CFDictionary::from_CFType_pairs(&[ (key.as_CFType(), value.as_CFType()) ]); + let font_collection_ref = + CTFontCollectionCreateWithFontDescriptors(descs.as_concrete_TypeRef(), + options.as_concrete_TypeRef()); + CTFontCollection::wrap_under_create_rule(font_collection_ref) + } +} + +pub fn create_for_all_families() -> CTFontCollection { + unsafe { + let key = CFString::wrap_under_get_rule(kCTFontCollectionRemoveDuplicatesOption); + let value = CFNumber::from(1i64); + let options = CFDictionary::from_CFType_pairs(&[ (key.as_CFType(), value.as_CFType()) ]); + let font_collection_ref = + CTFontCollectionCreateFromAvailableFonts(options.as_concrete_TypeRef()); + CTFontCollection::wrap_under_create_rule(font_collection_ref) + } +} + +pub fn create_for_family(family: &str) -> Option { + use font_descriptor::kCTFontFamilyNameAttribute; + + unsafe { + let family_attr = CFString::wrap_under_get_rule(kCTFontFamilyNameAttribute); + let family_name: CFString = family.parse().unwrap(); + let specified_attrs = CFDictionary::from_CFType_pairs(&[ + (family_attr.as_CFType(), family_name.as_CFType()) + ]); + + let wildcard_desc: CTFontDescriptor = + font_descriptor::new_from_attributes(&specified_attrs); + let mandatory_attrs = CFSet::from_slice(&[ family_attr.as_CFType() ]); + let matched_descs = CTFontDescriptorCreateMatchingFontDescriptors( + wildcard_desc.as_concrete_TypeRef(), + mandatory_attrs.as_concrete_TypeRef()); + if matched_descs == ptr::null() { + return None; + } + let matched_descs = CFArray::wrap_under_create_rule(matched_descs); + // I suppose one doesn't even need the CTFontCollection object at this point. + // But we stick descriptors into and out of it just to provide a nice wrapper API. + Some(new_from_descriptors(&matched_descs)) + } +} + +pub fn get_family_names() -> CFArray { + unsafe { + CFArray::wrap_under_create_rule(CTFontManagerCopyAvailableFontFamilyNames()) + } +} + +extern { + /* + * CTFontCollection.h + */ + + static kCTFontCollectionRemoveDuplicatesOption: CFStringRef; + + //fn CTFontCollectionCreateCopyWithFontDescriptors(original: CTFontCollectionRef, + // descriptors: CFArrayRef, + // options: CFDictionaryRef) -> CTFontCollectionRef; + fn CTFontCollectionCreateFromAvailableFonts(options: CFDictionaryRef) -> CTFontCollectionRef; + // this stupid function doesn't actually do any wildcard expansion; + // it just chooses the best match. Use + // CTFontDescriptorCreateMatchingDescriptors instead. + fn CTFontCollectionCreateMatchingFontDescriptors(collection: CTFontCollectionRef) -> CFArrayRef; + fn CTFontCollectionCreateWithFontDescriptors(descriptors: CFArrayRef, + options: CFDictionaryRef) -> CTFontCollectionRef; + //fn CTFontCollectionCreateMatchingFontDescriptorsSortedWithCallback; + fn CTFontCollectionGetTypeID() -> CFTypeID; +} diff --git a/core-text/src/font_descriptor.rs b/core-text/src/font_descriptor.rs new file mode 100644 index 0000000..9ae9680 --- /dev/null +++ b/core-text/src/font_descriptor.rs @@ -0,0 +1,354 @@ +// Copyright 2013 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(non_upper_case_globals)] + +use core_foundation::array::CFArrayRef; +use core_foundation::base::{CFType, CFTypeID, CFTypeRef, TCFType}; +use core_foundation::dictionary::{CFDictionary, CFDictionaryRef}; +use core_foundation::number::{CFNumber, CFNumberRef}; +use core_foundation::set::CFSetRef; +use core_foundation::string::{CFString, CFStringRef}; +use core_foundation::url::{CFURLCopyFileSystemPath, kCFURLPOSIXPathStyle, CFURL}; +use core_graphics::base::CGFloat; + +use libc::c_void; +use std::mem; + +/* +* CTFontTraits.h +*/ +// actually, these are extern enums +pub type CTFontFormat = u32; +pub const kCTFontFormatUnrecognized: CTFontFormat = 0; +pub const kCTFontFormatOpenTypePostScript: CTFontFormat = 1; +pub const kCTFontFormatOpenTypeTrueType: CTFontFormat = 2; +pub const kCTFontFormatTrueType: CTFontFormat = 3; +pub const kCTFontFormatPostScript: CTFontFormat = 4; +pub const kCTFontFormatBitmap: CTFontFormat = 5; + +pub const kCTFontClassMaskShift: u32 = 28; + +pub type CTFontSymbolicTraits = u32; +pub const kCTFontItalicTrait: CTFontSymbolicTraits = (1 << 0); +pub const kCTFontBoldTrait: CTFontSymbolicTraits = (1 << 1); +pub const kCTFontExpandedTrait: CTFontSymbolicTraits = (1 << 5); +pub const kCTFontCondensedTrait: CTFontSymbolicTraits = (1 << 6); +pub const kCTFontMonoSpaceTrait: CTFontSymbolicTraits = (1 << 10); +pub const kCTFontVerticalTrait: CTFontSymbolicTraits = (1 << 11); +pub const kCTFontUIOptimizedTrait: CTFontSymbolicTraits = (1 << 12); +pub const kCTFontColorGlyphsTrait: CTFontSymbolicTraits = (1 << 13); +pub const kCTFontClassMaskTrait: CTFontSymbolicTraits = (15 << kCTFontClassMaskShift ); + +pub trait SymbolicTraitAccessors { + fn is_italic(&self) -> bool; + fn is_bold(&self) -> bool; + fn is_expanded(&self) -> bool; + fn is_condensed(&self) -> bool; + fn is_monospace(&self) -> bool; +} + +impl SymbolicTraitAccessors for CTFontSymbolicTraits { + fn is_italic(&self) -> bool { (*self & kCTFontItalicTrait) != 0 } + fn is_bold(&self) -> bool { (*self & kCTFontBoldTrait) != 0 } + fn is_expanded(&self) -> bool { (*self & kCTFontExpandedTrait) != 0 } + fn is_condensed(&self) -> bool { (*self & kCTFontCondensedTrait) != 0 } + fn is_monospace(&self) -> bool { (*self & kCTFontMonoSpaceTrait) != 0 } +} + +pub type CTFontStylisticClass = u32; +pub const kCTFontUnknownClass: CTFontStylisticClass = (0 << kCTFontClassMaskShift ); +pub const kCTFontOldStyleSerifsClass: CTFontStylisticClass = (1 << kCTFontClassMaskShift ); +pub const kCTFontTransitionalSerifsClass: CTFontStylisticClass = (2 << kCTFontClassMaskShift ); +pub const kCTFontModernSerifsClass: CTFontStylisticClass = (3 << kCTFontClassMaskShift ); +pub const kCTFontClarendonSerifsClass: CTFontStylisticClass = (4 << kCTFontClassMaskShift ); +pub const kCTFontSlabSerifsClass: CTFontStylisticClass = (5 << kCTFontClassMaskShift ); +pub const kCTFontFreeformSerifsClass: CTFontStylisticClass = (7 << kCTFontClassMaskShift ); +pub const kCTFontSansSerifClass: CTFontStylisticClass = (8 << kCTFontClassMaskShift ); +pub const kCTFontOrnamentalsClass: CTFontStylisticClass = (9 << kCTFontClassMaskShift ); +pub const kCTFontScriptsClass: CTFontStylisticClass = (10 << kCTFontClassMaskShift ); +pub const kCTFontSymbolicClass: CTFontStylisticClass = (12 << kCTFontClassMaskShift ); + +pub trait StylisticClassAccessors { + fn is_serif(&self) -> bool; + fn is_sans_serif(&self) -> bool; + fn is_script(&self) -> bool; + fn is_fantasy(&self) -> bool; + fn is_symbols(&self) -> bool; +} + +impl StylisticClassAccessors for CTFontStylisticClass { + fn is_serif(&self) -> bool { + let any_serif_class = kCTFontOldStyleSerifsClass + | kCTFontTransitionalSerifsClass + | kCTFontModernSerifsClass + | kCTFontClarendonSerifsClass + | kCTFontSlabSerifsClass + | kCTFontFreeformSerifsClass; + + return (*self & any_serif_class) != 0; + } + + fn is_sans_serif(&self) -> bool { + return (*self & kCTFontSansSerifClass) != 0; + } + + fn is_script(&self) -> bool { + return (*self & kCTFontScriptsClass) != 0; + } + + fn is_fantasy(&self) -> bool { + return (*self & kCTFontOrnamentalsClass) != 0; + } + + fn is_symbols(&self) -> bool { + return (*self & kCTFontSymbolicClass) != 0; + } +} + +pub type CTFontAttributes = CFDictionary; + +pub type CTFontTraits = CFDictionary; + +pub trait TraitAccessors { + fn symbolic_traits(&self) -> CTFontSymbolicTraits; + fn normalized_weight(&self) -> f64; + fn normalized_width(&self) -> f64; + fn normalized_slant(&self) -> f64; +} + +trait TraitAccessorPrivate { + unsafe fn extract_number_for_key(&self, key: CFStringRef) -> CFNumber; +} + +impl TraitAccessorPrivate for CTFontTraits { + unsafe fn extract_number_for_key(&self, key: CFStringRef) -> CFNumber { + let cftype = self.get_CFType(mem::transmute(key)); + assert!(cftype.instance_of::()); + CFNumber::wrap_under_get_rule(mem::transmute(cftype.as_CFTypeRef())) + } + +} + +impl TraitAccessors for CTFontTraits { + fn symbolic_traits(&self) -> CTFontSymbolicTraits { + unsafe { + let number = self.extract_number_for_key(kCTFontSymbolicTrait); + number.to_i64().unwrap() as u32 + } + } + + fn normalized_weight(&self) -> f64 { + unsafe { + let number = self.extract_number_for_key(kCTFontWeightTrait); + number.to_f64().unwrap() + } + } + + fn normalized_width(&self) -> f64 { + unsafe { + let number = self.extract_number_for_key(kCTFontWidthTrait); + number.to_f64().unwrap() + } + } + + fn normalized_slant(&self) -> f64 { + unsafe { + let number = self.extract_number_for_key(kCTFontSlantTrait); + number.to_f64().unwrap() + } + } +} + +/* +* CTFontDescriptor.h +*/ +pub type CTFontOrientation = u32; +pub const kCTFontDefaultOrientation: CTFontOrientation = 0; +pub const kCTFontHorizontalOrientation: CTFontOrientation = 1; +pub const kCTFontVerticalOrientation: CTFontOrientation = 2; + +pub type CTFontPriority = u32; +pub const kCTFontPrioritySystem: CTFontPriority = 10000; +pub const kCTFontPriorityNetwork: CTFontPriority = 20000; +pub const kCTFontPriorityComputer: CTFontPriority = 30000; +pub const kCTFontPriorityUser: CTFontPriority = 40000; +pub const kCTFontPriorityDynamic: CTFontPriority = 50000; +pub const kCTFontPriorityProcess: CTFontPriority = 60000; + +#[repr(C)] +pub struct __CTFontDescriptor(c_void); + +pub type CTFontDescriptorRef = *const __CTFontDescriptor; + +declare_TCFType! { + CTFontDescriptor, CTFontDescriptorRef +} +impl_TCFType!(CTFontDescriptor, CTFontDescriptorRef, CTFontDescriptorGetTypeID); +impl_CFTypeDescription!(CTFontDescriptor); + + +impl CTFontDescriptor { + fn get_string_attribute(&self, attribute: CFStringRef) -> Option { + unsafe { + let value = CTFontDescriptorCopyAttribute(self.0, attribute); + if value.is_null() { + return None + } + + let value = CFType::wrap_under_create_rule(value); + assert!(value.instance_of::()); + let s = CFString::wrap_under_get_rule(mem::transmute(value.as_CFTypeRef())); + Some(s.to_string()) + } + } + +} + +impl CTFontDescriptor { + pub fn family_name(&self) -> String { + unsafe { + let value = self.get_string_attribute(kCTFontFamilyNameAttribute); + value.expect("A font must have a non-null family name.") + } + } + + pub fn font_name(&self) -> String { + unsafe { + let value = self.get_string_attribute(kCTFontNameAttribute); + value.expect("A font must have a non-null name.") + } + } + + pub fn style_name(&self) -> String { + unsafe { + let value = self.get_string_attribute(kCTFontStyleNameAttribute); + value.expect("A font must have a non-null style name.") + } + } + + pub fn display_name(&self) -> String { + unsafe { + let value = self.get_string_attribute(kCTFontDisplayNameAttribute); + value.expect("A font must have a non-null display name.") + } + } + + pub fn font_path(&self) -> Option { + unsafe { + let value = CTFontDescriptorCopyAttribute(self.0, kCTFontURLAttribute); + if value.is_null() { + return None; + } + + let value = CFType::wrap_under_create_rule(value); + assert!(value.instance_of::()); + let url = CFURL::wrap_under_get_rule(mem::transmute(value.as_CFTypeRef())); + let path = CFString::wrap_under_create_rule(CFURLCopyFileSystemPath( + url.as_concrete_TypeRef(), + kCFURLPOSIXPathStyle, + )).to_string(); + Some(path) + } + } + + pub fn traits(&self) -> CTFontTraits { + unsafe { + let value = CTFontDescriptorCopyAttribute(self.0, kCTFontTraitsAttribute); + assert!(!value.is_null()); + let value = CFType::wrap_under_create_rule(value); + assert!(value.instance_of::()); + CFDictionary::wrap_under_get_rule(mem::transmute(value.as_CFTypeRef())) + } + } +} + +pub fn new_from_attributes(attributes: &CFDictionary) -> CTFontDescriptor { + unsafe { + let result: CTFontDescriptorRef = + CTFontDescriptorCreateWithAttributes(attributes.as_concrete_TypeRef()); + CTFontDescriptor::wrap_under_create_rule(result) + } +} + +pub fn debug_descriptor(desc: &CTFontDescriptor) { + println!("family: {}", desc.family_name()); + println!("name: {}", desc.font_name()); + println!("style: {}", desc.style_name()); + println!("display: {}", desc.display_name()); + println!("path: {:?}", desc.font_path()); + desc.show(); +} + +extern { + /* + * CTFontTraits.h + */ + + // font trait constants + pub static kCTFontSymbolicTrait: CFStringRef; + pub static kCTFontWeightTrait: CFStringRef; + pub static kCTFontWidthTrait: CFStringRef; + pub static kCTFontSlantTrait: CFStringRef; + + /* + * CTFontDescriptor.h + */ + + // font attribute constants. Note that the name-related attributes + // here are somewhat flaky. Servo creates CTFont instances and + // then uses CTFontCopyName to get more fine-grained names. + pub static kCTFontURLAttribute: CFStringRef; // value: CFURLRef + pub static kCTFontNameAttribute: CFStringRef; // value: CFStringRef + pub static kCTFontDisplayNameAttribute: CFStringRef; // value: CFStringRef + pub static kCTFontFamilyNameAttribute: CFStringRef; // value: CFStringRef + pub static kCTFontStyleNameAttribute: CFStringRef; // value: CFStringRef + pub static kCTFontTraitsAttribute: CFStringRef; + pub static kCTFontVariationAttribute: CFStringRef; + pub static kCTFontSizeAttribute: CFStringRef; + pub static kCTFontMatrixAttribute: CFStringRef; + pub static kCTFontCascadeListAttribute: CFStringRef; + pub static kCTFontCharacterSetAttribute: CFStringRef; + pub static kCTFontLanguagesAttribute: CFStringRef; + pub static kCTFontBaselineAdjustAttribute: CFStringRef; + pub static kCTFontMacintoshEncodingsAttribute: CFStringRef; + pub static kCTFontFeaturesAttribute: CFStringRef; + pub static kCTFontFeatureSettingsAttribute: CFStringRef; + pub static kCTFontFixedAdvanceAttribute: CFStringRef; + pub static kCTFontOrientationAttribute: CFStringRef; + pub static kCTFontFormatAttribute: CFStringRef; + pub static kCTFontRegistrationScopeAttribute: CFStringRef; + pub static kCTFontPriorityAttribute: CFStringRef; + pub static kCTFontEnabledAttribute: CFStringRef; + + pub fn CTFontDescriptorCopyAttribute(descriptor: CTFontDescriptorRef, + attribute: CFStringRef) -> CFTypeRef; + pub fn CTFontDescriptorCopyAttributes(descriptor: CTFontDescriptorRef) -> CFDictionaryRef; + pub fn CTFontDescriptorCopyLocalizedAttribute(descriptor: CTFontDescriptorRef, + attribute: CFStringRef, + language: *mut CFStringRef) -> CFTypeRef; + pub fn CTFontDescriptorCreateCopyWithAttributes(original: CTFontDescriptorRef, + attributes: CFDictionaryRef) -> CTFontDescriptorRef; + pub fn CTFontDescriptorCreateCopyWithFeature(original: CTFontDescriptorRef, + featureTypeIdentifier: CFNumberRef, + featureSelectorIdentifier: CFNumberRef) -> CTFontDescriptorRef; + pub fn CTFontDescriptorCreateCopyWithVariation(original: CTFontDescriptorRef, + variationIdentifier: CFNumberRef, + variationValue: CGFloat) -> CTFontDescriptorRef; + pub fn CTFontDescriptorCreateMatchingFontDescriptor(descriptor: CTFontDescriptorRef, + mandatoryAttributes: CFSetRef) -> CTFontDescriptorRef; + pub fn CTFontDescriptorCreateWithAttributes(attributes: CFDictionaryRef) -> CTFontDescriptorRef; + pub fn CTFontDescriptorCreateWithNameAndSize(name: CFStringRef, size: CGFloat) -> CTFontDescriptorRef; + pub fn CTFontDescriptorGetTypeID() -> CFTypeID; +} + +extern { + pub fn CTFontDescriptorCreateMatchingFontDescriptors(descriptor: CTFontDescriptorRef, + mandatoryAttributes: CFSetRef) -> CFArrayRef; +} diff --git a/core-text/src/font_manager.rs b/core-text/src/font_manager.rs new file mode 100644 index 0000000..d9eca05 --- /dev/null +++ b/core-text/src/font_manager.rs @@ -0,0 +1,40 @@ +// Copyright 2013 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core_foundation::array::CFArrayRef; +use core_foundation::url::CFURLRef; + +extern { + /* + * CTFontManager.h + */ + + // Incomplete function bindings are mostly related to CoreText font matching, which + // we implement in a platform-independent manner using FontMatcher. + + //pub fn CTFontManagerCompareFontFamilyNames + pub fn CTFontManagerCopyAvailableFontURLs() -> CFArrayRef; + pub fn CTFontManagerCopyAvailableFontFamilyNames() -> CFArrayRef; + pub fn CTFontManagerCopyAvailablePostScriptNames() -> CFArrayRef; + pub fn CTFontManagerCreateFontDescriptorsFromURL(fileURL: CFURLRef) -> CFArrayRef; + //pub fn CTFontManagerCreateFontRequestRunLoopSource + //pub fn CTFontManagerEnableFontDescriptors + //pub fn CTFontManagerGetAutoActivationSetting + //pub fn CTFontManagerGetScopeForURL + //pub fn CTFontManagerGetAutoActivationSetting + //pub fn CTFontManagerGetScopeForURL + pub fn CTFontManagerIsSupportedFont(fontURL: CFURLRef) -> bool; + //pub fn CTFontManagerRegisterFontsForURL + //pub fn CTFontManagerRegisterFontsForURLs + //pub fn CTFontManagerRegisterGraphicsFont + //pub fn CTFontManagerSetAutoActivationSetting + //pub fn CTFontManagerUnregisterFontsForURL + //pub fn CTFontManagerUnregisterFontsForURLs + //pub fn CTFontManagerUnregisterGraphicsFont +} diff --git a/core-text/src/lib.rs b/core-text/src/lib.rs new file mode 100644 index 0000000..401146a --- /dev/null +++ b/core-text/src/lib.rs @@ -0,0 +1,25 @@ +// Copyright 2013 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "core_text"] +#![crate_type = "rlib"] + +#![allow(non_snake_case)] + +extern crate foreign_types; +extern crate libc; + +#[macro_use] +extern crate core_foundation; +extern crate core_graphics; + +pub mod font; +pub mod font_collection; +pub mod font_descriptor; +pub mod font_manager;