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 Shape an event's text. Calculates directional runs and shapes them.
26 * \param text_info event's text
27 * \param ctypes returns character types
28 * \param emblevels returns embedding levels (directional runs)
30 void ass_shaper_shape(TextInfo *text_info, FriBidiCharType *ctypes,
31 FriBidiLevel *emblevels)
35 FriBidiChar *event_text = calloc(sizeof(*event_text), text_info->length);
36 GlyphInfo *glyphs = text_info->glyphs;
38 // Get bidi character types and embedding levels
40 for (i = 0; i < text_info->length; i++) {
41 event_text[i] = glyphs[i].symbol;
42 // embedding levels should be calculated paragraph by paragraph
43 if (glyphs[i].symbol == '\n' || i == text_info->length - 1) {
44 //printf("paragraph from %d to %d\n", last_break, i);
46 fribidi_get_bidi_types(event_text + last_break, i - last_break + 1,
48 fribidi_get_par_embedding_levels(ctypes + last_break,
49 i - last_break + 1, &dir, emblevels + last_break);
56 for (i = 0; i < text_info->length; i++) {
57 printf("%d:%d ", ctypes[i], emblevels[i]);
62 // Call FriBidi's glyph mirroring shaper.
63 // This shaper implements rule L4 of the bidi algorithm
64 fribidi_shape_mirroring(emblevels, text_info->length, event_text);
65 for (i = 0; i < text_info->length; i++) {
66 glyphs[i].symbol = event_text[i];
69 // XXX: insert HarfBuzz shaper here
71 // Skip direction override characters
72 // NOTE: Behdad said HarfBuzz is supposed to remove these, but this hasn't
73 // been implemented yet
74 for (i = 0; i < text_info->length; i++) {
75 if (glyphs[i].symbol <= 0x202F && glyphs[i].symbol >= 0x202a) {
84 void ass_shaper_reorder(TextInfo *text_info, FriBidiCharType *ctypes,
85 FriBidiLevel *emblevels, FriBidiStrIndex *cmap)
88 FriBidiParType dir = FRIBIDI_PAR_LTR;
90 // Initialize reorder map
91 for (i = 0; i < text_info->length; i++)
94 // Create reorder map line-by-line
95 for (i = 0; i < text_info->n_lines; i++) {
96 LineInfo *line = text_info->lines + i;
99 // FIXME: we should actually specify
100 // the correct paragraph base direction
101 level = fribidi_reorder_line(FRIBIDI_FLAGS_DEFAULT,
102 ctypes + line->offset, line->len, 0, dir,
103 emblevels + line->offset, NULL, cmap + line->offset);
104 //printf("reorder line %d to level %d\n", i, level);
109 for (i = 0; i < text_info->length; i++) {
110 printf("%d ", cmap[i]);