fontconfig: Branch 'main' - 3 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon May 12 12:12:07 UTC 2025


 fc-fontations/attributes.rs         |   24 +++++++-
 fc-fontations/capabilities.rs       |  105 ++++++++++++++++++++++++++++++++++++
 fc-fontations/instance_enumerate.rs |    2 
 fc-fontations/mod.rs                |   14 ++++
 src/fcfreetype.c                    |    6 +-
 test/test_fontations_ft_query.py    |    1 
 6 files changed, 146 insertions(+), 6 deletions(-)

New commits:
commit c0118a3bea1d3857d5be13b4ae575c638decb9a3
Merge: 3454d29 bf3fbad
Author: Akira TAGOH <akira at tagoh.org>
Date:   Mon May 12 12:12:04 2025 +0000

    Merge branch 'capabilities' into 'main'
    
    [Fontations] Add Capabilities to Pattern
    
    See merge request fontconfig/fontconfig!403

commit bf3fbad0ffa955a63bc7b515da002d363cf4d5fc
Author: Dominik Röttsches <drott at chromium.org>
Date:   Thu May 8 15:01:30 2025 +0300

    [Fontations] Process and append font capabilities to Pattern
    
    * Touches capability: pattern object in FreeType: an extra space
      between `ttable:Silf` and the remaining OT-based capability
      indicators was removed.
    
    Changelog: changed

diff --git a/fc-fontations/capabilities.rs b/fc-fontations/capabilities.rs
new file mode 100644
index 0000000..87966c2
--- /dev/null
+++ b/fc-fontations/capabilities.rs
@@ -0,0 +1,105 @@
+/*
+ * fontconfig/fc-fontations/capabilities.rs
+ *
+ * Copyright 2025 Google LLC.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The authors make no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+use font_types::Tag;
+use read_fonts::tables::layout::ScriptRecord;
+use read_fonts::TableProvider;
+use skrifa::FontRef;
+use std::ffi::CString;
+
+// Mimicking issue in FreeType indexer inserting two delimiting spaces.
+const SILF_CAPABILITIES_PREFIX: &str = "ttable:Silf ";
+const SILF_TAG: Tag = Tag::new(b"Silf");
+
+fn capabilities_string<T: IntoIterator<Item = Tag>>(tags: T, has_silf: bool) -> Option<CString> {
+    let mut deduplicated_tags: Vec<Tag> = tags.into_iter().collect::<Vec<_>>();
+    deduplicated_tags.sort();
+    deduplicated_tags.dedup();
+    let mut capabilities = deduplicated_tags
+        .into_iter()
+        .map(|tag| format!("otlayout:{}", tag))
+        .collect::<Vec<_>>()
+        .join(" ");
+
+    has_silf.then(|| capabilities.insert_str(0, SILF_CAPABILITIES_PREFIX));
+    CString::new(capabilities).ok()
+}
+
+fn gsub_tags<'a>(font: &'a FontRef) -> Option<&'a [ScriptRecord]> {
+    Some(font.gsub().ok()?.script_list().ok()?.script_records())
+}
+
+fn gpos_tags<'a>(font: &'a FontRef) -> Option<&'a [ScriptRecord]> {
+    Some(font.gpos().ok()?.script_list().ok()?.script_records())
+}
+
+pub fn make_capabilities(font: &FontRef) -> Option<CString> {
+    let has_silf = font.table_data(SILF_TAG).is_some();
+    capabilities_string(
+        gsub_tags(font)
+            .into_iter()
+            .flatten()
+            .chain(gpos_tags(font).into_iter().flatten())
+            .map(|script_record| script_record.script_tag()),
+        has_silf,
+    )
+}
+
+#[cfg(test)]
+mod test {
+    use super::capabilities_string;
+    use font_types::Tag;
+    #[test]
+    fn capabilities() {
+        let tags = [Tag::new(b"DFLT"), Tag::new(b"cyrl"), Tag::new(b"grek")];
+        assert_eq!(
+            "otlayout:DFLT otlayout:cyrl otlayout:grek",
+            capabilities_string(tags, false).unwrap().to_str().unwrap()
+        );
+        assert_eq!(
+            "",
+            capabilities_string([], false).unwrap().to_str().unwrap()
+        );
+        let tags = [
+            Tag::new(b"DFLT"),
+            Tag::new(b"cyrl"),
+            Tag::new(b"cyrl"),
+            Tag::new(b"grek"),
+        ];
+
+        assert_eq!(
+            "otlayout:DFLT otlayout:cyrl otlayout:grek",
+            capabilities_string(tags, false).unwrap().to_str().unwrap()
+        );
+    }
+
+    #[test]
+    fn graphite_capabilities() {
+        let tags = [Tag::new(b"grek")];
+        assert_eq!(
+            "ttable:Silf otlayout:grek",
+            capabilities_string(tags, true).unwrap().to_str().unwrap()
+        );
+    }
+}
diff --git a/fc-fontations/mod.rs b/fc-fontations/mod.rs
index 3f43266..72f5ac7 100644
--- a/fc-fontations/mod.rs
+++ b/fc-fontations/mod.rs
@@ -23,19 +23,22 @@
  */
 
 mod attributes;
+mod capabilities;
 mod foundries;
 mod instance_enumerate;
 mod names;
 mod pattern_bindings;
 
 use attributes::append_style_elements;
+use capabilities::make_capabilities;
 use foundries::make_foundry;
 use names::add_names;
 
 use fc_fontations_bindgen::{
     fcint::{
-        FC_COLOR_OBJECT, FC_DECORATIVE_OBJECT, FC_FONTFORMAT_OBJECT, FC_FONTVERSION_OBJECT,
-        FC_FONT_HAS_HINT_OBJECT, FC_FOUNDRY_OBJECT, FC_OUTLINE_OBJECT, FC_SCALABLE_OBJECT,
+        FC_CAPABILITY_OBJECT, FC_COLOR_OBJECT, FC_DECORATIVE_OBJECT, FC_FONTFORMAT_OBJECT,
+        FC_FONTVERSION_OBJECT, FC_FONT_HAS_HINT_OBJECT, FC_FOUNDRY_OBJECT, FC_OUTLINE_OBJECT,
+        FC_SCALABLE_OBJECT,
     },
     FcFontSet, FcFontSetAdd, FcPattern,
 };
@@ -172,6 +175,13 @@ fn build_patterns_for_font(
         foundry_string.into(),
     ));
 
+    if let Some(capabilities) = make_capabilities(font) {
+        pattern.append_element(PatternElement::new(
+            FC_CAPABILITY_OBJECT as i32,
+            capabilities.into(),
+        ));
+    };
+
     let version = font
         .head()
         .ok()
diff --git a/src/fcfreetype.c b/src/fcfreetype.c
index c030612..e9df07b 100644
--- a/src/fcfreetype.c
+++ b/src/fcfreetype.c
@@ -493,6 +493,8 @@ static const FcMacRomanFake fcMacRomanFake[] = {
     { TT_MS_LANGID_ENGLISH_UNITED_STATES, "ASCII"    },
 };
 
+static const char fcSilfCapability[] = "ttable:Silf";
+
 static FcChar8 *
 FcFontCapabilities (FT_Face face);
 
@@ -2662,14 +2664,14 @@ FcFontCapabilities (FT_Face face)
 	goto bail;
 
     maxsize = (((FT_ULong)gpos_count + (FT_ULong)gsub_count) * OTLAYOUT_LEN +
-               (issilgraphitefont ? 13 : 0));
+               (issilgraphitefont ? strlen(fcSilfCapability) : 0));
     complex_ = malloc (sizeof (FcChar8) * maxsize);
     if (!complex_)
 	goto bail;
 
     complex_[0] = '\0';
     if (issilgraphitefont)
-	strcpy ((char *)complex_, "ttable:Silf ");
+	strcpy ((char *)complex_, fcSilfCapability);
 
     while ((indx1 < gsub_count) || (indx2 < gpos_count)) {
 	if (indx1 == gsub_count) {
diff --git a/test/test_fontations_ft_query.py b/test/test_fontations_ft_query.py
index 37a2aab..b7baf0b 100644
--- a/test/test_fontations_ft_query.py
+++ b/test/test_fontations_ft_query.py
@@ -65,6 +65,7 @@ def test_fontations_freetype_fcquery_equal(font_file):
         "weight",
         "width",
         "slant",
+        "capability",
     ]
     format_string = ":".join(
         "%{" + entity + "}" for entity in supported_format_entitites
commit b4ca3b1fc7c8449a372ca16a44de91a305d3cbb4
Author: Dominik Röttsches <drott at chromium.org>
Date:   Thu May 8 14:50:08 2025 +0300

    Amend license headers

diff --git a/fc-fontations/attributes.rs b/fc-fontations/attributes.rs
index 41c853b..be12b83 100644
--- a/fc-fontations/attributes.rs
+++ b/fc-fontations/attributes.rs
@@ -1,4 +1,26 @@
-extern crate fc_fontations_bindgen;
+/*
+ * fontconfig/fc-fontations/attributes.rs
+ *
+ * Copyright 2025 Google LLC.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The authors make no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
 
 use fc_fontations_bindgen::{
     fcint::{
diff --git a/fc-fontations/instance_enumerate.rs b/fc-fontations/instance_enumerate.rs
index 6f13bf9..84deb08 100644
--- a/fc-fontations/instance_enumerate.rs
+++ b/fc-fontations/instance_enumerate.rs
@@ -1,5 +1,5 @@
 /*
- * fontconfig/fc-fontations/mod.rs
+ * fontconfig/fc-fontations/instance_enumerate.rs
  *
  * Copyright 2025 Google LLC.
  *


More information about the Fontconfig mailing list