2 * Copyright (C) 2011 Grigori Goronzy <greg@chown.ath.cx>
4 * This file is part of libass.
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <fribidi/fribidi.h>
21 #include "ass_render.h"
22 #include "ass_shaper.h"
25 * \brief Print version information
27 void ass_shaper_info(ASS_Library *lib)
29 ass_msg(lib, MSGL_V, "Complex text layout enabled, using FriBidi "
34 * \brief Shape an event's text. Calculates directional runs and shapes them.
35 * \param text_info event's text
36 * \param ctypes returns character types
37 * \param emblevels returns embedding levels (directional runs)
39 void ass_shaper_shape(TextInfo *text_info, FriBidiCharType *ctypes,
40 FriBidiLevel *emblevels)
44 FriBidiChar *event_text = calloc(sizeof(*event_text), text_info->length);
45 GlyphInfo *glyphs = text_info->glyphs;
47 // Get bidi character types and embedding levels
49 for (i = 0; i < text_info->length; i++) {
50 event_text[i] = glyphs[i].symbol;
51 // embedding levels should be calculated paragraph by paragraph
52 if (glyphs[i].symbol == '\n' || i == text_info->length - 1) {
53 //printf("paragraph from %d to %d\n", last_break, i);
55 fribidi_get_bidi_types(event_text + last_break, i - last_break + 1,
57 fribidi_get_par_embedding_levels(ctypes + last_break,
58 i - last_break + 1, &dir, emblevels + last_break);
65 for (i = 0; i < text_info->length; i++) {
66 printf("%d:%d ", ctypes[i], emblevels[i]);
71 // Call FriBidi's glyph mirroring shaper.
72 // This shaper implements rule L4 of the bidi algorithm
73 fribidi_shape_mirroring(emblevels, text_info->length, event_text);
74 for (i = 0; i < text_info->length; i++) {
75 glyphs[i].symbol = event_text[i];
78 // XXX: insert HarfBuzz shaper here
80 // Skip direction override characters
81 // NOTE: Behdad said HarfBuzz is supposed to remove these, but this hasn't
82 // been implemented yet
83 for (i = 0; i < text_info->length; i++) {
84 if (glyphs[i].symbol <= 0x202F && glyphs[i].symbol >= 0x202a) {
93 void ass_shaper_reorder(TextInfo *text_info, FriBidiCharType *ctypes,
94 FriBidiLevel *emblevels, FriBidiStrIndex *cmap)
97 FriBidiParType dir = FRIBIDI_PAR_LTR;
99 // Initialize reorder map
100 for (i = 0; i < text_info->length; i++)
103 // Create reorder map line-by-line
104 for (i = 0; i < text_info->n_lines; i++) {
105 LineInfo *line = text_info->lines + i;
108 // FIXME: we should actually specify
109 // the correct paragraph base direction
110 level = fribidi_reorder_line(FRIBIDI_FLAGS_DEFAULT,
111 ctypes + line->offset, line->len, 0, dir,
112 emblevels + line->offset, NULL, cmap + line->offset);
113 //printf("reorder line %d to level %d\n", i, level);
118 for (i = 0; i < text_info->length; i++) {
119 printf("%d ", cmap[i]);