]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 1388: Initial work to support opentype font features.
authorJay Anderson <horndude77@gmail.com>
Sun, 31 Jan 2016 05:45:32 +0000 (22:45 -0700)
committerMasamichi Hosoda <trueroad@trueroad.jp>
Mon, 19 Jun 2017 14:52:51 +0000 (23:52 +0900)
configure.ac
input/regression/font-features.ly [new file with mode: 0644]
lily/font-interface.cc
lily/font-metric.cc
lily/include/font-metric.hh
lily/include/modified-font-metric.hh
lily/include/pango-font.hh
lily/modified-font-metric.cc
lily/pango-font.cc
lily/text-interface.cc
scm/define-grob-properties.scm

index 8f2f61abf810193486dcaedb5cdac715a8ac09e1..d2ec5ec9561b77c161a796e5f23303234136fff9 100644 (file)
@@ -260,7 +260,7 @@ AC_MSG_RESULT($rpath_b)
 HOST_ARCH=`$CC -dumpmachine`
 AC_SUBST(HOST_ARCH)
 
-STEPMAKE_PANGO_FT2(pangoft2, REQUIRED, 1.6.0)
+STEPMAKE_PANGO_FT2(pangoft2, REQUIRED, 1.38.0)
 STEPMAKE_FONTCONFIG(fontconfig, REQUIRED, 2.4.0)
 STEPMAKE_FREETYPE2(freetype2, REQUIRED, 2.1.10)
 
diff --git a/input/regression/font-features.ly b/input/regression/font-features.ly
new file mode 100644 (file)
index 0000000..ed01c1f
--- /dev/null
@@ -0,0 +1,22 @@
+\version "2.19.60"
+
+\header
+{
+  texidoc = "Exercise font features. Requires a font that supports the
+    features. This ensures no errors using the interface."
+}
+
+% Comparison between caps styles
+\markup { Hello }
+\markup { HELLO }
+\markup { \caps Hello }
+\markup { \fontCaps Hello }
+% True small caps
+\markup { \override #'(font-features . ("smcp")) Hello }
+
+% Comparison between number styles
+\markup { 0123456789 }
+\markup { \override #'(font-features . ("onum")) 0123456789 }
+
+% Multiple features
+\markup { \override #'(font-features . ("onum" "smcp")) { Hello 0123456789 } }
index de787fd852bf2e4ff04a1fdb96d80d54e412dc89..5e5f18ceb3f8a83d133820d762228c06a0cc44ad 100644 (file)
@@ -72,4 +72,5 @@ ADD_INTERFACE (Font_interface,
                "font-series "
                "font-shape "
                "font-size "
+               "font-features "
               );
index c9daa95f3edf2000d39fb47a5d856a8df505073a..77f02df579c9beaedc747dcf7d565f4e00c1d5ed 100644 (file)
@@ -147,7 +147,9 @@ Font_metric::sub_fonts () const
 
 Stencil
 Font_metric::text_stencil (Output_def *state,
-                           const string&, bool) const
+                           const string&,
+                           bool,
+                           const string&) const
 {
   (void) state;
 
index 7a388f86f35c1031f59c023805802b5c973c9cfc..429801db5520800c1043afafc43306b39346f303 100644 (file)
@@ -47,7 +47,9 @@ public:
   // Return stencil for given string. output_state may be modified to
   // record the font.
   virtual Stencil text_stencil (Output_def *output_state,
-                                const string &text, bool music) const;
+                                const string &text,
+                                bool music,
+                                const string &features_str) const;
 
   virtual string font_name () const;
   virtual size_t count () const;
index 0f4223d4ba90779d781a1720f886c55b273bd326..70016808633d6c0461f3a3006443f961fc55f779 100644 (file)
@@ -33,7 +33,7 @@ class Modified_font_metric : Preinit_Modified_font_metric,
                               public Font_metric
 {
 public:
-  Stencil text_stencil (Output_def *output_state, const string&, bool) const;
+  Stencil text_stencil (Output_def *output_state, const string&, bool, const string&) const;
   Real get_magnification () const;
 
   static SCM make_scaled_font_metric (Font_metric *fm, Real magnification);
index aaae077b769d01bd257e1e96414581a6ea147dd4..5e804f7a8f8f743430dd0c757d3220bd9df5619b 100644 (file)
@@ -63,7 +63,9 @@ public:
   Stencil pango_item_string_stencil (PangoGlyphItem const *) const;
 
   virtual Stencil text_stencil (Output_def *output_state,
-                                const string &text, bool music) const;
+                                const string &text,
+                                bool music,
+                                const string &features_str) const;
   virtual void derived_mark () const;
 };
 
index d68db92c4b897b6728ee0d37fec25410360a2f6e..a3beb4daefa0665be7fd0bacef73fe19571e49ef 100644 (file)
@@ -113,12 +113,14 @@ Modified_font_metric::derived_mark () const
 
 Stencil
 Modified_font_metric::text_stencil (Output_def *state,
-                                    const string &text, bool feta) const
+                                    const string &text,
+                                    bool feta,
+                                    const string &features_str) const
 {
   Box b;
   if (Pango_font *pf = dynamic_cast<Pango_font *> (orig_))
     {
-      Stencil stc = pf->text_stencil (state, text, feta);
+      Stencil stc = pf->text_stencil (state, text, feta, features_str);
 
       Box b = stc.extent_box ();
 
@@ -127,7 +129,7 @@ Modified_font_metric::text_stencil (Output_def *state,
       return scaled;
     }
 
-  return Font_metric::text_stencil (state, text, feta);
+  return Font_metric::text_stencil (state, text, feta, features_str);
 }
 
 Font_metric *
index 9fe6b78cb00a54a78273b5820c5bfe672ea10136..024d7b1d576f94bd731f1186351c26832da2fafe 100644 (file)
@@ -387,7 +387,9 @@ extern bool music_strings_to_paths;
 
 Stencil
 Pango_font::text_stencil (Output_def * /* state */,
-                          const string &str, bool music_string) const
+                          const string &str,
+                          bool music_string,
+                          const string &features_str) const
 {
   /*
     The text assigned to a PangoLayout is automatically divided
@@ -395,6 +397,16 @@ Pango_font::text_stencil (Output_def * /* state */,
     Bidirectional Algorithm, if necessary.
   */
   PangoLayout *layout = pango_layout_new (context_);
+
+  if (!features_str.empty())
+    {
+      PangoAttrList *list = pango_attr_list_new();
+      PangoAttribute *features_attr = pango_attr_font_features_new(features_str.c_str());
+      pango_attr_list_insert(list, features_attr);
+      pango_layout_set_attributes(layout, list);
+      pango_attr_list_unref(list);
+    }
+
   pango_layout_set_text (layout, str.c_str (), -1);
   GSList *lines = pango_layout_get_lines (layout);
 
index d930cdaa372868622e4624883c4ace2f5539e2a9..bad6d50281f626ccce966a8e15200b9a4f80ea8d 100644 (file)
@@ -92,8 +92,44 @@ Text_interface::interpret_string (SCM layout_smob,
                                      SCM_BOOL_F);
   SCM music_encodings = Lily::all_music_font_encodings;
 
+  SCM features = ly_chain_assoc_get (ly_symbol2scm ("font-features"),
+                                     props,
+                                     SCM_BOOL_F);
+
+  // The font-features value is stored in a scheme list. This joins the entries
+  // with commas for processing with pango.
+  string features_str = string ();
+  if (scm_is_pair (features))
+    {
+      bool first = true;
+      for (SCM s = features; scm_is_pair (s); s = scm_cdr (s))
+        {
+          SCM feature = scm_car (s);
+          if (scm_is_string (feature))
+            {
+              if (first)
+                {
+                  first = false;
+                }
+              else
+                {
+                  features_str += ",";
+                }
+              features_str += ly_scm2string (feature);
+            }
+          else
+            {
+              scm_misc_error (__FUNCTION__, "Found non-string in font-features list", SCM_EOL);
+            }
+        }
+    }
+  else if (!scm_is_false (features))
+    {
+      scm_misc_error (__FUNCTION__, "Expecting a list for font-features value", SCM_EOL);
+    }
+
   bool is_music = scm_is_true (scm_memq (encoding, music_encodings));
-  return fm->text_stencil (layout, str, is_music).smobbed_copy ();
+  return fm->text_stencil (layout, str, is_music, features_str).smobbed_copy ();
 }
 
 static size_t markup_depth = 0;
index fbcaa2b4bb85e74812e5b56a898d201417df33e7..0acc741f1cb93ad13ffa151b8fafc745df9037f0 100644 (file)
@@ -327,6 +327,7 @@ approximately 12% larger; 6@tie{}steps are exactly a factor@tie{}2
 larger.  If the context property @code{fontSize} is set, its value is
 added to this before the glyph is printed.  Fractional values are
 allowed.")
+     (font-features ,list? "Opentype features.")
      (footnote ,boolean? "Should this be a footnote or in-note?")
      (footnote-music ,ly:music? "Music creating a footnote.")
      (footnote-text ,markup? "A footnote for the grob.")