summaryrefslogtreecommitdiffstats
path: root/libass/ass_shaper.c
diff options
context:
space:
mode:
Diffstat (limited to 'libass/ass_shaper.c')
-rw-r--r--libass/ass_shaper.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c
index 8adfbef..816674c 100644
--- a/libass/ass_shaper.c
+++ b/libass/ass_shaper.c
@@ -26,6 +26,13 @@
#define MAX_RUNS 50
+enum {
+ VERT = 0,
+ VKNA,
+ KERN
+};
+#define NUM_FEATURES 3
+
struct ass_shaper {
// FriBidi log2vis
int n_glyphs;
@@ -33,6 +40,9 @@ struct ass_shaper {
FriBidiCharType *ctypes;
FriBidiLevel *emblevels;
FriBidiStrIndex *cmap;
+ // OpenType features
+ int n_features;
+ hb_feature_t *features;
};
/**
@@ -59,6 +69,23 @@ static void check_allocations(ASS_Shaper *shaper, size_t new_size)
}
/**
+ * \brief set up the HarfBuzz OpenType feature list with some
+ * standard features.
+ */
+static void init_features(ASS_Shaper *shaper)
+{
+ shaper->features = calloc(sizeof(hb_feature_t), NUM_FEATURES);
+
+ shaper->n_features = NUM_FEATURES;
+ shaper->features[VERT].tag = HB_TAG('v', 'e', 'r', 't');
+ shaper->features[VERT].end = INT_MAX;
+ shaper->features[VKNA].tag = HB_TAG('v', 'k', 'n', 'a');
+ shaper->features[VKNA].end = INT_MAX;
+ shaper->features[KERN].tag = HB_TAG('k', 'e', 'r', 'n');
+ shaper->features[KERN].end = INT_MAX;
+}
+
+/**
* \brief Create a new shaper instance and preallocate data structures
* \param prealloc preallocation size
*/
@@ -66,6 +93,7 @@ ASS_Shaper *ass_shaper_new(size_t prealloc)
{
ASS_Shaper *shaper = calloc(sizeof(*shaper), 1);
+ init_features(shaper);
check_allocations(shaper, prealloc);
return shaper;
}
@@ -79,10 +107,23 @@ void ass_shaper_free(ASS_Shaper *shaper)
free(shaper->ctypes);
free(shaper->emblevels);
free(shaper->cmap);
+ free(shaper->features);
free(shaper);
}
/**
+ * \brief Set features depending on properties of the run
+ */
+static void set_run_features(ASS_Shaper *shaper, GlyphInfo *info)
+{
+ // enable vertical substitutions for @font runs
+ if (info->font->desc.vertical)
+ shaper->features[VERT].value = shaper->features[VKNA].value = 1;
+ else
+ shaper->features[VERT].value = shaper->features[VKNA].value = 0;
+}
+
+/**
* \brief Shape event text with HarfBuzz. Full OpenType shaping.
* \param glyphs glyph clusters
* \param len number of clusters
@@ -112,11 +153,13 @@ static void shape_harfbuzz(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
runs[run].end = i;
runs[run].buf = hb_buffer_create(i - k + 1);
runs[run].font = hb_ft_font_create(run_font, NULL);
+ set_run_features(shaper, glyphs + k);
hb_buffer_set_direction(runs[run].buf, direction ? HB_DIRECTION_RTL :
HB_DIRECTION_LTR);
hb_buffer_add_utf32(runs[run].buf, shaper->event_text + k, i - k + 1,
0, i - k + 1);
- hb_shape(runs[run].font, runs[run].buf, NULL, 0);
+ hb_shape(runs[run].font, runs[run].buf, shaper->features,
+ shaper->n_features);
}
//printf("shaped %d runs\n", run);