Skip to content

Instantly share code, notes, and snippets.

@rcombs
Created December 28, 2023 21:59
Show Gist options
  • Save rcombs/c428c575a1f82f6055e3c1e9e8f9398e to your computer and use it in GitHub Desktop.
Save rcombs/c428c575a1f82f6055e3c1e9e8f9398e to your computer and use it in GitHub Desktop.
diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c
index f4e7367..032d902 100644
--- a/libass/ass_shaper.c
+++ b/libass/ass_shaper.c
@@ -31,13 +31,11 @@
#include FT_FREETYPE_H
#include FT_TRUETYPE_TABLES_H
enum {
- VERT = 0,
- VKNA,
- KERN,
+ KERN = 0,
LIGA,
CLIG
};
-#define NUM_FEATURES 5
+#define NUM_FEATURES 3
enum {
WHOLE_TEXT_LAYOUT_OFF,
@@ -167,10 +165,6 @@ static bool init_features(ASS_Shaper *shaper)
return false;
shaper->n_features = NUM_FEATURES;
- shaper->features[VERT].tag = HB_TAG('v', 'e', 'r', 't');
- shaper->features[VERT].end = UINT_MAX;
- shaper->features[VKNA].tag = HB_TAG('v', 'k', 'n', 'a');
- shaper->features[VKNA].end = UINT_MAX;
shaper->features[KERN].tag = HB_TAG('k', 'e', 'r', 'n');
shaper->features[KERN].end = UINT_MAX;
shaper->features[LIGA].tag = HB_TAG('l', 'i', 'g', 'a');
@@ -186,12 +180,6 @@ static bool init_features(ASS_Shaper *shaper)
*/
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;
-
// disable ligatures if horizontal spacing is non-standard
if (info->hspacing)
shaper->features[LIGA].value = shaper->features[CLIG].value = 0;
@@ -255,8 +243,19 @@ size_t ass_glyph_metrics_construct(void *key, void *value, void *priv)
// if @font rendering is enabled and the glyph should be rotated,
// make cached_h_advance pick up the right advance later
- if (k->vertical)
+ if (k->vertical) {
+ FT_Pos temp = v->horiAdvance;
v->horiAdvance = v->vertAdvance;
+ v->vertAdvance = temp;
+
+ temp = v->horiBearingX;
+ v->horiBearingX = v->vertBearingX;
+ v->vertBearingX = temp;
+
+ temp = v->horiBearingY;
+ v->horiBearingY = v->vertBearingY;
+ v->vertBearingY = temp;
+ }
return 1;
}
@@ -506,7 +505,7 @@ static hb_font_t *get_hb_font(ASS_Shaper *shaper, GlyphInfo *info)
// update hash key for cached metrics
struct ass_shaper_metrics_data *metrics =
font->shaper_priv->metrics_data[info->face_index];
- metrics->hash_key.vertical = !!(info->flags & DECO_ROTATE);
+ metrics->hash_key.vertical = !!info->font->desc.vertical != !!(info->flags & DECO_ROTATE);
metrics->hash_key.font = info->font;
metrics->hash_key.face_index = info->face_index;
metrics->hash_key.size = info->font_size;
@@ -639,6 +638,9 @@ shape_harfbuzz_process_run(GlyphInfo *glyphs, hb_buffer_t *buf, int offset)
hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(buf, NULL);
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions(buf, NULL);
+ bool v = glyphs[offset].font->desc.vertical;
+#define VERT(name, y) ((y != v) ? (-pos[j].y_ ## name) : (pos[j].x_ ## name)) * (v ? -1 : 1)
+
for (j = 0; j < num_glyphs; j++) {
unsigned idx = glyph_info[j].cluster + offset;
GlyphInfo *info = glyphs + idx;
@@ -661,10 +663,10 @@ shape_harfbuzz_process_run(GlyphInfo *glyphs, hb_buffer_t *buf, int offset)
// set position and advance
info->skip = false;
info->glyph_index = glyph_info[j].codepoint;
- info->offset.x = lrint(pos[j].x_offset * info->scale_x);
- info->offset.y = lrint(-pos[j].y_offset * info->scale_y);
- info->advance.x = lrint(pos[j].x_advance * info->scale_x);
- info->advance.y = lrint(-pos[j].y_advance * info->scale_y);
+ info->offset.x = lrint(VERT(offset, 0) * info->scale_x);
+ info->offset.y = lrint(VERT(offset, 1) * info->scale_y);
+ info->advance.x = lrint(VERT(advance, 0) * info->scale_x);
+ info->advance.y = lrint(VERT(advance, 1) * info->scale_y);
// accumulate advance in the root glyph
root->cluster_advance.x += info->advance.x;
@@ -725,8 +727,10 @@ static bool shape_harfbuzz(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
lead_context, i - offset + 1);
}
- props.direction = FRIBIDI_LEVEL_IS_RTL(level) ?
- HB_DIRECTION_RTL : HB_DIRECTION_LTR;
+ props.direction = glyphs[offset].font->desc.vertical ? HB_DIRECTION_TTB : HB_DIRECTION_LTR;
+ if (FRIBIDI_LEVEL_IS_RTL(level))
+ props.direction = HB_DIRECTION_REVERSE(props.direction);
+
props.script = glyphs[offset].script;
props.language = hb_shaper_get_run_language(shaper, props.script);
hb_buffer_set_segment_properties(buf, &props);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment