]> granicus.if.org Git - libass/commitdiff
Reindent all source code.
authorgreg <greg@blackbox>
Thu, 18 Jun 2009 15:54:08 +0000 (17:54 +0200)
committergreg <greg@blackbox>
Sat, 20 Jun 2009 01:38:00 +0000 (03:38 +0200)
Reindent complete source code (*.c, *.h) with indent, the exact command
line being:
indent -kr -i4 -bap -nut -l76 *.c *.h

From now on, new code should use (more or less) K&R style,
only spaces and no tabs, 4 spaces indent width. Avoid long lines.

Fix function declaration pointer spacing.

Remove spaces that were added to many function declarations by indent,
like some_func(foo_t * bar).
Fix indenting of macros in ass.c

20 files changed:
libass/ass.c
libass/ass.h
libass/ass_bitmap.c
libass/ass_bitmap.h
libass/ass_cache.c
libass/ass_cache.h
libass/ass_cache_template.c
libass/ass_font.c
libass/ass_font.h
libass/ass_fontconfig.c
libass/ass_fontconfig.h
libass/ass_library.c
libass/ass_library.h
libass/ass_render.c
libass/ass_types.h
libass/ass_utils.c
libass/ass_utils.h
libass/help_mp.h
libass/mputils.c
libass/mputils.h

index 822f1e03f8a3dadf243f76d847d1bb83bae26d84..af107594e8e44c5771b6c0dc13ce4d2e81c3cad9 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 #include "ass_library.h"
 #include "mputils.h"
 
-typedef enum {PST_UNKNOWN = 0, PST_INFO, PST_STYLES, PST_EVENTS, PST_FONTS} parser_state_t;
+typedef enum { PST_UNKNOWN =
+        0, PST_INFO, PST_STYLES, PST_EVENTS, PST_FONTS } parser_state_t;
 
 struct parser_priv_s {
-       parser_state_t state;
-       char* fontname;
-       char* fontdata;
-       int fontdata_size;
-       int fontdata_used;
+    parser_state_t state;
+    char *fontname;
+    char *fontdata;
+    int fontdata_size;
+    int fontdata_used;
 };
 
 #define ASS_STYLES_ALLOC 20
 #define ASS_EVENTS_ALLOC 200
 
-void ass_free_track(ass_track_t* track) {
-       int i;
-
-       if (track->parser_priv) {
-               if (track->parser_priv->fontname)
-                       free(track->parser_priv->fontname);
-               if (track->parser_priv->fontdata)
-                       free(track->parser_priv->fontdata);
-               free(track->parser_priv);
-       }
-       if (track->style_format)
-               free(track->style_format);
-       if (track->event_format)
-               free(track->event_format);
-       if (track->styles) {
-               for (i = 0; i < track->n_styles; ++i)
-                       ass_free_style(track, i);
-               free(track->styles);
-       }
-       if (track->events) {
-               for (i = 0; i < track->n_events; ++i)
-                       ass_free_event(track, i);
-               free(track->events);
-       }
+void ass_free_track(ass_track_t *track)
+{
+    int i;
+
+    if (track->parser_priv) {
+        if (track->parser_priv->fontname)
+            free(track->parser_priv->fontname);
+        if (track->parser_priv->fontdata)
+            free(track->parser_priv->fontdata);
+        free(track->parser_priv);
+    }
+    if (track->style_format)
+        free(track->style_format);
+    if (track->event_format)
+        free(track->event_format);
+    if (track->styles) {
+        for (i = 0; i < track->n_styles; ++i)
+            ass_free_style(track, i);
+        free(track->styles);
+    }
+    if (track->events) {
+        for (i = 0; i < track->n_events; ++i)
+            ass_free_event(track, i);
+        free(track->events);
+    }
 }
 
 /// \brief Allocate a new style struct
 /// \param track track
 /// \return style id
-int ass_alloc_style(ass_track_t* track) {
-       int sid;
+int ass_alloc_style(ass_track_t *track)
+{
+    int sid;
 
-       assert(track->n_styles <= track->max_styles);
+    assert(track->n_styles <= track->max_styles);
 
-       if (track->n_styles == track->max_styles) {
-               track->max_styles += ASS_STYLES_ALLOC;
-               track->styles = (ass_style_t*)realloc(track->styles, sizeof(ass_style_t)*track->max_styles);
-       }
+    if (track->n_styles == track->max_styles) {
+        track->max_styles += ASS_STYLES_ALLOC;
+        track->styles =
+            (ass_style_t *) realloc(track->styles,
+                                    sizeof(ass_style_t) *
+                                    track->max_styles);
+    }
 
-       sid = track->n_styles++;
-       memset(track->styles + sid, 0, sizeof(ass_style_t));
-       return sid;
+    sid = track->n_styles++;
+    memset(track->styles + sid, 0, sizeof(ass_style_t));
+    return sid;
 }
 
 /// \brief Allocate a new event struct
 /// \param track track
 /// \return event id
-int ass_alloc_event(ass_track_t* track) {
-       int eid;
+int ass_alloc_event(ass_track_t *track)
+{
+    int eid;
 
-       assert(track->n_events <= track->max_events);
+    assert(track->n_events <= track->max_events);
 
-       if (track->n_events == track->max_events) {
-               track->max_events += ASS_EVENTS_ALLOC;
-               track->events = (ass_event_t*)realloc(track->events, sizeof(ass_event_t)*track->max_events);
-       }
+    if (track->n_events == track->max_events) {
+        track->max_events += ASS_EVENTS_ALLOC;
+        track->events =
+            (ass_event_t *) realloc(track->events,
+                                    sizeof(ass_event_t) *
+                                    track->max_events);
+    }
 
-       eid = track->n_events++;
-       memset(track->events + eid, 0, sizeof(ass_event_t));
-       return eid;
+    eid = track->n_events++;
+    memset(track->events + eid, 0, sizeof(ass_event_t));
+    return eid;
 }
 
-void ass_free_event(ass_track_t* track, int eid) {
-       ass_event_t* event = track->events + eid;
-       if (event->Name)
-               free(event->Name);
-       if (event->Effect)
-               free(event->Effect);
-       if (event->Text)
-               free(event->Text);
-       if (event->render_priv)
-               free(event->render_priv);
+void ass_free_event(ass_track_t *track, int eid)
+{
+    ass_event_t *event = track->events + eid;
+    if (event->Name)
+        free(event->Name);
+    if (event->Effect)
+        free(event->Effect);
+    if (event->Text)
+        free(event->Text);
+    if (event->render_priv)
+        free(event->render_priv);
 }
 
-void ass_free_style(ass_track_t* track, int sid) {
-       ass_style_t* style = track->styles + sid;
-       if (style->Name)
-               free(style->Name);
-       if (style->FontName)
-               free(style->FontName);
+void ass_free_style(ass_track_t *track, int sid)
+{
+    ass_style_t *style = track->styles + sid;
+    if (style->Name)
+        free(style->Name);
+    if (style->FontName)
+        free(style->FontName);
 }
 
 // ==============================================================================================
 
-static void skip_spaces(char** str) {
-       char* p = *str;
-       while ((*p==' ') || (*p=='\t'))
-               ++p;
-       *str = p;
+static void skip_spaces(char **str)
+{
+    char *p = *str;
+    while ((*p == ' ') || (*p == '\t'))
+        ++p;
+    *str = p;
 }
 
-static void rskip_spaces(char** str, char* limit) {
-       char* p = *str;
-       while ((p >= limit) && ((*p==' ') || (*p=='\t')))
-               --p;
-       *str = p;
+static void rskip_spaces(char **str, char *limit)
+{
+    char *p = *str;
+    while ((p >= limit) && ((*p == ' ') || (*p == '\t')))
+        --p;
+    *str = p;
 }
 
 /**
@@ -160,47 +172,54 @@ static void rskip_spaces(char** str, char* limit) {
  * Returnes 0 if no styles found => expects at least 1 style.
  * Parsing code always adds "Default" style in the end.
  */
-static int lookup_style(ass_track_t* track, char* name) {
-       int i;
-       if (*name == '*') ++name; // FIXME: what does '*' really mean ?
-       for (i = track->n_styles - 1; i >= 0; --i) {
-               // FIXME: mb strcasecmp ?
-               if (strcmp(track->styles[i].Name, name) == 0)
-                       return i;
-       }
-       i = track->default_style;
-       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NoStyleNamedXFoundUsingY, track, name, track->styles[i].Name);
-       return i; // use the first style
+static int lookup_style(ass_track_t *track, char *name)
+{
+    int i;
+    if (*name == '*')
+        ++name;                 // FIXME: what does '*' really mean ?
+    for (i = track->n_styles - 1; i >= 0; --i) {
+        // FIXME: mb strcasecmp ?
+        if (strcmp(track->styles[i].Name, name) == 0)
+            return i;
+    }
+    i = track->default_style;
+    mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NoStyleNamedXFoundUsingY,
+           track, name, track->styles[i].Name);
+    return i;                   // use the first style
 }
 
-static uint32_t string2color(char* p) {
-       uint32_t tmp;
-       (void)strtocolor(&p, &tmp);
-       return tmp;
+static uint32_t string2color(char *p)
+{
+    uint32_t tmp;
+    (void) strtocolor(&p, &tmp);
+    return tmp;
 }
 
-static long long string2timecode(char* p) {
-       unsigned h, m, s, ms;
-       long long tm;
-       int res = sscanf(p, "%1d:%2d:%2d.%2d", &h, &m, &s, &ms);
-       if (res < 4) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_BadTimestamp);
-               return 0;
-       }
-       tm = ((h * 60 + m) * 60 + s) * 1000 + ms * 10;
-       return tm;
+static long long string2timecode(char *p)
+{
+    unsigned h, m, s, ms;
+    long long tm;
+    int res = sscanf(p, "%1d:%2d:%2d.%2d", &h, &m, &s, &ms);
+    if (res < 4) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_BadTimestamp);
+        return 0;
+    }
+    tm = ((h * 60 + m) * 60 + s) * 1000 + ms * 10;
+    return tm;
 }
 
 /**
  * \brief converts numpad-style align to align.
  */
-static int numpad2align(int val) {
-       int res, v;
-       v = (val - 1) / 3; // 0, 1 or 2 for vertical alignment
-       if (v != 0) v = 3 - v;
-       res = ((val - 1) % 3) + 1; // horizontal alignment
-       res += v*4;
-       return res;
+static int numpad2align(int val)
+{
+    int res, v;
+    v = (val - 1) / 3;          // 0, 1 or 2 for vertical alignment
+    if (v != 0)
+        v = 3 - v;
+    res = ((val - 1) % 3) + 1;  // horizontal alignment
+    res += v * 4;
+    return res;
 }
 
 #define NEXT(str,token) \
@@ -230,31 +249,34 @@ static int numpad2align(int val) {
 #define ALIAS(alias,name) \
        if (strcasecmp(tname, #alias) == 0) {tname = #name;}
 
-static char* next_token(char** str) {
-       char* p = *str;
-       char* start;
-       skip_spaces(&p);
-       if (*p == '\0') {
-               *str = p;
-               return 0;
-       }
-       start = p; // start of the token
-       for (; (*p != '\0') && (*p != ','); ++p) {}
-       if (*p == '\0') {
-               *str = p; // eos found, str will point to '\0' at exit
-       } else {
-               *p = '\0';
-               *str = p + 1; // ',' found, str will point to the next char (beginning of the next token)
-       }
-       --p; // end of current token
-       rskip_spaces(&p, start);
-       if (p < start)
-               p = start; // empty token
-       else
-               ++p; // the first space character, or '\0'
-       *p = '\0';
-       return start;
+static char *next_token(char **str)
+{
+    char *p = *str;
+    char *start;
+    skip_spaces(&p);
+    if (*p == '\0') {
+        *str = p;
+        return 0;
+    }
+    start = p;                  // start of the token
+    for (; (*p != '\0') && (*p != ','); ++p) {
+    }
+    if (*p == '\0') {
+        *str = p;               // eos found, str will point to '\0' at exit
+    } else {
+        *p = '\0';
+        *str = p + 1;           // ',' found, str will point to the next char (beginning of the next token)
+    }
+    --p;                        // end of current token
+    rskip_spaces(&p, start);
+    if (p < start)
+        p = start;              // empty token
+    else
+        ++p;                    // the first space character, or '\0'
+    *p = '\0';
+    return start;
 }
+
 /**
  * \brief Parse the tail of Dialogue line
  * \param track track
@@ -262,61 +284,62 @@ static char* next_token(char** str) {
  * \param str string to parse, zero-terminated
  * \param n_ignored number of format options to skip at the beginning
 */
-static int process_event_tail(ass_track_t* track, ass_event_t* event, char* str, int n_ignored)
+static int process_event_tail(ass_track_t *track, ass_event_t *event,
+                              char *str, int n_ignored)
 {
-       char* token;
-       char* tname;
-       char* p = str;
-       int i;
-       ass_event_t* target = event;
-
-       char* format = strdup(track->event_format);
-       char* q = format; // format scanning pointer
-
-       if (track->n_styles == 0) {
-               // add "Default" style to the end
-               // will be used if track does not contain a default style (or even does not contain styles at all)
-               int sid = ass_alloc_style(track);
-               track->styles[sid].Name = strdup("Default");
-               track->styles[sid].FontName = strdup("Arial");
-       }
-
-       for (i = 0; i < n_ignored; ++i) {
-               NEXT(q, tname);
-       }
-
-       while (1) {
-               NEXT(q, tname);
-               if (strcasecmp(tname, "Text") == 0) {
-                       char* last;
-                       event->Text = strdup(p);
-                       if (*event->Text != 0) {
-                               last = event->Text + strlen(event->Text) - 1;
-                               if (last >= event->Text && *last == '\r')
-                                       *last = 0;
-                       }
-                       mp_msg(MSGT_ASS, MSGL_DBG2, "Text = %s\n", event->Text);
-                       event->Duration -= event->Start;
-                       free(format);
-                       return 0; // "Text" is always the last
-               }
-               NEXT(p, token);
-
-               ALIAS(End,Duration) // temporarily store end timecode in event->Duration
-               if (0) { // cool ;)
-                       INTVAL(Layer)
-                       STYLEVAL(Style)
-                       STRVAL(Name)
-                       STRVAL(Effect)
-                       INTVAL(MarginL)
-                       INTVAL(MarginR)
-                       INTVAL(MarginV)
-                       TIMEVAL(Start)
-                       TIMEVAL(Duration)
-               }
-       }
-       free(format);
-       return 1;
+    char *token;
+    char *tname;
+    char *p = str;
+    int i;
+    ass_event_t *target = event;
+
+    char *format = strdup(track->event_format);
+    char *q = format;           // format scanning pointer
+
+    if (track->n_styles == 0) {
+        // add "Default" style to the end
+        // will be used if track does not contain a default style (or even does not contain styles at all)
+        int sid = ass_alloc_style(track);
+        track->styles[sid].Name = strdup("Default");
+        track->styles[sid].FontName = strdup("Arial");
+    }
+
+    for (i = 0; i < n_ignored; ++i) {
+        NEXT(q, tname);
+    }
+
+    while (1) {
+        NEXT(q, tname);
+        if (strcasecmp(tname, "Text") == 0) {
+            char *last;
+            event->Text = strdup(p);
+            if (*event->Text != 0) {
+                last = event->Text + strlen(event->Text) - 1;
+                if (last >= event->Text && *last == '\r')
+                    *last = 0;
+            }
+            mp_msg(MSGT_ASS, MSGL_DBG2, "Text = %s\n", event->Text);
+            event->Duration -= event->Start;
+            free(format);
+            return 0;           // "Text" is always the last
+        }
+        NEXT(p, token);
+
+        ALIAS(End, Duration)    // temporarily store end timecode in event->Duration
+        if (0) {            // cool ;)
+            INTVAL(Layer)
+            STYLEVAL(Style)
+            STRVAL(Name)
+            STRVAL(Effect)
+            INTVAL(MarginL)
+            INTVAL(MarginR)
+            INTVAL(MarginV)
+            TIMEVAL(Start)
+            TIMEVAL(Duration)
+        }
+    }
+    free(format);
+    return 1;
 }
 
 /**
@@ -324,73 +347,77 @@ static int process_event_tail(ass_track_t* track, ass_event_t* event, char* str,
  * \param track track to apply overrides to
  * The format for overrides is [StyleName.]Field=Value
  */
-void process_force_style(ass_track_t* track) {
-       char **fs, *eq, *dt, *style, *tname, *token;
-       ass_style_t* target;
-       int sid;
-       char** list = track->library->style_overrides;
-
-       if (!list) return;
-
-       for (fs = list; *fs; ++fs) {
-               eq = strrchr(*fs, '=');
-               if (!eq)
-                       continue;
-               *eq = '\0';
-               token = eq + 1;
-
-               if(!strcasecmp(*fs, "PlayResX"))
-                       track->PlayResX = atoi(token);
-               else if(!strcasecmp(*fs, "PlayResY"))
-                       track->PlayResY = atoi(token);
-               else if(!strcasecmp(*fs, "Timer"))
-                       track->Timer = atof(token);
-               else if(!strcasecmp(*fs, "WrapStyle"))
-                       track->WrapStyle = atoi(token);
-               else if(!strcasecmp(*fs, "ScaledBorderAndShadow"))
-                       track->ScaledBorderAndShadow = parse_bool(token);
-
-               dt = strrchr(*fs, '.');
-               if (dt) {
-                       *dt = '\0';
-                       style = *fs;
-                       tname = dt + 1;
-               } else {
-                       style = NULL;
-                       tname = *fs;
-               }
-               for (sid = 0; sid < track->n_styles; ++sid) {
-                       if (style == NULL || strcasecmp(track->styles[sid].Name, style) == 0) {
-                               target = track->styles + sid;
-                               if (0) {
-                                       STRVAL(FontName)
-                                       COLORVAL(PrimaryColour)
-                                       COLORVAL(SecondaryColour)
-                                       COLORVAL(OutlineColour)
-                                       COLORVAL(BackColour)
-                                       FPVAL(FontSize)
-                                       INTVAL(Bold)
-                                       INTVAL(Italic)
-                                       INTVAL(Underline)
-                                       INTVAL(StrikeOut)
-                                       FPVAL(Spacing)
-                                       INTVAL(Angle)
-                                       INTVAL(BorderStyle)
-                                       INTVAL(Alignment)
-                                       INTVAL(MarginL)
-                                       INTVAL(MarginR)
-                                       INTVAL(MarginV)
-                                       INTVAL(Encoding)
-                                       FPVAL(ScaleX)
-                                       FPVAL(ScaleY)
-                                       FPVAL(Outline)
-                                       FPVAL(Shadow)
-                               }
-                       }
-               }
-               *eq = '=';
-               if (dt) *dt = '.';
-       }
+void process_force_style(ass_track_t *track)
+{
+    char **fs, *eq, *dt, *style, *tname, *token;
+    ass_style_t *target;
+    int sid;
+    char **list = track->library->style_overrides;
+
+    if (!list)
+        return;
+
+    for (fs = list; *fs; ++fs) {
+        eq = strrchr(*fs, '=');
+        if (!eq)
+            continue;
+        *eq = '\0';
+        token = eq + 1;
+
+        if (!strcasecmp(*fs, "PlayResX"))
+            track->PlayResX = atoi(token);
+        else if (!strcasecmp(*fs, "PlayResY"))
+            track->PlayResY = atoi(token);
+        else if (!strcasecmp(*fs, "Timer"))
+            track->Timer = atof(token);
+        else if (!strcasecmp(*fs, "WrapStyle"))
+            track->WrapStyle = atoi(token);
+        else if (!strcasecmp(*fs, "ScaledBorderAndShadow"))
+            track->ScaledBorderAndShadow = parse_bool(token);
+
+        dt = strrchr(*fs, '.');
+        if (dt) {
+            *dt = '\0';
+            style = *fs;
+            tname = dt + 1;
+        } else {
+            style = NULL;
+            tname = *fs;
+        }
+        for (sid = 0; sid < track->n_styles; ++sid) {
+            if (style == NULL
+                || strcasecmp(track->styles[sid].Name, style) == 0) {
+                target = track->styles + sid;
+                if (0) {
+                    STRVAL(FontName)
+                    COLORVAL(PrimaryColour)
+                    COLORVAL(SecondaryColour)
+                    COLORVAL(OutlineColour)
+                    COLORVAL(BackColour)
+                    FPVAL(FontSize)
+                    INTVAL(Bold)
+                    INTVAL(Italic)
+                    INTVAL(Underline)
+                    INTVAL(StrikeOut)
+                    FPVAL(Spacing)
+                    INTVAL(Angle)
+                    INTVAL(BorderStyle)
+                    INTVAL(Alignment)
+                    INTVAL(MarginL)
+                    INTVAL(MarginR)
+                    INTVAL(MarginV)
+                    INTVAL(Encoding)
+                    FPVAL(ScaleX)
+                    FPVAL(ScaleY)
+                    FPVAL(Outline)
+                    FPVAL(Shadow)
+                }
+            }
+        }
+        *eq = '=';
+        if (dt)
+            *dt = '.';
+    }
 }
 
 /**
@@ -399,257 +426,276 @@ void process_force_style(ass_track_t* track) {
  * \param str string to parse, zero-terminated
  * Allocates a new style struct.
 */
-static int process_style(ass_track_ttrack, char *str)
+static int process_style(ass_track_t *track, char *str)
 {
 
-       char* token;
-       char* tname;
-       char* p = str;
-       char* format;
-       char* q; // format scanning pointer
-       int sid;
-       ass_style_t* style;
-       ass_style_t* target;
-
-       if (!track->style_format) {
-               // no style format header
-               // probably an ancient script version
-               if (track->track_type == TRACK_TYPE_SSA)
-                       track->style_format = strdup("Name, Fontname, Fontsize, PrimaryColour, SecondaryColour,"
-                                       "TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline,"
-                                       "Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding");
-               else
-                       track->style_format = strdup("Name, Fontname, Fontsize, PrimaryColour, SecondaryColour,"
-                                       "OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut,"
-                                       "ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow,"
-                                       "Alignment, MarginL, MarginR, MarginV, Encoding");
-       }
-
-       q = format = strdup(track->style_format);
-
-       mp_msg(MSGT_ASS, MSGL_V, "[%p] Style: %s\n", track, str);
-
-       sid = ass_alloc_style(track);
-
-       style = track->styles + sid;
-       target = style;
+    char *token;
+    char *tname;
+    char *p = str;
+    char *format;
+    char *q;                    // format scanning pointer
+    int sid;
+    ass_style_t *style;
+    ass_style_t *target;
+
+    if (!track->style_format) {
+        // no style format header
+        // probably an ancient script version
+        if (track->track_type == TRACK_TYPE_SSA)
+            track->style_format =
+                strdup
+                ("Name, Fontname, Fontsize, PrimaryColour, SecondaryColour,"
+                 "TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline,"
+                 "Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding");
+        else
+            track->style_format =
+                strdup
+                ("Name, Fontname, Fontsize, PrimaryColour, SecondaryColour,"
+                 "OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut,"
+                 "ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow,"
+                 "Alignment, MarginL, MarginR, MarginV, Encoding");
+    }
+
+    q = format = strdup(track->style_format);
+
+    mp_msg(MSGT_ASS, MSGL_V, "[%p] Style: %s\n", track, str);
+
+    sid = ass_alloc_style(track);
+
+    style = track->styles + sid;
+    target = style;
 // fill style with some default values
-       style->ScaleX = 100.;
-       style->ScaleY = 100.;
-
-       while (1) {
-               NEXT(q, tname);
-               NEXT(p, token);
-
-//             ALIAS(TertiaryColour,OutlineColour) // ignore TertiaryColour; it appears only in SSA, and is overridden by BackColour
-
-               if (0) { // cool ;)
-                       STRVAL(Name)
-                               if ((strcmp(target->Name, "Default")==0) || (strcmp(target->Name, "*Default")==0))
-                                       track->default_style = sid;
-                       STRVAL(FontName)
-                       COLORVAL(PrimaryColour)
-                       COLORVAL(SecondaryColour)
-                       COLORVAL(OutlineColour) // TertiaryColor
-                       COLORVAL(BackColour)
-                               // SSA uses BackColour for both outline and shadow
-                               // this will destroy SSA's TertiaryColour, but i'm not going to use it anyway
-                               if (track->track_type == TRACK_TYPE_SSA)
-                                       target->OutlineColour = target->BackColour;
-                       FPVAL(FontSize)
-                       INTVAL(Bold)
-                       INTVAL(Italic)
-                       INTVAL(Underline)
-                       INTVAL(StrikeOut)
-                       FPVAL(Spacing)
-                       INTVAL(Angle)
-                       INTVAL(BorderStyle)
-                       INTVAL(Alignment)
-                               if (track->track_type == TRACK_TYPE_ASS)
-                                       target->Alignment = numpad2align(target->Alignment);
-                       INTVAL(MarginL)
-                       INTVAL(MarginR)
-                       INTVAL(MarginV)
-                       INTVAL(Encoding)
-                       FPVAL(ScaleX)
-                       FPVAL(ScaleY)
-                       FPVAL(Outline)
-                       FPVAL(Shadow)
-               }
-       }
-       style->ScaleX /= 100.;
-       style->ScaleY /= 100.;
-       style->Bold = !!style->Bold;
-       style->Italic = !!style->Italic;
-       style->Underline = !!style->Underline;
-       if (!style->Name)
-               style->Name = strdup("Default");
-       if (!style->FontName)
-               style->FontName = strdup("Arial");
-       // skip '@' at the start of the font name
-       if (*style->FontName == '@') {
-               p = style->FontName;
-               style->FontName = strdup(p + 1);
-               free(p);
-       }
-       free(format);
-       return 0;
+    style->ScaleX = 100.;
+    style->ScaleY = 100.;
+
+    while (1) {
+        NEXT(q, tname);
+        NEXT(p, token);
+
+//              ALIAS(TertiaryColour,OutlineColour) // ignore TertiaryColour; it appears only in SSA, and is overridden by BackColour
+
+        if (0) {                // cool ;)
+            STRVAL(Name)
+            if ((strcmp(target->Name, "Default") == 0)
+                || (strcmp(target->Name, "*Default") == 0))
+            track->default_style = sid;
+            STRVAL(FontName)
+            COLORVAL(PrimaryColour)
+            COLORVAL(SecondaryColour)
+            COLORVAL(OutlineColour) // TertiaryColor
+            COLORVAL(BackColour)
+            // SSA uses BackColour for both outline and shadow
+            // this will destroy SSA's TertiaryColour, but i'm not going to use it anyway
+            if (track->track_type == TRACK_TYPE_SSA)
+                target->OutlineColour = target->BackColour;
+            FPVAL(FontSize)
+            INTVAL(Bold)
+            INTVAL(Italic)
+            INTVAL(Underline)
+            INTVAL(StrikeOut)
+            FPVAL(Spacing)
+            INTVAL(Angle)
+            INTVAL(BorderStyle)
+            INTVAL(Alignment)
+            if (track->track_type == TRACK_TYPE_ASS)
+                target->Alignment = numpad2align(target->Alignment);
+            INTVAL(MarginL)
+            INTVAL(MarginR)
+            INTVAL(MarginV)
+            INTVAL(Encoding)
+            FPVAL(ScaleX)
+            FPVAL(ScaleY)
+            FPVAL(Outline)
+            FPVAL(Shadow)
+        }
+    }
+    style->ScaleX /= 100.;
+    style->ScaleY /= 100.;
+    style->Bold = !!style->Bold;
+    style->Italic = !!style->Italic;
+    style->Underline = !!style->Underline;
+    if (!style->Name)
+        style->Name = strdup("Default");
+    if (!style->FontName)
+        style->FontName = strdup("Arial");
+    // skip '@' at the start of the font name
+    if (*style->FontName == '@') {
+        p = style->FontName;
+        style->FontName = strdup(p + 1);
+        free(p);
+    }
+    free(format);
+    return 0;
 
 }
 
-static int process_styles_line(ass_track_ttrack, char *str)
+static int process_styles_line(ass_track_t *track, char *str)
 {
-       if (!strncmp(str,"Format:", 7)) {
-               char* p = str + 7;
-               skip_spaces(&p);
-               track->style_format = strdup(p);
-               mp_msg(MSGT_ASS, MSGL_DBG2, "Style format: %s\n", track->style_format);
-       } else if (!strncmp(str,"Style:", 6)) {
-               char* p = str + 6;
-               skip_spaces(&p);
-               process_style(track, p);
-       }
-       return 0;
+    if (!strncmp(str, "Format:", 7)) {
+        char *p = str + 7;
+        skip_spaces(&p);
+        track->style_format = strdup(p);
+        mp_msg(MSGT_ASS, MSGL_DBG2, "Style format: %s\n",
+               track->style_format);
+    } else if (!strncmp(str, "Style:", 6)) {
+        char *p = str + 6;
+        skip_spaces(&p);
+        process_style(track, p);
+    }
+    return 0;
 }
 
-static int process_info_line(ass_track_ttrack, char *str)
+static int process_info_line(ass_track_t *track, char *str)
 {
-       if (!strncmp(str, "PlayResX:", 9)) {
-               track->PlayResX = atoi(str + 9);
-       } else if (!strncmp(str,"PlayResY:", 9)) {
-               track->PlayResY = atoi(str + 9);
-       } else if (!strncmp(str,"Timer:", 6)) {
-               track->Timer = atof(str + 6);
-       } else if (!strncmp(str,"WrapStyle:", 10)) {
-               track->WrapStyle = atoi(str + 10);
-       } else if (!strncmp(str, "ScaledBorderAndShadow:", 22)) {
-               track->ScaledBorderAndShadow = parse_bool(str + 22);
-       }
-       return 0;
+    if (!strncmp(str, "PlayResX:", 9)) {
+        track->PlayResX = atoi(str + 9);
+    } else if (!strncmp(str, "PlayResY:", 9)) {
+        track->PlayResY = atoi(str + 9);
+    } else if (!strncmp(str, "Timer:", 6)) {
+        track->Timer = atof(str + 6);
+    } else if (!strncmp(str, "WrapStyle:", 10)) {
+        track->WrapStyle = atoi(str + 10);
+    } else if (!strncmp(str, "ScaledBorderAndShadow:", 22)) {
+        track->ScaledBorderAndShadow = parse_bool(str + 22);
+    }
+    return 0;
 }
 
-static int process_events_line(ass_track_ttrack, char *str)
+static int process_events_line(ass_track_t *track, char *str)
 {
-       if (!strncmp(str, "Format:", 7)) {
-               char* p = str + 7;
-               skip_spaces(&p);
-               track->event_format = strdup(p);
-               mp_msg(MSGT_ASS, MSGL_DBG2, "Event format: %s\n", track->event_format);
-       } else if (!strncmp(str, "Dialogue:", 9)) {
-               // This should never be reached for embedded subtitles.
-               // They have slightly different format and are parsed in ass_process_chunk,
-               // called directly from demuxer
-               int eid;
-               ass_event_t* event;
-
-               str += 9;
-               skip_spaces(&str);
-
-               eid = ass_alloc_event(track);
-               event = track->events + eid;
-
-               process_event_tail(track, event, str, 0);
-       } else {
-               mp_msg(MSGT_ASS, MSGL_V, "Not understood: %s  \n", str);
-       }
-       return 0;
+    if (!strncmp(str, "Format:", 7)) {
+        char *p = str + 7;
+        skip_spaces(&p);
+        track->event_format = strdup(p);
+        mp_msg(MSGT_ASS, MSGL_DBG2, "Event format: %s\n",
+               track->event_format);
+    } else if (!strncmp(str, "Dialogue:", 9)) {
+        // This should never be reached for embedded subtitles.
+        // They have slightly different format and are parsed in ass_process_chunk,
+        // called directly from demuxer
+        int eid;
+        ass_event_t *event;
+
+        str += 9;
+        skip_spaces(&str);
+
+        eid = ass_alloc_event(track);
+        event = track->events + eid;
+
+        process_event_tail(track, event, str, 0);
+    } else {
+        mp_msg(MSGT_ASS, MSGL_V, "Not understood: %s  \n", str);
+    }
+    return 0;
 }
 
 // Copied from mkvtoolnix
-static unsigned char* decode_chars(unsigned char c1, unsigned char c2,
-               unsigned char c3, unsigned char c4, unsigned char* dst, int cnt)
+static unsigned char *decode_chars(unsigned char c1, unsigned char c2,
+                                   unsigned char c3, unsigned char c4,
+                                   unsigned char *dst, int cnt)
 {
-       uint32_t value;
-       unsigned char bytes[3];
-       int i;
-
-       value = ((c1 - 33) << 18) + ((c2 - 33) << 12) + ((c3 - 33) << 6) + (c4 - 33);
-       bytes[2] = value & 0xff;
-       bytes[1] = (value & 0xff00) >> 8;
-       bytes[0] = (value & 0xff0000) >> 16;
-
-       for (i = 0; i < cnt; ++i)
-               *dst++ = bytes[i];
-       return dst;
+    uint32_t value;
+    unsigned char bytes[3];
+    int i;
+
+    value =
+        ((c1 - 33) << 18) + ((c2 - 33) << 12) + ((c3 - 33) << 6) + (c4 -
+                                                                    33);
+    bytes[2] = value & 0xff;
+    bytes[1] = (value & 0xff00) >> 8;
+    bytes[0] = (value & 0xff0000) >> 16;
+
+    for (i = 0; i < cnt; ++i)
+        *dst++ = bytes[i];
+    return dst;
 }
 
-static int decode_font(ass_track_ttrack)
+static int decode_font(ass_track_t *track)
 {
-       unsigned char* p;
-       unsigned char* q;
-       int i;
-       int size; // original size
-       int dsize; // decoded size
-       unsigned char* buf = 0;
-
-       mp_msg(MSGT_ASS, MSGL_V, "font: %d bytes encoded data \n", track->parser_priv->fontdata_used);
-       size = track->parser_priv->fontdata_used;
-       if (size % 4 == 1) {
-               mp_msg(MSGT_ASS, MSGL_ERR, MSGTR_LIBASS_BadEncodedDataSize);
-               goto error_decode_font;
-       }
-       buf = malloc(size / 4 * 3 + 2);
-       q = buf;
-       for (i = 0, p = (unsigned char*)track->parser_priv->fontdata; i < size / 4; i++, p+=4) {
-               q = decode_chars(p[0], p[1], p[2], p[3], q, 3);
-       }
-       if (size % 4 == 2) {
-               q = decode_chars(p[0], p[1], 0, 0, q, 1);
-       } else if (size % 4 == 3) {
-               q = decode_chars(p[0], p[1], p[2], 0, q, 2);
-       }
-       dsize = q - buf;
-       assert(dsize <= size / 4 * 3 + 2);
-
-       if (track->library->extract_fonts) {
-               ass_add_font(track->library, track->parser_priv->fontname, (char*)buf, dsize);
-               buf = 0;
-       }
-
-error_decode_font:
-       if (buf) free(buf);
-       free(track->parser_priv->fontname);
-       free(track->parser_priv->fontdata);
-       track->parser_priv->fontname = 0;
-       track->parser_priv->fontdata = 0;
-       track->parser_priv->fontdata_size = 0;
-       track->parser_priv->fontdata_used = 0;
-       return 0;
+    unsigned char *p;
+    unsigned char *q;
+    int i;
+    int size;                   // original size
+    int dsize;                  // decoded size
+    unsigned char *buf = 0;
+
+    mp_msg(MSGT_ASS, MSGL_V, "font: %d bytes encoded data \n",
+           track->parser_priv->fontdata_used);
+    size = track->parser_priv->fontdata_used;
+    if (size % 4 == 1) {
+        mp_msg(MSGT_ASS, MSGL_ERR, MSGTR_LIBASS_BadEncodedDataSize);
+        goto error_decode_font;
+    }
+    buf = malloc(size / 4 * 3 + 2);
+    q = buf;
+    for (i = 0, p = (unsigned char *) track->parser_priv->fontdata;
+         i < size / 4; i++, p += 4) {
+        q = decode_chars(p[0], p[1], p[2], p[3], q, 3);
+    }
+    if (size % 4 == 2) {
+        q = decode_chars(p[0], p[1], 0, 0, q, 1);
+    } else if (size % 4 == 3) {
+        q = decode_chars(p[0], p[1], p[2], 0, q, 2);
+    }
+    dsize = q - buf;
+    assert(dsize <= size / 4 * 3 + 2);
+
+    if (track->library->extract_fonts) {
+        ass_add_font(track->library, track->parser_priv->fontname,
+                     (char *) buf, dsize);
+        buf = 0;
+    }
+
+  error_decode_font:
+    if (buf)
+        free(buf);
+    free(track->parser_priv->fontname);
+    free(track->parser_priv->fontdata);
+    track->parser_priv->fontname = 0;
+    track->parser_priv->fontdata = 0;
+    track->parser_priv->fontdata_size = 0;
+    track->parser_priv->fontdata_used = 0;
+    return 0;
 }
 
-static int process_fonts_line(ass_track_ttrack, char *str)
+static int process_fonts_line(ass_track_t *track, char *str)
 {
-       int len;
-
-       if (!strncmp(str, "fontname:", 9)) {
-               char* p = str + 9;
-               skip_spaces(&p);
-               if (track->parser_priv->fontname) {
-                       decode_font(track);
-               }
-               track->parser_priv->fontname = strdup(p);
-               mp_msg(MSGT_ASS, MSGL_V, "fontname: %s\n", track->parser_priv->fontname);
-               return 0;
-       }
-
-       if (!track->parser_priv->fontname) {
-               mp_msg(MSGT_ASS, MSGL_V, "Not understood: %s  \n", str);
-               return 0;
-       }
-
-       len = strlen(str);
-       if (len > 80) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FontLineTooLong, len, str);
-               return 0;
-       }
-       if (track->parser_priv->fontdata_used + len > track->parser_priv->fontdata_size) {
-               track->parser_priv->fontdata_size += 100 * 1024;
-               track->parser_priv->fontdata = realloc(track->parser_priv->fontdata, track->parser_priv->fontdata_size);
-       }
-       memcpy(track->parser_priv->fontdata + track->parser_priv->fontdata_used, str, len);
-       track->parser_priv->fontdata_used += len;
-
-       return 0;
+    int len;
+
+    if (!strncmp(str, "fontname:", 9)) {
+        char *p = str + 9;
+        skip_spaces(&p);
+        if (track->parser_priv->fontname) {
+            decode_font(track);
+        }
+        track->parser_priv->fontname = strdup(p);
+        mp_msg(MSGT_ASS, MSGL_V, "fontname: %s\n",
+               track->parser_priv->fontname);
+        return 0;
+    }
+
+    if (!track->parser_priv->fontname) {
+        mp_msg(MSGT_ASS, MSGL_V, "Not understood: %s  \n", str);
+        return 0;
+    }
+
+    len = strlen(str);
+    if (len > 80) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FontLineTooLong, len, str);
+        return 0;
+    }
+    if (track->parser_priv->fontdata_used + len >
+        track->parser_priv->fontdata_size) {
+        track->parser_priv->fontdata_size += 100 * 1024;
+        track->parser_priv->fontdata =
+            realloc(track->parser_priv->fontdata,
+                    track->parser_priv->fontdata_size);
+    }
+    memcpy(track->parser_priv->fontdata + track->parser_priv->fontdata_used,
+           str, len);
+    track->parser_priv->fontdata_used += len;
+
+    return 0;
 }
 
 /**
@@ -657,67 +703,72 @@ static int process_fonts_line(ass_track_t* track, char *str)
  * \param track track
  * \param str string to parse, zero-terminated
 */
-static int process_line(ass_track_ttrack, char *str)
+static int process_line(ass_track_t *track, char *str)
 {
-       if (!strncasecmp(str, "[Script Info]", 13)) {
-               track->parser_priv->state = PST_INFO;
-       } else if (!strncasecmp(str, "[V4 Styles]", 11)) {
-               track->parser_priv->state = PST_STYLES;
-               track->track_type = TRACK_TYPE_SSA;
-       } else if (!strncasecmp(str, "[V4+ Styles]", 12)) {
-               track->parser_priv->state = PST_STYLES;
-               track->track_type = TRACK_TYPE_ASS;
-       } else if (!strncasecmp(str, "[Events]", 8)) {
-               track->parser_priv->state = PST_EVENTS;
-       } else if (!strncasecmp(str, "[Fonts]", 7)) {
-               track->parser_priv->state = PST_FONTS;
-       } else {
-               switch (track->parser_priv->state) {
-               case PST_INFO:
-                       process_info_line(track, str);
-                       break;
-               case PST_STYLES:
-                       process_styles_line(track, str);
-                       break;
-               case PST_EVENTS:
-                       process_events_line(track, str);
-                       break;
-               case PST_FONTS:
-                       process_fonts_line(track, str);
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       // there is no explicit end-of-font marker in ssa/ass
-       if ((track->parser_priv->state != PST_FONTS) && (track->parser_priv->fontname))
-               decode_font(track);
-
-       return 0;
+    if (!strncasecmp(str, "[Script Info]", 13)) {
+        track->parser_priv->state = PST_INFO;
+    } else if (!strncasecmp(str, "[V4 Styles]", 11)) {
+        track->parser_priv->state = PST_STYLES;
+        track->track_type = TRACK_TYPE_SSA;
+    } else if (!strncasecmp(str, "[V4+ Styles]", 12)) {
+        track->parser_priv->state = PST_STYLES;
+        track->track_type = TRACK_TYPE_ASS;
+    } else if (!strncasecmp(str, "[Events]", 8)) {
+        track->parser_priv->state = PST_EVENTS;
+    } else if (!strncasecmp(str, "[Fonts]", 7)) {
+        track->parser_priv->state = PST_FONTS;
+    } else {
+        switch (track->parser_priv->state) {
+        case PST_INFO:
+            process_info_line(track, str);
+            break;
+        case PST_STYLES:
+            process_styles_line(track, str);
+            break;
+        case PST_EVENTS:
+            process_events_line(track, str);
+            break;
+        case PST_FONTS:
+            process_fonts_line(track, str);
+            break;
+        default:
+            break;
+        }
+    }
+
+    // there is no explicit end-of-font marker in ssa/ass
+    if ((track->parser_priv->state != PST_FONTS)
+        && (track->parser_priv->fontname))
+        decode_font(track);
+
+    return 0;
 }
 
-static int process_text(ass_track_t* track, char* str)
+static int process_text(ass_track_t *track, char *str)
 {
-       char* p = str;
-       while(1) {
-               char* q;
-               while (1) {
-                       if ((*p=='\r')||(*p=='\n')) ++p;
-                       else if (p[0]=='\xef' && p[1]=='\xbb' && p[2]=='\xbf') p+=3; // U+FFFE (BOM)
-                       else break;
-               }
-               for (q=p; ((*q!='\0')&&(*q!='\r')&&(*q!='\n')); ++q) {};
-               if (q==p)
-                       break;
-               if (*q != '\0')
-                       *(q++) = '\0';
-               process_line(track, p);
-               if (*q == '\0')
-                       break;
-               p = q;
-       }
-       return 0;
+    char *p = str;
+    while (1) {
+        char *q;
+        while (1) {
+            if ((*p == '\r') || (*p == '\n'))
+                ++p;
+            else if (p[0] == '\xef' && p[1] == '\xbb' && p[2] == '\xbf')
+                p += 3;         // U+FFFE (BOM)
+            else
+                break;
+        }
+        for (q = p; ((*q != '\0') && (*q != '\r') && (*q != '\n')); ++q) {
+        };
+        if (q == p)
+            break;
+        if (*q != '\0')
+            *(q++) = '\0';
+        process_line(track, p);
+        if (*q == '\0')
+            break;
+        p = q;
+    }
+    return 0;
 }
 
 /**
@@ -726,16 +777,16 @@ static int process_text(ass_track_t* track, char* str)
  * \param data string to parse
  * \param size length of data
 */
-void ass_process_data(ass_track_t* track, char* data, int size)
+void ass_process_data(ass_track_t *track, char *data, int size)
 {
-       char* str = malloc(size + 1);
+    char *str = malloc(size + 1);
 
-       memcpy(str, data, size);
-       str[size] = '\0';
+    memcpy(str, data, size);
+    str[size] = '\0';
 
-       mp_msg(MSGT_ASS, MSGL_V, "event: %s\n", str);
-       process_text(track, str);
-       free(str);
+    mp_msg(MSGT_ASS, MSGL_V, "event: %s\n", str);
+    process_text(track, str);
+    free(str);
 }
 
 /**
@@ -745,30 +796,34 @@ void ass_process_data(ass_track_t* track, char* data, int size)
  * \param size length of data
  CodecPrivate section contains [Stream Info] and [V4+ Styles] ([V4 Styles] for SSA) sections
 */
-void ass_process_codec_private(ass_track_ttrack, char *data, int size)
+void ass_process_codec_private(ass_track_t *track, char *data, int size)
 {
-       ass_process_data(track, data, size);
-
-       if (!track->event_format) {
-               // probably an mkv produced by ancient mkvtoolnix
-               // such files don't have [Events] and Format: headers
-               track->parser_priv->state = PST_EVENTS;
-               if (track->track_type == TRACK_TYPE_SSA)
-                       track->event_format = strdup("Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text");
-               else
-                       track->event_format = strdup("Format: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text");
-       }
-
-       process_force_style(track);
+    ass_process_data(track, data, size);
+
+    if (!track->event_format) {
+        // probably an mkv produced by ancient mkvtoolnix
+        // such files don't have [Events] and Format: headers
+        track->parser_priv->state = PST_EVENTS;
+        if (track->track_type == TRACK_TYPE_SSA)
+            track->event_format =
+                strdup
+                ("Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text");
+        else
+            track->event_format =
+                strdup
+                ("Format: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text");
+    }
+
+    process_force_style(track);
 }
 
-static int check_duplicate_event(ass_track_ttrack, int ReadOrder)
+static int check_duplicate_event(ass_track_t *track, int ReadOrder)
 {
-       int i;
-       for (i = 0; i<track->n_events - 1; ++i) // ignoring last event, it is the one we are comparing with
-               if (track->events[i].ReadOrder == ReadOrder)
-                       return 1;
-       return 0;
+    int i;
+    for (i = 0; i < track->n_events - 1; ++i)   // ignoring last event, it is the one we are comparing with
+        if (track->events[i].ReadOrder == ReadOrder)
+            return 1;
+    return 0;
 }
 
 /**
@@ -779,51 +834,53 @@ static int check_duplicate_event(ass_track_t* track, int ReadOrder)
  * \param timecode starting time of the event (milliseconds)
  * \param duration duration of the event (milliseconds)
 */
-void ass_process_chunk(ass_track_t* track, char *data, int size, long long timecode, long long duration)
+void ass_process_chunk(ass_track_t *track, char *data, int size,
+                       long long timecode, long long duration)
 {
-       char* str;
-       int eid;
-       char* p;
-       char* token;
-       ass_event_t* event;
-
-       if (!track->event_format) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_EventFormatHeaderMissing);
-               return;
-       }
-
-       str = malloc(size + 1);
-       memcpy(str, data, size);
-       str[size] = '\0';
-       mp_msg(MSGT_ASS, MSGL_V, "event at %" PRId64 ", +%" PRId64 ": %s  \n", (int64_t)timecode, (int64_t)duration, str);
-
-       eid = ass_alloc_event(track);
-       event = track->events + eid;
-
-       p = str;
-
-       do {
-               NEXT(p, token);
-               event->ReadOrder = atoi(token);
-               if (check_duplicate_event(track, event->ReadOrder))
-                       break;
-
-               NEXT(p, token);
-               event->Layer = atoi(token);
-
-               process_event_tail(track, event, p, 3);
-
-               event->Start = timecode;
-               event->Duration = duration;
-
-               free(str);
-               return;
-//             dump_events(tid);
-       } while (0);
-       // some error
-       ass_free_event(track, eid);
-       track->n_events--;
-       free(str);
+    char *str;
+    int eid;
+    char *p;
+    char *token;
+    ass_event_t *event;
+
+    if (!track->event_format) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_EventFormatHeaderMissing);
+        return;
+    }
+
+    str = malloc(size + 1);
+    memcpy(str, data, size);
+    str[size] = '\0';
+    mp_msg(MSGT_ASS, MSGL_V, "event at %" PRId64 ", +%" PRId64 ": %s  \n",
+           (int64_t) timecode, (int64_t) duration, str);
+
+    eid = ass_alloc_event(track);
+    event = track->events + eid;
+
+    p = str;
+
+    do {
+        NEXT(p, token);
+        event->ReadOrder = atoi(token);
+        if (check_duplicate_event(track, event->ReadOrder))
+            break;
+
+        NEXT(p, token);
+        event->Layer = atoi(token);
+
+        process_event_tail(track, event, p, 3);
+
+        event->Start = timecode;
+        event->Duration = duration;
+
+        free(str);
+        return;
+//              dump_events(tid);
+    } while (0);
+    // some error
+    ass_free_event(track, eid);
+    track->n_events--;
+    free(str);
 }
 
 #ifdef CONFIG_ICONV
@@ -833,75 +890,79 @@ void ass_process_chunk(ass_track_t* track, char *data, int size, long long timec
  * \param size buffer size
  * \return a pointer to recoded buffer, caller is responsible for freeing it
 **/
-static char* sub_recode(char* data, size_t size, char* codepage)
+static char *sub_recode(char *data, size_t size, char *codepage)
 {
-       static iconv_t icdsc = (iconv_t)(-1);
-       char* tocp = "UTF-8";
-       char* outbuf;
-       assert(codepage);
+    static iconv_t icdsc = (iconv_t) (-1);
+    char *tocp = "UTF-8";
+    char *outbuf;
+    assert(codepage);
 
-       {
-               const char* cp_tmp = codepage;
+    {
+        const char *cp_tmp = codepage;
 #ifdef CONFIG_ENCA
-               char enca_lang[3], enca_fallback[100];
-               if (sscanf(codepage, "enca:%2s:%99s", enca_lang, enca_fallback) == 2
-                               || sscanf(codepage, "ENCA:%2s:%99s", enca_lang, enca_fallback) == 2) {
-                       cp_tmp = guess_buffer_cp((unsigned char*)data, size, enca_lang, enca_fallback);
-               }
+        char enca_lang[3], enca_fallback[100];
+        if (sscanf(codepage, "enca:%2s:%99s", enca_lang, enca_fallback) == 2
+            || sscanf(codepage, "ENCA:%2s:%99s", enca_lang,
+                      enca_fallback) == 2) {
+            cp_tmp =
+                guess_buffer_cp((unsigned char *) data, size, enca_lang,
+                                enca_fallback);
+        }
 #endif
-               if ((icdsc = iconv_open (tocp, cp_tmp)) != (iconv_t)(-1)){
-                       mp_msg(MSGT_ASS,MSGL_V,"LIBSUB: opened iconv descriptor.\n");
-               } else
-                       mp_msg(MSGT_ASS,MSGL_ERR,MSGTR_LIBASS_ErrorOpeningIconvDescriptor);
-       }
-
-       {
-               size_t osize = size;
-               size_t ileft = size;
-               size_t oleft = size - 1;
-               char* ip;
-               char* op;
-               size_t rc;
-               int clear = 0;
-
-               outbuf = malloc(osize);
-               ip = data;
-               op = outbuf;
-
-               while (1) {
-                       if (ileft)
-                               rc = iconv(icdsc, &ip, &ileft, &op, &oleft);
-                       else {// clear the conversion state and leave
-                               clear = 1;
-                               rc = iconv(icdsc, NULL, NULL, &op, &oleft);
-                       }
-                       if (rc == (size_t)(-1)) {
-                               if (errno == E2BIG) {
-                                       size_t offset = op - outbuf;
-                                       outbuf = (char*)realloc(outbuf, osize + size);
-                                       op = outbuf + offset;
-                                       osize += size;
-                                       oleft += size;
-                               } else {
-                                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorRecodingFile);
-                                       return NULL;
-                               }
-                       } else
-                               if (clear)
-                                       break;
-               }
-               outbuf[osize - oleft - 1] = 0;
-       }
-
-       if (icdsc != (iconv_t)(-1)) {
-               (void)iconv_close(icdsc);
-               icdsc = (iconv_t)(-1);
-               mp_msg(MSGT_ASS,MSGL_V,"LIBSUB: closed iconv descriptor.\n");
-       }
-
-       return outbuf;
+        if ((icdsc = iconv_open(tocp, cp_tmp)) != (iconv_t) (-1)) {
+            mp_msg(MSGT_ASS, MSGL_V, "LIBSUB: opened iconv descriptor.\n");
+        } else
+            mp_msg(MSGT_ASS, MSGL_ERR,
+                   MSGTR_LIBASS_ErrorOpeningIconvDescriptor);
+    }
+
+    {
+        size_t osize = size;
+        size_t ileft = size;
+        size_t oleft = size - 1;
+        char *ip;
+        char *op;
+        size_t rc;
+        int clear = 0;
+
+        outbuf = malloc(osize);
+        ip = data;
+        op = outbuf;
+
+        while (1) {
+            if (ileft)
+                rc = iconv(icdsc, &ip, &ileft, &op, &oleft);
+            else {              // clear the conversion state and leave
+                clear = 1;
+                rc = iconv(icdsc, NULL, NULL, &op, &oleft);
+            }
+            if (rc == (size_t) (-1)) {
+                if (errno == E2BIG) {
+                    size_t offset = op - outbuf;
+                    outbuf = (char *) realloc(outbuf, osize + size);
+                    op = outbuf + offset;
+                    osize += size;
+                    oleft += size;
+                } else {
+                    mp_msg(MSGT_ASS, MSGL_WARN,
+                           MSGTR_LIBASS_ErrorRecodingFile);
+                    return NULL;
+                }
+            } else if (clear)
+                break;
+        }
+        outbuf[osize - oleft - 1] = 0;
+    }
+
+    if (icdsc != (iconv_t) (-1)) {
+        (void) iconv_close(icdsc);
+        icdsc = (iconv_t) (-1);
+        mp_msg(MSGT_ASS, MSGL_V, "LIBSUB: closed iconv descriptor.\n");
+    }
+
+    return outbuf;
 }
-#endif // ICONV
+#endif                          // ICONV
 
 /**
  * \brief read file contents into newly allocated buffer
@@ -909,86 +970,88 @@ static char* sub_recode(char* data, size_t size, char* codepage)
  * \param bufsize out: file size
  * \return pointer to file contents. Caller is responsible for its deallocation.
  */
-static char* read_file(char* fname, size_t *bufsize)
+static char *read_file(char *fname, size_t *bufsize)
 {
-       int res;
-       long sz;
-       long bytes_read;
-       char* buf;
-
-       FILE* fp = fopen(fname, "rb");
-       if (!fp) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FopenFailed, fname);
-               return 0;
-       }
-       res = fseek(fp, 0, SEEK_END);
-       if (res == -1) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FseekFailed, fname);
-               fclose(fp);
-               return 0;
-       }
-
-       sz = ftell(fp);
-       rewind(fp);
-
-       if (sz > 10*1024*1024) {
-               mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_RefusingToLoadSubtitlesLargerThan10M, fname);
-               fclose(fp);
-               return 0;
-       }
-
-       mp_msg(MSGT_ASS, MSGL_V, "file size: %ld\n", sz);
-
-       buf = malloc(sz + 1);
-       assert(buf);
-       bytes_read = 0;
-       do {
-               res = fread(buf + bytes_read, 1, sz - bytes_read, fp);
-               if (res <= 0) {
-                       mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_ReadFailed, errno, strerror(errno));
-                       fclose(fp);
-                       free(buf);
-                       return 0;
-               }
-               bytes_read += res;
-       } while (sz - bytes_read > 0);
-       buf[sz] = '\0';
-       fclose(fp);
-
-       if (bufsize)
-               *bufsize = sz;
-       return buf;
+    int res;
+    long sz;
+    long bytes_read;
+    char *buf;
+
+    FILE *fp = fopen(fname, "rb");
+    if (!fp) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FopenFailed, fname);
+        return 0;
+    }
+    res = fseek(fp, 0, SEEK_END);
+    if (res == -1) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FseekFailed, fname);
+        fclose(fp);
+        return 0;
+    }
+
+    sz = ftell(fp);
+    rewind(fp);
+
+    if (sz > 10 * 1024 * 1024) {
+        mp_msg(MSGT_ASS, MSGL_INFO,
+               MSGTR_LIBASS_RefusingToLoadSubtitlesLargerThan10M, fname);
+        fclose(fp);
+        return 0;
+    }
+
+    mp_msg(MSGT_ASS, MSGL_V, "file size: %ld\n", sz);
+
+    buf = malloc(sz + 1);
+    assert(buf);
+    bytes_read = 0;
+    do {
+        res = fread(buf + bytes_read, 1, sz - bytes_read, fp);
+        if (res <= 0) {
+            mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_ReadFailed, errno,
+                   strerror(errno));
+            fclose(fp);
+            free(buf);
+            return 0;
+        }
+        bytes_read += res;
+    } while (sz - bytes_read > 0);
+    buf[sz] = '\0';
+    fclose(fp);
+
+    if (bufsize)
+        *bufsize = sz;
+    return buf;
 }
 
 /*
  * \param buf pointer to subtitle text in utf-8
  */
-static ass_track_t* parse_memory(ass_library_t* library, char* buf)
+static ass_track_t *parse_memory(ass_library_t *library, char *buf)
 {
-       ass_track_t* track;
-       int i;
+    ass_track_t *track;
+    int i;
 
-       track = ass_new_track(library);
+    track = ass_new_track(library);
 
-       // process header
-       process_text(track, buf);
+    // process header
+    process_text(track, buf);
 
-       // external SSA/ASS subs does not have ReadOrder field
-       for (i = 0; i < track->n_events; ++i)
-               track->events[i].ReadOrder = i;
+    // external SSA/ASS subs does not have ReadOrder field
+    for (i = 0; i < track->n_events; ++i)
+        track->events[i].ReadOrder = i;
 
-       // there is no explicit end-of-font marker in ssa/ass
-       if (track->parser_priv->fontname)
-               decode_font(track);
+    // there is no explicit end-of-font marker in ssa/ass
+    if (track->parser_priv->fontname)
+        decode_font(track);
 
-       if (track->track_type == TRACK_TYPE_UNKNOWN) {
-               ass_free_track(track);
-               return 0;
-       }
+    if (track->track_type == TRACK_TYPE_UNKNOWN) {
+        ass_free_track(track);
+        return 0;
+    }
 
-       process_force_style(track);
+    process_force_style(track);
 
-       return track;
+    return track;
 }
 
 /**
@@ -999,51 +1062,53 @@ static ass_track_t* parse_memory(ass_library_t* library, char* buf)
  * \param codepage recode buffer contents from given codepage
  * \return newly allocated track
 */
-ass_track_t* ass_read_memory(ass_library_t* library, char* buf, size_t bufsize, char* codepage)
+ass_track_t *ass_read_memory(ass_library_t *library, char *buf,
+                             size_t bufsize, char *codepage)
 {
-       ass_track_t* track;
-       int need_free = 0;
+    ass_track_t *track;
+    int need_free = 0;
 
-       if (!buf)
-               return 0;
+    if (!buf)
+        return 0;
 
 #ifdef CONFIG_ICONV
-       if (codepage)
-               buf = sub_recode(buf, bufsize, codepage);
-       if (!buf)
-               return 0;
-       else
-               need_free = 1;
+    if (codepage)
+        buf = sub_recode(buf, bufsize, codepage);
+    if (!buf)
+        return 0;
+    else
+        need_free = 1;
 #endif
-       track = parse_memory(library, buf);
-       if (need_free)
-               free(buf);
-       if (!track)
-               return 0;
-
-       mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_AddedSubtitleFileMemory, track->n_styles, track->n_events);
-       return track;
+    track = parse_memory(library, buf);
+    if (need_free)
+        free(buf);
+    if (!track)
+        return 0;
+
+    mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_AddedSubtitleFileMemory,
+           track->n_styles, track->n_events);
+    return track;
 }
 
-char* read_file_recode(char* fname, char* codepage, size_t* size)
+char *read_file_recode(char *fname, char *codepage, size_t *size)
 {
-       char* buf;
-       size_t bufsize;
+    char *buf;
+    size_t bufsize;
 
-       buf = read_file(fname, &bufsize);
-       if (!buf)
-               return 0;
+    buf = read_file(fname, &bufsize);
+    if (!buf)
+        return 0;
 #ifdef CONFIG_ICONV
-       if (codepage) {
-                char* tmpbuf = sub_recode(buf, bufsize, codepage);
-                free(buf);
-                buf = tmpbuf;
-       }
-       if (!buf)
-               return 0;
+    if (codepage) {
+        char *tmpbuf = sub_recode(buf, bufsize, codepage);
+        free(buf);
+        buf = tmpbuf;
+    }
+    if (!buf)
+        return 0;
 #endif
-       *size = bufsize;
-       return buf;
+    *size = bufsize;
+    return buf;
 }
 
 /**
@@ -1053,83 +1118,98 @@ char* read_file_recode(char* fname, char* codepage, size_t* size)
  * \param codepage recode buffer contents from given codepage
  * \return newly allocated track
 */
-ass_track_t* ass_read_file(ass_library_t* library, char* fname, char* codepage)
+ass_track_t *ass_read_file(ass_library_t *library, char *fname,
+                           char *codepage)
 {
-       char* buf;
-       ass_track_t* track;
-       size_t bufsize;
+    char *buf;
+    ass_track_t *track;
+    size_t bufsize;
 
-       buf = read_file_recode(fname, codepage, &bufsize);
-       if (!buf)
-               return 0;
-       track = parse_memory(library, buf);
-       free(buf);
-       if (!track)
-               return 0;
+    buf = read_file_recode(fname, codepage, &bufsize);
+    if (!buf)
+        return 0;
+    track = parse_memory(library, buf);
+    free(buf);
+    if (!track)
+        return 0;
 
-       track->name = strdup(fname);
+    track->name = strdup(fname);
 
-       mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_AddedSubtitleFileFname, fname, track->n_styles, track->n_events);
+    mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_AddedSubtitleFileFname, fname,
+           track->n_styles, track->n_events);
 
-//     dump_events(forced_tid);
-       return track;
+//      dump_events(forced_tid);
+    return track;
 }
 
 /**
  * \brief read styles from file into already initialized track
  */
-int ass_read_styles(ass_track_t* track, char* fname, char* codepage)
+int ass_read_styles(ass_track_t *track, char *fname, char *codepage)
 {
-       char* buf;
-       parser_state_t old_state;
-       size_t sz;
+    char *buf;
+    parser_state_t old_state;
+    size_t sz;
 
-       buf = read_file(fname, &sz);
-       if (!buf)
-               return 1;
+    buf = read_file(fname, &sz);
+    if (!buf)
+        return 1;
 #ifdef CONFIG_ICONV
-       if (codepage) {
-               char* tmpbuf;
-               tmpbuf = sub_recode(buf, sz, codepage);
-               free(buf);
-               buf = tmpbuf;
-       }
-       if (!buf)
-               return 0;
+    if (codepage) {
+        char *tmpbuf;
+        tmpbuf = sub_recode(buf, sz, codepage);
+        free(buf);
+        buf = tmpbuf;
+    }
+    if (!buf)
+        return 0;
 #endif
 
-       old_state = track->parser_priv->state;
-       track->parser_priv->state = PST_STYLES;
-       process_text(track, buf);
-       track->parser_priv->state = old_state;
+    old_state = track->parser_priv->state;
+    track->parser_priv->state = PST_STYLES;
+    process_text(track, buf);
+    track->parser_priv->state = old_state;
 
-       return 0;
+    return 0;
 }
 
-long long ass_step_sub(ass_track_t* track, long long now, int movement) {
-       int i;
-
-       if (movement == 0) return 0;
-       if (track->n_events == 0) return 0;
-
-       if (movement < 0)
-               for (i = 0; (i < track->n_events) && ((long long)(track->events[i].Start + track->events[i].Duration) <= now); ++i) {}
-       else
-               for (i = track->n_events - 1; (i >= 0) && ((long long)(track->events[i].Start) > now); --i) {}
-
-       // -1 and n_events are ok
-       assert(i >= -1); assert(i <= track->n_events);
-       i += movement;
-       if (i < 0) i = 0;
-       if (i >= track->n_events) i = track->n_events - 1;
-       return ((long long)track->events[i].Start) - now;
+long long ass_step_sub(ass_track_t *track, long long now, int movement)
+{
+    int i;
+
+    if (movement == 0)
+        return 0;
+    if (track->n_events == 0)
+        return 0;
+
+    if (movement < 0)
+        for (i = 0;
+             (i < track->n_events)
+             &&
+             ((long long) (track->events[i].Start +
+                           track->events[i].Duration) <= now); ++i) {
+    } else
+        for (i = track->n_events - 1;
+             (i >= 0) && ((long long) (track->events[i].Start) > now);
+             --i) {
+        }
+
+    // -1 and n_events are ok
+    assert(i >= -1);
+    assert(i <= track->n_events);
+    i += movement;
+    if (i < 0)
+        i = 0;
+    if (i >= track->n_events)
+        i = track->n_events - 1;
+    return ((long long) track->events[i].Start) - now;
 }
 
-ass_track_t* ass_new_track(ass_library_t* library) {
-       ass_track_t* track = calloc(1, sizeof(ass_track_t));
-       track->library = library;
-       track->ScaledBorderAndShadow = 1;
-       track->parser_priv = calloc(1, sizeof(parser_priv_t));
-       return track;
+ass_track_t *ass_new_track(ass_library_t *library)
+{
+    ass_track_t *track = calloc(1, sizeof(ass_track_t));
+    track->library = library;
+    track->ScaledBorderAndShadow = 1;
+    track->parser_priv = calloc(1, sizeof(parser_priv_t));
+    return track;
 }
-
index e98b4264b704f44292c2a534c6925c6b8108df60..f5a989a7fe21b86611a3b30c1d8e48e265b954d2 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
@@ -31,74 +29,70 @@ typedef struct ass_renderer_s ass_renderer_t;
 
 /// a linked list of images produced by ass renderer
 typedef struct ass_image_s {
-       int w, h; // bitmap width/height
-       int stride; // bitmap stride
-       unsigned char* bitmap; // 1bpp stride*h alpha buffer
-       uint32_t color; // RGBA
-       int dst_x, dst_y; // bitmap placement inside the video frame
+    int w, h;                   // bitmap width/height
+    int stride;                 // bitmap stride
+    unsigned char *bitmap;      // 1bpp stride*h alpha buffer
+    uint32_t color;             // RGBA
+    int dst_x, dst_y;           // bitmap placement inside the video frame
 
-       struct ass_image_s* next; // linked list
+    struct ass_image_s *next;   // linked list
 } ass_image_t;
 
 /// Hinting type
-typedef enum {ASS_HINTING_NONE = 0,
-             ASS_HINTING_LIGHT,
-             ASS_HINTING_NORMAL,
-             ASS_HINTING_NATIVE
+typedef enum { ASS_HINTING_NONE = 0,
+    ASS_HINTING_LIGHT,
+    ASS_HINTING_NORMAL,
+    ASS_HINTING_NATIVE
 } ass_hinting_t;
 
 /**
  * \brief initialize the library
  * \return library handle or NULL if failed
  */
-ass_library_tass_library_init(void);
+ass_library_t *ass_library_init(void);
 
 /**
  * \brief finalize the library
  * \param priv library handle
  */
-void ass_library_done(ass_library_t*);
+void ass_library_done(ass_library_t *);
 
 /**
  * \brief set private font directory
  * It is used for saving embedded fonts and also in font lookup.
  */
-void ass_set_fonts_dir(ass_library_t* priv, const char* fonts_dir);
+void ass_set_fonts_dir(ass_library_t *priv, const char *fonts_dir);
 
-void ass_set_extract_fonts(ass_library_tpriv, int extract);
+void ass_set_extract_fonts(ass_library_t *priv, int extract);
 
-void ass_set_style_overrides(ass_library_t* priv, char** list);
+void ass_set_style_overrides(ass_library_t *priv, char **list);
 
 /**
  * \brief initialize the renderer
  * \param priv library handle
  * \return renderer handle or NULL if failed
  */
-ass_renderer_t* ass_renderer_init(ass_library_t*);
+ass_renderer_t *ass_renderer_init(ass_library_t *);
 
 /**
  * \brief finalize the renderer
  * \param priv renderer handle
  */
-void ass_renderer_done(ass_renderer_tpriv);
+void ass_renderer_done(ass_renderer_t *priv);
 
-void ass_set_frame_size(ass_renderer_tpriv, int w, int h);
-void ass_set_margins(ass_renderer_tpriv, int t, int b, int l, int r);
-void ass_set_use_margins(ass_renderer_tpriv, int use);
-void ass_set_aspect_ratio(ass_renderer_tpriv, double ar);
-void ass_set_font_scale(ass_renderer_tpriv, double font_scale);
-void ass_set_hinting(ass_renderer_tpriv, ass_hinting_t ht);
-void ass_set_line_spacing(ass_renderer_tpriv, double line_spacing);
+void ass_set_frame_size(ass_renderer_t *priv, int w, int h);
+void ass_set_margins(ass_renderer_t *priv, int t, int b, int l, int r);
+void ass_set_use_margins(ass_renderer_t *priv, int use);
+void ass_set_aspect_ratio(ass_renderer_t *priv, double ar);
+void ass_set_font_scale(ass_renderer_t *priv, double font_scale);
+void ass_set_hinting(ass_renderer_t *priv, ass_hinting_t ht);
+void ass_set_line_spacing(ass_renderer_t *priv, double line_spacing);
 
 /**
  * \brief set font lookup defaults
  */
-int  ass_set_fonts(ass_renderer_t* priv, const char* default_font, const char* default_family);
-
-/**
- * \brief set font lookup defaults, don't use fontconfig even if it is available
- */
-int  ass_set_fonts_nofc(ass_renderer_t* priv, const char* default_font, const char* default_family);
+int ass_set_fonts(ass_renderer_t *priv, const char *default_font,
+                  const char *default_family, int fc);
 
 /**
  * \brief render a frame, producing a list of ass_image_t
@@ -106,7 +100,8 @@ int  ass_set_fonts_nofc(ass_renderer_t* priv, const char* default_font, const ch
  * \param track subtitle track
  * \param now video timestamp in milliseconds
  */
-ass_image_t* ass_render_frame(ass_renderer_t *priv, ass_track_t* track, long long now, int* detect_change);
+ass_image_t *ass_render_frame(ass_renderer_t *priv, ass_track_t *track,
+                              long long now, int *detect_change);
 
 
 // The following functions operate on track objects and do not need an ass_renderer //
@@ -115,27 +110,27 @@ ass_image_t* ass_render_frame(ass_renderer_t *priv, ass_track_t* track, long lon
  * \brief allocate a new empty track object
  * \return pointer to empty track
  */
-ass_track_t* ass_new_track(ass_library_t*);
+ass_track_t *ass_new_track(ass_library_t *);
 
 /**
  * \brief deallocate track and all its child objects (styles and events)
  * \param track track to deallocate
  */
-void ass_free_track(ass_track_ttrack);
+void ass_free_track(ass_track_t *track);
 
 /**
  * \brief allocate new style
  * \param track track
  * \return newly allocated style id
  */
-int ass_alloc_style(ass_track_ttrack);
+int ass_alloc_style(ass_track_t *track);
 
 /**
  * \brief allocate new event
  * \param track track
  * \return newly allocated event id
  */
-int ass_alloc_event(ass_track_ttrack);
+int ass_alloc_event(ass_track_t *track);
 
 /**
  * \brief delete a style
@@ -143,7 +138,7 @@ int ass_alloc_event(ass_track_t* track);
  * \param sid style id
  * Deallocates style data. Does not modify track->n_styles.
  */
-void ass_free_style(ass_track_ttrack, int sid);
+void ass_free_style(ass_track_t *track, int sid);
 
 /**
  * \brief delete an event
@@ -151,7 +146,7 @@ void ass_free_style(ass_track_t* track, int sid);
  * \param eid event id
  * Deallocates event data. Does not modify track->n_events.
  */
-void ass_free_event(ass_track_ttrack, int eid);
+void ass_free_event(ass_track_t *track, int eid);
 
 /**
  * \brief Parse a chunk of subtitle stream data.
@@ -159,7 +154,7 @@ void ass_free_event(ass_track_t* track, int eid);
  * \param data string to parse
  * \param size length of data
  */
-void ass_process_data(ass_track_t* track, char* data, int size);
+void ass_process_data(ass_track_t *track, char *data, int size);
 
 /**
  * \brief Parse Codec Private section of subtitle stream
@@ -167,7 +162,7 @@ void ass_process_data(ass_track_t* track, char* data, int size);
  * \param data string to parse
  * \param size length of data
  */
-void ass_process_codec_private(ass_track_ttrack, char *data, int size);
+void ass_process_codec_private(ass_track_t *track, char *data, int size);
 
 /**
  * \brief Parse a chunk of subtitle stream data. In Matroska, this contains exactly 1 event (or a commentary).
@@ -177,16 +172,18 @@ void ass_process_codec_private(ass_track_t* track, char *data, int size);
  * \param timecode starting time of the event (milliseconds)
  * \param duration duration of the event (milliseconds)
 */
-void ass_process_chunk(ass_track_t* track, char *data, int size, long long timecode, long long duration);
+void ass_process_chunk(ass_track_t *track, char *data, int size,
+                       long long timecode, long long duration);
 
-char* read_file_recode(char* fname, char* codepage, size_t* size);
+char *read_file_recode(char *fname, char *codepage, size_t *size);
 
 /**
  * \brief Read subtitles from file.
  * \param fname file name
  * \return newly allocated track
 */
-ass_track_t* ass_read_file(ass_library_t* library, char* fname, char* codepage);
+ass_track_t *ass_read_file(ass_library_t *library, char *fname,
+                           char *codepage);
 
 /**
  * \brief Read subtitles from memory.
@@ -196,12 +193,13 @@ ass_track_t* ass_read_file(ass_library_t* library, char* fname, char* codepage);
  * \param codepage recode buffer contents from given codepage
  * \return newly allocated track
 */
-ass_track_t* ass_read_memory(ass_library_t* library, char* buf, size_t bufsize, char* codepage);
+ass_track_t *ass_read_memory(ass_library_t *library, char *buf,
+                             size_t bufsize, char *codepage);
 /**
  * \brief read styles from file into already initialized track
  * \return 0 on success
  */
-int ass_read_styles(ass_track_t* track, char* fname, char* codepage);
+int ass_read_styles(ass_track_t *track, char *fname, char *codepage);
 
 /**
  * \brief Add a memory font.
@@ -209,12 +207,13 @@ int ass_read_styles(ass_track_t* track, char* fname, char* codepage);
  * \param data binary font data
  * \param data_size data size
 */
-void ass_add_font(ass_library_t* library, char* name, char* data, int data_size);
+void ass_add_font(ass_library_t *library, char *name, char *data,
+                  int data_size);
 
 /**
  * \brief Remove all fonts stored in ass_library object
  */
-void ass_clear_fonts(ass_library_tlibrary);
+void ass_clear_fonts(ass_library_t *library);
 
 /**
  * \brief Calculates timeshift from now to the start of some other subtitle event, depending on movement parameter
@@ -224,6 +223,6 @@ void ass_clear_fonts(ass_library_t* library);
  * +2 means "the one after the next", -1 means "previous"
  * \return timeshift, ms
  */
-long long ass_step_sub(ass_track_ttrack, long long now, int movement);
+long long ass_step_sub(ass_track_t *track, long long now, int movement);
 
-#endif /* LIBASS_ASS_H */
+#endif                          /* LIBASS_ASS_H */
index eac8223eff87636c9861abc86d5973956c379f7f..8df24f6e08d45a2a9646a5f527b3c3ff5335d873 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 #include "ass_bitmap.h"
 
 struct ass_synth_priv_s {
-       int tmp_w, tmp_h;
-       unsigned short* tmp;
+    int tmp_w, tmp_h;
+    unsigned short *tmp;
 
-       int g_r;
-       int g_w;
+    int g_r;
+    int g_w;
 
-       unsigned *g;
-       unsigned *gt2;
+    unsigned *g;
+    unsigned *gt2;
 
-       double radius;
+    double radius;
 };
 
 static const unsigned int maxcolor = 255;
 static const unsigned base = 256;
 
-static int generate_tables(ass_synth_priv_tpriv, double radius)
+static int generate_tables(ass_synth_priv_t *priv, double radius)
 {
-       double A = log(1.0/base)/(radius*radius*2);
-       int mx, i;
-       double volume_diff, volume_factor = 0;
-       unsigned volume;
-
-       if (priv->radius == radius)
-               return 0;
-       else
-               priv->radius = radius;
-
-       priv->g_r = ceil(radius);
-       priv->g_w = 2*priv->g_r+1;
-
-       if (priv->g_r) {
-               priv->g = realloc(priv->g, priv->g_w * sizeof(unsigned));
-               priv->gt2 = realloc(priv->gt2, 256 * priv->g_w * sizeof(unsigned));
-               if (priv->g==NULL || priv->gt2==NULL) {
-                       return -1;
-               }
-       }
-
-       if (priv->g_r) {
-               // gaussian curve with volume = 256
-               for (volume_diff=10000000; volume_diff>0.0000001; volume_diff*=0.5){
-                       volume_factor+= volume_diff;
-                       volume=0;
-                       for (i = 0; i<priv->g_w; ++i) {
-                               priv->g[i] = (unsigned)(exp(A * (i-priv->g_r)*(i-priv->g_r)) * volume_factor + .5);
-                               volume+= priv->g[i];
-                       }
-                       if(volume>256) volume_factor-= volume_diff;
-               }
-               volume=0;
-               for (i = 0; i<priv->g_w; ++i) {
-                       priv->g[i] = (unsigned)(exp(A * (i-priv->g_r)*(i-priv->g_r)) * volume_factor + .5);
-                       volume+= priv->g[i];
-               }
-
-               // gauss table:
-               for(mx=0;mx<priv->g_w;mx++){
-                       for(i=0;i<256;i++){
-                               priv->gt2[mx+i*priv->g_w] = i*priv->g[mx];
-                       }
-               }
-       }
-
-       return 0;
+    double A = log(1.0 / base) / (radius * radius * 2);
+    int mx, i;
+    double volume_diff, volume_factor = 0;
+    unsigned volume;
+
+    if (priv->radius == radius)
+        return 0;
+    else
+        priv->radius = radius;
+
+    priv->g_r = ceil(radius);
+    priv->g_w = 2 * priv->g_r + 1;
+
+    if (priv->g_r) {
+        priv->g = realloc(priv->g, priv->g_w * sizeof(unsigned));
+        priv->gt2 = realloc(priv->gt2, 256 * priv->g_w * sizeof(unsigned));
+        if (priv->g == NULL || priv->gt2 == NULL) {
+            return -1;
+        }
+    }
+
+    if (priv->g_r) {
+        // gaussian curve with volume = 256
+        for (volume_diff = 10000000; volume_diff > 0.0000001;
+             volume_diff *= 0.5) {
+            volume_factor += volume_diff;
+            volume = 0;
+            for (i = 0; i < priv->g_w; ++i) {
+                priv->g[i] =
+                    (unsigned) (exp(A * (i - priv->g_r) * (i - priv->g_r)) *
+                                volume_factor + .5);
+                volume += priv->g[i];
+            }
+            if (volume > 256)
+                volume_factor -= volume_diff;
+        }
+        volume = 0;
+        for (i = 0; i < priv->g_w; ++i) {
+            priv->g[i] =
+                (unsigned) (exp(A * (i - priv->g_r) * (i - priv->g_r)) *
+                            volume_factor + .5);
+            volume += priv->g[i];
+        }
+
+        // gauss table:
+        for (mx = 0; mx < priv->g_w; mx++) {
+            for (i = 0; i < 256; i++) {
+                priv->gt2[mx + i * priv->g_w] = i * priv->g[mx];
+            }
+        }
+    }
+
+    return 0;
 }
 
-static void resize_tmp(ass_synth_priv_tpriv, int w, int h)
+static void resize_tmp(ass_synth_priv_t *priv, int w, int h)
 {
-       if (priv->tmp_w >= w && priv->tmp_h >= h)
-               return;
-       if (priv->tmp_w == 0)
-               priv->tmp_w = 64;
-       if (priv->tmp_h == 0)
-               priv->tmp_h = 64;
-       while (priv->tmp_w < w) priv->tmp_w *= 2;
-       while (priv->tmp_h < h) priv->tmp_h *= 2;
-       if (priv->tmp)
-               free(priv->tmp);
-       priv->tmp = malloc((priv->tmp_w + 1) * priv->tmp_h * sizeof(short));
+    if (priv->tmp_w >= w && priv->tmp_h >= h)
+        return;
+    if (priv->tmp_w == 0)
+        priv->tmp_w = 64;
+    if (priv->tmp_h == 0)
+        priv->tmp_h = 64;
+    while (priv->tmp_w < w)
+        priv->tmp_w *= 2;
+    while (priv->tmp_h < h)
+        priv->tmp_h *= 2;
+    if (priv->tmp)
+        free(priv->tmp);
+    priv->tmp = malloc((priv->tmp_w + 1) * priv->tmp_h * sizeof(short));
 }
 
-ass_synth_priv_tass_synth_init(double radius)
+ass_synth_priv_t *ass_synth_init(double radius)
 {
-       ass_synth_priv_t* priv = calloc(1, sizeof(ass_synth_priv_t));
-       generate_tables(priv, radius);
-       return priv;
+    ass_synth_priv_t *priv = calloc(1, sizeof(ass_synth_priv_t));
+    generate_tables(priv, radius);
+    return priv;
 }
 
-void ass_synth_done(ass_synth_priv_tpriv)
+void ass_synth_done(ass_synth_priv_t *priv)
 {
-       if (priv->tmp)
-               free(priv->tmp);
-       if (priv->g)
-               free(priv->g);
-       if (priv->gt2)
-               free(priv->gt2);
-       free(priv);
+    if (priv->tmp)
+        free(priv->tmp);
+    if (priv->g)
+        free(priv->g);
+    if (priv->gt2)
+        free(priv->gt2);
+    free(priv);
 }
 
-static bitmap_talloc_bitmap(int w, int h)
+static bitmap_t *alloc_bitmap(int w, int h)
 {
-       bitmap_t* bm;
-       bm = calloc(1, sizeof(bitmap_t));
-       bm->buffer = malloc(w*h);
-       bm->w = w;
-       bm->h = h;
-       bm->left = bm->top = 0;
-       return bm;
+    bitmap_t *bm;
+    bm = calloc(1, sizeof(bitmap_t));
+    bm->buffer = malloc(w * h);
+    bm->w = w;
+    bm->h = h;
+    bm->left = bm->top = 0;
+    return bm;
 }
 
-void ass_free_bitmap(bitmap_tbm)
+void ass_free_bitmap(bitmap_t *bm)
 {
-       if (bm) {
-               if (bm->buffer) free(bm->buffer);
-               free(bm);
-       }
+    if (bm) {
+        if (bm->buffer)
+            free(bm->buffer);
+        free(bm);
+    }
 }
 
-static bitmap_t* copy_bitmap(const bitmap_t* src)
+static bitmap_t *copy_bitmap(const bitmap_t *src)
 {
-       bitmap_t* dst = alloc_bitmap(src->w, src->h);
-       dst->left = src->left;
-       dst->top = src->top;
-       memcpy(dst->buffer, src->buffer, src->w * src->h);
-       return dst;
+    bitmap_t *dst = alloc_bitmap(src->w, src->h);
+    dst->left = src->left;
+    dst->top = src->top;
+    memcpy(dst->buffer, src->buffer, src->w * src->h);
+    return dst;
 }
 
 static int check_glyph_area(FT_Glyph glyph)
 {
-       FT_BBox bbox;
-       long long dx, dy;
-       FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox);
-       dx = bbox.xMax - bbox.xMin;
-       dy = bbox.yMax - bbox.yMin;
-       if (dx * dy > 8000000) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_GlyphBBoxTooLarge, (int)dx, (int)dy);
-               return 1;
-       } else
-               return 0;
+    FT_BBox bbox;
+    long long dx, dy;
+    FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox);
+    dx = bbox.xMax - bbox.xMin;
+    dy = bbox.yMax - bbox.yMin;
+    if (dx * dy > 8000000) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_GlyphBBoxTooLarge,
+               (int) dx, (int) dy);
+        return 1;
+    } else
+        return 0;
 }
 
-static bitmap_tglyph_to_bitmap_internal(FT_Glyph glyph, int bord)
+static bitmap_t *glyph_to_bitmap_internal(FT_Glyph glyph, int bord)
 {
-       FT_BitmapGlyph bg;
-       FT_Bitmap* bit;
-       bitmap_t* bm;
-       int w, h;
-       unsigned char* src;
-       unsigned char* dst;
-       int i;
-       int error;
-
-       if (check_glyph_area(glyph))
-               return 0;
-       error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 0);
-       if (error) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FT_Glyph_To_BitmapError, error);
-               return 0;
-       }
-
-       bg = (FT_BitmapGlyph)glyph;
-       bit = &(bg->bitmap);
-       if (bit->pixel_mode != FT_PIXEL_MODE_GRAY) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UnsupportedPixelMode, (int)(bit->pixel_mode));
-               FT_Done_Glyph(glyph);
-               return 0;
-       }
-
-       w = bit->width;
-       h = bit->rows;
-       bm = alloc_bitmap(w + 2*bord, h + 2*bord);
-       memset(bm->buffer, 0, bm->w * bm->h);
-       bm->left = bg->left - bord;
-       bm->top = - bg->top - bord;
-
-       src = bit->buffer;
-       dst = bm->buffer + bord + bm->w * bord;
-       for (i = 0; i < h; ++i) {
-               memcpy(dst, src, w);
-               src += bit->pitch;
-               dst += bm->w;
-       }
-
-       FT_Done_Glyph(glyph);
-       return bm;
+    FT_BitmapGlyph bg;
+    FT_Bitmap *bit;
+    bitmap_t *bm;
+    int w, h;
+    unsigned char *src;
+    unsigned char *dst;
+    int i;
+    int error;
+
+    if (check_glyph_area(glyph))
+        return 0;
+    error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 0);
+    if (error) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FT_Glyph_To_BitmapError,
+               error);
+        return 0;
+    }
+
+    bg = (FT_BitmapGlyph) glyph;
+    bit = &(bg->bitmap);
+    if (bit->pixel_mode != FT_PIXEL_MODE_GRAY) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UnsupportedPixelMode,
+               (int) (bit->pixel_mode));
+        FT_Done_Glyph(glyph);
+        return 0;
+    }
+
+    w = bit->width;
+    h = bit->rows;
+    bm = alloc_bitmap(w + 2 * bord, h + 2 * bord);
+    memset(bm->buffer, 0, bm->w * bm->h);
+    bm->left = bg->left - bord;
+    bm->top = -bg->top - bord;
+
+    src = bit->buffer;
+    dst = bm->buffer + bord + bm->w * bord;
+    for (i = 0; i < h; ++i) {
+        memcpy(dst, src, w);
+        src += bit->pitch;
+        dst += bm->w;
+    }
+
+    FT_Done_Glyph(glyph);
+    return bm;
 }
 
 /**
@@ -224,114 +234,126 @@ static bitmap_t* glyph_to_bitmap_internal(FT_Glyph glyph, int bord)
  * 1. Glyph bitmap is subtracted from outline bitmap. This way looks much better in some cases.
  * 2. Shadow bitmap is created as a sum of glyph and outline bitmaps.
  */
-static bitmap_t* fix_outline_and_shadow(bitmap_t* bm_g, bitmap_t* bm_o)
+static bitmap_t *fix_outline_and_shadow(bitmap_t *bm_g, bitmap_t *bm_o)
 {
-       int x, y;
-       const int l = bm_o->left > bm_g->left ? bm_o->left : bm_g->left;
-       const int t = bm_o->top > bm_g->top ? bm_o->top : bm_g->top;
-       const int r = bm_o->left + bm_o->w < bm_g->left + bm_g->w ? bm_o->left + bm_o->w : bm_g->left + bm_g->w;
-       const int b = bm_o->top + bm_o->h < bm_g->top + bm_g->h ? bm_o->top + bm_o->h : bm_g->top + bm_g->h;
-
-       bitmap_t* bm_s = copy_bitmap(bm_o);
-
-       unsigned char* g = bm_g->buffer + (t - bm_g->top) * bm_g->w + (l - bm_g->left);
-       unsigned char* o = bm_o->buffer + (t - bm_o->top) * bm_o->w + (l - bm_o->left);
-       unsigned char* s = bm_s->buffer + (t - bm_s->top) * bm_s->w + (l - bm_s->left);
-
-       for (y = 0; y < b - t; ++y) {
-               for (x = 0; x < r - l; ++x) {
-                       unsigned char c_g, c_o;
-                       c_g = g[x];
-                       c_o = o[x];
-                       o[x] = (c_o > c_g) ? c_o - (c_g/2) : 0;
-                       s[x] = (c_o < 0xFF - c_g) ? c_o + c_g : 0xFF;
-               }
-               g += bm_g->w;
-               o += bm_o->w;
-               s += bm_s->w;
-       }
-
-       assert(bm_s);
-       return bm_s;
+    int x, y;
+    const int l = bm_o->left > bm_g->left ? bm_o->left : bm_g->left;
+    const int t = bm_o->top > bm_g->top ? bm_o->top : bm_g->top;
+    const int r =
+        bm_o->left + bm_o->w <
+        bm_g->left + bm_g->w ? bm_o->left + bm_o->w : bm_g->left + bm_g->w;
+    const int b =
+        bm_o->top + bm_o->h <
+        bm_g->top + bm_g->h ? bm_o->top + bm_o->h : bm_g->top + bm_g->h;
+
+    bitmap_t *bm_s = copy_bitmap(bm_o);
+
+    unsigned char *g =
+        bm_g->buffer + (t - bm_g->top) * bm_g->w + (l - bm_g->left);
+    unsigned char *o =
+        bm_o->buffer + (t - bm_o->top) * bm_o->w + (l - bm_o->left);
+    unsigned char *s =
+        bm_s->buffer + (t - bm_s->top) * bm_s->w + (l - bm_s->left);
+
+    for (y = 0; y < b - t; ++y) {
+        for (x = 0; x < r - l; ++x) {
+            unsigned char c_g, c_o;
+            c_g = g[x];
+            c_o = o[x];
+            o[x] = (c_o > c_g) ? c_o - (c_g / 2) : 0;
+            s[x] = (c_o < 0xFF - c_g) ? c_o + c_g : 0xFF;
+        }
+        g += bm_g->w;
+        o += bm_o->w;
+        s += bm_s->w;
+    }
+
+    assert(bm_s);
+    return bm_s;
 }
 
 /**
  * \brief Blur with [[1,2,1]. [2,4,2], [1,2,1]] kernel
  * This blur is the same as the one employed by vsfilter.
  */
-static void be_blur(unsigned char *buf, int w, int h) {
-       unsigned int x, y;
-       unsigned int old_sum, new_sum;
-
-       for (y=0; y<h; y++) {
-               old_sum = 2 * buf[y*w];
-               for (x=0; x<w-1; x++) {
-                       new_sum = buf[y*w+x] + buf[y*w+x+1];
-                       buf[y*w+x] = (old_sum + new_sum) >> 2;
-                       old_sum = new_sum;
-               }
-       }
-
-       for (x=0; x<w; x++) {
-               old_sum = 2 * buf[x];
-               for (y=0; y<h-1; y++) {
-                       new_sum = buf[y*w+x] + buf[(y+1)*w+x];
-                       buf[y*w+x] = (old_sum + new_sum) >> 2;
-                       old_sum = new_sum;
-               }
-       }
+static void be_blur(unsigned char *buf, int w, int h)
+{
+    unsigned int x, y;
+    unsigned int old_sum, new_sum;
+
+    for (y = 0; y < h; y++) {
+        old_sum = 2 * buf[y * w];
+        for (x = 0; x < w - 1; x++) {
+            new_sum = buf[y * w + x] + buf[y * w + x + 1];
+            buf[y * w + x] = (old_sum + new_sum) >> 2;
+            old_sum = new_sum;
+        }
+    }
+
+    for (x = 0; x < w; x++) {
+        old_sum = 2 * buf[x];
+        for (y = 0; y < h - 1; y++) {
+            new_sum = buf[y * w + x] + buf[(y + 1) * w + x];
+            buf[y * w + x] = (old_sum + new_sum) >> 2;
+            old_sum = new_sum;
+        }
+    }
 }
 
-int glyph_to_bitmap(ass_synth_priv_t* priv_blur,
-               FT_Glyph glyph, FT_Glyph outline_glyph, bitmap_t** bm_g,
-               bitmap_t** bm_o, bitmap_t** bm_s, int be, double blur_radius)
+int glyph_to_bitmap(ass_synth_priv_t *priv_blur,
+                    FT_Glyph glyph, FT_Glyph outline_glyph,
+                    bitmap_t **bm_g, bitmap_t **bm_o, bitmap_t **bm_s,
+                    int be, double blur_radius)
 {
-       int bord = be ? (be/4+1) : 0;
-       blur_radius *= 2;
-       bord = (blur_radius > 0.0) ? blur_radius+1 : bord;
-
-       assert(bm_g && bm_o && bm_s);
-
-       *bm_g = *bm_o = *bm_s = 0;
-
-       if (glyph)
-               *bm_g = glyph_to_bitmap_internal(glyph, bord);
-       if (!*bm_g)
-               return 1;
-
-       if (outline_glyph) {
-               *bm_o = glyph_to_bitmap_internal(outline_glyph, bord);
-               if (!*bm_o) {
-                       ass_free_bitmap(*bm_g);
-                       return 1;
-               }
-       }
-       if (*bm_o)
-               resize_tmp(priv_blur, (*bm_o)->w, (*bm_o)->h);
-       resize_tmp(priv_blur, (*bm_g)->w, (*bm_g)->h);
-
-       if (be) {
-               while (be--) {
-                       if (*bm_o)
-                               be_blur((*bm_o)->buffer, (*bm_o)->w, (*bm_o)->h);
-                       else
-                               be_blur((*bm_g)->buffer, (*bm_g)->w, (*bm_g)->h);
-               }
-       } else {
-               if (blur_radius > 0.0) {
-                       generate_tables(priv_blur, blur_radius);
-                       if (*bm_o)
-                               blur((*bm_o)->buffer, priv_blur->tmp, (*bm_o)->w, (*bm_o)->h, (*bm_o)->w, (int*)priv_blur->gt2, priv_blur->g_r, priv_blur->g_w);
-                       else
-                               blur((*bm_g)->buffer, priv_blur->tmp, (*bm_g)->w, (*bm_g)->h, (*bm_g)->w, (int*)priv_blur->gt2, priv_blur->g_r, priv_blur->g_w);
-               }
-       }
-       if (*bm_o)
-               *bm_s = fix_outline_and_shadow(*bm_g, *bm_o);
-       else
-               *bm_s = copy_bitmap(*bm_g);
-
-       assert(bm_s);
-       return 0;
+    int bord = be ? (be / 4 + 1) : 0;
+    blur_radius *= 2;
+    bord = (blur_radius > 0.0) ? blur_radius + 1 : bord;
+
+    assert(bm_g && bm_o && bm_s);
+
+    *bm_g = *bm_o = *bm_s = 0;
+
+    if (glyph)
+        *bm_g = glyph_to_bitmap_internal(glyph, bord);
+    if (!*bm_g)
+        return 1;
+
+    if (outline_glyph) {
+        *bm_o = glyph_to_bitmap_internal(outline_glyph, bord);
+        if (!*bm_o) {
+            ass_free_bitmap(*bm_g);
+            return 1;
+        }
+    }
+    if (*bm_o)
+        resize_tmp(priv_blur, (*bm_o)->w, (*bm_o)->h);
+    resize_tmp(priv_blur, (*bm_g)->w, (*bm_g)->h);
+
+    if (be) {
+        while (be--) {
+            if (*bm_o)
+                be_blur((*bm_o)->buffer, (*bm_o)->w, (*bm_o)->h);
+            else
+                be_blur((*bm_g)->buffer, (*bm_g)->w, (*bm_g)->h);
+        }
+    } else {
+        if (blur_radius > 0.0) {
+            generate_tables(priv_blur, blur_radius);
+            if (*bm_o)
+                blur((*bm_o)->buffer, priv_blur->tmp, (*bm_o)->w,
+                     (*bm_o)->h, (*bm_o)->w, (int *) priv_blur->gt2,
+                     priv_blur->g_r, priv_blur->g_w);
+            else
+                blur((*bm_g)->buffer, priv_blur->tmp, (*bm_g)->w,
+                     (*bm_g)->h, (*bm_g)->w, (int *) priv_blur->gt2,
+                     priv_blur->g_r, priv_blur->g_w);
+        }
+    }
+    if (*bm_o)
+        *bm_s = fix_outline_and_shadow(*bm_g, *bm_o);
+    else
+        *bm_s = copy_bitmap(*bm_g);
+
+    assert(bm_s);
+    return 0;
 }
-
index c0b4ad201f6f5cbc874e1f1ddd95da3a1bf2fb58..73a36698b742a6e5f4f1e38f96a320b9920795e4 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 
 typedef struct ass_synth_priv_s ass_synth_priv_t;
 
-ass_synth_priv_tass_synth_init(double);
-void ass_synth_done(ass_synth_priv_tpriv);
+ass_synth_priv_t *ass_synth_init(double);
+void ass_synth_done(ass_synth_priv_t *priv);
 
 typedef struct bitmap_s {
-       int left, top;
-       int w, h; // width, height
-       unsigned char* buffer; // w x h buffer
+    int left, top;
+    int w, h;                   // width, height
+    unsigned char *buffer;      // w x h buffer
 } bitmap_t;
 
 /**
@@ -46,8 +44,11 @@ typedef struct bitmap_s {
  * \param bm_g out: pointer to the bitmap of glyph shadow is returned here
  * \param be 1 = produces blurred bitmaps, 0 = normal bitmaps
  */
-int glyph_to_bitmap(ass_synth_priv_t* priv_blur, FT_Glyph glyph, FT_Glyph outline_glyph, bitmap_t** bm_g, bitmap_t** bm_o, bitmap_t** bm_s, int be, double blur_radius);
+int glyph_to_bitmap(ass_synth_priv_t *priv_blur, FT_Glyph glyph,
+                    FT_Glyph outline_glyph, bitmap_t **bm_g,
+                    bitmap_t **bm_o, bitmap_t **bm_s, int be,
+                    double blur_radius);
 
-void ass_free_bitmap(bitmap_tbm);
+void ass_free_bitmap(bitmap_t *bm);
 
-#endif /* LIBASS_BITMAP_H */
+#endif                          /* LIBASS_BITMAP_H */
index 69efa55bcf6545c4ad7665174458df659ffb3416..534300d9621ef39e72c2d9c9cd85d457c2550089 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 
 #define FNV1_32A_INIT (unsigned)0x811c9dc5
 
-static inline unsigned fnv_32a_buf(voidbuf, size_t len, unsigned hval)
+static inline unsigned fnv_32a_buf(void *buf, size_t len, unsigned hval)
 {
-       unsigned char *bp = buf;
-       unsigned char *be = bp + len;
-       while (bp < be) {
-               hval ^= (unsigned)*bp++;
-               hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
-       }
-       return hval;
+    unsigned char *bp = buf;
+    unsigned char *be = bp + len;
+    while (bp < be) {
+        hval ^= (unsigned) *bp++;
+        hval +=
+            (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) +
+            (hval << 24);
+    }
+    return hval;
 }
-static inline unsigned fnv_32a_str(charstr, unsigned hval)
+static inline unsigned fnv_32a_str(char *str, unsigned hval)
 {
-       unsigned char* s = (unsigned char*)str;
-       while (*s) {
-               hval ^= (unsigned)*s++;
-               hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
-       }
-       return hval;
+    unsigned char *s = (unsigned char *) str;
+    while (*s) {
+        hval ^= (unsigned) *s++;
+        hval +=
+            (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) +
+            (hval << 24);
+    }
+    return hval;
 }
 
-static unsigned hashmap_hash(voidbuf, size_t len)
+static unsigned hashmap_hash(void *buf, size_t len)
 {
-       return fnv_32a_buf(buf, len, FNV1_32A_INIT);
+    return fnv_32a_buf(buf, len, FNV1_32A_INIT);
 }
 
-static int hashmap_key_compare(void* a, void* b, size_t size)
+static int hashmap_key_compare(void *a, void *b, size_t size)
 {
-       return memcmp(a, b, size) == 0;
+    return memcmp(a, b, size) == 0;
 }
 
-static void hashmap_item_dtor(void* key, size_t key_size, void* value, size_t value_size)
+static void hashmap_item_dtor(void *key, size_t key_size, void *value,
+                              size_t value_size)
 {
-       free(key);
-       free(value);
+    free(key);
+    free(value);
 }
 
-hashmap_t* hashmap_init(size_t key_size, size_t value_size, int nbuckets,
-                       hashmap_item_dtor_t item_dtor, hashmap_key_compare_t key_compare,
-                       hashmap_hash_t hash)
+hashmap_t *hashmap_init(size_t key_size, size_t value_size, int nbuckets,
+                        hashmap_item_dtor_t item_dtor,
+                        hashmap_key_compare_t key_compare,
+                        hashmap_hash_t hash)
 {
-       hashmap_t* map = calloc(1, sizeof(hashmap_t));
-       map->nbuckets = nbuckets;
-       map->key_size = key_size;
-       map->value_size = value_size;
-       map->root = calloc(nbuckets, sizeof(hashmap_item_p));
-       map->item_dtor = item_dtor ? item_dtor : hashmap_item_dtor;
-       map->key_compare = key_compare ? key_compare : hashmap_key_compare;
-       map->hash = hash ? hash : hashmap_hash;
-       return map;
+    hashmap_t *map = calloc(1, sizeof(hashmap_t));
+    map->nbuckets = nbuckets;
+    map->key_size = key_size;
+    map->value_size = value_size;
+    map->root = calloc(nbuckets, sizeof(hashmap_item_p));
+    map->item_dtor = item_dtor ? item_dtor : hashmap_item_dtor;
+    map->key_compare = key_compare ? key_compare : hashmap_key_compare;
+    map->hash = hash ? hash : hashmap_hash;
+    return map;
 }
 
-void hashmap_done(hashmap_tmap)
+void hashmap_done(hashmap_t *map)
 {
-       int i;
-       // print stats
-       if (map->count > 0 || map->hit_count + map->miss_count > 0)
-               mp_msg(MSGT_ASS, MSGL_V, "cache statistics: \n  total accesses: %d\n  hits: %d\n  misses: %d\n  object count: %d\n",
-                      map->hit_count + map->miss_count, map->hit_count, map->miss_count, map->count);
+    int i;
+    // print stats
+    if (map->count > 0 || map->hit_count + map->miss_count > 0)
+        mp_msg(MSGT_ASS, MSGL_V,
+               "cache statistics: \n  total accesses: %d\n  hits: %d\n  misses: %d\n  object count: %d\n",
+               map->hit_count + map->miss_count, map->hit_count,
+               map->miss_count, map->count);
 
-       for (i = 0; i < map->nbuckets; ++i) {
-               hashmap_item_t* item = map->root[i];
-               while (item) {
-                       hashmap_item_t* next = item->next;
-                       map->item_dtor(item->key, map->key_size, item->value, map->value_size);
-                       free(item);
-                       item = next;
-               }
-       }
-       free(map->root);
-       free(map);
+    for (i = 0; i < map->nbuckets; ++i) {
+        hashmap_item_t *item = map->root[i];
+        while (item) {
+            hashmap_item_t *next = item->next;
+            map->item_dtor(item->key, map->key_size, item->value,
+                           map->value_size);
+            free(item);
+            item = next;
+        }
+    }
+    free(map->root);
+    free(map);
 }
 
 // does nothing if key already exists
-void* hashmap_insert(hashmap_t* map, void* key, void* value)
-{
-       unsigned hash = map->hash(key, map->key_size);
-       hashmap_item_t** next = map->root + (hash % map->nbuckets);
-       while (*next) {
-               if (map->key_compare(key, (*next)->key, map->key_size))
-                       return (*next)->value;
-               next = &((*next)->next);
-               assert(next);
-       }
-       (*next) = malloc(sizeof(hashmap_item_t));
-       (*next)->key = malloc(map->key_size);
-       (*next)->value = malloc(map->value_size);
-       memcpy((*next)->key, key, map->key_size);
-       memcpy((*next)->value, value, map->value_size);
-       (*next)->next = 0;
-
-       map->count ++;
-       return (*next)->value;
-}
-
-void* hashmap_find(hashmap_t* map, void* key)
-{
-       unsigned hash = map->hash(key, map->key_size);
-       hashmap_item_t* item = map->root[hash % map->nbuckets];
-       while (item) {
-               if (map->key_compare(key, item->key, map->key_size)) {
-                       map->hit_count++;
-                       return item->value;
-               }
-               item = item->next;
-       }
-       map->miss_count++;
-       return 0;
+void *hashmap_insert(hashmap_t *map, void *key, void *value)
+{
+    unsigned hash = map->hash(key, map->key_size);
+    hashmap_item_t **next = map->root + (hash % map->nbuckets);
+    while (*next) {
+        if (map->key_compare(key, (*next)->key, map->key_size))
+            return (*next)->value;
+        next = &((*next)->next);
+        assert(next);
+    }
+    (*next) = malloc(sizeof(hashmap_item_t));
+    (*next)->key = malloc(map->key_size);
+    (*next)->value = malloc(map->value_size);
+    memcpy((*next)->key, key, map->key_size);
+    memcpy((*next)->value, value, map->value_size);
+    (*next)->next = 0;
+
+    map->count++;
+    return (*next)->value;
+}
+
+void *hashmap_find(hashmap_t *map, void *key)
+{
+    unsigned hash = map->hash(key, map->key_size);
+    hashmap_item_t *item = map->root[hash % map->nbuckets];
+    while (item) {
+        if (map->key_compare(key, item->key, map->key_size)) {
+            map->hit_count++;
+            return item->value;
+        }
+        item = item->next;
+    }
+    map->miss_count++;
+    return 0;
 }
 
 //---------------------------------
 // font cache
 
-static unsigned font_desc_hash(voidbuf, size_t len)
+static unsigned font_desc_hash(void *buf, size_t len)
 {
-       ass_font_desc_t* desc = buf;
-       unsigned hval;
-       hval = fnv_32a_str(desc->family, FNV1_32A_INIT);
-       hval = fnv_32a_buf(&desc->bold, sizeof(desc->bold), hval);
-       hval = fnv_32a_buf(&desc->italic, sizeof(desc->italic), hval);
-       return hval;
+    ass_font_desc_t *desc = buf;
+    unsigned hval;
+    hval = fnv_32a_str(desc->family, FNV1_32A_INIT);
+    hval = fnv_32a_buf(&desc->bold, sizeof(desc->bold), hval);
+    hval = fnv_32a_buf(&desc->italic, sizeof(desc->italic), hval);
+    return hval;
 }
 
-static int font_compare(void* key1, void* key2, size_t key_size) {
-       ass_font_desc_t* a = key1;
-       ass_font_desc_t* b = key2;
-       if (strcmp(a->family, b->family) != 0)
-               return 0;
-       if (a->bold != b->bold)
-               return 0;
-       if (a->italic != b->italic)
-               return 0;
-       if (a->treat_family_as_pattern != b->treat_family_as_pattern)
-               return 0;
-       return 1;
+static int font_compare(void *key1, void *key2, size_t key_size)
+{
+    ass_font_desc_t *a = key1;
+    ass_font_desc_t *b = key2;
+    if (strcmp(a->family, b->family) != 0)
+        return 0;
+    if (a->bold != b->bold)
+        return 0;
+    if (a->italic != b->italic)
+        return 0;
+    if (a->treat_family_as_pattern != b->treat_family_as_pattern)
+        return 0;
+    return 1;
 }
 
-static void font_hash_dtor(void* key, size_t key_size, void* value, size_t value_size)
+static void font_hash_dtor(void *key, size_t key_size, void *value,
+                           size_t value_size)
 {
-       ass_font_free(value);
-       free(key);
+    ass_font_free(value);
+    free(key);
 }
 
-ass_font_t* ass_font_cache_find(hashmap_t* font_cache, ass_font_desc_t* desc)
+ass_font_t *ass_font_cache_find(hashmap_t *font_cache,
+                                ass_font_desc_t *desc)
 {
-       return hashmap_find(font_cache, desc);
+    return hashmap_find(font_cache, desc);
 }
 
 /**
  * \brief Add a face struct to cache.
  * \param font font struct
 */
-void* ass_font_cache_add(hashmap_t* font_cache, ass_font_t* font)
+void *ass_font_cache_add(hashmap_t *font_cache, ass_font_t *font)
 {
-       return hashmap_insert(font_cache, &(font->desc), font);
+    return hashmap_insert(font_cache, &(font->desc), font);
 }
 
-hashmap_tass_font_cache_init(void)
+hashmap_t *ass_font_cache_init(void)
 {
-       hashmap_t* font_cache;
-       font_cache = hashmap_init(sizeof(ass_font_desc_t),
-                                 sizeof(ass_font_t),
-                                 1000,
-                                 font_hash_dtor, font_compare, font_desc_hash);
-       return font_cache;
+    hashmap_t *font_cache;
+    font_cache = hashmap_init(sizeof(ass_font_desc_t),
+                              sizeof(ass_font_t),
+                              1000,
+                              font_hash_dtor, font_compare, font_desc_hash);
+    return font_cache;
 }
 
-void ass_font_cache_done(hashmap_tfont_cache)
+void ass_font_cache_done(hashmap_t *font_cache)
 {
-       hashmap_done(font_cache);
+    hashmap_done(font_cache);
 }
 
 
@@ -220,19 +230,24 @@ void ass_font_cache_done(hashmap_t* font_cache)
 //---------------------------------
 // bitmap cache
 
-static void bitmap_hash_dtor(void* key, size_t key_size, void* value, size_t value_size)
+static void bitmap_hash_dtor(void *key, size_t key_size, void *value,
+                             size_t value_size)
 {
-       bitmap_hash_val_t* v = value;
-       if (v->bm) ass_free_bitmap(v->bm);
-       if (v->bm_o) ass_free_bitmap(v->bm_o);
-       if (v->bm_s) ass_free_bitmap(v->bm_s);
-       free(key);
-       free(value);
+    bitmap_hash_val_t *v = value;
+    if (v->bm)
+        ass_free_bitmap(v->bm);
+    if (v->bm_o)
+        ass_free_bitmap(v->bm_o);
+    if (v->bm_s)
+        ass_free_bitmap(v->bm_s);
+    free(key);
+    free(value);
 }
 
-void* cache_add_bitmap(hashmap_t* bitmap_cache, bitmap_hash_key_t* key, bitmap_hash_val_t* val)
+void *cache_add_bitmap(hashmap_t *bitmap_cache, bitmap_hash_key_t *key,
+                       bitmap_hash_val_t *val)
 {
-       return hashmap_insert(bitmap_cache, key, val);
+    return hashmap_insert(bitmap_cache, key, val);
 }
 
 /**
@@ -240,48 +255,53 @@ void* cache_add_bitmap(hashmap_t* bitmap_cache, bitmap_hash_key_t* key, bitmap_h
  * \param key hash key
  * \return requested hash val or 0 if not found
 */
-bitmap_hash_val_t* cache_find_bitmap(hashmap_t* bitmap_cache, bitmap_hash_key_t* key)
+bitmap_hash_val_t *cache_find_bitmap(hashmap_t *bitmap_cache,
+                                     bitmap_hash_key_t *key)
 {
-       return hashmap_find(bitmap_cache, key);
+    return hashmap_find(bitmap_cache, key);
 }
 
-hashmap_tass_bitmap_cache_init(void)
+hashmap_t *ass_bitmap_cache_init(void)
 {
-       hashmap_t* bitmap_cache;
-       bitmap_cache = hashmap_init(sizeof(bitmap_hash_key_t),
-                                  sizeof(bitmap_hash_val_t),
-                                  0xFFFF + 13,
-                                  bitmap_hash_dtor, bitmap_compare,
-                                  bitmap_hash);
-       return bitmap_cache;
+    hashmap_t *bitmap_cache;
+    bitmap_cache = hashmap_init(sizeof(bitmap_hash_key_t),
+                                sizeof(bitmap_hash_val_t),
+                                0xFFFF + 13,
+                                bitmap_hash_dtor, bitmap_compare,
+                                bitmap_hash);
+    return bitmap_cache;
 }
 
-void ass_bitmap_cache_done(hashmap_tbitmap_cache)
+void ass_bitmap_cache_done(hashmap_t *bitmap_cache)
 {
-       hashmap_done(bitmap_cache);
+    hashmap_done(bitmap_cache);
 }
 
-hashmap_t* ass_bitmap_cache_reset(hashmap_t* bitmap_cache)
+hashmap_t *ass_bitmap_cache_reset(hashmap_t *bitmap_cache)
 {
-       ass_bitmap_cache_done(bitmap_cache);
-       return ass_bitmap_cache_init();
+    ass_bitmap_cache_done(bitmap_cache);
+    return ass_bitmap_cache_init();
 }
 
 //---------------------------------
 // glyph cache
 
-static void glyph_hash_dtor(void* key, size_t key_size, void* value, size_t value_size)
+static void glyph_hash_dtor(void *key, size_t key_size, void *value,
+                            size_t value_size)
 {
-       glyph_hash_val_t* v = value;
-       if (v->glyph) FT_Done_Glyph(v->glyph);
-       if (v->outline_glyph) FT_Done_Glyph(v->outline_glyph);
-       free(key);
-       free(value);
+    glyph_hash_val_t *v = value;
+    if (v->glyph)
+        FT_Done_Glyph(v->glyph);
+    if (v->outline_glyph)
+        FT_Done_Glyph(v->outline_glyph);
+    free(key);
+    free(value);
 }
 
-void* cache_add_glyph(hashmap_t* glyph_cache, glyph_hash_key_t* key, glyph_hash_val_t* val)
+void *cache_add_glyph(hashmap_t *glyph_cache, glyph_hash_key_t *key,
+                      glyph_hash_val_t *val)
 {
-       return hashmap_insert(glyph_cache, key, val);
+    return hashmap_insert(glyph_cache, key, val);
 }
 
 /**
@@ -289,48 +309,52 @@ void* cache_add_glyph(hashmap_t* glyph_cache, glyph_hash_key_t* key, glyph_hash_
  * \param key hash key
  * \return requested hash val or 0 if not found
 */
-glyph_hash_val_t* cache_find_glyph(hashmap_t* glyph_cache, glyph_hash_key_t* key)
+glyph_hash_val_t *cache_find_glyph(hashmap_t *glyph_cache,
+                                   glyph_hash_key_t *key)
 {
-       return hashmap_find(glyph_cache, key);
+    return hashmap_find(glyph_cache, key);
 }
 
-hashmap_tass_glyph_cache_init(void)
+hashmap_t *ass_glyph_cache_init(void)
 {
-       hashmap_t* glyph_cache;
-       glyph_cache = hashmap_init(sizeof(glyph_hash_key_t),
-                                  sizeof(glyph_hash_val_t),
-                                  0xFFFF + 13,
-                                  glyph_hash_dtor, glyph_compare, glyph_hash);
-       return glyph_cache;
+    hashmap_t *glyph_cache;
+    glyph_cache = hashmap_init(sizeof(glyph_hash_key_t),
+                               sizeof(glyph_hash_val_t),
+                               0xFFFF + 13,
+                               glyph_hash_dtor, glyph_compare, glyph_hash);
+    return glyph_cache;
 }
 
-void ass_glyph_cache_done(hashmap_tglyph_cache)
+void ass_glyph_cache_done(hashmap_t *glyph_cache)
 {
-       hashmap_done(glyph_cache);
+    hashmap_done(glyph_cache);
 }
 
-hashmap_t* ass_glyph_cache_reset(hashmap_t* glyph_cache)
+hashmap_t *ass_glyph_cache_reset(hashmap_t *glyph_cache)
 {
-       ass_glyph_cache_done(glyph_cache);
-       return ass_glyph_cache_init();
+    ass_glyph_cache_done(glyph_cache);
+    return ass_glyph_cache_init();
 }
 
 
 //---------------------------------
 // composite cache
 
-static void composite_hash_dtor(void* key, size_t key_size, void* value, size_t value_size)
+static void composite_hash_dtor(void *key, size_t key_size, void *value,
+                                size_t value_size)
 {
-       composite_hash_val_t* v = value;
-       free(v->a);
-       free(v->b);
-       free(key);
-       free(value);
+    composite_hash_val_t *v = value;
+    free(v->a);
+    free(v->b);
+    free(key);
+    free(value);
 }
 
-void* cache_add_composite(hashmap_t* composite_cache, composite_hash_key_t* key, composite_hash_val_t* val)
+void *cache_add_composite(hashmap_t *composite_cache,
+                          composite_hash_key_t *key,
+                          composite_hash_val_t *val)
 {
-       return hashmap_insert(composite_cache, key, val);
+    return hashmap_insert(composite_cache, key, val);
 }
 
 /**
@@ -338,29 +362,29 @@ void* cache_add_composite(hashmap_t* composite_cache, composite_hash_key_t* key,
  * \param key hash key
  * \return requested hash val or 0 if not found
 */
-composite_hash_val_t* cache_find_composite(hashmap_t* composite_cache, composite_hash_key_t* key)
+composite_hash_val_t *cache_find_composite(hashmap_t *composite_cache,
+                                           composite_hash_key_t *key)
 {
-       return hashmap_find(composite_cache, key);
+    return hashmap_find(composite_cache, key);
 }
 
-hashmap_tass_composite_cache_init(void)
+hashmap_t *ass_composite_cache_init(void)
 {
-       hashmap_t* composite_cache;
-       composite_cache = hashmap_init(sizeof(composite_hash_key_t),
-                                  sizeof(composite_hash_val_t),
-                                  0xFFFF + 13,
-                                  composite_hash_dtor, NULL, NULL);
-       return composite_cache;
+    hashmap_t *composite_cache;
+    composite_cache = hashmap_init(sizeof(composite_hash_key_t),
+                                   sizeof(composite_hash_val_t),
+                                   0xFFFF + 13,
+                                   composite_hash_dtor, NULL, NULL);
+    return composite_cache;
 }
 
-void ass_composite_cache_done(hashmap_tcomposite_cache)
+void ass_composite_cache_done(hashmap_t *composite_cache)
 {
-       hashmap_done(composite_cache);
+    hashmap_done(composite_cache);
 }
 
-hashmap_t* ass_composite_cache_reset(hashmap_t* composite_cache)
+hashmap_t *ass_composite_cache_reset(hashmap_t *composite_cache)
 {
-       ass_composite_cache_done(composite_cache);
-       return ass_composite_cache_init();
+    ass_composite_cache_done(composite_cache);
+    return ass_composite_cache_init();
 }
-
index 55c543e2c2092e820bd747c39ab7fd2fe8acc81d..f374b86fcc70be57fd909667ba78072dc2bc4229 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 #include "ass_font.h"
 #include "ass_bitmap.h"
 
-typedef void (*hashmap_item_dtor_t)(void* key, size_t key_size, void* value, size_t value_size);
-typedef int (*hashmap_key_compare_t)(void* key1, void* key2, size_t key_size);
-typedef unsigned (*hashmap_hash_t)(void* key, size_t key_size);
+typedef void (*hashmap_item_dtor_t) (void *key, size_t key_size,
+                                     void *value, size_t value_size);
+typedef int (*hashmap_key_compare_t) (void *key1, void *key2,
+                                      size_t key_size);
+typedef unsigned (*hashmap_hash_t) (void *key, size_t key_size);
 
 typedef struct hashmap_item_s {
-       void* key;
-       void* value;
-       struct hashmap_item_s* next;
+    void *key;
+    void *value;
+    struct hashmap_item_s *next;
 } hashmap_item_t;
-typedef hashmap_item_thashmap_item_p;
+typedef hashmap_item_t *hashmap_item_p;
 
 typedef struct hashmap_s {
-       int nbuckets;
-       size_t key_size, value_size;
-       hashmap_item_p* root;
-       hashmap_item_dtor_t item_dtor; // a destructor for hashmap key/value pairs
-       hashmap_key_compare_t key_compare;
-       hashmap_hash_t hash;
-       // stats
-       int hit_count;
-       int miss_count;
-       int count;
+    int nbuckets;
+    size_t key_size, value_size;
+    hashmap_item_p *root;
+    hashmap_item_dtor_t item_dtor;      // a destructor for hashmap key/value pairs
+    hashmap_key_compare_t key_compare;
+    hashmap_hash_t hash;
+    // stats
+    int hit_count;
+    int miss_count;
+    int count;
 } hashmap_t;
 
-hashmap_t* hashmap_init(size_t key_size, size_t value_size, int nbuckets,
-                       hashmap_item_dtor_t item_dtor, hashmap_key_compare_t key_compare,
-                       hashmap_hash_t hash);
-void hashmap_done(hashmap_t* map);
-void* hashmap_insert(hashmap_t* map, void* key, void* value);
-void* hashmap_find(hashmap_t* map, void* key);
+hashmap_t *hashmap_init(size_t key_size, size_t value_size, int nbuckets,
+                        hashmap_item_dtor_t item_dtor,
+                        hashmap_key_compare_t key_compare,
+                        hashmap_hash_t hash);
+void hashmap_done(hashmap_t *map);
+void *hashmap_insert(hashmap_t *map, void *key, void *value);
+void *hashmap_find(hashmap_t *map, void *key);
 
-hashmap_tass_font_cache_init(void);
-ass_font_t* ass_font_cache_find(hashmap_t*, ass_font_desc_t* desc);
-void* ass_font_cache_add(hashmap_t*, ass_font_t* font);
-void ass_font_cache_done(hashmap_t*);
+hashmap_t *ass_font_cache_init(void);
+ass_font_t *ass_font_cache_find(hashmap_t *, ass_font_desc_t *desc);
+void *ass_font_cache_add(hashmap_t *, ass_font_t *font);
+void ass_font_cache_done(hashmap_t *);
 
 // Create definitions for bitmap_hash_key and glyph_hash_key
 #define CREATE_STRUCT_DEFINITIONS
 #include "ass_cache_template.c"
 
 typedef struct bitmap_hash_val_s {
-       bitmap_t* bm; // the actual bitmaps
-       bitmap_t* bm_o;
-       bitmap_t* bm_s;
+    bitmap_t *bm;               // the actual bitmaps
+    bitmap_t *bm_o;
+    bitmap_t *bm_s;
 } bitmap_hash_val_t;
 
-hashmap_t* ass_bitmap_cache_init(void);
-void* cache_add_bitmap(hashmap_t*, bitmap_hash_key_t* key, bitmap_hash_val_t* val);
-bitmap_hash_val_t* cache_find_bitmap(hashmap_t* bitmap_cache, bitmap_hash_key_t* key);
-hashmap_t* ass_bitmap_cache_reset(hashmap_t* bitmap_cache);
-void ass_bitmap_cache_done(hashmap_t* bitmap_cache);
+hashmap_t *ass_bitmap_cache_init(void);
+void *cache_add_bitmap(hashmap_t *, bitmap_hash_key_t *key,
+                       bitmap_hash_val_t *val);
+bitmap_hash_val_t *cache_find_bitmap(hashmap_t *bitmap_cache,
+                                     bitmap_hash_key_t *key);
+hashmap_t *ass_bitmap_cache_reset(hashmap_t *bitmap_cache);
+void ass_bitmap_cache_done(hashmap_t *bitmap_cache);
 
 
 // Cache for composited bitmaps
 typedef struct composite_hash_key_s {
-       int aw, ah, bw, bh;
-       int ax, ay, bx, by;
-       bitmap_hash_key_t a;
-       bitmap_hash_key_t b;
+    int aw, ah, bw, bh;
+    int ax, ay, bx, by;
+    bitmap_hash_key_t a;
+    bitmap_hash_key_t b;
 } composite_hash_key_t;
 
 typedef struct composite_hash_val_s {
-       unsigned char* a;
-       unsigned char* b;
+    unsigned char *a;
+    unsigned char *b;
 } composite_hash_val_t;
 
-hashmap_t* ass_composite_cache_init(void);
-void* cache_add_composite(hashmap_t*, composite_hash_key_t* key, composite_hash_val_t* val);
-composite_hash_val_t* cache_find_composite(hashmap_t* composite_cache, composite_hash_key_t* key);
-hashmap_t* ass_composite_cache_reset(hashmap_t* composite_cache);
-void ass_composite_cache_done(hashmap_t* composite_cache);
+hashmap_t *ass_composite_cache_init(void);
+void *cache_add_composite(hashmap_t *, composite_hash_key_t *key,
+                          composite_hash_val_t *val);
+composite_hash_val_t *cache_find_composite(hashmap_t *composite_cache,
+                                           composite_hash_key_t *key);
+hashmap_t *ass_composite_cache_reset(hashmap_t *composite_cache);
+void ass_composite_cache_done(hashmap_t *composite_cache);
 
 
 typedef struct glyph_hash_val_s {
-       FT_Glyph glyph;
-       FT_Glyph outline_glyph;
-       FT_BBox bbox_scaled; // bbox after scaling, but before rotation
-       FT_Vector advance; // 26.6, advance distance to the next bitmap in line
+    FT_Glyph glyph;
+    FT_Glyph outline_glyph;
+    FT_BBox bbox_scaled;        // bbox after scaling, but before rotation
+    FT_Vector advance;          // 26.6, advance distance to the next bitmap in line
 } glyph_hash_val_t;
 
-hashmap_t* ass_glyph_cache_init(void);
-void* cache_add_glyph(hashmap_t*, glyph_hash_key_t* key, glyph_hash_val_t* val);
-glyph_hash_val_t* cache_find_glyph(hashmap_t* glyph_cache, glyph_hash_key_t* key);
-hashmap_t* ass_glyph_cache_reset(hashmap_t* glyph_cache);
-void ass_glyph_cache_done(hashmap_t* glyph_cache);
+hashmap_t *ass_glyph_cache_init(void);
+void *cache_add_glyph(hashmap_t *, glyph_hash_key_t *key,
+                      glyph_hash_val_t *val);
+glyph_hash_val_t *cache_find_glyph(hashmap_t *glyph_cache,
+                                   glyph_hash_key_t *key);
+hashmap_t *ass_glyph_cache_reset(hashmap_t *glyph_cache);
+void ass_glyph_cache_done(hashmap_t *glyph_cache);
 
-#endif /* LIBASS_CACHE_H */
+#endif                          /* LIBASS_CACHE_H */
index 7f9ec95f570348f464c08b7b157efefb392a989f..b03de5387afd1e579ac75f093deadc3fe0a635d1 100644 (file)
@@ -16,7 +16,7 @@
     { \
         struct structname *a = key1; \
         struct structname *b = key2; \
-        return // conditions follow
+        return                  // conditions follow
 #define GENERIC(type, member) \
             a->member == b->member &&
 #define FTVECTOR(member) \
 
 // describes a bitmap; bitmaps with equivalents structs are considered identical
 START(bitmap, bipmap_hash_key_s)
-    GENERIC(char, bitmap) // bool : true = bitmap, false = outline
+    GENERIC(char, bitmap)       // bool : true = bitmap, false = outline
     GENERIC(ass_font_t *, font)
-    GENERIC(double, size) // font size
-    GENERIC(uint32_t, ch) // character code
-    GENERIC(unsigned, outline) // border width, 16.16 fixed point value
-    GENERIC(int, bold)
-    GENERIC(int, italic)
-    GENERIC(char, be) // blur edges
-    GENERIC(double, blur) // gaussian blur
-    GENERIC(unsigned, scale_x) // 16.16
-    GENERIC(unsigned, scale_y) // 16.16
-    GENERIC(int, frx) // signed 16.16
-    GENERIC(int, fry) // signed 16.16
-    GENERIC(int, frz) // signed 16.16
+    GENERIC(double, size)       // font size
+    GENERIC(uint32_t, ch)           // character code
+    GENERIC(unsigned, outline)      // border width, 16.16 fixed point value
+    GENERIC(int, bold) GENERIC(int, italic) GENERIC(char, be)       // blur edges
+    GENERIC(double, blur)           // gaussian blur
+    GENERIC(unsigned, scale_x)      // 16.16
+    GENERIC(unsigned, scale_y)      // 16.16
+    GENERIC(int, frx)               // signed 16.16
+    GENERIC(int, fry)               // signed 16.16
+    GENERIC(int, frz)               // signed 16.16
     // shift vector that was added to glyph before applying rotation
     // = 0, if frx = fry = frx = 0
     // = (glyph base point) - (rotation origin), otherwise
-    GENERIC(int, shift_x)
-    GENERIC(int, shift_y)
-    FTVECTOR(advance) // subpixel shift vector
-END(bitmap_hash_key_t)
-
-// describes an outline glyph
-START(glyph, glyph_hash_key_s)
-    GENERIC(ass_font_t *, font)
-    GENERIC(double, size) // font size
-    GENERIC(uint32_t, ch) // character code
-    GENERIC(int, bold)
-    GENERIC(int, italic)
-    GENERIC(unsigned, scale_x) // 16.16
-    GENERIC(unsigned, scale_y) // 16.16
-    FTVECTOR(advance) // subpixel shift vector
-    GENERIC(unsigned, outline) // border width, 16.16
+    GENERIC(int, shift_x) GENERIC(int, shift_y) FTVECTOR(advance)   // subpixel shift vector
+    END(bitmap_hash_key_t)
+    // describes an outline glyph
+    START(glyph, glyph_hash_key_s) GENERIC(ass_font_t *, font) GENERIC(double, size)        // font size
+    GENERIC(uint32_t, ch)           // character code
+    GENERIC(int, bold) GENERIC(int, italic) GENERIC(unsigned, scale_x)      // 16.16
+    GENERIC(unsigned, scale_y)      // 16.16
+    FTVECTOR(advance)               // subpixel shift vector
+    GENERIC(unsigned, outline)      // border width, 16.16
 END(glyph_hash_key_t)
-
 #undef START
 #undef GENERIC
 #undef FTVECTOR
index 57b2fdf14eb30bbf296fd2ea9584308f23beb73e..b34239356b613cc58c761909971620d251d5a5d6 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
  */
 static void charmap_magic(FT_Face face)
 {
-       int i;
-       for (i = 0; i < face->num_charmaps; ++i) {
-               FT_CharMap cmap = face->charmaps[i];
-               unsigned pid = cmap->platform_id;
-               unsigned eid = cmap->encoding_id;
-               if (pid == 3 /*microsoft*/ && (eid == 1 /*unicode bmp*/ || eid == 10 /*full unicode*/)) {
-                       FT_Set_Charmap(face, cmap);
-                       return;
-               }
-       }
-
-       if (!face->charmap) {
-               if (face->num_charmaps == 0) {
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NoCharmaps);
-                       return;
-               }
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NoCharmapAutodetected);
-               FT_Set_Charmap(face, face->charmaps[0]);
-               return;
-       }
+    int i;
+    for (i = 0; i < face->num_charmaps; ++i) {
+        FT_CharMap cmap = face->charmaps[i];
+        unsigned pid = cmap->platform_id;
+        unsigned eid = cmap->encoding_id;
+        if (pid == 3 /*microsoft */ 
+            && (eid == 1 /*unicode bmp */ 
+                || eid == 10 /*full unicode */ )) {
+            FT_Set_Charmap(face, cmap);
+            return;
+        }
+    }
+
+    if (!face->charmap) {
+        if (face->num_charmaps == 0) {
+            mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NoCharmaps);
+            return;
+        }
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NoCharmapAutodetected);
+        FT_Set_Charmap(face, face->charmaps[0]);
+        return;
+    }
 }
 
-static void update_transform(ass_font_tfont)
+static void update_transform(ass_font_t *font)
 {
-       int i;
-       FT_Matrix m;
-       m.xx = double_to_d16(font->scale_x);
-       m.yy = double_to_d16(font->scale_y);
-       m.xy = m.yx = 0;
-       for (i = 0; i < font->n_faces; ++i)
-               FT_Set_Transform(font->faces[i], &m, &font->v);
+    int i;
+    FT_Matrix m;
+    m.xx = double_to_d16(font->scale_x);
+    m.yy = double_to_d16(font->scale_y);
+    m.xy = m.yx = 0;
+    for (i = 0; i < font->n_faces; ++i)
+        FT_Set_Transform(font->faces[i], &m, &font->v);
 }
 
 /**
  * \brief find a memory font by name
  */
-static int find_font(ass_library_t* library, char* name)
+static int find_font(ass_library_t *library, char *name)
 {
-       int i;
-       for (i = 0; i < library->num_fontdata; ++i)
-               if (strcasecmp(name, library->fontdata[i].name) == 0)
-                       return i;
-       return -1;
+    int i;
+    for (i = 0; i < library->num_fontdata; ++i)
+        if (strcasecmp(name, library->fontdata[i].name) == 0)
+            return i;
+    return -1;
 }
 
 static void face_set_size(FT_Face face, double size);
 
 static void buggy_font_workaround(FT_Face face)
 {
-       // Some fonts have zero Ascender/Descender fields in 'hhea' table.
-       // In this case, get the information from 'os2' table or, as
-       // a last resort, from face.bbox.
-       if (face->ascender + face->descender == 0 || face->height == 0) {
-               TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
-               if (os2) {
-                       face->ascender = os2->sTypoAscender;
-                       face->descender = os2->sTypoDescender;
-                       face->height = face->ascender - face->descender;
-               } else {
-                       face->ascender = face->bbox.yMax;
-                       face->descender = face->bbox.yMin;
-                       face->height = face->ascender - face->descender;
-               }
-       }
+    // Some fonts have zero Ascender/Descender fields in 'hhea' table.
+    // In this case, get the information from 'os2' table or, as
+    // a last resort, from face.bbox.
+    if (face->ascender + face->descender == 0 || face->height == 0) {
+        TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+        if (os2) {
+            face->ascender = os2->sTypoAscender;
+            face->descender = os2->sTypoDescender;
+            face->height = face->ascender - face->descender;
+        } else {
+            face->ascender = face->bbox.yMax;
+            face->descender = face->bbox.yMin;
+            face->height = face->ascender - face->descender;
+        }
+    }
 }
 
 /**
  * \brief Select a face with the given charcode and add it to ass_font_t
  * \return index of the new face in font->faces, -1 if failed
  */
-static int add_face(void* fc_priv, ass_font_t* font, uint32_t ch)
+static int add_face(void *fc_priv, ass_font_t *font, uint32_t ch)
 {
-       char* path;
-       int index;
-       FT_Face face;
-       int error;
-       int mem_idx;
-
-       if (font->n_faces == ASS_FONT_MAX_FACES)
-               return -1;
-
-       path = fontconfig_select(fc_priv, font->desc.family, font->desc.treat_family_as_pattern, font->desc.bold,
-                                             font->desc.italic, &index, ch);
-       if (!path)
-               return -1;
-
-       mem_idx = find_font(font->library, path);
-       if (mem_idx >= 0) {
-               error = FT_New_Memory_Face(font->ftlibrary, (unsigned char*)font->library->fontdata[mem_idx].data,
-                                          font->library->fontdata[mem_idx].size, 0, &face);
-               if (error) {
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningMemoryFont, path);
-                       return -1;
-               }
-       } else {
-               error = FT_New_Face(font->ftlibrary, path, index, &face);
-               if (error) {
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningFont, path, index);
-                       return -1;
-               }
-       }
-       charmap_magic(face);
-       buggy_font_workaround(face);
-
-       font->faces[font->n_faces++] = face;
-       update_transform(font);
-       face_set_size(face, font->size);
-       return font->n_faces - 1;
+    char *path;
+    int index;
+    FT_Face face;
+    int error;
+    int mem_idx;
+
+    if (font->n_faces == ASS_FONT_MAX_FACES)
+        return -1;
+
+    path =
+        fontconfig_select(fc_priv, font->desc.family,
+                          font->desc.treat_family_as_pattern,
+                          font->desc.bold, font->desc.italic, &index, ch);
+    if (!path)
+        return -1;
+
+    mem_idx = find_font(font->library, path);
+    if (mem_idx >= 0) {
+        error =
+            FT_New_Memory_Face(font->ftlibrary,
+                               (unsigned char *) font->library->
+                               fontdata[mem_idx].data,
+                               font->library->fontdata[mem_idx].size, 0,
+                               &face);
+        if (error) {
+            mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningMemoryFont,
+                   path);
+            return -1;
+        }
+    } else {
+        error = FT_New_Face(font->ftlibrary, path, index, &face);
+        if (error) {
+            mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningFont, path,
+                   index);
+            return -1;
+        }
+    }
+    charmap_magic(face);
+    buggy_font_workaround(face);
+
+    font->faces[font->n_faces++] = face;
+    update_transform(font);
+    face_set_size(face, font->size);
+    return font->n_faces - 1;
 }
 
 /**
  * \brief Create a new ass_font_t according to "desc" argument
  */
-ass_font_t* ass_font_new(void* font_cache, ass_library_t* library, FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc)
+ass_font_t *ass_font_new(void *font_cache, ass_library_t *library,
+                         FT_Library ftlibrary, void *fc_priv,
+                         ass_font_desc_t *desc)
 {
-       int error;
-       ass_font_t* fontp;
-       ass_font_t font;
-
-       fontp = ass_font_cache_find((hashmap_t*)font_cache, desc);
-       if (fontp)
-               return fontp;
-
-       font.library = library;
-       font.ftlibrary = ftlibrary;
-       font.n_faces = 0;
-       font.desc.family = strdup(desc->family);
-       font.desc.treat_family_as_pattern = desc->treat_family_as_pattern;
-       font.desc.bold = desc->bold;
-       font.desc.italic = desc->italic;
-
-       font.scale_x = font.scale_y = 1.;
-       font.v.x = font.v.y = 0;
-       font.size = 0.;
-
-       error = add_face(fc_priv, &font, 0);
-       if (error == -1) {
-               free(font.desc.family);
-               return 0;
-       } else
-               return ass_font_cache_add((hashmap_t*)font_cache, &font);
+    int error;
+    ass_font_t *fontp;
+    ass_font_t font;
+
+    fontp = ass_font_cache_find((hashmap_t *) font_cache, desc);
+    if (fontp)
+        return fontp;
+
+    font.library = library;
+    font.ftlibrary = ftlibrary;
+    font.n_faces = 0;
+    font.desc.family = strdup(desc->family);
+    font.desc.treat_family_as_pattern = desc->treat_family_as_pattern;
+    font.desc.bold = desc->bold;
+    font.desc.italic = desc->italic;
+
+    font.scale_x = font.scale_y = 1.;
+    font.v.x = font.v.y = 0;
+    font.size = 0.;
+
+    error = add_face(fc_priv, &font, 0);
+    if (error == -1) {
+        free(font.desc.family);
+        return 0;
+    } else
+        return ass_font_cache_add((hashmap_t *) font_cache, &font);
 }
 
 /**
  * \brief Set font transformation matrix and shift vector
  **/
-void ass_font_set_transform(ass_font_t* font, double scale_x, double scale_y, FT_Vector* v)
+void ass_font_set_transform(ass_font_t *font, double scale_x,
+                            double scale_y, FT_Vector * v)
 {
-       font->scale_x = scale_x;
-       font->scale_y = scale_y;
-       font->v.x = v->x;
-       font->v.y = v->y;
-       update_transform(font);
+    font->scale_x = scale_x;
+    font->scale_y = scale_y;
+    font->v.x = v->x;
+    font->v.y = v->y;
+    update_transform(font);
 }
 
 static void face_set_size(FT_Face face, double size)
 {
 #if (FREETYPE_MAJOR > 2) || ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR > 1))
-       TT_HoriHeader *hori = FT_Get_Sfnt_Table(face, ft_sfnt_hhea);
-       TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
-       double mscale = 1.;
-       FT_Size_RequestRec rq;
-       FT_Size_Metrics *m = &face->size->metrics;
-       // VSFilter uses metrics from TrueType OS/2 table
-       // The idea was borrowed from asa (http://asa.diac24.net)
-       if (hori && os2) {
-               int hori_height = hori->Ascender - hori->Descender;
-               int os2_height = os2->usWinAscent + os2->usWinDescent;
-               if (hori_height && os2_height)
-                       mscale = (double)hori_height / os2_height;
-       }
-       memset(&rq, 0, sizeof(rq));
-       rq.type = FT_SIZE_REQUEST_TYPE_REAL_DIM;
-       rq.width = 0;
-       rq.height = double_to_d6(size * mscale);
-       rq.horiResolution = rq.vertResolution = 0;
-       FT_Request_Size(face, &rq);
-       m->ascender /= mscale;
-       m->descender /= mscale;
-       m->height /= mscale;
+    TT_HoriHeader *hori = FT_Get_Sfnt_Table(face, ft_sfnt_hhea);
+    TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+    double mscale = 1.;
+    FT_Size_RequestRec rq;
+    FT_Size_Metrics *m = &face->size->metrics;
+    // VSFilter uses metrics from TrueType OS/2 table
+    // The idea was borrowed from asa (http://asa.diac24.net)
+    if (hori && os2) {
+        int hori_height = hori->Ascender - hori->Descender;
+        int os2_height = os2->usWinAscent + os2->usWinDescent;
+        if (hori_height && os2_height)
+            mscale = (double) hori_height / os2_height;
+    }
+    memset(&rq, 0, sizeof(rq));
+    rq.type = FT_SIZE_REQUEST_TYPE_REAL_DIM;
+    rq.width = 0;
+    rq.height = double_to_d6(size * mscale);
+    rq.horiResolution = rq.vertResolution = 0;
+    FT_Request_Size(face, &rq);
+    m->ascender /= mscale;
+    m->descender /= mscale;
+    m->height /= mscale;
 #else
-       FT_Set_Char_Size(face, 0, double_to_d6(size), 0, 0);
+    FT_Set_Char_Size(face, 0, double_to_d6(size), 0, 0);
 #endif
 }
 
 /**
  * \brief Set font size
  **/
-void ass_font_set_size(ass_font_tfont, double size)
+void ass_font_set_size(ass_font_t *font, double size)
 {
-       int i;
-       if (font->size != size) {
-               font->size = size;
-               for (i = 0; i < font->n_faces; ++i)
-                       face_set_size(font->faces[i], size);
-       }
+    int i;
+    if (font->size != size) {
+        font->size = size;
+        for (i = 0; i < font->n_faces; ++i)
+            face_set_size(font->faces[i], size);
+    }
 }
 
 /**
@@ -247,125 +258,138 @@ void ass_font_set_size(ass_font_t* font, double size)
  * \param ch character code
  * The values are extracted from the font face that provides glyphs for the given character
  **/
-void ass_font_get_asc_desc(ass_font_t* font, uint32_t ch, int* asc, int* desc)
+void ass_font_get_asc_desc(ass_font_t *font, uint32_t ch, int *asc,
+                           int *desc)
 {
-       int i;
-       for (i = 0; i < font->n_faces; ++i) {
-               FT_Face face = font->faces[i];
-               if (FT_Get_Char_Index(face, ch)) {
-                       *asc = face->size->metrics.ascender;
-                       *desc = - face->size->metrics.descender;
-                       return;
-               }
-       }
-
-       *asc = *desc = 0;
+    int i;
+    for (i = 0; i < font->n_faces; ++i) {
+        FT_Face face = font->faces[i];
+        if (FT_Get_Char_Index(face, ch)) {
+            *asc = face->size->metrics.ascender;
+            *desc = -face->size->metrics.descender;
+            return;
+        }
+    }
+
+    *asc = *desc = 0;
 }
 
 /**
  * \brief Get a glyph
  * \param ch character code
  **/
-FT_Glyph ass_font_get_glyph(void* fontconfig_priv, ass_font_t* font, uint32_t ch, ass_hinting_t hinting)
+FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ass_font_t *font,
+                            uint32_t ch, ass_hinting_t hinting)
 {
-       int error;
-       int index = 0;
-       int i;
-       FT_Glyph glyph;
-       FT_Face face = 0;
-       int flags = 0;
-
-       if (ch < 0x20)
-               return 0;
-       if (font->n_faces == 0)
-               return 0;
-
-       for (i = 0; i < font->n_faces; ++i) {
-               face = font->faces[i];
-               index = FT_Get_Char_Index(face, ch);
-               if (index)
-                       break;
-       }
+    int error;
+    int index = 0;
+    int i;
+    FT_Glyph glyph;
+    FT_Face face = 0;
+    int flags = 0;
+
+    if (ch < 0x20)
+        return 0;
+    if (font->n_faces == 0)
+        return 0;
+
+    for (i = 0; i < font->n_faces; ++i) {
+        face = font->faces[i];
+        index = FT_Get_Char_Index(face, ch);
+        if (index)
+            break;
+    }
 
 #ifdef CONFIG_FONTCONFIG
-       if (index == 0) {
-               int face_idx;
-               mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_GlyphNotFoundReselectingFont,
-                      ch, font->desc.family, font->desc.bold, font->desc.italic);
-               face_idx = add_face(fontconfig_priv, font, ch);
-               if (face_idx >= 0) {
-                       face = font->faces[face_idx];
-                       index = FT_Get_Char_Index(face, ch);
-                       if (index == 0) {
-                               mp_msg(MSGT_ASS, MSGL_ERR, MSGTR_LIBASS_GlyphNotFound,
-                                      ch, font->desc.family, font->desc.bold, font->desc.italic);
-                       }
-               }
-       }
+    if (index == 0) {
+        int face_idx;
+        mp_msg(MSGT_ASS, MSGL_INFO,
+               MSGTR_LIBASS_GlyphNotFoundReselectingFont, ch,
+               font->desc.family, font->desc.bold, font->desc.italic);
+        face_idx = add_face(fontconfig_priv, font, ch);
+        if (face_idx >= 0) {
+            face = font->faces[face_idx];
+            index = FT_Get_Char_Index(face, ch);
+            if (index == 0) {
+                mp_msg(MSGT_ASS, MSGL_ERR, MSGTR_LIBASS_GlyphNotFound,
+                       ch, font->desc.family, font->desc.bold,
+                       font->desc.italic);
+            }
+        }
+    }
 #endif
 
-       switch (hinting) {
-       case ASS_HINTING_NONE: flags = FT_LOAD_NO_HINTING; break;
-       case ASS_HINTING_LIGHT: flags = FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT; break;
-       case ASS_HINTING_NORMAL: flags = FT_LOAD_FORCE_AUTOHINT; break;
-       case ASS_HINTING_NATIVE: flags = 0; break;
-       }
-
-       error = FT_Load_Glyph(face, index, FT_LOAD_NO_BITMAP | flags);
-       if (error) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph);
-               return 0;
-       }
-
+    switch (hinting) {
+    case ASS_HINTING_NONE:
+        flags = FT_LOAD_NO_HINTING;
+        break;
+    case ASS_HINTING_LIGHT:
+        flags = FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT;
+        break;
+    case ASS_HINTING_NORMAL:
+        flags = FT_LOAD_FORCE_AUTOHINT;
+        break;
+    case ASS_HINTING_NATIVE:
+        flags = 0;
+        break;
+    }
+
+    error = FT_Load_Glyph(face, index, FT_LOAD_NO_BITMAP | flags);
+    if (error) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph);
+        return 0;
+    }
 #if (FREETYPE_MAJOR > 2) || \
     ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR >= 2)) || \
     ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR == 1) && (FREETYPE_PATCH >= 10))
 // FreeType >= 2.1.10 required
-       if (!(face->style_flags & FT_STYLE_FLAG_ITALIC) &&
-                       (font->desc.italic > 55)) {
-               FT_GlyphSlot_Oblique(face->glyph);
-       }
+    if (!(face->style_flags & FT_STYLE_FLAG_ITALIC) &&
+        (font->desc.italic > 55)) {
+        FT_GlyphSlot_Oblique(face->glyph);
+    }
 #endif
-       error = FT_Get_Glyph(face->glyph, &glyph);
-       if (error) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph);
-               return 0;
-       }
+    error = FT_Get_Glyph(face->glyph, &glyph);
+    if (error) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph);
+        return 0;
+    }
 
-       return glyph;
+    return glyph;
 }
 
 /**
  * \brief Get kerning for the pair of glyphs.
  **/
-FT_Vector ass_font_get_kerning(ass_font_tfont, uint32_t c1, uint32_t c2)
+FT_Vector ass_font_get_kerning(ass_font_t *font, uint32_t c1, uint32_t c2)
 {
-       FT_Vector v = {0, 0};
-       int i;
-
-       for (i = 0; i < font->n_faces; ++i) {
-               FT_Face face = font->faces[i];
-               int i1 = FT_Get_Char_Index(face, c1);
-               int i2 = FT_Get_Char_Index(face, c2);
-               if (i1 && i2) {
-                       if (FT_HAS_KERNING(face))
-                               FT_Get_Kerning(face, i1, i2, FT_KERNING_DEFAULT, &v);
-                       return v;
-               }
-               if (i1 || i2) // these glyphs are from different font faces, no kerning information
-                       return v;
-       }
-       return v;
+    FT_Vector v = { 0, 0 };
+    int i;
+
+    for (i = 0; i < font->n_faces; ++i) {
+        FT_Face face = font->faces[i];
+        int i1 = FT_Get_Char_Index(face, c1);
+        int i2 = FT_Get_Char_Index(face, c2);
+        if (i1 && i2) {
+            if (FT_HAS_KERNING(face))
+                FT_Get_Kerning(face, i1, i2, FT_KERNING_DEFAULT, &v);
+            return v;
+        }
+        if (i1 || i2)           // these glyphs are from different font faces, no kerning information
+            return v;
+    }
+    return v;
 }
 
 /**
  * \brief Deallocate ass_font_t
  **/
-void ass_font_free(ass_font_tfont)
+void ass_font_free(ass_font_t *font)
 {
-       int i;
-       for (i = 0; i < font->n_faces; ++i)
-               if (font->faces[i]) FT_Done_Face(font->faces[i]);
-       if (font->desc.family) free(font->desc.family);
-       free(font);
+    int i;
+    for (i = 0; i < font->n_faces; ++i)
+        if (font->faces[i])
+            FT_Done_Face(font->faces[i]);
+    if (font->desc.family)
+        free(font->desc.family);
+    free(font);
 }
index 6a6793d663cbf524155e321b0739e2d94d824400..b208064297c07b5dd2b61dfbca3cb580839f0948 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 #include "ass_types.h"
 
 typedef struct ass_font_desc_s {
-       char* family;
-       unsigned bold;
-       unsigned italic;
-       int treat_family_as_pattern;
+    char *family;
+    unsigned bold;
+    unsigned italic;
+    int treat_family_as_pattern;
 } ass_font_desc_t;
 
 #define ASS_FONT_MAX_FACES 10
 
 typedef struct ass_font_s {
-       ass_font_desc_t desc;
-       ass_library_t* library;
-       FT_Library ftlibrary;
-       FT_Face faces[ASS_FONT_MAX_FACES];
-       int n_faces;
-       double scale_x, scale_y; // current transform
-       FT_Vector v; // current shift
-       double size;
+    ass_font_desc_t desc;
+    ass_library_t *library;
+    FT_Library ftlibrary;
+    FT_Face faces[ASS_FONT_MAX_FACES];
+    int n_faces;
+    double scale_x, scale_y;    // current transform
+    FT_Vector v;                // current shift
+    double size;
 } ass_font_t;
 
 // FIXME: passing the hashmap via a void pointer is very ugly.
-ass_font_t* ass_font_new(void* font_cache, ass_library_t* library, FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc);
-void ass_font_set_transform(ass_font_t* font, double scale_x, double scale_y, FT_Vector* v);
-void ass_font_set_size(ass_font_t* font, double size);
-void ass_font_get_asc_desc(ass_font_t* font, uint32_t ch, int* asc, int* desc);
-FT_Glyph ass_font_get_glyph(void* fontconfig_priv, ass_font_t* font, uint32_t ch, ass_hinting_t hinting);
-FT_Vector ass_font_get_kerning(ass_font_t* font, uint32_t c1, uint32_t c2);
-void ass_font_free(ass_font_t* font);
+ass_font_t *ass_font_new(void *font_cache, ass_library_t *library,
+                         FT_Library ftlibrary, void *fc_priv,
+                         ass_font_desc_t *desc);
+void ass_font_set_transform(ass_font_t *font, double scale_x,
+                            double scale_y, FT_Vector * v);
+void ass_font_set_size(ass_font_t *font, double size);
+void ass_font_get_asc_desc(ass_font_t *font, uint32_t ch, int *asc,
+                           int *desc);
+FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ass_font_t *font,
+                            uint32_t ch, ass_hinting_t hinting);
+FT_Vector ass_font_get_kerning(ass_font_t *font, uint32_t c1, uint32_t c2);
+void ass_font_free(ass_font_t *font);
 
-#endif /* LIBASS_FONT_H */
+#endif                          /* LIBASS_FONT_H */
index 2e7b5f0f647530188104cdecc54247b4868e6ce4..3a33cd1cd16e662617a2f5b832fd12904d9e5295 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 
 struct fc_instance_s {
 #ifdef CONFIG_FONTCONFIG
-       FcConfig* config;
+    FcConfig *config;
 #endif
-       char* family_default;
-       char* path_default;
-       int index_default;
+    char *family_default;
+    char *path_default;
+    int index_default;
 };
 
 #ifdef CONFIG_FONTCONFIG
@@ -73,156 +71,162 @@ struct fc_instance_s {
  * \param code: the character that should be present in the font, can be 0
  * \return font file path
 */
-static char* _select_font(fc_instance_t* priv, const char* family, int treat_family_as_pattern,
-                         unsigned bold, unsigned italic, int* index, uint32_t code)
+static char *_select_font(fc_instance_t *priv, const char *family,
+                          int treat_family_as_pattern, unsigned bold,
+                          unsigned italic, int *index, uint32_t code)
 {
-       FcBool rc;
-       FcResult result;
-       FcPattern *pat = NULL, *rpat = NULL;
-       int r_index, r_slant, r_weight;
-       FcChar8 *r_family, *r_style, *r_file, *r_fullname;
-       FcBool r_outline, r_embolden;
-       FcCharSet* r_charset;
-       FcFontSet* fset = NULL;
-       int curf;
-       char* retval = NULL;
-       int family_cnt;
-
-       *index = 0;
-
-       if (treat_family_as_pattern)
-               pat = FcNameParse((const FcChar8*)family);
-       else
-               pat = FcPatternCreate();
-
-       if (!pat)
-               goto error;
-
-       if (!treat_family_as_pattern) {
-               FcPatternAddString(pat, FC_FAMILY, (const FcChar8*)family);
-
-               // In SSA/ASS fonts are sometimes referenced by their "full name",
-               // which is usually a concatenation of family name and font
-               // style (ex. Ottawa Bold). Full name is available from
-               // FontConfig pattern element FC_FULLNAME, but it is never
-               // used for font matching.
-               // Therefore, I'm removing words from the end of the name one
-               // by one, and adding shortened names to the pattern. It seems
-               // that the first value (full name in this case) has
-               // precedence in matching.
-               // An alternative approach could be to reimplement FcFontSort
-               // using FC_FULLNAME instead of FC_FAMILY.
-               family_cnt = 1;
-               {
-                       char* s = strdup(family);
-                       char* p = s + strlen(s);
-                       while (--p > s)
-                               if (*p == ' ' || *p == '-') {
-                                       *p = '\0';
-                                       FcPatternAddString(pat, FC_FAMILY, (const FcChar8*)s);
-                                       ++ family_cnt;
-                               }
-                       free(s);
-               }
-       }
-       FcPatternAddBool(pat, FC_OUTLINE, FcTrue);
-       FcPatternAddInteger(pat, FC_SLANT, italic);
-       FcPatternAddInteger(pat, FC_WEIGHT, bold);
-
-       FcDefaultSubstitute(pat);
-
-       rc = FcConfigSubstitute(priv->config, pat, FcMatchPattern);
-       if (!rc)
-               goto error;
-
-       fset = FcFontSort(priv->config, pat, FcTrue, NULL, &result);
-       if (!fset)
-               goto error;
-
-       for (curf = 0; curf < fset->nfont; ++curf) {
-               FcPattern* curp = fset->fonts[curf];
-
-               result = FcPatternGetBool(curp, FC_OUTLINE, 0, &r_outline);
-               if (result != FcResultMatch)
-                       continue;
-               if (r_outline != FcTrue)
-                       continue;
-               if (!code)
-                       break;
-               result = FcPatternGetCharSet(curp, FC_CHARSET, 0, &r_charset);
-               if (result != FcResultMatch)
-                       continue;
-               if (FcCharSetHasChar(r_charset, code))
-                       break;
-       }
-
-       if (curf >= fset->nfont)
-               goto error;
+    FcBool rc;
+    FcResult result;
+    FcPattern *pat = NULL, *rpat = NULL;
+    int r_index, r_slant, r_weight;
+    FcChar8 *r_family, *r_style, *r_file, *r_fullname;
+    FcBool r_outline, r_embolden;
+    FcCharSet *r_charset;
+    FcFontSet *fset = NULL;
+    int curf;
+    char *retval = NULL;
+    int family_cnt;
+
+    *index = 0;
+
+    if (treat_family_as_pattern)
+        pat = FcNameParse((const FcChar8 *) family);
+    else
+        pat = FcPatternCreate();
+
+    if (!pat)
+        goto error;
+
+    if (!treat_family_as_pattern) {
+        FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *) family);
+
+        // In SSA/ASS fonts are sometimes referenced by their "full name",
+        // which is usually a concatenation of family name and font
+        // style (ex. Ottawa Bold). Full name is available from
+        // FontConfig pattern element FC_FULLNAME, but it is never
+        // used for font matching.
+        // Therefore, I'm removing words from the end of the name one
+        // by one, and adding shortened names to the pattern. It seems
+        // that the first value (full name in this case) has
+        // precedence in matching.
+        // An alternative approach could be to reimplement FcFontSort
+        // using FC_FULLNAME instead of FC_FAMILY.
+        family_cnt = 1;
+        {
+            char *s = strdup(family);
+            char *p = s + strlen(s);
+            while (--p > s)
+                if (*p == ' ' || *p == '-') {
+                    *p = '\0';
+                    FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *) s);
+                    ++family_cnt;
+                }
+            free(s);
+        }
+    }
+    FcPatternAddBool(pat, FC_OUTLINE, FcTrue);
+    FcPatternAddInteger(pat, FC_SLANT, italic);
+    FcPatternAddInteger(pat, FC_WEIGHT, bold);
+
+    FcDefaultSubstitute(pat);
+
+    rc = FcConfigSubstitute(priv->config, pat, FcMatchPattern);
+    if (!rc)
+        goto error;
+
+    fset = FcFontSort(priv->config, pat, FcTrue, NULL, &result);
+    if (!fset)
+        goto error;
+
+    for (curf = 0; curf < fset->nfont; ++curf) {
+        FcPattern *curp = fset->fonts[curf];
+
+        result = FcPatternGetBool(curp, FC_OUTLINE, 0, &r_outline);
+        if (result != FcResultMatch)
+            continue;
+        if (r_outline != FcTrue)
+            continue;
+        if (!code)
+            break;
+        result = FcPatternGetCharSet(curp, FC_CHARSET, 0, &r_charset);
+        if (result != FcResultMatch)
+            continue;
+        if (FcCharSetHasChar(r_charset, code))
+            break;
+    }
+
+    if (curf >= fset->nfont)
+        goto error;
 
 #if (FC_VERSION >= 20297)
-       if (!treat_family_as_pattern) {
-               // Remove all extra family names from original pattern.
-               // After this, FcFontRenderPrepare will select the most relevant family
-               // name in case there are more than one of them.
-               for (; family_cnt > 1; --family_cnt)
-                       FcPatternRemove(pat, FC_FAMILY, family_cnt - 1);
-       }
+    if (!treat_family_as_pattern) {
+        // Remove all extra family names from original pattern.
+        // After this, FcFontRenderPrepare will select the most relevant family
+        // name in case there are more than one of them.
+        for (; family_cnt > 1; --family_cnt)
+            FcPatternRemove(pat, FC_FAMILY, family_cnt - 1);
+    }
 #endif
 
-       rpat = FcFontRenderPrepare(priv->config, pat, fset->fonts[curf]);
-       if (!rpat)
-               goto error;
-
-       result = FcPatternGetInteger(rpat, FC_INDEX, 0, &r_index);
-       if (result != FcResultMatch)
-               goto error;
-       *index = r_index;
-
-       result = FcPatternGetString(rpat, FC_FILE, 0, &r_file);
-       if (result != FcResultMatch)
-               goto error;
-       retval = strdup((const char*)r_file);
-
-       result = FcPatternGetString(rpat, FC_FAMILY, 0, &r_family);
-       if (result != FcResultMatch)
-               r_family = NULL;
-
-       result = FcPatternGetString(rpat, FC_FULLNAME, 0, &r_fullname);
-       if (result != FcResultMatch)
-               r_fullname = NULL;
-
-       if (!treat_family_as_pattern &&
-               !(r_family && strcasecmp((const char*)r_family, family) == 0) &&
-           !(r_fullname && strcasecmp((const char*)r_fullname, family) == 0))
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_SelectedFontFamilyIsNotTheRequestedOne,
-                      (const char*)(r_fullname ? r_fullname : r_family), family);
-
-       result = FcPatternGetString(rpat, FC_STYLE, 0, &r_style);
-       if (result != FcResultMatch)
-               r_style = NULL;
-
-       result = FcPatternGetInteger(rpat, FC_SLANT, 0, &r_slant);
-       if (result != FcResultMatch)
-               r_slant = 0;
-
-       result = FcPatternGetInteger(rpat, FC_WEIGHT, 0, &r_weight);
-       if (result != FcResultMatch)
-               r_weight = 0;
-
-       result = FcPatternGetBool(rpat, FC_EMBOLDEN, 0, &r_embolden);
-       if (result != FcResultMatch)
-               r_embolden = 0;
-
-       mp_msg(MSGT_ASS, MSGL_V, "[ass] Font info: family '%s', style '%s', fullname '%s',"
-              " slant %d, weight %d%s\n",
-              (const char*)r_family, (const char*)r_style, (const char*)r_fullname,
-              r_slant, r_weight, r_embolden ? ", embolden" : "");
-
- error:
-       if (pat) FcPatternDestroy(pat);
-       if (rpat) FcPatternDestroy(rpat);
-       if (fset) FcFontSetDestroy(fset);
-       return retval;
+    rpat = FcFontRenderPrepare(priv->config, pat, fset->fonts[curf]);
+    if (!rpat)
+        goto error;
+
+    result = FcPatternGetInteger(rpat, FC_INDEX, 0, &r_index);
+    if (result != FcResultMatch)
+        goto error;
+    *index = r_index;
+
+    result = FcPatternGetString(rpat, FC_FILE, 0, &r_file);
+    if (result != FcResultMatch)
+        goto error;
+    retval = strdup((const char *) r_file);
+
+    result = FcPatternGetString(rpat, FC_FAMILY, 0, &r_family);
+    if (result != FcResultMatch)
+        r_family = NULL;
+
+    result = FcPatternGetString(rpat, FC_FULLNAME, 0, &r_fullname);
+    if (result != FcResultMatch)
+        r_fullname = NULL;
+
+    if (!treat_family_as_pattern &&
+        !(r_family && strcasecmp((const char *) r_family, family) == 0) &&
+        !(r_fullname && strcasecmp((const char *) r_fullname, family) == 0))
+        mp_msg(MSGT_ASS, MSGL_WARN,
+               MSGTR_LIBASS_SelectedFontFamilyIsNotTheRequestedOne,
+               (const char *) (r_fullname ? r_fullname : r_family), family);
+
+    result = FcPatternGetString(rpat, FC_STYLE, 0, &r_style);
+    if (result != FcResultMatch)
+        r_style = NULL;
+
+    result = FcPatternGetInteger(rpat, FC_SLANT, 0, &r_slant);
+    if (result != FcResultMatch)
+        r_slant = 0;
+
+    result = FcPatternGetInteger(rpat, FC_WEIGHT, 0, &r_weight);
+    if (result != FcResultMatch)
+        r_weight = 0;
+
+    result = FcPatternGetBool(rpat, FC_EMBOLDEN, 0, &r_embolden);
+    if (result != FcResultMatch)
+        r_embolden = 0;
+
+    mp_msg(MSGT_ASS, MSGL_V,
+           "[ass] Font info: family '%s', style '%s', fullname '%s',"
+           " slant %d, weight %d%s\n", (const char *) r_family,
+           (const char *) r_style, (const char *) r_fullname, r_slant,
+           r_weight, r_embolden ? ", embolden" : "");
+
+  error:
+    if (pat)
+        FcPatternDestroy(pat);
+    if (rpat)
+        FcPatternDestroy(rpat);
+    if (fset)
+        FcFontSetDestroy(fset);
+    return retval;
 }
 
 /**
@@ -236,75 +240,78 @@ static char* _select_font(fc_instance_t* priv, const char* family, int treat_fam
  * \param code: the character that should be present in the font, can be 0
  * \return font file path
 */
-char* fontconfig_select(fc_instance_t* priv, const char* family, int treat_family_as_pattern,
-                       unsigned bold, unsigned italic, int* index, uint32_t code)
+char *fontconfig_select(fc_instance_t *priv, const char *family,
+                        int treat_family_as_pattern, unsigned bold,
+                        unsigned italic, int *index, uint32_t code)
 {
-       char* res = 0;
-       if (!priv->config) {
-               *index = priv->index_default;
-               return priv->path_default;
-       }
-       if (family && *family)
-               res = _select_font(priv, family, treat_family_as_pattern, bold, italic, index, code);
-       if (!res && priv->family_default) {
-               res = _select_font(priv, priv->family_default, 0, bold, italic, index, code);
-               if (res)
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UsingDefaultFontFamily,
-                                       family, bold, italic, res, *index);
-       }
-       if (!res && priv->path_default) {
-               res = priv->path_default;
-               *index = priv->index_default;
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UsingDefaultFont,
-                      family, bold, italic, res, *index);
-       }
-       if (!res) {
-               res = _select_font(priv, "Arial", 0, bold, italic, index, code);
-               if (res)
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UsingArialFontFamily,
-                                       family, bold, italic, res, *index);
-       }
-       if (res)
-               mp_msg(MSGT_ASS, MSGL_V, "fontconfig_select: (%s, %d, %d) -> %s, %d\n",
-                               family, bold, italic, res, *index);
-       return res;
+    char *res = 0;
+    if (!priv->config) {
+        *index = priv->index_default;
+        return priv->path_default;
+    }
+    if (family && *family)
+        res =
+            _select_font(priv, family, treat_family_as_pattern, bold,
+                         italic, index, code);
+    if (!res && priv->family_default) {
+        res =
+            _select_font(priv, priv->family_default, 0, bold, italic, index,
+                         code);
+        if (res)
+            mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UsingDefaultFontFamily,
+                   family, bold, italic, res, *index);
+    }
+    if (!res && priv->path_default) {
+        res = priv->path_default;
+        *index = priv->index_default;
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UsingDefaultFont,
+               family, bold, italic, res, *index);
+    }
+    if (!res) {
+        res = _select_font(priv, "Arial", 0, bold, italic, index, code);
+        if (res)
+            mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UsingArialFontFamily,
+                   family, bold, italic, res, *index);
+    }
+    if (res)
+        mp_msg(MSGT_ASS, MSGL_V,
+               "fontconfig_select: (%s, %d, %d) -> %s, %d\n", family, bold,
+               italic, res, *index);
+    return res;
 }
 
 #if (FC_VERSION < 20402)
-static char* validate_fname(char* name)
+static char *validate_fname(char *name)
 {
-       char* fname;
-       char* p;
-       char* q;
-       unsigned code;
-       int sz = strlen(name);
-
-       q = fname = malloc(sz + 1);
-       p = name;
-       while (*p) {
-               code = utf8_get_char(&p);
-               if (code == 0)
-                       break;
-               if (    (code > 0x7F) ||
-                       (code == '\\') ||
-                       (code == '/') ||
-                       (code == ':') ||
-                       (code == '*') ||
-                       (code == '?') ||
-                       (code == '<') ||
-                       (code == '>') ||
-                       (code == '|') ||
-                       (code == 0))
-               {
-                       *q++ = '_';
-               } else {
-                       *q++ = code;
-               }
-               if (p - name > sz)
-                       break;
-       }
-       *q = 0;
-       return fname;
+    char *fname;
+    char *p;
+    char *q;
+    unsigned code;
+    int sz = strlen(name);
+
+    q = fname = malloc(sz + 1);
+    p = name;
+    while (*p) {
+        code = utf8_get_char(&p);
+        if (code == 0)
+            break;
+        if ((code > 0x7F) ||
+            (code == '\\') ||
+            (code == '/') ||
+            (code == ':') ||
+            (code == '*') ||
+            (code == '?') ||
+            (code == '<') ||
+            (code == '>') || (code == '|') || (code == 0)) {
+            *q++ = '_';
+        } else {
+            *q++ = code;
+        }
+        if (p - name > sz)
+            break;
+    }
+    *q = 0;
+    return fname;
 }
 #endif
 
@@ -317,86 +324,96 @@ static char* validate_fname(char* name)
  * With FontConfig >= 2.4.2, builds a font pattern in memory via FT_New_Memory_Face/FcFreeTypeQueryFace.
  * With older FontConfig versions, save the font to ~/.mplayer/fonts.
 */
-static void process_fontdata(fc_instance_t* priv, ass_library_t* library, FT_Library ftlibrary, int idx)
+static void process_fontdata(fc_instance_t *priv, ass_library_t *library,
+                             FT_Library ftlibrary, int idx)
 {
-       int rc;
-       const char* name = library->fontdata[idx].name;
-       const char* data = library->fontdata[idx].data;
-       int data_size = library->fontdata[idx].size;
+    int rc;
+    const char *name = library->fontdata[idx].name;
+    const char *data = library->fontdata[idx].data;
+    int data_size = library->fontdata[idx].size;
 
 #if (FC_VERSION < 20402)
-       struct stat st;
-       char* fname;
-       const char* fonts_dir = library->fonts_dir;
-       char buf[1000];
-       FILE* fp = NULL;
-
-       if (!fonts_dir)
-               return;
-       rc = stat(fonts_dir, &st);
-       if (rc) {
-               int res;
+    struct stat st;
+    char *fname;
+    const char *fonts_dir = library->fonts_dir;
+    char buf[1000];
+    FILE *fp = NULL;
+
+    if (!fonts_dir)
+        return;
+    rc = stat(fonts_dir, &st);
+    if (rc) {
+        int res;
 #ifndef __MINGW32__
-               res = mkdir(fonts_dir, 0700);
+        res = mkdir(fonts_dir, 0700);
 #else
-               res = mkdir(fonts_dir);
+        res = mkdir(fonts_dir);
 #endif
-               if (res) {
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FailedToCreateDirectory, fonts_dir);
-               }
-       } else if (!S_ISDIR(st.st_mode)) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NotADirectory, fonts_dir);
-       }
-
-       fname = validate_fname((char*)name);
-
-       snprintf(buf, 1000, "%s/%s", fonts_dir, fname);
-       free(fname);
-
-       fp = fopen(buf, "wb");
-       if (!fp) return;
-
-       fwrite(data, data_size, 1, fp);
-       fclose(fp);
-
-#else // (FC_VERSION >= 20402)
-       FT_Face face;
-       FcPattern* pattern;
-       FcFontSet* fset;
-       FcBool res;
-       int face_index, num_faces = 1;
-
-       for (face_index = 0; face_index < num_faces; ++face_index) {
-               rc = FT_New_Memory_Face(ftlibrary, (unsigned char*)data, data_size, face_index, &face);
-               if (rc) {
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningMemoryFont, name);
-                       return;
-               }
-               num_faces = face->num_faces;
-
-               pattern = FcFreeTypeQueryFace(face, (unsigned char*)name, 0, FcConfigGetBlanks(priv->config));
-               if (!pattern) {
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcFreeTypeQueryFace");
-                       FT_Done_Face(face);
-                       return;
-               }
-
-               fset = FcConfigGetFonts(priv->config, FcSetSystem); // somehow it failes when asked for FcSetApplication
-               if (!fset) {
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcConfigGetFonts");
-                       FT_Done_Face(face);
-                       return;
-               }
-
-               res = FcFontSetAdd(fset, pattern);
-               if (!res) {
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcFontSetAdd");
-                       FT_Done_Face(face);
-                       return;
-               }
-
-               FT_Done_Face(face);
-       }
+        if (res) {
+            mp_msg(MSGT_ASS, MSGL_WARN,
+                   MSGTR_LIBASS_FailedToCreateDirectory, fonts_dir);
+        }
+    } else if (!S_ISDIR(st.st_mode)) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NotADirectory, fonts_dir);
+    }
+
+    fname = validate_fname((char *) name);
+
+    snprintf(buf, 1000, "%s/%s", fonts_dir, fname);
+    free(fname);
+
+    fp = fopen(buf, "wb");
+    if (!fp)
+        return;
+
+    fwrite(data, data_size, 1, fp);
+    fclose(fp);
+
+#else                           // (FC_VERSION >= 20402)
+    FT_Face face;
+    FcPattern *pattern;
+    FcFontSet *fset;
+    FcBool res;
+    int face_index, num_faces = 1;
+
+    for (face_index = 0; face_index < num_faces; ++face_index) {
+        rc = FT_New_Memory_Face(ftlibrary, (unsigned char *) data,
+                                data_size, face_index, &face);
+        if (rc) {
+            mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningMemoryFont,
+                   name);
+            return;
+        }
+        num_faces = face->num_faces;
+
+        pattern =
+            FcFreeTypeQueryFace(face, (unsigned char *) name, 0,
+                                FcConfigGetBlanks(priv->config));
+        if (!pattern) {
+            mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed,
+                   "FcFreeTypeQueryFace");
+            FT_Done_Face(face);
+            return;
+        }
+
+        fset = FcConfigGetFonts(priv->config, FcSetSystem);     // somehow it failes when asked for FcSetApplication
+        if (!fset) {
+            mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed,
+                   "FcConfigGetFonts");
+            FT_Done_Face(face);
+            return;
+        }
+
+        res = FcFontSetAdd(fset, pattern);
+        if (!res) {
+            mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed,
+                   "FcFontSetAdd");
+            FT_Done_Face(face);
+            return;
+        }
+
+        FT_Done_Face(face);
+    }
 #endif
 }
 
@@ -408,111 +425,122 @@ static void process_fontdata(fc_instance_t* priv, ass_library_t* library, FT_Lib
  * \param path default font path
  * \return pointer to fontconfig private data
 */
-fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path, int fc)
+fc_instance_t *fontconfig_init(ass_library_t *library,
+                               FT_Library ftlibrary, const char *family,
+                               const char *path, int fc)
 {
-       int rc;
-       fc_instance_t* priv = calloc(1, sizeof(fc_instance_t));
-       const char* dir = library->fonts_dir;
-       int i;
-
-       if (!fc) {
-               mp_msg(MSGT_ASS, MSGL_WARN,
-                      MSGTR_LIBASS_FontconfigDisabledDefaultFontWillBeUsed);
-               goto exit;
-       }
-
-       rc = FcInit();
-       assert(rc);
-
-       priv->config = FcConfigGetCurrent();
-       if (!priv->config) {
-               mp_msg(MSGT_ASS, MSGL_FATAL, MSGTR_LIBASS_FcInitLoadConfigAndFontsFailed);
-               goto exit;
-       }
-
-       for (i = 0; i < library->num_fontdata; ++i)
-               process_fontdata(priv, library, ftlibrary, i);
-
-       if (dir) {
-               if (FcDirCacheValid((const FcChar8 *)dir) == FcFalse)
-                       {
-                               mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_UpdatingFontCache);
-                               if (FcGetVersion() >= 20390 && FcGetVersion() < 20400)
-                                       mp_msg(MSGT_ASS, MSGL_WARN,
-                                              MSGTR_LIBASS_BetaVersionsOfFontconfigAreNotSupported);
-                               // FontConfig >= 2.4.0 updates cache automatically in FcConfigAppFontAddDir()
-                               if (FcGetVersion() < 20390) {
-                                       FcFontSet* fcs;
-                                       FcStrSet* fss;
-                                       fcs = FcFontSetCreate();
-                                       fss = FcStrSetCreate();
-                                       rc = FcStrSetAdd(fss, (const FcChar8*)dir);
-                                       if (!rc) {
-                                               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcStrSetAddFailed);
-                                               goto ErrorFontCache;
-                                       }
-
-                                       rc = FcDirScan(fcs, fss, NULL, FcConfigGetBlanks(priv->config),
-                                                      (const FcChar8 *)dir, FcFalse);
-                                       if (!rc) {
-                                               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcDirScanFailed);
-                                               goto ErrorFontCache;
-                                       }
-
-                                       rc = FcDirSave(fcs, fss, (const FcChar8 *)dir);
-                                       if (!rc) {
-                                               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcDirSave);
-                                               goto ErrorFontCache;
-                                       }
-                               ErrorFontCache:
-                                       ;
-                               }
-                       }
-
-               rc = FcConfigAppFontAddDir(priv->config, (const FcChar8*)dir);
-               if (!rc) {
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcConfigAppFontAddDirFailed);
-               }
-       }
-
-       priv->family_default = family ? strdup(family) : NULL;
-exit:
-       priv->path_default = path ? strdup(path) : NULL;
-       priv->index_default = 0;
-
-       return priv;
+    int rc;
+    fc_instance_t *priv = calloc(1, sizeof(fc_instance_t));
+    const char *dir = library->fonts_dir;
+    int i;
+
+    if (!fc) {
+        mp_msg(MSGT_ASS, MSGL_WARN,
+               MSGTR_LIBASS_FontconfigDisabledDefaultFontWillBeUsed);
+        goto exit;
+    }
+
+    rc = FcInit();
+    assert(rc);
+
+    priv->config = FcConfigGetCurrent();
+    if (!priv->config) {
+        mp_msg(MSGT_ASS, MSGL_FATAL,
+               MSGTR_LIBASS_FcInitLoadConfigAndFontsFailed);
+        goto exit;
+    }
+
+    for (i = 0; i < library->num_fontdata; ++i)
+        process_fontdata(priv, library, ftlibrary, i);
+
+    if (dir) {
+        if (FcDirCacheValid((const FcChar8 *) dir) == FcFalse) {
+            mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_UpdatingFontCache);
+            if (FcGetVersion() >= 20390 && FcGetVersion() < 20400)
+                mp_msg(MSGT_ASS, MSGL_WARN,
+                       MSGTR_LIBASS_BetaVersionsOfFontconfigAreNotSupported);
+            // FontConfig >= 2.4.0 updates cache automatically in FcConfigAppFontAddDir()
+            if (FcGetVersion() < 20390) {
+                FcFontSet *fcs;
+                FcStrSet *fss;
+                fcs = FcFontSetCreate();
+                fss = FcStrSetCreate();
+                rc = FcStrSetAdd(fss, (const FcChar8 *) dir);
+                if (!rc) {
+                    mp_msg(MSGT_ASS, MSGL_WARN,
+                           MSGTR_LIBASS_FcStrSetAddFailed);
+                    goto ErrorFontCache;
+                }
+
+                rc = FcDirScan(fcs, fss, NULL,
+                               FcConfigGetBlanks(priv->config),
+                               (const FcChar8 *) dir, FcFalse);
+                if (!rc) {
+                    mp_msg(MSGT_ASS, MSGL_WARN,
+                           MSGTR_LIBASS_FcDirScanFailed);
+                    goto ErrorFontCache;
+                }
+
+                rc = FcDirSave(fcs, fss, (const FcChar8 *) dir);
+                if (!rc) {
+                    mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcDirSave);
+                    goto ErrorFontCache;
+                }
+              ErrorFontCache:
+                ;
+            }
+        }
+
+        rc = FcConfigAppFontAddDir(priv->config, (const FcChar8 *) dir);
+        if (!rc) {
+            mp_msg(MSGT_ASS, MSGL_WARN,
+                   MSGTR_LIBASS_FcConfigAppFontAddDirFailed);
+        }
+    }
+
+    priv->family_default = family ? strdup(family) : NULL;
+  exit:
+    priv->path_default = path ? strdup(path) : NULL;
+    priv->index_default = 0;
+
+    return priv;
 }
 
-#else /* CONFIG_FONTCONFIG */
+#else                           /* CONFIG_FONTCONFIG */
 
-char* fontconfig_select(fc_instance_t* priv, const char* family, int treat_family_as_pattern,
-                       unsigned bold, unsigned italic, int* index, uint32_t code)
+char *fontconfig_select(fc_instance_t *priv, const char *family,
+                        int treat_family_as_pattern, unsigned bold,
+                        unsigned italic, int *index, uint32_t code)
 {
-       *index = priv->index_default;
-       return priv->path_default;
+    *index = priv->index_default;
+    return priv->path_default;
 }
 
-fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path, int fc)
+fc_instance_t *fontconfig_init(ass_library_t *library,
+                               FT_Library ftlibrary, const char *family,
+                               const char *path, int fc)
 {
-       fc_instance_t* priv;
+    fc_instance_t *priv;
 
-       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FontconfigDisabledDefaultFontWillBeUsed);
+    mp_msg(MSGT_ASS, MSGL_WARN,
+           MSGTR_LIBASS_FontconfigDisabledDefaultFontWillBeUsed);
 
-       priv = calloc(1, sizeof(fc_instance_t));
+    priv = calloc(1, sizeof(fc_instance_t));
 
-       priv->path_default = strdup(path);
-       priv->index_default = 0;
-       return priv;
+    priv->path_default = strdup(path);
+    priv->index_default = 0;
+    return priv;
 }
 
 #endif
 
-void fontconfig_done(fc_instance_tpriv)
+void fontconfig_done(fc_instance_t *priv)
 {
-       // don't call FcFini() here, library can still be used by some code
-       if (priv && priv->path_default) free(priv->path_default);
-       if (priv && priv->family_default) free(priv->family_default);
-       if (priv) free(priv);
+    // don't call FcFini() here, library can still be used by some code
+    if (priv && priv->path_default)
+        free(priv->path_default);
+    if (priv && priv->family_default)
+        free(priv->family_default);
+    if (priv)
+        free(priv);
 }
-
-
index 77806909cf6d1288e7e1e6edbcd1b63db9800096..199c6ccef32e6a4ee0afbcf893d49c5fe5614af5 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 
 typedef struct fc_instance_s fc_instance_t;
 
-fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path, int fc);
-char* fontconfig_select(fc_instance_t* priv, const char* family, int treat_family_as_pattern, unsigned bold, unsigned italic, int* index, uint32_t code);
-void fontconfig_done(fc_instance_t* priv);
+fc_instance_t *fontconfig_init(ass_library_t *library,
+                               FT_Library ftlibrary, const char *family,
+                               const char *path, int fc);
+char *fontconfig_select(fc_instance_t *priv, const char *family,
+                        int treat_family_as_pattern, unsigned bold,
+                        unsigned italic, int *index, uint32_t code);
+void fontconfig_done(fc_instance_t *priv);
 
-#endif /* LIBASS_FONTCONFIG_H */
+#endif                          /* LIBASS_FONTCONFIG_H */
index 304f2326de2dab1a0269ba9e8a71cd4defdb468a..ce877da7e056e0aa0ced11eda68fc95fb267c9d0 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 #include "ass_library.h"
 
 
-ass_library_tass_library_init(void)
+ass_library_t *ass_library_init(void)
 {
-       return calloc(1, sizeof(ass_library_t));
+    return calloc(1, sizeof(ass_library_t));
 }
 
-void ass_library_done(ass_library_tpriv)
+void ass_library_done(ass_library_t *priv)
 {
-       if (priv) {
-               ass_set_fonts_dir(priv, NULL);
-               ass_set_style_overrides(priv, NULL);
-               ass_clear_fonts(priv);
-               free(priv);
-       }
+    if (priv) {
+        ass_set_fonts_dir(priv, NULL);
+        ass_set_style_overrides(priv, NULL);
+        ass_clear_fonts(priv);
+        free(priv);
+    }
 }
 
-void ass_set_fonts_dir(ass_library_t* priv, const char* fonts_dir)
+void ass_set_fonts_dir(ass_library_t *priv, const char *fonts_dir)
 {
-       if (priv->fonts_dir)
-               free(priv->fonts_dir);
+    if (priv->fonts_dir)
+        free(priv->fonts_dir);
 
-       priv->fonts_dir = fonts_dir ? strdup(fonts_dir) : 0;
+    priv->fonts_dir = fonts_dir ? strdup(fonts_dir) : 0;
 }
 
-void ass_set_extract_fonts(ass_library_tpriv, int extract)
+void ass_set_extract_fonts(ass_library_t *priv, int extract)
 {
-       priv->extract_fonts = !!extract;
+    priv->extract_fonts = !!extract;
 }
 
-void ass_set_style_overrides(ass_library_t* priv, char** list)
+void ass_set_style_overrides(ass_library_t *priv, char **list)
 {
-       char** p;
-       char** q;
-       int cnt;
-
-       if (priv->style_overrides) {
-               for (p = priv->style_overrides; *p; ++p)
-                       free(*p);
-               free(priv->style_overrides);
-       }
-
-       if (!list) return;
-
-       for (p = list, cnt = 0; *p; ++p, ++cnt) {}
-
-       priv->style_overrides = malloc((cnt + 1) * sizeof(char*));
-       for (p = list, q = priv->style_overrides; *p; ++p, ++q)
-               *q = strdup(*p);
-       priv->style_overrides[cnt] = NULL;
+    char **p;
+    char **q;
+    int cnt;
+
+    if (priv->style_overrides) {
+        for (p = priv->style_overrides; *p; ++p)
+            free(*p);
+        free(priv->style_overrides);
+    }
+
+    if (!list)
+        return;
+
+    for (p = list, cnt = 0; *p; ++p, ++cnt) {
+    }
+
+    priv->style_overrides = malloc((cnt + 1) * sizeof(char *));
+    for (p = list, q = priv->style_overrides; *p; ++p, ++q)
+        *q = strdup(*p);
+    priv->style_overrides[cnt] = NULL;
 }
 
 static void grow_array(void **array, int nelem, size_t elsize)
 {
-       if (!(nelem & 31))
-               *array = realloc(*array, (nelem + 32) * elsize);
+    if (!(nelem & 31))
+        *array = realloc(*array, (nelem + 32) * elsize);
 }
 
-void ass_add_font(ass_library_t* priv, char* name, char* data, int size)
+void ass_add_font(ass_library_t *priv, char *name, char *data, int size)
 {
-       int idx = priv->num_fontdata;
-       if (!name || !data || !size)
-               return;
-       grow_array((void**)&priv->fontdata, priv->num_fontdata, sizeof(*priv->fontdata));
+    int idx = priv->num_fontdata;
+    if (!name || !data || !size)
+        return;
+    grow_array((void **) &priv->fontdata, priv->num_fontdata,
+               sizeof(*priv->fontdata));
 
-       priv->fontdata[idx].name = strdup(name);
+    priv->fontdata[idx].name = strdup(name);
 
-       priv->fontdata[idx].data = malloc(size);
-       memcpy(priv->fontdata[idx].data, data, size);
+    priv->fontdata[idx].data = malloc(size);
+    memcpy(priv->fontdata[idx].data, data, size);
 
-       priv->fontdata[idx].size = size;
+    priv->fontdata[idx].size = size;
 
-       priv->num_fontdata ++;
+    priv->num_fontdata++;
 }
 
-void ass_clear_fonts(ass_library_tpriv)
+void ass_clear_fonts(ass_library_t *priv)
 {
-       int i;
-       for (i = 0; i < priv->num_fontdata; ++i) {
-               free(priv->fontdata[i].name);
-               free(priv->fontdata[i].data);
-       }
-       free(priv->fontdata);
-       priv->fontdata = NULL;
-       priv->num_fontdata = 0;
+    int i;
+    for (i = 0; i < priv->num_fontdata; ++i) {
+        free(priv->fontdata[i].name);
+        free(priv->fontdata[i].data);
+    }
+    free(priv->fontdata);
+    priv->fontdata = NULL;
+    priv->num_fontdata = 0;
 }
index ecf46f342ea0914634337b3307a61a0272832e74..48ffefe8b1a6ff11cfd1d6ade1802b409f4ce58f 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 #define LIBASS_LIBRARY_H
 
 typedef struct ass_fontdata_s {
-       char* name;
-       char* data;
-       int size;
+    char *name;
+    char *data;
+    int size;
 } ass_fontdata_t;
 
 struct ass_library_s {
-       char* fonts_dir;
-       int extract_fonts;
-       char** style_overrides;
+    char *fonts_dir;
+    int extract_fonts;
+    char **style_overrides;
 
-       ass_fontdata_t* fontdata;
-       int num_fontdata;
+    ass_fontdata_t *fontdata;
+    int num_fontdata;
 };
 
-#endif /* LIBASS_LIBRARY_H */
+#endif                          /* LIBASS_LIBRARY_H */
index 00a5f39a3dd8cd2eb7a2f482be228ec93792c22d..33d059be0008d3a4bebbeb359879bf186e880d7d 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 #define BLUR_MAX_RADIUS 100.0
 #define MAX_BE 100
 #define ROUND(x) ((int) ((x) + .5))
-#define SUBPIXEL_MASK 56       // d6 bitmask for subpixel accuracy adjustment
+#define SUBPIXEL_MASK 56        // d6 bitmask for subpixel accuracy adjustment
 
 static int last_render_id = 0;
 
 typedef struct ass_settings_s {
-       int frame_width;
-       int frame_height;
-       double font_size_coeff; // font size multiplier
-       double line_spacing; // additional line spacing (in frame pixels)
-       int top_margin; // height of top margin. Everything except toptitles is shifted down by top_margin.
-       int bottom_margin; // height of bottom margin. (frame_height - top_margin - bottom_margin) is original video height.
-       int left_margin;
-       int right_margin;
-       int use_margins; // 0 - place all subtitles inside original frame
-                        // 1 - use margins for placing toptitles and subtitles
-       double aspect; // frame aspect ratio, d_width / d_height.
-       ass_hinting_t hinting;
-
-       char* default_font;
-       char* default_family;
+    int frame_width;
+    int frame_height;
+    double font_size_coeff;     // font size multiplier
+    double line_spacing;        // additional line spacing (in frame pixels)
+    int top_margin;             // height of top margin. Everything except toptitles is shifted down by top_margin.
+    int bottom_margin;          // height of bottom margin. (frame_height - top_margin - bottom_margin) is original video height.
+    int left_margin;
+    int right_margin;
+    int use_margins;            // 0 - place all subtitles inside original frame
+    // 1 - use margins for placing toptitles and subtitles
+    double aspect;              // frame aspect ratio, d_width / d_height.
+    ass_hinting_t hinting;
+
+    char *default_font;
+    char *default_family;
 } ass_settings_t;
 
 // a rendered event
 typedef struct event_images_s {
-       ass_image_t* imgs;
-       int top, height;
-       int detect_collisions;
-       int shift_direction;
-       ass_event_t* event;
+    ass_image_t *imgs;
+    int top, height;
+    int detect_collisions;
+    int shift_direction;
+    ass_event_t *event;
 } event_images_t;
 
-typedef enum {EF_NONE = 0, EF_KARAOKE, EF_KARAOKE_KF, EF_KARAOKE_KO} effect_t;
+typedef enum { EF_NONE = 0, EF_KARAOKE, EF_KARAOKE_KF, EF_KARAOKE_KO
+} effect_t;
 
 // describes a glyph
 // glyph_info_t and text_info_t are used for text centering and word-wrapping operations
 typedef struct glyph_info_s {
-       unsigned symbol;
-       FT_Glyph glyph;
-       FT_Glyph outline_glyph;
-       bitmap_t* bm; // glyph bitmap
-       bitmap_t* bm_o; // outline bitmap
-       bitmap_t* bm_s; // shadow bitmap
-       FT_BBox bbox;
-       FT_Vector pos;
-       char linebreak; // the first (leading) glyph of some line ?
-       uint32_t c[4]; // colors
-       FT_Vector advance; // 26.6
-       effect_t effect_type;
-       int effect_timing; // time duration of current karaoke word
-                          // after process_karaoke_effects: distance in pixels from the glyph origin.
-                          // part of the glyph to the left of it is displayed in a different color.
-       int effect_skip_timing; // delay after the end of last karaoke word
-       int asc, desc; // font max ascender and descender
-//     int height;
-       int be; // blur edges
-       double blur; // gaussian blur
-       double shadow;
-       double frx, fry, frz; // rotation
-
-       bitmap_hash_key_t hash_key;
+    unsigned symbol;
+    FT_Glyph glyph;
+    FT_Glyph outline_glyph;
+    bitmap_t *bm;               // glyph bitmap
+    bitmap_t *bm_o;             // outline bitmap
+    bitmap_t *bm_s;             // shadow bitmap
+    FT_BBox bbox;
+    FT_Vector pos;
+    char linebreak;             // the first (leading) glyph of some line ?
+    uint32_t c[4];              // colors
+    FT_Vector advance;          // 26.6
+    effect_t effect_type;
+    int effect_timing;          // time duration of current karaoke word
+    // after process_karaoke_effects: distance in pixels from the glyph origin.
+    // part of the glyph to the left of it is displayed in a different color.
+    int effect_skip_timing;     // delay after the end of last karaoke word
+    int asc, desc;              // font max ascender and descender
+//      int height;
+    int be;                     // blur edges
+    double blur;                // gaussian blur
+    double shadow;
+    double frx, fry, frz;       // rotation
+
+    bitmap_hash_key_t hash_key;
 } glyph_info_t;
 
 typedef struct line_info_s {
-       int asc, desc;
+    int asc, desc;
 } line_info_t;
 
 typedef struct text_info_s {
-       glyph_info_t* glyphs;
-       int length;
-       line_info_t* lines;
-       int n_lines;
-       int height;
-       int max_glyphs;
-       int max_lines;
+    glyph_info_t *glyphs;
+    int length;
+    line_info_t *lines;
+    int n_lines;
+    int height;
+    int max_glyphs;
+    int max_lines;
 } text_info_t;
 
 
 // Renderer state.
 // Values like current font face, color, screen position, clipping and so on are stored here.
 typedef struct render_context_s {
-       ass_event_t* event;
-       ass_style_t* style;
-
-       ass_font_t* font;
-       char* font_path;
-       double font_size;
-
-       FT_Stroker stroker;
-       int alignment; // alignment overrides go here; if zero, style value will be used
-       double frx, fry, frz;
-       enum {  EVENT_NORMAL, // "normal" top-, sub- or mid- title
-               EVENT_POSITIONED, // happens after pos(,), margins are ignored
-               EVENT_HSCROLL, // "Banner" transition effect, text_width is unlimited
-               EVENT_VSCROLL // "Scroll up", "Scroll down" transition effects
-               } evt_type;
-       double pos_x, pos_y; // position
-       double org_x, org_y; // origin
-       char have_origin; // origin is explicitly defined; if 0, get_base_point() is used
-       double scale_x, scale_y;
-       double hspacing; // distance between letters, in pixels
-       double border; // outline width
-       uint32_t c[4]; // colors(Primary, Secondary, so on) in RGBA
-       int clip_x0, clip_y0, clip_x1, clip_y1;
-       char detect_collisions;
-       uint32_t fade; // alpha from \fad
-       char be; // blur edges
-       double blur; // gaussian blur
-       double shadow;
-       int drawing_mode; // not implemented; when != 0 text is discarded, except for style override tags
-
-       effect_t effect_type;
-       int effect_timing;
-       int effect_skip_timing;
-
-       enum { SCROLL_LR, // left-to-right
-              SCROLL_RL,
-              SCROLL_TB, // top-to-bottom
-              SCROLL_BT
-              } scroll_direction; // for EVENT_HSCROLL, EVENT_VSCROLL
-       int scroll_shift;
-
-       // face properties
-       char* family;
-       unsigned bold;
-       unsigned italic;
-       int treat_family_as_pattern;
+    ass_event_t *event;
+    ass_style_t *style;
+
+    ass_font_t *font;
+    char *font_path;
+    double font_size;
+
+    FT_Stroker stroker;
+    int alignment;              // alignment overrides go here; if zero, style value will be used
+    double frx, fry, frz;
+    enum { EVENT_NORMAL,        // "normal" top-, sub- or mid- title
+        EVENT_POSITIONED,       // happens after pos(,), margins are ignored
+        EVENT_HSCROLL,          // "Banner" transition effect, text_width is unlimited
+        EVENT_VSCROLL           // "Scroll up", "Scroll down" transition effects
+    } evt_type;
+    double pos_x, pos_y;        // position
+    double org_x, org_y;        // origin
+    char have_origin;           // origin is explicitly defined; if 0, get_base_point() is used
+    double scale_x, scale_y;
+    double hspacing;            // distance between letters, in pixels
+    double border;              // outline width
+    uint32_t c[4];              // colors(Primary, Secondary, so on) in RGBA
+    int clip_x0, clip_y0, clip_x1, clip_y1;
+    char detect_collisions;
+    uint32_t fade;              // alpha from \fad
+    char be;                    // blur edges
+    double blur;                // gaussian blur
+    double shadow;
+    int drawing_mode;           // not implemented; when != 0 text is discarded, except for style override tags
+
+    effect_t effect_type;
+    int effect_timing;
+    int effect_skip_timing;
+
+    enum { SCROLL_LR,           // left-to-right
+        SCROLL_RL,
+        SCROLL_TB,              // top-to-bottom
+        SCROLL_BT
+    } scroll_direction;         // for EVENT_HSCROLL, EVENT_VSCROLL
+    int scroll_shift;
+
+    // face properties
+    char *family;
+    unsigned bold;
+    unsigned italic;
+    int treat_family_as_pattern;
 
 } render_context_t;
 
 typedef struct cache_store_s {
-       hashmap_t* font_cache;
-       hashmap_t* glyph_cache;
-       hashmap_t* bitmap_cache;
-       hashmap_t* composite_cache;
+    hashmap_t *font_cache;
+    hashmap_t *glyph_cache;
+    hashmap_t *bitmap_cache;
+    hashmap_t *composite_cache;
 } cache_store_t;
 
 struct ass_renderer_s {
-       ass_library_t* library;
-       FT_Library ftlibrary;
-       fc_instance_t* fontconfig_priv;
-       ass_settings_t settings;
-       int render_id;
-       ass_synth_priv_t* synth_priv;
-
-       ass_image_t* images_root; // rendering result is stored here
-       ass_image_t* prev_images_root;
-
-       event_images_t* eimg; // temporary buffer for sorting rendered events
-       int eimg_size; // allocated buffer size
-
-       // frame-global data
-       int width, height; // screen dimensions
-       int orig_height; // frame height ( = screen height - margins )
-       int orig_width; // frame width ( = screen width - margins )
-       int orig_height_nocrop; // frame height ( = screen height - margins + cropheight)
-       int orig_width_nocrop; // frame width ( = screen width - margins + cropwidth)
-       ass_track_t* track;
-       long long time; // frame's timestamp, ms
-       double font_scale;
-       double font_scale_x; // x scale applied to all glyphs to preserve text aspect ratio
-       double border_scale;
-       
-       render_context_t state;
-       text_info_t text_info;
-       cache_store_t cache;
+    ass_library_t *library;
+    FT_Library ftlibrary;
+    fc_instance_t *fontconfig_priv;
+    ass_settings_t settings;
+    int render_id;
+    ass_synth_priv_t *synth_priv;
+
+    ass_image_t *images_root;   // rendering result is stored here
+    ass_image_t *prev_images_root;
+
+    event_images_t *eimg;       // temporary buffer for sorting rendered events
+    int eimg_size;              // allocated buffer size
+
+    // frame-global data
+    int width, height;          // screen dimensions
+    int orig_height;            // frame height ( = screen height - margins )
+    int orig_width;             // frame width ( = screen width - margins )
+    int orig_height_nocrop;     // frame height ( = screen height - margins + cropheight)
+    int orig_width_nocrop;      // frame width ( = screen width - margins + cropwidth)
+    ass_track_t *track;
+    long long time;             // frame's timestamp, ms
+    double font_scale;
+    double font_scale_x;        // x scale applied to all glyphs to preserve text aspect ratio
+    double border_scale;
+
+    render_context_t state;
+    text_info_t text_info;
+    cache_store_t cache;
 };
 
 struct render_priv_s {
-       int top, height;
-       int render_id;
+    int top, height;
+    int render_id;
 };
 
-static void ass_lazy_track_init(ass_renderer_trender_priv)
+static void ass_lazy_track_init(ass_renderer_t *render_priv)
 {
-       ass_track_t* track = render_priv->track;
-       ass_settings_t* settings_priv = &render_priv->settings;
-       
-       if (track->PlayResX && track->PlayResY)
-               return;
-       if (!track->PlayResX && !track->PlayResY) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NeitherPlayResXNorPlayResYDefined);
-               track->PlayResX = 384;
-               track->PlayResY = 288;
-       } else {
-               double orig_aspect = (settings_priv->aspect * render_priv->height * render_priv->orig_width) /
-                       render_priv->orig_height / render_priv->width;
-               if (!track->PlayResY && track->PlayResX == 1280) {
-                       track->PlayResY = 1024;
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_PlayResYUndefinedSettingY, track->PlayResY);
-               } else if (!track->PlayResY) {
-                       track->PlayResY = track->PlayResX / orig_aspect + .5;
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_PlayResYUndefinedSettingY, track->PlayResY);
-               } else if (!track->PlayResX && track->PlayResY == 1024) {
-                       track->PlayResX = 1280;
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_PlayResXUndefinedSettingX, track->PlayResX);
-               } else if (!track->PlayResX) {
-                       track->PlayResX = track->PlayResY * orig_aspect + .5;
-                       mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_PlayResXUndefinedSettingX, track->PlayResX);
-               }
-       }
+    ass_track_t *track = render_priv->track;
+    ass_settings_t *settings_priv = &render_priv->settings;
+
+    if (track->PlayResX && track->PlayResY)
+        return;
+    if (!track->PlayResX && !track->PlayResY) {
+        mp_msg(MSGT_ASS, MSGL_WARN,
+               MSGTR_LIBASS_NeitherPlayResXNorPlayResYDefined);
+        track->PlayResX = 384;
+        track->PlayResY = 288;
+    } else {
+        double orig_aspect =
+            (settings_priv->aspect * render_priv->height *
+             render_priv->orig_width) / render_priv->orig_height /
+            render_priv->width;
+        if (!track->PlayResY && track->PlayResX == 1280) {
+            track->PlayResY = 1024;
+            mp_msg(MSGT_ASS, MSGL_WARN,
+                   MSGTR_LIBASS_PlayResYUndefinedSettingY, track->PlayResY);
+        } else if (!track->PlayResY) {
+            track->PlayResY = track->PlayResX / orig_aspect + .5;
+            mp_msg(MSGT_ASS, MSGL_WARN,
+                   MSGTR_LIBASS_PlayResYUndefinedSettingY, track->PlayResY);
+        } else if (!track->PlayResX && track->PlayResY == 1024) {
+            track->PlayResX = 1280;
+            mp_msg(MSGT_ASS, MSGL_WARN,
+                   MSGTR_LIBASS_PlayResXUndefinedSettingX, track->PlayResX);
+        } else if (!track->PlayResX) {
+            track->PlayResX = track->PlayResY * orig_aspect + .5;
+            mp_msg(MSGT_ASS, MSGL_WARN,
+                   MSGTR_LIBASS_PlayResXUndefinedSettingX, track->PlayResX);
+        }
+    }
 }
 
-ass_renderer_t* ass_renderer_init(ass_library_t* library)
+ass_renderer_t *ass_renderer_init(ass_library_t *library)
 {
-       int error;
-       FT_Library ft;
-       ass_renderer_t* priv = 0;
-       int vmajor, vminor, vpatch;
-
-       error = FT_Init_FreeType( &ft );
-       if ( error ) {
-               mp_msg(MSGT_ASS, MSGL_FATAL, MSGTR_LIBASS_FT_Init_FreeTypeFailed);
-               goto ass_init_exit;
-       }
-
-       FT_Library_Version(ft, &vmajor, &vminor, &vpatch);
-       mp_msg(MSGT_ASS, MSGL_V, "FreeType library version: %d.%d.%d\n",
-              vmajor, vminor, vpatch);
-       mp_msg(MSGT_ASS, MSGL_V, "FreeType headers version: %d.%d.%d\n",
-              FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH);
-
-       priv = calloc(1, sizeof(ass_renderer_t));
-       if (!priv) {
-               FT_Done_FreeType(ft);
-               goto ass_init_exit;
-       }
-
-       priv->synth_priv = ass_synth_init(BLUR_MAX_RADIUS);
-
-       priv->library = library;
-       priv->ftlibrary = ft;
-       // images_root and related stuff is zero-filled in calloc
-
-       priv->cache.font_cache = ass_font_cache_init();
-       priv->cache.bitmap_cache = ass_bitmap_cache_init();
-       priv->cache.composite_cache = ass_composite_cache_init();
-       priv->cache.glyph_cache = ass_glyph_cache_init();
-
-       priv->text_info.max_glyphs = MAX_GLYPHS_INITIAL;
-       priv->text_info.max_lines = MAX_LINES_INITIAL;
-       priv->text_info.glyphs = calloc(MAX_GLYPHS_INITIAL, sizeof(glyph_info_t));
-       priv->text_info.lines = calloc(MAX_LINES_INITIAL, sizeof(line_info_t));
-
-ass_init_exit:
-       if (priv) mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_Init);
-       else mp_msg(MSGT_ASS, MSGL_ERR, MSGTR_LIBASS_InitFailed);
-
-       return priv;
+    int error;
+    FT_Library ft;
+    ass_renderer_t *priv = 0;
+    int vmajor, vminor, vpatch;
+
+    error = FT_Init_FreeType(&ft);
+    if (error) {
+        mp_msg(MSGT_ASS, MSGL_FATAL, MSGTR_LIBASS_FT_Init_FreeTypeFailed);
+        goto ass_init_exit;
+    }
+
+    FT_Library_Version(ft, &vmajor, &vminor, &vpatch);
+    mp_msg(MSGT_ASS, MSGL_V, "FreeType library version: %d.%d.%d\n",
+           vmajor, vminor, vpatch);
+    mp_msg(MSGT_ASS, MSGL_V, "FreeType headers version: %d.%d.%d\n",
+           FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH);
+
+    priv = calloc(1, sizeof(ass_renderer_t));
+    if (!priv) {
+        FT_Done_FreeType(ft);
+        goto ass_init_exit;
+    }
+
+    priv->synth_priv = ass_synth_init(BLUR_MAX_RADIUS);
+
+    priv->library = library;
+    priv->ftlibrary = ft;
+    // images_root and related stuff is zero-filled in calloc
+
+    priv->cache.font_cache = ass_font_cache_init();
+    priv->cache.bitmap_cache = ass_bitmap_cache_init();
+    priv->cache.composite_cache = ass_composite_cache_init();
+    priv->cache.glyph_cache = ass_glyph_cache_init();
+
+    priv->text_info.max_glyphs = MAX_GLYPHS_INITIAL;
+    priv->text_info.max_lines = MAX_LINES_INITIAL;
+    priv->text_info.glyphs =
+        calloc(MAX_GLYPHS_INITIAL, sizeof(glyph_info_t));
+    priv->text_info.lines = calloc(MAX_LINES_INITIAL, sizeof(line_info_t));
+
+  ass_init_exit:
+    if (priv)
+        mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_Init);
+    else
+        mp_msg(MSGT_ASS, MSGL_ERR, MSGTR_LIBASS_InitFailed);
+
+    return priv;
 }
 
-void ass_renderer_done(ass_renderer_trender_priv)
+void ass_renderer_done(ass_renderer_t *render_priv)
 {
-       ass_font_cache_done(render_priv->cache.font_cache);
-       ass_bitmap_cache_done(render_priv->cache.bitmap_cache);
-       ass_composite_cache_done(render_priv->cache.composite_cache);
-       ass_glyph_cache_done(render_priv->cache.glyph_cache);
-       if (render_priv->state.stroker) {
-               FT_Stroker_Done(render_priv->state.stroker);
-               render_priv->state.stroker = 0;
-       }
-       if (render_priv && render_priv->ftlibrary) FT_Done_FreeType(render_priv->ftlibrary);
-       if (render_priv && render_priv->fontconfig_priv) fontconfig_done(render_priv->fontconfig_priv);
-       if (render_priv && render_priv->synth_priv) ass_synth_done(render_priv->synth_priv);
-       if (render_priv && render_priv->eimg) free(render_priv->eimg);
-       free(render_priv);
-       free(render_priv->text_info.glyphs);
-       free(render_priv->text_info.lines);
+    ass_font_cache_done(render_priv->cache.font_cache);
+    ass_bitmap_cache_done(render_priv->cache.bitmap_cache);
+    ass_composite_cache_done(render_priv->cache.composite_cache);
+    ass_glyph_cache_done(render_priv->cache.glyph_cache);
+    if (render_priv->state.stroker) {
+        FT_Stroker_Done(render_priv->state.stroker);
+        render_priv->state.stroker = 0;
+    }
+    if (render_priv && render_priv->ftlibrary)
+        FT_Done_FreeType(render_priv->ftlibrary);
+    if (render_priv && render_priv->fontconfig_priv)
+        fontconfig_done(render_priv->fontconfig_priv);
+    if (render_priv && render_priv->synth_priv)
+        ass_synth_done(render_priv->synth_priv);
+    if (render_priv && render_priv->eimg)
+        free(render_priv->eimg);
+    free(render_priv);
+    free(render_priv->text_info.glyphs);
+    free(render_priv->text_info.lines);
 }
 
 /**
  * \brief Create a new ass_image_t
  * Parameters are the same as ass_image_t fields.
  */
-static ass_image_t* my_draw_bitmap(unsigned char* bitmap, int bitmap_w, int bitmap_h, int stride, int dst_x, int dst_y, uint32_t color)
+static ass_image_t *my_draw_bitmap(unsigned char *bitmap, int bitmap_w,
+                                   int bitmap_h, int stride, int dst_x,
+                                   int dst_y, uint32_t color)
 {
-       ass_image_t* img = calloc(1, sizeof(ass_image_t));
+    ass_image_t *img = calloc(1, sizeof(ass_image_t));
 
-       img->w = bitmap_w;
-       img->h = bitmap_h;
-       img->stride = stride;
-       img->bitmap = bitmap;
-       img->color = color;
-       img->dst_x = dst_x;
-       img->dst_y = dst_y;
+    img->w = bitmap_w;
+    img->h = bitmap_h;
+    img->stride = stride;
+    img->bitmap = bitmap;
+    img->color = color;
+    img->dst_x = dst_x;
+    img->dst_y = dst_y;
 
-       return img;
+    return img;
 }
 
 /**
@@ -346,71 +361,76 @@ static ass_image_t* my_draw_bitmap(unsigned char* bitmap, int bitmap_w, int bitm
  * \return pointer to the new list tail
  * Performs clipping. Uses my_draw_bitmap for actual bitmap convertion.
  */
-static ass_image_t** render_glyph(ass_renderer_t* render_priv, bitmap_t* bm, int dst_x, int dst_y, uint32_t color, uint32_t color2, int brk, ass_image_t** tail)
+static ass_image_t **render_glyph(ass_renderer_t *render_priv,
+                                  bitmap_t *bm, int dst_x, int dst_y,
+                                  uint32_t color, uint32_t color2, int brk,
+                                  ass_image_t ** tail)
 {
-       // brk is relative to dst_x
-       // color = color left of brk
-       // color2 = color right of brk
-       int b_x0, b_y0, b_x1, b_y1; // visible part of the bitmap
-       int clip_x0, clip_y0, clip_x1, clip_y1;
-       int tmp;
-       ass_image_t* img;
-
-       dst_x += bm->left;
-       dst_y += bm->top;
-       brk -= bm->left;
-
-       // clipping
-       clip_x0 = render_priv->state.clip_x0;
-       clip_y0 = render_priv->state.clip_y0;
-       clip_x1 = render_priv->state.clip_x1;
-       clip_y1 = render_priv->state.clip_y1;
-       b_x0 = 0;
-       b_y0 = 0;
-       b_x1 = bm->w;
-       b_y1 = bm->h;
-
-       tmp = dst_x - clip_x0;
-       if (tmp < 0) {
-               mp_msg(MSGT_ASS, MSGL_DBG2, "clip left\n");
-               b_x0 = - tmp;
-       }
-       tmp = dst_y - clip_y0;
-       if (tmp < 0) {
-               mp_msg(MSGT_ASS, MSGL_DBG2, "clip top\n");
-               b_y0 = - tmp;
-       }
-       tmp = clip_x1 - dst_x - bm->w;
-       if (tmp < 0) {
-               mp_msg(MSGT_ASS, MSGL_DBG2, "clip right\n");
-               b_x1 = bm->w + tmp;
-       }
-       tmp = clip_y1 - dst_y - bm->h;
-       if (tmp < 0) {
-               mp_msg(MSGT_ASS, MSGL_DBG2, "clip bottom\n");
-               b_y1 = bm->h + tmp;
-       }
-
-       if ((b_y0 >= b_y1) || (b_x0 >= b_x1))
-               return tail;
-
-       if (brk > b_x0) { // draw left part
-               if (brk > b_x1) brk = b_x1;
-               img = my_draw_bitmap(bm->buffer + bm->w * b_y0 + b_x0,
-                       brk - b_x0, b_y1 - b_y0, bm->w,
-                       dst_x + b_x0, dst_y + b_y0, color);
-               *tail = img;
-               tail = &img->next;
-       }
-       if (brk < b_x1) { // draw right part
-               if (brk < b_x0) brk = b_x0;
-               img = my_draw_bitmap(bm->buffer + bm->w * b_y0 + brk,
-                       b_x1 - brk, b_y1 - b_y0, bm->w,
-                       dst_x + brk, dst_y + b_y0, color2);
-               *tail = img;
-               tail = &img->next;
-       }
-       return tail;
+    // brk is relative to dst_x
+    // color = color left of brk
+    // color2 = color right of brk
+    int b_x0, b_y0, b_x1, b_y1; // visible part of the bitmap
+    int clip_x0, clip_y0, clip_x1, clip_y1;
+    int tmp;
+    ass_image_t *img;
+
+    dst_x += bm->left;
+    dst_y += bm->top;
+    brk -= bm->left;
+
+    // clipping
+    clip_x0 = render_priv->state.clip_x0;
+    clip_y0 = render_priv->state.clip_y0;
+    clip_x1 = render_priv->state.clip_x1;
+    clip_y1 = render_priv->state.clip_y1;
+    b_x0 = 0;
+    b_y0 = 0;
+    b_x1 = bm->w;
+    b_y1 = bm->h;
+
+    tmp = dst_x - clip_x0;
+    if (tmp < 0) {
+        mp_msg(MSGT_ASS, MSGL_DBG2, "clip left\n");
+        b_x0 = -tmp;
+    }
+    tmp = dst_y - clip_y0;
+    if (tmp < 0) {
+        mp_msg(MSGT_ASS, MSGL_DBG2, "clip top\n");
+        b_y0 = -tmp;
+    }
+    tmp = clip_x1 - dst_x - bm->w;
+    if (tmp < 0) {
+        mp_msg(MSGT_ASS, MSGL_DBG2, "clip right\n");
+        b_x1 = bm->w + tmp;
+    }
+    tmp = clip_y1 - dst_y - bm->h;
+    if (tmp < 0) {
+        mp_msg(MSGT_ASS, MSGL_DBG2, "clip bottom\n");
+        b_y1 = bm->h + tmp;
+    }
+
+    if ((b_y0 >= b_y1) || (b_x0 >= b_x1))
+        return tail;
+
+    if (brk > b_x0) {           // draw left part
+        if (brk > b_x1)
+            brk = b_x1;
+        img = my_draw_bitmap(bm->buffer + bm->w * b_y0 + b_x0,
+                             brk - b_x0, b_y1 - b_y0, bm->w,
+                             dst_x + b_x0, dst_y + b_y0, color);
+        *tail = img;
+        tail = &img->next;
+    }
+    if (brk < b_x1) {           // draw right part
+        if (brk < b_x0)
+            brk = b_x0;
+        img = my_draw_bitmap(bm->buffer + bm->w * b_y0 + brk,
+                             b_x1 - brk, b_y1 - b_y0, bm->w,
+                             dst_x + brk, dst_y + b_y0, color2);
+        *tail = img;
+        tail = &img->next;
+    }
+    return tail;
 }
 
 /**
@@ -419,331 +439,386 @@ static ass_image_t** render_glyph(ass_renderer_t* render_priv, bitmap_t* bm, int
  * Mainly useful for translucent glyphs and especially borders, to avoid the
  * luminance adding up where they overlap (which looks ugly)
  */
-static void render_overlap(ass_renderer_t* render_priv, ass_image_t** last_tail, ass_image_t** tail, bitmap_hash_key_t *last_hash, bitmap_hash_key_t* hash) {
-       int left, top, bottom, right;
-       int old_left, old_top, w, h, cur_left, cur_top;
-       int x, y, opos, cpos;
-       char m;
-       composite_hash_key_t hk;
-       composite_hash_val_t *hv;
-       composite_hash_key_t *nhk;
-       int ax = (*last_tail)->dst_x;
-       int ay = (*last_tail)->dst_y;
-       int aw = (*last_tail)->w;
-       int as = (*last_tail)->stride;
-       int ah = (*last_tail)->h;
-       int bx = (*tail)->dst_x;
-       int by = (*tail)->dst_y;
-       int bw = (*tail)->w;
-       int bs = (*tail)->stride;
-       int bh = (*tail)->h;
-       unsigned char* a;
-       unsigned char* b;
-
-       if ((*last_tail)->bitmap == (*tail)->bitmap)
-               return;
-
-       if ((*last_tail)->color != (*tail)->color)
-               return;
-
-       // Calculate overlap coordinates
-       left = (ax > bx) ? ax : bx;
-       top = (ay > by) ? ay : by;
-       right = ((ax+aw) < (bx+bw)) ? (ax+aw) : (bx+bw);
-       bottom = ((ay+ah) < (by+bh)) ? (ay+ah) : (by+bh);
-       if ((right <= left) || (bottom <= top))
-               return;
-       old_left = left-ax;
-       old_top = top-ay;
-       w = right-left;
-       h = bottom-top;
-       cur_left = left-bx;
-       cur_top = top-by;
-
-       // Query cache
-       memset(&hk, 0, sizeof(hk));
-       memcpy(&hk.a, last_hash, sizeof(*last_hash));
-       memcpy(&hk.b, hash, sizeof(*hash));
-       hk.aw = aw;
-       hk.ah = ah;
-       hk.bw = bw;
-       hk.bh = bh;
-       hk.ax = ax;
-       hk.ay = ay;
-       hk.bx = bx;
-       hk.by = by;
-       hv = cache_find_composite(render_priv->cache.composite_cache, &hk);
-       if (hv) {
-               (*last_tail)->bitmap = hv->a;
-               (*tail)->bitmap = hv->b;
-               return;
-       }
-
-       // Allocate new bitmaps and copy over data
-       a = (*last_tail)->bitmap;
-       b = (*tail)->bitmap;
-       (*last_tail)->bitmap = malloc(as*ah);
-       (*tail)->bitmap = malloc(bs*bh);
-       memcpy((*last_tail)->bitmap, a, as*ah);
-       memcpy((*tail)->bitmap, b, bs*bh);
-
-       // Composite overlapping area
-       for (y=0; y<h; y++)
-               for (x=0; x<w; x++) {
-                       opos = (old_top+y)*(as) + (old_left+x);
-                       cpos = (cur_top+y)*(bs) + (cur_left+x);
-                       m = (a[opos] > b[cpos]) ? a[opos] : b[cpos];
-                       (*last_tail)->bitmap[opos] = 0;
-                       (*tail)->bitmap[cpos] = m;
-               }
-
-       // Insert bitmaps into the cache
-       nhk = calloc(1, sizeof(*nhk));
-       memcpy(nhk, &hk, sizeof(*nhk));
-       hv = calloc(1, sizeof(*hv));
-       hv->a = (*last_tail)->bitmap;
-       hv->b = (*tail)->bitmap;
-       cache_add_composite(render_priv->cache.composite_cache, nhk, hv);
+static void
+render_overlap(ass_renderer_t *render_priv, ass_image_t ** last_tail,
+               ass_image_t ** tail, bitmap_hash_key_t *last_hash,
+               bitmap_hash_key_t *hash)
+{
+    int left, top, bottom, right;
+    int old_left, old_top, w, h, cur_left, cur_top;
+    int x, y, opos, cpos;
+    char m;
+    composite_hash_key_t hk;
+    composite_hash_val_t *hv;
+    composite_hash_key_t *nhk;
+    int ax = (*last_tail)->dst_x;
+    int ay = (*last_tail)->dst_y;
+    int aw = (*last_tail)->w;
+    int as = (*last_tail)->stride;
+    int ah = (*last_tail)->h;
+    int bx = (*tail)->dst_x;
+    int by = (*tail)->dst_y;
+    int bw = (*tail)->w;
+    int bs = (*tail)->stride;
+    int bh = (*tail)->h;
+    unsigned char *a;
+    unsigned char *b;
+
+    if ((*last_tail)->bitmap == (*tail)->bitmap)
+        return;
+
+    if ((*last_tail)->color != (*tail)->color)
+        return;
+
+    // Calculate overlap coordinates
+    left = (ax > bx) ? ax : bx;
+    top = (ay > by) ? ay : by;
+    right = ((ax + aw) < (bx + bw)) ? (ax + aw) : (bx + bw);
+    bottom = ((ay + ah) < (by + bh)) ? (ay + ah) : (by + bh);
+    if ((right <= left) || (bottom <= top))
+        return;
+    old_left = left - ax;
+    old_top = top - ay;
+    w = right - left;
+    h = bottom - top;
+    cur_left = left - bx;
+    cur_top = top - by;
+
+    // Query cache
+    memset(&hk, 0, sizeof(hk));
+    memcpy(&hk.a, last_hash, sizeof(*last_hash));
+    memcpy(&hk.b, hash, sizeof(*hash));
+    hk.aw = aw;
+    hk.ah = ah;
+    hk.bw = bw;
+    hk.bh = bh;
+    hk.ax = ax;
+    hk.ay = ay;
+    hk.bx = bx;
+    hk.by = by;
+    hv = cache_find_composite(render_priv->cache.composite_cache, &hk);
+    if (hv) {
+        (*last_tail)->bitmap = hv->a;
+        (*tail)->bitmap = hv->b;
+        return;
+    }
+    // Allocate new bitmaps and copy over data
+    a = (*last_tail)->bitmap;
+    b = (*tail)->bitmap;
+    (*last_tail)->bitmap = malloc(as * ah);
+    (*tail)->bitmap = malloc(bs * bh);
+    memcpy((*last_tail)->bitmap, a, as * ah);
+    memcpy((*tail)->bitmap, b, bs * bh);
+
+    // Composite overlapping area
+    for (y = 0; y < h; y++)
+        for (x = 0; x < w; x++) {
+            opos = (old_top + y) * (as) + (old_left + x);
+            cpos = (cur_top + y) * (bs) + (cur_left + x);
+            m = (a[opos] > b[cpos]) ? a[opos] : b[cpos];
+            (*last_tail)->bitmap[opos] = 0;
+            (*tail)->bitmap[cpos] = m;
+        }
+
+    // Insert bitmaps into the cache
+    nhk = calloc(1, sizeof(*nhk));
+    memcpy(nhk, &hk, sizeof(*nhk));
+    hv = calloc(1, sizeof(*hv));
+    hv->a = (*last_tail)->bitmap;
+    hv->b = (*tail)->bitmap;
+    cache_add_composite(render_priv->cache.composite_cache, nhk, hv);
 }
 
 /**
  * \brief Convert text_info_t struct to ass_image_t list
  * Splits glyphs in halves when needed (for \kf karaoke).
  */
-static ass_image_t* render_text(ass_renderer_t* render_priv, int dst_x, int dst_y)
+static ass_image_t *render_text(ass_renderer_t *render_priv, int dst_x,
+                                int dst_y)
 {
-       int pen_x, pen_y;
-       int i;
-       bitmap_t* bm;
-       ass_image_t* head;
-       ass_image_t** tail = &head;
-       ass_image_t** last_tail = 0;
-       ass_image_t** here_tail = 0;
-       bitmap_hash_key_t* last_hash = 0;
-       text_info_t* text_info = &render_priv->text_info;
-
-       for (i = 0; i < text_info->length; ++i) {
-               glyph_info_t* info = text_info->glyphs + i;
-               if ((info->symbol == 0) || (info->symbol == '\n') || !info->bm_s || (info->shadow == 0))
-                       continue;
-
-               pen_x = dst_x + info->pos.x + ROUND(info->shadow * render_priv->border_scale);
-               pen_y = dst_y + info->pos.y + ROUND(info->shadow * render_priv->border_scale);
-               bm = info->bm_s;
-
-               here_tail = tail;
-               tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[3], 0, 1000000, tail);
-               if (last_tail && tail != here_tail && ((info->c[3] & 0xff) > 0))
-                       render_overlap(render_priv, last_tail, here_tail, last_hash, &info->hash_key);
-               last_tail = here_tail;
-               last_hash = &info->hash_key;
-       }
-
-       last_tail = 0;
-       for (i = 0; i < text_info->length; ++i) {
-               glyph_info_t* info = text_info->glyphs + i;
-               if ((info->symbol == 0) || (info->symbol == '\n') || !info->bm_o)
-                       continue;
-
-               pen_x = dst_x + info->pos.x;
-               pen_y = dst_y + info->pos.y;
-               bm = info->bm_o;
-
-               if ((info->effect_type == EF_KARAOKE_KO) && (info->effect_timing <= info->bbox.xMax)) {
-                       // do nothing
-               } else {
-                       here_tail = tail;
-                       tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[2], 0, 1000000, tail);
-                       if (last_tail && tail != here_tail && ((info->c[2] & 0xff) > 0))
-                               render_overlap(render_priv, last_tail, here_tail, last_hash, &info->hash_key);
-                       last_tail = here_tail;
-                       last_hash = &info->hash_key;
-               }
-       }
-       for (i = 0; i < text_info->length; ++i) {
-               glyph_info_t* info = text_info->glyphs + i;
-               if ((info->symbol == 0) || (info->symbol == '\n') || !info->bm)
-                       continue;
-
-               pen_x = dst_x + info->pos.x;
-               pen_y = dst_y + info->pos.y;
-               bm = info->bm;
-
-               if ((info->effect_type == EF_KARAOKE) || (info->effect_type == EF_KARAOKE_KO)) {
-                       if (info->effect_timing > info->bbox.xMax)
-                               tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[0], 0, 1000000, tail);
-                       else
-                               tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[1], 0, 1000000, tail);
-               } else if (info->effect_type == EF_KARAOKE_KF) {
-                       tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[0], info->c[1], info->effect_timing, tail);
-               } else
-                       tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[0], 0, 1000000, tail);
-       }
-
-       *tail = 0;
-       return head;
+    int pen_x, pen_y;
+    int i;
+    bitmap_t *bm;
+    ass_image_t *head;
+    ass_image_t **tail = &head;
+    ass_image_t **last_tail = 0;
+    ass_image_t **here_tail = 0;
+    bitmap_hash_key_t *last_hash = 0;
+    text_info_t *text_info = &render_priv->text_info;
+
+    for (i = 0; i < text_info->length; ++i) {
+        glyph_info_t *info = text_info->glyphs + i;
+        if ((info->symbol == 0) || (info->symbol == '\n') || !info->bm_s
+            || (info->shadow == 0))
+            continue;
+
+        pen_x =
+            dst_x + info->pos.x +
+            ROUND(info->shadow * render_priv->border_scale);
+        pen_y =
+            dst_y + info->pos.y +
+            ROUND(info->shadow * render_priv->border_scale);
+        bm = info->bm_s;
+
+        here_tail = tail;
+        tail =
+            render_glyph(render_priv, bm, pen_x, pen_y, info->c[3], 0,
+                         1000000, tail);
+        if (last_tail && tail != here_tail && ((info->c[3] & 0xff) > 0))
+            render_overlap(render_priv, last_tail, here_tail, last_hash,
+                           &info->hash_key);
+        last_tail = here_tail;
+        last_hash = &info->hash_key;
+    }
+
+    last_tail = 0;
+    for (i = 0; i < text_info->length; ++i) {
+        glyph_info_t *info = text_info->glyphs + i;
+        if ((info->symbol == 0) || (info->symbol == '\n') || !info->bm_o)
+            continue;
+
+        pen_x = dst_x + info->pos.x;
+        pen_y = dst_y + info->pos.y;
+        bm = info->bm_o;
+
+        if ((info->effect_type == EF_KARAOKE_KO)
+            && (info->effect_timing <= info->bbox.xMax)) {
+            // do nothing
+        } else {
+            here_tail = tail;
+            tail =
+                render_glyph(render_priv, bm, pen_x, pen_y, info->c[2],
+                             0, 1000000, tail);
+            if (last_tail && tail != here_tail && ((info->c[2] & 0xff) > 0))
+                render_overlap(render_priv, last_tail, here_tail,
+                               last_hash, &info->hash_key);
+            last_tail = here_tail;
+            last_hash = &info->hash_key;
+        }
+    }
+    for (i = 0; i < text_info->length; ++i) {
+        glyph_info_t *info = text_info->glyphs + i;
+        if ((info->symbol == 0) || (info->symbol == '\n') || !info->bm)
+            continue;
+
+        pen_x = dst_x + info->pos.x;
+        pen_y = dst_y + info->pos.y;
+        bm = info->bm;
+
+        if ((info->effect_type == EF_KARAOKE)
+            || (info->effect_type == EF_KARAOKE_KO)) {
+            if (info->effect_timing > info->bbox.xMax)
+                tail =
+                    render_glyph(render_priv, bm, pen_x, pen_y,
+                                 info->c[0], 0, 1000000, tail);
+            else
+                tail =
+                    render_glyph(render_priv, bm, pen_x, pen_y,
+                                 info->c[1], 0, 1000000, tail);
+        } else if (info->effect_type == EF_KARAOKE_KF) {
+            tail =
+                render_glyph(render_priv, bm, pen_x, pen_y, info->c[0],
+                             info->c[1], info->effect_timing, tail);
+        } else
+            tail =
+                render_glyph(render_priv, bm, pen_x, pen_y, info->c[0],
+                             0, 1000000, tail);
+    }
+
+    *tail = 0;
+    return head;
 }
 
 /**
  * \brief Mapping between script and screen coordinates
  */
-static int x2scr(ass_renderer_t* render_priv, double x) {
-       return x*render_priv->orig_width_nocrop / render_priv->track->PlayResX +
-               FFMAX(render_priv->settings.left_margin, 0);
+static int x2scr(ass_renderer_t *render_priv, double x)
+{
+    return x * render_priv->orig_width_nocrop /
+        render_priv->track->PlayResX +
+        FFMAX(render_priv->settings.left_margin, 0);
 }
-static double x2scr_pos(ass_renderer_t* render_priv, double x) {
-       return x*render_priv->orig_width / render_priv->track->PlayResX +
-               render_priv->settings.left_margin;
+static double x2scr_pos(ass_renderer_t *render_priv, double x)
+{
+    return x * render_priv->orig_width / render_priv->track->PlayResX +
+        render_priv->settings.left_margin;
 }
+
 /**
  * \brief Mapping between script and screen coordinates
  */
-static double y2scr(ass_renderer_t* render_priv, double y) {
-       return y * render_priv->orig_height_nocrop / render_priv->track->PlayResY +
-               FFMAX(render_priv->settings.top_margin, 0);
+static double y2scr(ass_renderer_t *render_priv, double y)
+{
+    return y * render_priv->orig_height_nocrop /
+        render_priv->track->PlayResY +
+        FFMAX(render_priv->settings.top_margin, 0);
 }
-static double y2scr_pos(ass_renderer_t* render_priv, double y) {
-       return y * render_priv->orig_height / render_priv->track->PlayResY +
-               render_priv->settings.top_margin;
+static double y2scr_pos(ass_renderer_t *render_priv, double y)
+{
+    return y * render_priv->orig_height / render_priv->track->PlayResY +
+        render_priv->settings.top_margin;
 }
 
 // the same for toptitles
-static int y2scr_top(ass_renderer_t* render_priv, double y) {
-       if (render_priv->settings.use_margins)
-               return y * render_priv->orig_height_nocrop / render_priv->track->PlayResY;
-       else
-               return y * render_priv->orig_height_nocrop / render_priv->track->PlayResY +
-                       FFMAX(render_priv->settings.top_margin, 0);
+static int y2scr_top(ass_renderer_t *render_priv, double y)
+{
+    if (render_priv->settings.use_margins)
+        return y * render_priv->orig_height_nocrop /
+            render_priv->track->PlayResY;
+    else
+        return y * render_priv->orig_height_nocrop /
+            render_priv->track->PlayResY +
+            FFMAX(render_priv->settings.top_margin, 0);
 }
+
 // the same for subtitles
-static int y2scr_sub(ass_renderer_t* render_priv, double y) {
-       if (render_priv->settings.use_margins)
-               return y * render_priv->orig_height_nocrop / render_priv->track->PlayResY +
-                       FFMAX(render_priv->settings.top_margin, 0) +
-                       FFMAX(render_priv->settings.bottom_margin, 0);
-       else
-               return y * render_priv->orig_height_nocrop / render_priv->track->PlayResY +
-                       FFMAX(render_priv->settings.top_margin, 0);
+static int y2scr_sub(ass_renderer_t *render_priv, double y)
+{
+    if (render_priv->settings.use_margins)
+        return y * render_priv->orig_height_nocrop /
+            render_priv->track->PlayResY +
+            FFMAX(render_priv->settings.top_margin,
+                  0) + FFMAX(render_priv->settings.bottom_margin, 0);
+    else
+        return y * render_priv->orig_height_nocrop /
+            render_priv->track->PlayResY +
+            FFMAX(render_priv->settings.top_margin, 0);
 }
 
-static void compute_string_bbox( text_info_t* info, FT_BBox *abbox ) {
-       FT_BBox bbox;
-       int i;
-
-       if (info->length > 0) {
-               bbox.xMin = 32000;
-               bbox.xMax = -32000;
-               bbox.yMin = - d6_to_int(info->lines[0].asc) + info->glyphs[0].pos.y;
-               bbox.yMax = d6_to_int(info->height - info->lines[0].asc) + info->glyphs[0].pos.y;
-
-               for (i = 0; i < info->length; ++i) {
-                       int s = info->glyphs[i].pos.x;
-                       int e = s + d6_to_int(info->glyphs[i].advance.x);
-                       bbox.xMin = FFMIN(bbox.xMin, s);
-                       bbox.xMax = FFMAX(bbox.xMax, e);
-               }
-       } else
-               bbox.xMin = bbox.xMax = bbox.yMin = bbox.yMax = 0;
-
-       /* return string bbox */
-       *abbox = bbox;
+static void compute_string_bbox(text_info_t *info, FT_BBox * abbox)
+{
+    FT_BBox bbox;
+    int i;
+
+    if (info->length > 0) {
+        bbox.xMin = 32000;
+        bbox.xMax = -32000;
+        bbox.yMin = -d6_to_int(info->lines[0].asc) + info->glyphs[0].pos.y;
+        bbox.yMax =
+            d6_to_int(info->height - info->lines[0].asc) +
+            info->glyphs[0].pos.y;
+
+        for (i = 0; i < info->length; ++i) {
+            int s = info->glyphs[i].pos.x;
+            int e = s + d6_to_int(info->glyphs[i].advance.x);
+            bbox.xMin = FFMIN(bbox.xMin, s);
+            bbox.xMax = FFMAX(bbox.xMax, e);
+        }
+    } else
+        bbox.xMin = bbox.xMax = bbox.yMin = bbox.yMax = 0;
+
+    /* return string bbox */
+    *abbox = bbox;
 }
 
 
 /**
  * \brief Check if starting part of (*p) matches sample. If true, shift p to the first symbol after the matching part.
  */
-static inline int mystrcmp(char** p, const char* sample) {
-       int len = strlen(sample);
-       if (strncmp(*p, sample, len) == 0) {
-               (*p) += len;
-               return 1;
-       } else
-               return 0;
+static inline int mystrcmp(char **p, const char *sample)
+{
+    int len = strlen(sample);
+    if (strncmp(*p, sample, len) == 0) {
+        (*p) += len;
+        return 1;
+    } else
+        return 0;
 }
 
-static void change_font_size(ass_renderer_trender_priv, double sz)
+static void change_font_size(ass_renderer_t *render_priv, double sz)
 {
-       double size = sz * render_priv->font_scale;
+    double size = sz * render_priv->font_scale;
 
-       if (size < 1)
-               size = 1;
-       else if (size > render_priv->height * 2)
-               size = render_priv->height * 2;
+    if (size < 1)
+        size = 1;
+    else if (size > render_priv->height * 2)
+        size = render_priv->height * 2;
 
-       ass_font_set_size(render_priv->state.font, size);
+    ass_font_set_size(render_priv->state.font, size);
 
-       render_priv->state.font_size = sz;
+    render_priv->state.font_size = sz;
 }
 
 /**
  * \brief Change current font, using setting from render_priv->state.
  */
-static void update_font(ass_renderer_trender_priv)
+static void update_font(ass_renderer_t *render_priv)
 {
-       unsigned val;
-       ass_font_desc_t desc;
-       desc.family = strdup(render_priv->state.family);
-       desc.treat_family_as_pattern = render_priv->state.treat_family_as_pattern;
-
-       val = render_priv->state.bold;
-       // 0 = normal, 1 = bold, >1 = exact weight
-       if (val == 0) val = 80; // normal
-       else if (val == 1) val = 200; // bold
-       desc.bold = val;
-
-       val = render_priv->state.italic;
-       if (val == 0) val = 0; // normal
-       else if (val == 1) val = 110; //italic
-       desc.italic = val;
-
-       render_priv->state.font = ass_font_new(render_priv->cache.font_cache, render_priv->library, render_priv->ftlibrary, render_priv->fontconfig_priv, &desc);
-       free(desc.family);
-
-       if (render_priv->state.font)
-               change_font_size(render_priv, render_priv->state.font_size);
+    unsigned val;
+    ass_font_desc_t desc;
+    desc.family = strdup(render_priv->state.family);
+    desc.treat_family_as_pattern =
+        render_priv->state.treat_family_as_pattern;
+
+    val = render_priv->state.bold;
+    // 0 = normal, 1 = bold, >1 = exact weight
+    if (val == 0)
+        val = 80;               // normal
+    else if (val == 1)
+        val = 200;              // bold
+    desc.bold = val;
+
+    val = render_priv->state.italic;
+    if (val == 0)
+        val = 0;                // normal
+    else if (val == 1)
+        val = 110;              //italic
+    desc.italic = val;
+
+    render_priv->state.font =
+        ass_font_new(render_priv->cache.font_cache, render_priv->library,
+                     render_priv->ftlibrary, render_priv->fontconfig_priv,
+                     &desc);
+    free(desc.family);
+
+    if (render_priv->state.font)
+        change_font_size(render_priv, render_priv->state.font_size);
 }
 
 /**
  * \brief Change border width
  * negative value resets border to style value
  */
-static void change_border(ass_renderer_trender_priv, double border)
+static void change_border(ass_renderer_t *render_priv, double border)
 {
-       int b;
-       if (!render_priv->state.font) return;
-
-       if (border < 0) {
-               if (render_priv->state.style->BorderStyle == 1)
-                       border = render_priv->state.style->Outline;
-               else
-                       border = 1.;
-       }
-       render_priv->state.border = border;
-
-       b = 64 * border * render_priv->border_scale;
-       if (b > 0) {
-               if (!render_priv->state.stroker) {
-                       int error;
+    int b;
+    if (!render_priv->state.font)
+        return;
+
+    if (border < 0) {
+        if (render_priv->state.style->BorderStyle == 1)
+            border = render_priv->state.style->Outline;
+        else
+            border = 1.;
+    }
+    render_priv->state.border = border;
+
+    b = 64 * border * render_priv->border_scale;
+    if (b > 0) {
+        if (!render_priv->state.stroker) {
+            int error;
 #if (FREETYPE_MAJOR > 2) || ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR > 1))
-                       error = FT_Stroker_New( render_priv->ftlibrary, &render_priv->state.stroker );
-#else // < 2.2
-                       error = FT_Stroker_New( render_priv->state.font->faces[0]->memory, &render_priv->state.stroker );
+            error =
+                FT_Stroker_New(render_priv->ftlibrary,
+                               &render_priv->state.stroker);
+#else                           // < 2.2
+            error =
+                FT_Stroker_New(render_priv->state.font->faces[0]->
+                               memory, &render_priv->state.stroker);
 #endif
-                       if (error) {
-                               mp_msg(MSGT_ASS, MSGL_V, "failed to get stroker\n");
-                               render_priv->state.stroker = 0;
-                       }
-               }
-               if (render_priv->state.stroker)
-                       FT_Stroker_Set( render_priv->state.stroker, b,
-                                       FT_STROKER_LINECAP_ROUND,
-                                       FT_STROKER_LINEJOIN_ROUND,
-                                       0 );
-       } else {
-               FT_Stroker_Done(render_priv->state.stroker);
-               render_priv->state.stroker = 0;
-       }
+            if (error) {
+                mp_msg(MSGT_ASS, MSGL_V, "failed to get stroker\n");
+                render_priv->state.stroker = 0;
+            }
+        }
+        if (render_priv->state.stroker)
+            FT_Stroker_Set(render_priv->state.stroker, b,
+                           FT_STROKER_LINECAP_ROUND,
+                           FT_STROKER_LINEJOIN_ROUND, 0);
+    } else {
+        FT_Stroker_Done(render_priv->state.stroker);
+        render_priv->state.stroker = 0;
+    }
 }
 
 #define _r(c)  ((c)>>24)
@@ -755,18 +830,19 @@ static void change_border(ass_renderer_t* render_priv, double border)
  * \brief Calculate a weighted average of two colors
  * calculates c1*(1-a) + c2*a, but separately for each component except alpha
  */
-static void change_color(uint32_tvar, uint32_t new, double pwr)
+static void change_color(uint32_t *var, uint32_t new, double pwr)
 {
-       (*var)= ((uint32_t)(_r(*var) * (1 - pwr) + _r(new) * pwr) << 24) +
-               ((uint32_t)(_g(*var) * (1 - pwr) + _g(new) * pwr) << 16) +
-               ((uint32_t)(_b(*var) * (1 - pwr) + _b(new) * pwr) << 8) +
-               _a(*var);
+    (*var) = ((uint32_t) (_r(*var) * (1 - pwr) + _r(new) * pwr) << 24) +
+        ((uint32_t) (_g(*var) * (1 - pwr) + _g(new) * pwr) << 16) +
+        ((uint32_t) (_b(*var) * (1 - pwr) + _b(new) * pwr) << 8) + _a(*var);
 }
 
 // like change_color, but for alpha component only
-static void change_alpha(uint32_tvar, uint32_t new, double pwr)
+static void change_alpha(uint32_t *var, uint32_t new, double pwr)
 {
-       *var = (_r(*var) << 24) + (_g(*var) << 16) + (_b(*var) << 8) + (_a(*var) * (1 - pwr) + _a(new) * pwr);
+    *var =
+        (_r(*var) << 24) + (_g(*var) << 16) + (_b(*var) << 8) +
+        (_a(*var) * (1 - pwr) + _a(new) * pwr);
 }
 
 /**
@@ -778,467 +854,527 @@ static void change_alpha(uint32_t* var, uint32_t new, double pwr)
  */
 static uint32_t mult_alpha(uint32_t a, uint32_t b)
 {
-       return 0xFF - (0xFF - a) * (0xFF - b) / 0xFF;
+    return 0xFF - (0xFF - a) * (0xFF - b) / 0xFF;
 }
 
 /**
  * \brief Calculate alpha value by piecewise linear function
  * Used for \fad, \fade implementation.
  */
-static unsigned interpolate_alpha(long long now,
-               long long t1, long long t2, long long t3, long long t4,
-               unsigned a1, unsigned a2, unsigned a3)
+static unsigned
+interpolate_alpha(long long now,
+                  long long t1, long long t2, long long t3, long long t4,
+                  unsigned a1, unsigned a2, unsigned a3)
 {
-       unsigned a;
-       double cf;
-       if (now <= t1) {
-               a = a1;
-       } else if (now >= t4) {
-               a = a3;
-       } else if (now < t2) { // and > t1
-               cf = ((double)(now - t1)) / (t2 - t1);
-               a = a1 * (1 - cf) + a2 * cf;
-       } else if (now > t3) {
-               cf = ((double)(now - t3)) / (t4 - t3);
-               a = a2 * (1 - cf) + a3 * cf;
-       } else { // t2 <= now <= t3
-               a = a2;
-       }
-
-       return a;
+    unsigned a;
+    double cf;
+    if (now <= t1) {
+        a = a1;
+    } else if (now >= t4) {
+        a = a3;
+    } else if (now < t2) {      // and > t1
+        cf = ((double) (now - t1)) / (t2 - t1);
+        a = a1 * (1 - cf) + a2 * cf;
+    } else if (now > t3) {
+        cf = ((double) (now - t3)) / (t4 - t3);
+        a = a2 * (1 - cf) + a3 * cf;
+    } else {                    // t2 <= now <= t3
+        a = a2;
+    }
+
+    return a;
 }
 
-static void reset_render_context(ass_renderer_t*);
+static void reset_render_context(ass_renderer_t *);
 
 /**
  * \brief Parse style override tag.
  * \param p string to parse
  * \param pwr multiplier for some tag effects (comes from \t tags)
  */
-static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) {
+static char *parse_tag(ass_renderer_t *render_priv, char *p, double pwr)
+{
 #define skip_to(x) while ((*p != (x)) && (*p != '}') && (*p != 0)) { ++p;}
 #define skip(x) if (*p == (x)) ++p; else { return p; }
 
-       skip_to('\\');
-       skip('\\');
-       if ((*p == '}') || (*p == 0))
-               return p;
-
-       // New tags introduced in vsfilter 2.39
-       if (mystrcmp(&p, "xbord")) {
-               double val;
-               if (mystrtod(&p, &val))
-                       mp_msg(MSGT_ASS, MSGL_V, "stub: \\xbord%.2f\n", val);
-       } else if (mystrcmp(&p, "ybord")) {
-               double val;
-               if (mystrtod(&p, &val))
-                       mp_msg(MSGT_ASS, MSGL_V, "stub: \\ybord%.2f\n", val);
-       } else if (mystrcmp(&p, "xshad")) {
-               int val;
-               if (mystrtoi(&p, &val))
-                       mp_msg(MSGT_ASS, MSGL_V, "stub: \\xshad%d\n", val);
-       } else if (mystrcmp(&p, "yshad")) {
-               int val;
-               if (mystrtoi(&p, &val))
-                       mp_msg(MSGT_ASS, MSGL_V, "stub: \\yshad%d\n", val);
-       } else if (mystrcmp(&p, "fax")) {
-               int val;
-               if (mystrtoi(&p, &val))
-                       mp_msg(MSGT_ASS, MSGL_V, "stub: \\fax%d\n", val);
-       } else if (mystrcmp(&p, "fay")) {
-               int val;
-               if (mystrtoi(&p, &val))
-                       mp_msg(MSGT_ASS, MSGL_V, "stub: \\fay%d\n", val);
-       } else if (mystrcmp(&p, "iclip")) {
-               int x0, y0, x1, y1;
-               int res = 1;
-               skip('(');
-               res &= mystrtoi(&p, &x0);
-               skip(',');
-               res &= mystrtoi(&p, &y0);
-               skip(',');
-               res &= mystrtoi(&p, &x1);
-               skip(',');
-               res &= mystrtoi(&p, &y1);
-               skip(')');
-               mp_msg(MSGT_ASS, MSGL_V, "stub: \\iclip(%d,%d,%d,%d)\n", x0, y0, x1, y1);
-       } else if (mystrcmp(&p, "blur")) {
-               double val;
-               if (mystrtod(&p, &val)) {
-                       val = render_priv->state.blur * (1-pwr) + val*pwr;
-                       val = (val < 0) ? 0 : val;
-                       val = (val > BLUR_MAX_RADIUS) ? BLUR_MAX_RADIUS : val;
-                       render_priv->state.blur = val;
-               } else
-                       render_priv->state.blur = 0.0;
-       // ASS standard tags
-       } else if (mystrcmp(&p, "fsc")) {
-               char tp = *p++;
-               double val;
-               if (tp == 'x') {
-                       if (mystrtod(&p, &val)) {
-                               val /= 100;
-                               render_priv->state.scale_x = render_priv->state.scale_x * ( 1 - pwr) + val * pwr;
-                       } else
-                               render_priv->state.scale_x = render_priv->state.style->ScaleX;
-               } else if (tp == 'y') {
-                       if (mystrtod(&p, &val)) {
-                               val /= 100;
-                               render_priv->state.scale_y = render_priv->state.scale_y * ( 1 - pwr) + val * pwr;
-                       } else
-                               render_priv->state.scale_y = render_priv->state.style->ScaleY;
-               }
-       } else if (mystrcmp(&p, "fsp")) {
-               double val;
-               if (mystrtod(&p, &val))
-                       render_priv->state.hspacing = render_priv->state.hspacing * ( 1 - pwr ) + val * pwr;
-               else
-                       render_priv->state.hspacing = render_priv->state.style->Spacing;
-       } else if (mystrcmp(&p, "fs")) {
-               double val;
-               if (mystrtod(&p, &val))
-                       val = render_priv->state.font_size * ( 1 - pwr ) + val * pwr;
-               else
-                       val = render_priv->state.style->FontSize;
-               if (render_priv->state.font)
-                       change_font_size(render_priv, val);
-       } else if (mystrcmp(&p, "bord")) {
-               double val;
-               if (mystrtod(&p, &val))
-                       val = render_priv->state.border * ( 1 - pwr ) + val * pwr;
-               else
-                       val = -1.; // reset to default
-               change_border(render_priv, val);
-       } else if (mystrcmp(&p, "move")) {
-               double x1, x2, y1, y2;
-               long long t1, t2, delta_t, t;
-               double x, y;
-               double k;
-               skip('(');
-               mystrtod(&p, &x1);
-               skip(',');
-               mystrtod(&p, &y1);
-               skip(',');
-               mystrtod(&p, &x2);
-               skip(',');
-               mystrtod(&p, &y2);
-               if (*p == ',') {
-                       skip(',');
-                       mystrtoll(&p, &t1);
-                       skip(',');
-                       mystrtoll(&p, &t2);
-                       mp_msg(MSGT_ASS, MSGL_DBG2, "movement6: (%f, %f) -> (%f, %f), (%" PRId64 " .. %" PRId64 ")\n",
-                               x1, y1, x2, y2, (int64_t)t1, (int64_t)t2);
-               } else {
-                       t1 = 0;
-                       t2 = render_priv->state.event->Duration;
-                       mp_msg(MSGT_ASS, MSGL_DBG2, "movement: (%f, %f) -> (%f, %f)\n", x1, y1, x2, y2);
-               }
-               skip(')');
-               delta_t = t2 - t1;
-               t = render_priv->time - render_priv->state.event->Start;
-               if (t < t1)
-                       k = 0.;
-               else if (t > t2)
-                       k = 1.;
-               else k = ((double)(t - t1)) / delta_t;
-               x = k * (x2 - x1) + x1;
-               y = k * (y2 - y1) + y1;
-               if (render_priv->state.evt_type != EVENT_POSITIONED) {
-                       render_priv->state.pos_x = x;
-                       render_priv->state.pos_y = y;
-                       render_priv->state.detect_collisions = 0;
-                       render_priv->state.evt_type = EVENT_POSITIONED;
-               }
-       } else if (mystrcmp(&p, "frx")) {
-               double val;
-               if (mystrtod(&p, &val)) {
-                       val *= M_PI / 180;
-                       render_priv->state.frx = val * pwr + render_priv->state.frx * (1-pwr);
-               } else
-                       render_priv->state.frx = 0.;
-       } else if (mystrcmp(&p, "fry")) {
-               double val;
-               if (mystrtod(&p, &val)) {
-                       val *= M_PI / 180;
-                       render_priv->state.fry = val * pwr + render_priv->state.fry * (1-pwr);
-               } else
-                       render_priv->state.fry = 0.;
-       } else if (mystrcmp(&p, "frz") || mystrcmp(&p, "fr")) {
-               double val;
-               if (mystrtod(&p, &val)) {
-                       val *= M_PI / 180;
-                       render_priv->state.frz = val * pwr + render_priv->state.frz * (1-pwr);
-               } else
-                       render_priv->state.frz = M_PI * render_priv->state.style->Angle / 180.;
-       } else if (mystrcmp(&p, "fn")) {
-               char* start = p;
-               char* family;
-               skip_to('\\');
-               if (p > start) {
-                       family = malloc(p - start + 1);
-                       strncpy(family, start, p - start);
-                       family[p - start] = '\0';
-               } else
-                       family = strdup(render_priv->state.style->FontName);
-               if (render_priv->state.family)
-                       free(render_priv->state.family);
-               render_priv->state.family = family;
-               update_font(render_priv);
-       } else if (mystrcmp(&p, "alpha")) {
-               uint32_t val;
-               int i;
-               if (strtocolor(&p, &val)) {
-                       unsigned char a = val >> 24;
-                       for (i = 0; i < 4; ++i)
-                               change_alpha(&render_priv->state.c[i], a, pwr);
-               } else {
-                       change_alpha(&render_priv->state.c[0], render_priv->state.style->PrimaryColour, pwr);
-                       change_alpha(&render_priv->state.c[1], render_priv->state.style->SecondaryColour, pwr);
-                       change_alpha(&render_priv->state.c[2], render_priv->state.style->OutlineColour, pwr);
-                       change_alpha(&render_priv->state.c[3], render_priv->state.style->BackColour, pwr);
-               }
-               // FIXME: simplify
-       } else if (mystrcmp(&p, "an")) {
-               int val;
-               if (mystrtoi(&p, &val) && val) {
-                       int v = (val - 1) / 3; // 0, 1 or 2 for vertical alignment
-                       mp_msg(MSGT_ASS, MSGL_DBG2, "an %d\n", val);
-                       if (v != 0) v = 3 - v;
-                       val = ((val - 1) % 3) + 1; // horizontal alignment
-                       val += v*4;
-                       mp_msg(MSGT_ASS, MSGL_DBG2, "align %d\n", val);
-                       render_priv->state.alignment = val;
-               } else
-                       render_priv->state.alignment = render_priv->state.style->Alignment;
-       } else if (mystrcmp(&p, "a")) {
-               int val;
-               if (mystrtoi(&p, &val) && val)
-                       render_priv->state.alignment = val;
-               else
-                       render_priv->state.alignment = render_priv->state.style->Alignment;
-       } else if (mystrcmp(&p, "pos")) {
-               double v1, v2;
-               skip('(');
-               mystrtod(&p, &v1);
-               skip(',');
-               mystrtod(&p, &v2);
-               skip(')');
-               mp_msg(MSGT_ASS, MSGL_DBG2, "pos(%f, %f)\n", v1, v2);
-               if (render_priv->state.evt_type == EVENT_POSITIONED) {
-                       mp_msg(MSGT_ASS, MSGL_V, "Subtitle has a new \\pos "
-                              "after \\move or \\pos, ignoring\n");
-               } else {
-                       render_priv->state.evt_type = EVENT_POSITIONED;
-                       render_priv->state.detect_collisions = 0;
-                       render_priv->state.pos_x = v1;
-                       render_priv->state.pos_y = v2;
-               }
-       } else if (mystrcmp(&p, "fad")) {
-               int a1, a2, a3;
-               long long t1, t2, t3, t4;
-               if (*p == 'e') ++p; // either \fad or \fade
-               skip('(');
-               mystrtoi(&p, &a1);
-               skip(',');
-               mystrtoi(&p, &a2);
-               if (*p == ')') {
-                       // 2-argument version (\fad, according to specs)
-                       // a1 and a2 are fade-in and fade-out durations
-                       t1 = 0;
-                       t4 = render_priv->state.event->Duration;
-                       t2 = a1;
-                       t3 = t4 - a2;
-                       a1 = 0xFF;
-                       a2 = 0;
-                       a3 = 0xFF;
-               } else {
-                       // 6-argument version (\fade)
-                       // a1 and a2 (and a3) are opacity values
-                       skip(',');
-                       mystrtoi(&p, &a3);
-                       skip(',');
-                       mystrtoll(&p, &t1);
-                       skip(',');
-                       mystrtoll(&p, &t2);
-                       skip(',');
-                       mystrtoll(&p, &t3);
-                       skip(',');
-                       mystrtoll(&p, &t4);
-               }
-               skip(')');
-               render_priv->state.fade = interpolate_alpha(render_priv->time - render_priv->state.event->Start, t1, t2, t3, t4, a1, a2, a3);
-       } else if (mystrcmp(&p, "org")) {
-               int v1, v2;
-               skip('(');
-               mystrtoi(&p, &v1);
-               skip(',');
-               mystrtoi(&p, &v2);
-               skip(')');
-               mp_msg(MSGT_ASS, MSGL_DBG2, "org(%d, %d)\n", v1, v2);
-               //                              render_priv->state.evt_type = EVENT_POSITIONED;
-               if (!render_priv->state.have_origin) {
-                       render_priv->state.org_x = v1;
-                       render_priv->state.org_y = v2;
-                       render_priv->state.have_origin = 1;
-                       render_priv->state.detect_collisions = 0;
-               }
-       } else if (mystrcmp(&p, "t")) {
-               double v[3];
-               int v1, v2;
-               double v3;
-               int cnt;
-               long long t1, t2, t, delta_t;
-               double k;
-               skip('(');
-               for (cnt = 0; cnt < 3; ++cnt) {
-                       if (*p == '\\')
-                               break;
-                       v[cnt] = strtod(p, &p);
-                       skip(',');
-               }
-               if (cnt == 3) {
-                       v1 = v[0]; v2 = v[1]; v3 = v[2];
-               } else if (cnt == 2) {
-                       v1 = v[0]; v2 = v[1]; v3 = 1.;
-               } else if (cnt == 1) {
-                       v1 = 0; v2 = render_priv->state.event->Duration; v3 = v[0];
-               } else { // cnt == 0
-                       v1 = 0; v2 = render_priv->state.event->Duration; v3 = 1.;
-               }
-               render_priv->state.detect_collisions = 0;
-               t1 = v1;
-               t2 = v2;
-               delta_t = v2 - v1;
-               if (v3 < 0.)
-                       v3 = 0.;
-               t = render_priv->time - render_priv->state.event->Start; // FIXME: move to render_context
-               if (t <= t1)
-                       k = 0.;
-               else if (t >= t2)
-                       k = 1.;
-               else {
-                       assert(delta_t != 0.);
-                       k = pow(((double)(t - t1)) / delta_t, v3);
-               }
-               while (*p == '\\')
-                       p = parse_tag(render_priv, p, k); // maybe k*pwr ? no, specs forbid nested \t's 
-               skip_to(')'); // in case there is some unknown tag or a comment
-               skip(')');
-       } else if (mystrcmp(&p, "clip")) {
-               int x0, y0, x1, y1;
-               int res = 1;
-               skip('(');
-               res &= mystrtoi(&p, &x0);
-               skip(',');
-               res &= mystrtoi(&p, &y0);
-               skip(',');
-               res &= mystrtoi(&p, &x1);
-               skip(',');
-               res &= mystrtoi(&p, &y1);
-               skip(')');
-               if (res) {
-                       render_priv->state.clip_x0 = render_priv->state.clip_x0 * (1-pwr) + x0 * pwr;
-                       render_priv->state.clip_x1 = render_priv->state.clip_x1 * (1-pwr) + x1 * pwr;
-                       render_priv->state.clip_y0 = render_priv->state.clip_y0 * (1-pwr) + y0 * pwr;
-                       render_priv->state.clip_y1 = render_priv->state.clip_y1 * (1-pwr) + y1 * pwr;
-               } else {
-                       render_priv->state.clip_x0 = 0;
-                       render_priv->state.clip_y0 = 0;
-                       render_priv->state.clip_x1 = render_priv->track->PlayResX;
-                       render_priv->state.clip_y1 = render_priv->track->PlayResY;
-               }
-       } else if (mystrcmp(&p, "c")) {
-               uint32_t val;
-               if (!strtocolor(&p, &val))
-                       val = render_priv->state.style->PrimaryColour;
-               mp_msg(MSGT_ASS, MSGL_DBG2, "color: %X\n", val);
-               change_color(&render_priv->state.c[0], val, pwr);
-       } else if ((*p >= '1') && (*p <= '4') && (++p) && (mystrcmp(&p, "c") || mystrcmp(&p, "a"))) {
-               char n = *(p-2);
-               int cidx = n - '1';
-               char cmd = *(p-1);
-               uint32_t val;
-               assert((n >= '1') && (n <= '4'));
-               if (!strtocolor(&p, &val))
-                       switch(n) {
-                               case '1': val = render_priv->state.style->PrimaryColour; break;
-                               case '2': val = render_priv->state.style->SecondaryColour; break;
-                               case '3': val = render_priv->state.style->OutlineColour; break;
-                               case '4': val = render_priv->state.style->BackColour; break;
-                               default : val = 0; break; // impossible due to assert; avoid compilation warning
-                       }
-               switch (cmd) {
-                       case 'c': change_color(render_priv->state.c + cidx, val, pwr); break;
-                       case 'a': change_alpha(render_priv->state.c + cidx, val >> 24, pwr); break;
-                       default: mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_BadCommand, n, cmd); break;
-               }
-               mp_msg(MSGT_ASS, MSGL_DBG2, "single c/a at %f: %c%c = %X   \n", pwr, n, cmd, render_priv->state.c[cidx]);
-       } else if (mystrcmp(&p, "r")) {
-               reset_render_context(render_priv);
-       } else if (mystrcmp(&p, "be")) {
-               int val;
-               if (mystrtoi(&p, &val)) {
-                       // Clamp to a safe upper limit, since high values need excessive CPU
-                       val = (val < 0) ? 0 : val;
-                       val = (val > MAX_BE) ? MAX_BE : val;
-                       render_priv->state.be = val;
-               } else
-                       render_priv->state.be = 0;
-       } else if (mystrcmp(&p, "b")) {
-               int b;
-               if (mystrtoi(&p, &b)) {
-                       if (pwr >= .5)
-                               render_priv->state.bold = b;
-               } else
-                       render_priv->state.bold = render_priv->state.style->Bold;
-               update_font(render_priv);
-       } else if (mystrcmp(&p, "i")) {
-               int i;
-               if (mystrtoi(&p, &i)) {
-                       if (pwr >= .5)
-                               render_priv->state.italic = i;
-               } else
-                       render_priv->state.italic = render_priv->state.style->Italic;
-               update_font(render_priv);
-       } else if (mystrcmp(&p, "kf") || mystrcmp(&p, "K")) {
-               int val = 0;
-               mystrtoi(&p, &val);
-               render_priv->state.effect_type = EF_KARAOKE_KF;
-               if (render_priv->state.effect_timing)
-                       render_priv->state.effect_skip_timing += render_priv->state.effect_timing;
-               render_priv->state.effect_timing = val * 10;
-       } else if (mystrcmp(&p, "ko")) {
-               int val = 0;
-               mystrtoi(&p, &val);
-               render_priv->state.effect_type = EF_KARAOKE_KO;
-               if (render_priv->state.effect_timing)
-                       render_priv->state.effect_skip_timing += render_priv->state.effect_timing;
-               render_priv->state.effect_timing = val * 10;
-       } else if (mystrcmp(&p, "k")) {
-               int val = 0;
-               mystrtoi(&p, &val);
-               render_priv->state.effect_type = EF_KARAOKE;
-               if (render_priv->state.effect_timing)
-                       render_priv->state.effect_skip_timing += render_priv->state.effect_timing;
-               render_priv->state.effect_timing = val * 10;
-       } else if (mystrcmp(&p, "shad")) {
-               int val;
-               if (mystrtoi(&p, &val))
-                       render_priv->state.shadow = val;
-               else
-                       render_priv->state.shadow = render_priv->state.style->Shadow;
-       } else if (mystrcmp(&p, "pbo")) {
-               int val = 0;
-               mystrtoi(&p, &val); // ignored
-       } else if (mystrcmp(&p, "p")) {
-               int val;
-               if (!mystrtoi(&p, &val))
-                       val = 0;
-               render_priv->state.drawing_mode = !!val;
-       }
-
-       return p;
+    skip_to('\\');
+    skip('\\');
+    if ((*p == '}') || (*p == 0))
+        return p;
+
+    // New tags introduced in vsfilter 2.39
+    if (mystrcmp(&p, "xbord")) {
+        double val;
+        if (mystrtod(&p, &val))
+            mp_msg(MSGT_ASS, MSGL_V, "stub: \\xbord%.2f\n", val);
+    } else if (mystrcmp(&p, "ybord")) {
+        double val;
+        if (mystrtod(&p, &val))
+            mp_msg(MSGT_ASS, MSGL_V, "stub: \\ybord%.2f\n", val);
+    } else if (mystrcmp(&p, "xshad")) {
+        int val;
+        if (mystrtoi(&p, &val))
+            mp_msg(MSGT_ASS, MSGL_V, "stub: \\xshad%d\n", val);
+    } else if (mystrcmp(&p, "yshad")) {
+        int val;
+        if (mystrtoi(&p, &val))
+            mp_msg(MSGT_ASS, MSGL_V, "stub: \\yshad%d\n", val);
+    } else if (mystrcmp(&p, "fax")) {
+        int val;
+        if (mystrtoi(&p, &val))
+            mp_msg(MSGT_ASS, MSGL_V, "stub: \\fax%d\n", val);
+    } else if (mystrcmp(&p, "fay")) {
+        int val;
+        if (mystrtoi(&p, &val))
+            mp_msg(MSGT_ASS, MSGL_V, "stub: \\fay%d\n", val);
+    } else if (mystrcmp(&p, "iclip")) {
+        int x0, y0, x1, y1;
+        int res = 1;
+        skip('(');
+        res &= mystrtoi(&p, &x0);
+        skip(',');
+        res &= mystrtoi(&p, &y0);
+        skip(',');
+        res &= mystrtoi(&p, &x1);
+        skip(',');
+        res &= mystrtoi(&p, &y1);
+        skip(')');
+        mp_msg(MSGT_ASS, MSGL_V, "stub: \\iclip(%d,%d,%d,%d)\n", x0, y0,
+               x1, y1);
+    } else if (mystrcmp(&p, "blur")) {
+        double val;
+        if (mystrtod(&p, &val)) {
+            val = render_priv->state.blur * (1 - pwr) + val * pwr;
+            val = (val < 0) ? 0 : val;
+            val = (val > BLUR_MAX_RADIUS) ? BLUR_MAX_RADIUS : val;
+            render_priv->state.blur = val;
+        } else
+            render_priv->state.blur = 0.0;
+        // ASS standard tags
+    } else if (mystrcmp(&p, "fsc")) {
+        char tp = *p++;
+        double val;
+        if (tp == 'x') {
+            if (mystrtod(&p, &val)) {
+                val /= 100;
+                render_priv->state.scale_x =
+                    render_priv->state.scale_x * (1 - pwr) + val * pwr;
+            } else
+                render_priv->state.scale_x =
+                    render_priv->state.style->ScaleX;
+        } else if (tp == 'y') {
+            if (mystrtod(&p, &val)) {
+                val /= 100;
+                render_priv->state.scale_y =
+                    render_priv->state.scale_y * (1 - pwr) + val * pwr;
+            } else
+                render_priv->state.scale_y =
+                    render_priv->state.style->ScaleY;
+        }
+    } else if (mystrcmp(&p, "fsp")) {
+        double val;
+        if (mystrtod(&p, &val))
+            render_priv->state.hspacing =
+                render_priv->state.hspacing * (1 - pwr) + val * pwr;
+        else
+            render_priv->state.hspacing = render_priv->state.style->Spacing;
+    } else if (mystrcmp(&p, "fs")) {
+        double val;
+        if (mystrtod(&p, &val))
+            val = render_priv->state.font_size * (1 - pwr) + val * pwr;
+        else
+            val = render_priv->state.style->FontSize;
+        if (render_priv->state.font)
+            change_font_size(render_priv, val);
+    } else if (mystrcmp(&p, "bord")) {
+        double val;
+        if (mystrtod(&p, &val))
+            val = render_priv->state.border * (1 - pwr) + val * pwr;
+        else
+            val = -1.;          // reset to default
+        change_border(render_priv, val);
+    } else if (mystrcmp(&p, "move")) {
+        double x1, x2, y1, y2;
+        long long t1, t2, delta_t, t;
+        double x, y;
+        double k;
+        skip('(');
+        mystrtod(&p, &x1);
+        skip(',');
+        mystrtod(&p, &y1);
+        skip(',');
+        mystrtod(&p, &x2);
+        skip(',');
+        mystrtod(&p, &y2);
+        if (*p == ',') {
+            skip(',');
+            mystrtoll(&p, &t1);
+            skip(',');
+            mystrtoll(&p, &t2);
+            mp_msg(MSGT_ASS, MSGL_DBG2,
+                   "movement6: (%f, %f) -> (%f, %f), (%" PRId64 " .. %"
+                   PRId64 ")\n", x1, y1, x2, y2, (int64_t) t1,
+                   (int64_t) t2);
+        } else {
+            t1 = 0;
+            t2 = render_priv->state.event->Duration;
+            mp_msg(MSGT_ASS, MSGL_DBG2,
+                   "movement: (%f, %f) -> (%f, %f)\n", x1, y1, x2, y2);
+        }
+        skip(')');
+        delta_t = t2 - t1;
+        t = render_priv->time - render_priv->state.event->Start;
+        if (t < t1)
+            k = 0.;
+        else if (t > t2)
+            k = 1.;
+        else
+            k = ((double) (t - t1)) / delta_t;
+        x = k * (x2 - x1) + x1;
+        y = k * (y2 - y1) + y1;
+        if (render_priv->state.evt_type != EVENT_POSITIONED) {
+            render_priv->state.pos_x = x;
+            render_priv->state.pos_y = y;
+            render_priv->state.detect_collisions = 0;
+            render_priv->state.evt_type = EVENT_POSITIONED;
+        }
+    } else if (mystrcmp(&p, "frx")) {
+        double val;
+        if (mystrtod(&p, &val)) {
+            val *= M_PI / 180;
+            render_priv->state.frx =
+                val * pwr + render_priv->state.frx * (1 - pwr);
+        } else
+            render_priv->state.frx = 0.;
+    } else if (mystrcmp(&p, "fry")) {
+        double val;
+        if (mystrtod(&p, &val)) {
+            val *= M_PI / 180;
+            render_priv->state.fry =
+                val * pwr + render_priv->state.fry * (1 - pwr);
+        } else
+            render_priv->state.fry = 0.;
+    } else if (mystrcmp(&p, "frz") || mystrcmp(&p, "fr")) {
+        double val;
+        if (mystrtod(&p, &val)) {
+            val *= M_PI / 180;
+            render_priv->state.frz =
+                val * pwr + render_priv->state.frz * (1 - pwr);
+        } else
+            render_priv->state.frz =
+                M_PI * render_priv->state.style->Angle / 180.;
+    } else if (mystrcmp(&p, "fn")) {
+        char *start = p;
+        char *family;
+        skip_to('\\');
+        if (p > start) {
+            family = malloc(p - start + 1);
+            strncpy(family, start, p - start);
+            family[p - start] = '\0';
+        } else
+            family = strdup(render_priv->state.style->FontName);
+        if (render_priv->state.family)
+            free(render_priv->state.family);
+        render_priv->state.family = family;
+        update_font(render_priv);
+    } else if (mystrcmp(&p, "alpha")) {
+        uint32_t val;
+        int i;
+        if (strtocolor(&p, &val)) {
+            unsigned char a = val >> 24;
+            for (i = 0; i < 4; ++i)
+                change_alpha(&render_priv->state.c[i], a, pwr);
+        } else {
+            change_alpha(&render_priv->state.c[0],
+                         render_priv->state.style->PrimaryColour, pwr);
+            change_alpha(&render_priv->state.c[1],
+                         render_priv->state.style->SecondaryColour, pwr);
+            change_alpha(&render_priv->state.c[2],
+                         render_priv->state.style->OutlineColour, pwr);
+            change_alpha(&render_priv->state.c[3],
+                         render_priv->state.style->BackColour, pwr);
+        }
+        // FIXME: simplify
+    } else if (mystrcmp(&p, "an")) {
+        int val;
+        if (mystrtoi(&p, &val) && val) {
+            int v = (val - 1) / 3;      // 0, 1 or 2 for vertical alignment
+            mp_msg(MSGT_ASS, MSGL_DBG2, "an %d\n", val);
+            if (v != 0)
+                v = 3 - v;
+            val = ((val - 1) % 3) + 1;  // horizontal alignment
+            val += v * 4;
+            mp_msg(MSGT_ASS, MSGL_DBG2, "align %d\n", val);
+            render_priv->state.alignment = val;
+        } else
+            render_priv->state.alignment =
+                render_priv->state.style->Alignment;
+    } else if (mystrcmp(&p, "a")) {
+        int val;
+        if (mystrtoi(&p, &val) && val)
+            render_priv->state.alignment = val;
+        else
+            render_priv->state.alignment =
+                render_priv->state.style->Alignment;
+    } else if (mystrcmp(&p, "pos")) {
+        double v1, v2;
+        skip('(');
+        mystrtod(&p, &v1);
+        skip(',');
+        mystrtod(&p, &v2);
+        skip(')');
+        mp_msg(MSGT_ASS, MSGL_DBG2, "pos(%f, %f)\n", v1, v2);
+        if (render_priv->state.evt_type == EVENT_POSITIONED) {
+            mp_msg(MSGT_ASS, MSGL_V, "Subtitle has a new \\pos "
+                   "after \\move or \\pos, ignoring\n");
+        } else {
+            render_priv->state.evt_type = EVENT_POSITIONED;
+            render_priv->state.detect_collisions = 0;
+            render_priv->state.pos_x = v1;
+            render_priv->state.pos_y = v2;
+        }
+    } else if (mystrcmp(&p, "fad")) {
+        int a1, a2, a3;
+        long long t1, t2, t3, t4;
+        if (*p == 'e')
+            ++p;                // either \fad or \fade
+        skip('(');
+        mystrtoi(&p, &a1);
+        skip(',');
+        mystrtoi(&p, &a2);
+        if (*p == ')') {
+            // 2-argument version (\fad, according to specs)
+            // a1 and a2 are fade-in and fade-out durations
+            t1 = 0;
+            t4 = render_priv->state.event->Duration;
+            t2 = a1;
+            t3 = t4 - a2;
+            a1 = 0xFF;
+            a2 = 0;
+            a3 = 0xFF;
+        } else {
+            // 6-argument version (\fade)
+            // a1 and a2 (and a3) are opacity values
+            skip(',');
+            mystrtoi(&p, &a3);
+            skip(',');
+            mystrtoll(&p, &t1);
+            skip(',');
+            mystrtoll(&p, &t2);
+            skip(',');
+            mystrtoll(&p, &t3);
+            skip(',');
+            mystrtoll(&p, &t4);
+        }
+        skip(')');
+        render_priv->state.fade =
+            interpolate_alpha(render_priv->time -
+                              render_priv->state.event->Start, t1, t2,
+                              t3, t4, a1, a2, a3);
+    } else if (mystrcmp(&p, "org")) {
+        int v1, v2;
+        skip('(');
+        mystrtoi(&p, &v1);
+        skip(',');
+        mystrtoi(&p, &v2);
+        skip(')');
+        mp_msg(MSGT_ASS, MSGL_DBG2, "org(%d, %d)\n", v1, v2);
+        //                              render_priv->state.evt_type = EVENT_POSITIONED;
+        if (!render_priv->state.have_origin) {
+            render_priv->state.org_x = v1;
+            render_priv->state.org_y = v2;
+            render_priv->state.have_origin = 1;
+            render_priv->state.detect_collisions = 0;
+        }
+    } else if (mystrcmp(&p, "t")) {
+        double v[3];
+        int v1, v2;
+        double v3;
+        int cnt;
+        long long t1, t2, t, delta_t;
+        double k;
+        skip('(');
+        for (cnt = 0; cnt < 3; ++cnt) {
+            if (*p == '\\')
+                break;
+            v[cnt] = strtod(p, &p);
+            skip(',');
+        }
+        if (cnt == 3) {
+            v1 = v[0];
+            v2 = v[1];
+            v3 = v[2];
+        } else if (cnt == 2) {
+            v1 = v[0];
+            v2 = v[1];
+            v3 = 1.;
+        } else if (cnt == 1) {
+            v1 = 0;
+            v2 = render_priv->state.event->Duration;
+            v3 = v[0];
+        } else {                // cnt == 0
+            v1 = 0;
+            v2 = render_priv->state.event->Duration;
+            v3 = 1.;
+        }
+        render_priv->state.detect_collisions = 0;
+        t1 = v1;
+        t2 = v2;
+        delta_t = v2 - v1;
+        if (v3 < 0.)
+            v3 = 0.;
+        t = render_priv->time - render_priv->state.event->Start;        // FIXME: move to render_context
+        if (t <= t1)
+            k = 0.;
+        else if (t >= t2)
+            k = 1.;
+        else {
+            assert(delta_t != 0.);
+            k = pow(((double) (t - t1)) / delta_t, v3);
+        }
+        while (*p == '\\')
+            p = parse_tag(render_priv, p, k);   // maybe k*pwr ? no, specs forbid nested \t's
+        skip_to(')');           // in case there is some unknown tag or a comment
+        skip(')');
+    } else if (mystrcmp(&p, "clip")) {
+        int x0, y0, x1, y1;
+        int res = 1;
+        skip('(');
+        res &= mystrtoi(&p, &x0);
+        skip(',');
+        res &= mystrtoi(&p, &y0);
+        skip(',');
+        res &= mystrtoi(&p, &x1);
+        skip(',');
+        res &= mystrtoi(&p, &y1);
+        skip(')');
+        if (res) {
+            render_priv->state.clip_x0 =
+                render_priv->state.clip_x0 * (1 - pwr) + x0 * pwr;
+            render_priv->state.clip_x1 =
+                render_priv->state.clip_x1 * (1 - pwr) + x1 * pwr;
+            render_priv->state.clip_y0 =
+                render_priv->state.clip_y0 * (1 - pwr) + y0 * pwr;
+            render_priv->state.clip_y1 =
+                render_priv->state.clip_y1 * (1 - pwr) + y1 * pwr;
+        } else {
+            render_priv->state.clip_x0 = 0;
+            render_priv->state.clip_y0 = 0;
+            render_priv->state.clip_x1 = render_priv->track->PlayResX;
+            render_priv->state.clip_y1 = render_priv->track->PlayResY;
+        }
+    } else if (mystrcmp(&p, "c")) {
+        uint32_t val;
+        if (!strtocolor(&p, &val))
+            val = render_priv->state.style->PrimaryColour;
+        mp_msg(MSGT_ASS, MSGL_DBG2, "color: %X\n", val);
+        change_color(&render_priv->state.c[0], val, pwr);
+    } else if ((*p >= '1') && (*p <= '4') && (++p)
+               && (mystrcmp(&p, "c") || mystrcmp(&p, "a"))) {
+        char n = *(p - 2);
+        int cidx = n - '1';
+        char cmd = *(p - 1);
+        uint32_t val;
+        assert((n >= '1') && (n <= '4'));
+        if (!strtocolor(&p, &val))
+            switch (n) {
+            case '1':
+                val = render_priv->state.style->PrimaryColour;
+                break;
+            case '2':
+                val = render_priv->state.style->SecondaryColour;
+                break;
+            case '3':
+                val = render_priv->state.style->OutlineColour;
+                break;
+            case '4':
+                val = render_priv->state.style->BackColour;
+                break;
+            default:
+                val = 0;
+                break;          // impossible due to assert; avoid compilation warning
+            }
+        switch (cmd) {
+        case 'c':
+            change_color(render_priv->state.c + cidx, val, pwr);
+            break;
+        case 'a':
+            change_alpha(render_priv->state.c + cidx, val >> 24, pwr);
+            break;
+        default:
+            mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_BadCommand, n, cmd);
+            break;
+        }
+        mp_msg(MSGT_ASS, MSGL_DBG2, "single c/a at %f: %c%c = %X   \n",
+               pwr, n, cmd, render_priv->state.c[cidx]);
+    } else if (mystrcmp(&p, "r")) {
+        reset_render_context(render_priv);
+    } else if (mystrcmp(&p, "be")) {
+        int val;
+        if (mystrtoi(&p, &val)) {
+            // Clamp to a safe upper limit, since high values need excessive CPU
+            val = (val < 0) ? 0 : val;
+            val = (val > MAX_BE) ? MAX_BE : val;
+            render_priv->state.be = val;
+        } else
+            render_priv->state.be = 0;
+    } else if (mystrcmp(&p, "b")) {
+        int b;
+        if (mystrtoi(&p, &b)) {
+            if (pwr >= .5)
+                render_priv->state.bold = b;
+        } else
+            render_priv->state.bold = render_priv->state.style->Bold;
+        update_font(render_priv);
+    } else if (mystrcmp(&p, "i")) {
+        int i;
+        if (mystrtoi(&p, &i)) {
+            if (pwr >= .5)
+                render_priv->state.italic = i;
+        } else
+            render_priv->state.italic = render_priv->state.style->Italic;
+        update_font(render_priv);
+    } else if (mystrcmp(&p, "kf") || mystrcmp(&p, "K")) {
+        int val = 0;
+        mystrtoi(&p, &val);
+        render_priv->state.effect_type = EF_KARAOKE_KF;
+        if (render_priv->state.effect_timing)
+            render_priv->state.effect_skip_timing +=
+                render_priv->state.effect_timing;
+        render_priv->state.effect_timing = val * 10;
+    } else if (mystrcmp(&p, "ko")) {
+        int val = 0;
+        mystrtoi(&p, &val);
+        render_priv->state.effect_type = EF_KARAOKE_KO;
+        if (render_priv->state.effect_timing)
+            render_priv->state.effect_skip_timing +=
+                render_priv->state.effect_timing;
+        render_priv->state.effect_timing = val * 10;
+    } else if (mystrcmp(&p, "k")) {
+        int val = 0;
+        mystrtoi(&p, &val);
+        render_priv->state.effect_type = EF_KARAOKE;
+        if (render_priv->state.effect_timing)
+            render_priv->state.effect_skip_timing +=
+                render_priv->state.effect_timing;
+        render_priv->state.effect_timing = val * 10;
+    } else if (mystrcmp(&p, "shad")) {
+        int val;
+        if (mystrtoi(&p, &val))
+            render_priv->state.shadow = val;
+        else
+            render_priv->state.shadow = render_priv->state.style->Shadow;
+    } else if (mystrcmp(&p, "pbo")) {
+        int val = 0;
+        mystrtoi(&p, &val);     // ignored
+    } else if (mystrcmp(&p, "p")) {
+        int val;
+        if (!mystrtoi(&p, &val))
+            val = 0;
+        render_priv->state.drawing_mode = !!val;
+    }
+
+    return p;
 
 #undef skip
 #undef skip_to
@@ -1250,110 +1386,123 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) {
  * \return ucs4 code of the next char
  * On return str points to the unparsed part of the string
  */
-static unsigned get_next_char(ass_renderer_t* render_priv, char** str)
+static unsigned get_next_char(ass_renderer_t *render_priv, char **str)
 {
-       char* p = *str;
-       unsigned chr;
-       if (*p == '{') { // '\0' goes here
-               p++;
-               while (1) {
-                       p = parse_tag(render_priv, p, 1.);
-                       if (*p == '}') { // end of tag
-                               p++;
-                               if (*p == '{') {
-                                       p++;
-                                       continue;
-                               } else
-                                       break;
-                       } else if (*p != '\\')
-                               mp_msg(MSGT_ASS, MSGL_V, "Unable to parse: \"%s\" \n", p);
-                       if (*p == 0)
-                               break;
-               }
-       }
-       if (*p == '\t') {
-               ++p;
-               *str = p;
-               return ' ';
-       }
-       if (*p == '\\') {
-               if ((*(p+1) == 'N') || ((*(p+1) == 'n') && (render_priv->track->WrapStyle == 2))) {
-                       p += 2;
-                       *str = p;
-                       return '\n';
-               } else if ((*(p+1) == 'n') || (*(p+1) == 'h')) {
-                       p += 2;
-                       *str = p;
-                       return ' ';
-               }
-       }
-       chr = utf8_get_char((char **)&p);
-       *str = p;
-       return chr;
+    char *p = *str;
+    unsigned chr;
+    if (*p == '{') {            // '\0' goes here
+        p++;
+        while (1) {
+            p = parse_tag(render_priv, p, 1.);
+            if (*p == '}') {    // end of tag
+                p++;
+                if (*p == '{') {
+                    p++;
+                    continue;
+                } else
+                    break;
+            } else if (*p != '\\')
+                mp_msg(MSGT_ASS, MSGL_V, "Unable to parse: \"%s\" \n", p);
+            if (*p == 0)
+                break;
+        }
+    }
+    if (*p == '\t') {
+        ++p;
+        *str = p;
+        return ' ';
+    }
+    if (*p == '\\') {
+        if ((*(p + 1) == 'N')
+            || ((*(p + 1) == 'n')
+                && (render_priv->track->WrapStyle == 2))) {
+            p += 2;
+            *str = p;
+            return '\n';
+        } else if ((*(p + 1) == 'n') || (*(p + 1) == 'h')) {
+            p += 2;
+            *str = p;
+            return ' ';
+        }
+    }
+    chr = utf8_get_char((char **) &p);
+    *str = p;
+    return chr;
 }
 
-static void apply_transition_effects(ass_renderer_t* render_priv, ass_event_t* event)
+static void
+apply_transition_effects(ass_renderer_t *render_priv, ass_event_t *event)
 {
-       int v[4];
-       int cnt;
-       char* p = event->Effect;
-
-       if (!p || !*p) return;
-
-       cnt = 0;
-       while (cnt < 4 && (p = strchr(p, ';'))) {
-               v[cnt++] = atoi(++p);
-       }
-
-       if (strncmp(event->Effect, "Banner;", 7) == 0) {
-               int delay;
-               if (cnt < 1) {
-                       mp_msg(MSGT_ASS, MSGL_V, "Error parsing effect: %s \n", event->Effect);
-                       return;
-               }
-               if (cnt >= 2 && v[1] == 0) // right-to-left
-                       render_priv->state.scroll_direction = SCROLL_RL;
-               else // left-to-right
-                       render_priv->state.scroll_direction = SCROLL_LR;
-
-               delay = v[0];
-               if (delay == 0) delay = 1; // ?
-               render_priv->state.scroll_shift = (render_priv->time - render_priv->state.event->Start) / delay;
-               render_priv->state.evt_type = EVENT_HSCROLL;
-               return;
-       }
-
-       if (strncmp(event->Effect, "Scroll up;", 10) == 0) {
-               render_priv->state.scroll_direction = SCROLL_BT;
-       } else if (strncmp(event->Effect, "Scroll down;", 12) == 0) {
-               render_priv->state.scroll_direction = SCROLL_TB;
-       } else {
-               mp_msg(MSGT_ASS, MSGL_V, "Unknown transition effect: %s \n", event->Effect);
-               return;
-       }
-       // parse scroll up/down parameters
-       {
-               int delay;
-               int y0, y1;
-               if (cnt < 3) {
-                       mp_msg(MSGT_ASS, MSGL_V, "Error parsing effect: %s \n", event->Effect);
-                       return;
-               }
-               delay = v[2];
-               if (delay == 0) delay = 1; // ?
-               render_priv->state.scroll_shift = (render_priv->time - render_priv->state.event->Start) / delay;
-               if (v[0] < v[1]) {
-                       y0 = v[0]; y1 = v[1];
-               } else {
-                       y0 = v[1]; y1 = v[0];
-               }
-               if (y1 == 0)
-                       y1 = render_priv->track->PlayResY; // y0=y1=0 means fullscreen scrolling
-               render_priv->state.clip_y0 = y0;
-               render_priv->state.clip_y1 = y1;
-               render_priv->state.evt_type = EVENT_VSCROLL;
-               render_priv->state.detect_collisions = 0;
-       }
+    int v[4];
+    int cnt;
+    char *p = event->Effect;
+
+    if (!p || !*p)
+        return;
+
+    cnt = 0;
+    while (cnt < 4 && (p = strchr(p, ';'))) {
+        v[cnt++] = atoi(++p);
+    }
+
+    if (strncmp(event->Effect, "Banner;", 7) == 0) {
+        int delay;
+        if (cnt < 1) {
+            mp_msg(MSGT_ASS, MSGL_V, "Error parsing effect: %s \n",
+                   event->Effect);
+            return;
+        }
+        if (cnt >= 2 && v[1] == 0)      // right-to-left
+            render_priv->state.scroll_direction = SCROLL_RL;
+        else                    // left-to-right
+            render_priv->state.scroll_direction = SCROLL_LR;
+
+        delay = v[0];
+        if (delay == 0)
+            delay = 1;          // ?
+        render_priv->state.scroll_shift =
+            (render_priv->time - render_priv->state.event->Start) / delay;
+        render_priv->state.evt_type = EVENT_HSCROLL;
+        return;
+    }
+
+    if (strncmp(event->Effect, "Scroll up;", 10) == 0) {
+        render_priv->state.scroll_direction = SCROLL_BT;
+    } else if (strncmp(event->Effect, "Scroll down;", 12) == 0) {
+        render_priv->state.scroll_direction = SCROLL_TB;
+    } else {
+        mp_msg(MSGT_ASS, MSGL_V, "Unknown transition effect: %s \n",
+               event->Effect);
+        return;
+    }
+    // parse scroll up/down parameters
+    {
+        int delay;
+        int y0, y1;
+        if (cnt < 3) {
+            mp_msg(MSGT_ASS, MSGL_V, "Error parsing effect: %s \n",
+                   event->Effect);
+            return;
+        }
+        delay = v[2];
+        if (delay == 0)
+            delay = 1;          // ?
+        render_priv->state.scroll_shift =
+            (render_priv->time - render_priv->state.event->Start) / delay;
+        if (v[0] < v[1]) {
+            y0 = v[0];
+            y1 = v[1];
+        } else {
+            y0 = v[1];
+            y1 = v[0];
+        }
+        if (y1 == 0)
+            y1 = render_priv->track->PlayResY;  // y0=y1=0 means fullscreen scrolling
+        render_priv->state.clip_y0 = y0;
+        render_priv->state.clip_y1 = y1;
+        render_priv->state.evt_type = EVENT_VSCROLL;
+        render_priv->state.detect_collisions = 0;
+    }
 
 }
 
@@ -1361,64 +1510,66 @@ static void apply_transition_effects(ass_renderer_t* render_priv, ass_event_t* e
  * \brief partially reset render_context to style values
  * Works like {\r}: resets some style overrides
  */
-static void reset_render_context(ass_renderer_trender_priv)
+static void reset_render_context(ass_renderer_t *render_priv)
 {
-       render_priv->state.c[0] = render_priv->state.style->PrimaryColour;
-       render_priv->state.c[1] = render_priv->state.style->SecondaryColour;
-       render_priv->state.c[2] = render_priv->state.style->OutlineColour;
-       render_priv->state.c[3] = render_priv->state.style->BackColour;
-       render_priv->state.font_size = render_priv->state.style->FontSize;
-
-       if (render_priv->state.family)
-               free(render_priv->state.family);
-       render_priv->state.family = strdup(render_priv->state.style->FontName);
-       render_priv->state.treat_family_as_pattern = render_priv->state.style->treat_fontname_as_pattern;
-       render_priv->state.bold = render_priv->state.style->Bold;
-       render_priv->state.italic = render_priv->state.style->Italic;
-       update_font(render_priv);
-
-       change_border(render_priv, -1.);
-       render_priv->state.scale_x = render_priv->state.style->ScaleX;
-       render_priv->state.scale_y = render_priv->state.style->ScaleY;
-       render_priv->state.hspacing = render_priv->state.style->Spacing;
-       render_priv->state.be = 0;
-       render_priv->state.blur = 0.0;
-       render_priv->state.shadow = render_priv->state.style->Shadow;
-       render_priv->state.frx = render_priv->state.fry = 0.;
-       render_priv->state.frz = M_PI * render_priv->state.style->Angle / 180.;
-
-       // FIXME: does not reset unsupported attributes.
+    render_priv->state.c[0] = render_priv->state.style->PrimaryColour;
+    render_priv->state.c[1] = render_priv->state.style->SecondaryColour;
+    render_priv->state.c[2] = render_priv->state.style->OutlineColour;
+    render_priv->state.c[3] = render_priv->state.style->BackColour;
+    render_priv->state.font_size = render_priv->state.style->FontSize;
+
+    if (render_priv->state.family)
+        free(render_priv->state.family);
+    render_priv->state.family = strdup(render_priv->state.style->FontName);
+    render_priv->state.treat_family_as_pattern =
+        render_priv->state.style->treat_fontname_as_pattern;
+    render_priv->state.bold = render_priv->state.style->Bold;
+    render_priv->state.italic = render_priv->state.style->Italic;
+    update_font(render_priv);
+
+    change_border(render_priv, -1.);
+    render_priv->state.scale_x = render_priv->state.style->ScaleX;
+    render_priv->state.scale_y = render_priv->state.style->ScaleY;
+    render_priv->state.hspacing = render_priv->state.style->Spacing;
+    render_priv->state.be = 0;
+    render_priv->state.blur = 0.0;
+    render_priv->state.shadow = render_priv->state.style->Shadow;
+    render_priv->state.frx = render_priv->state.fry = 0.;
+    render_priv->state.frz = M_PI * render_priv->state.style->Angle / 180.;
+
+    // FIXME: does not reset unsupported attributes.
 }
 
 /**
  * \brief Start new event. Reset render_priv->state.
  */
-static void init_render_context(ass_renderer_t* render_priv, ass_event_t* event)
+static void
+init_render_context(ass_renderer_t *render_priv, ass_event_t *event)
 {
-       render_priv->state.event = event;
-       render_priv->state.style = render_priv->track->styles + event->Style;
-
-       reset_render_context(render_priv);
-
-       render_priv->state.evt_type = EVENT_NORMAL;
-       render_priv->state.alignment = render_priv->state.style->Alignment;
-       render_priv->state.pos_x = 0;
-       render_priv->state.pos_y = 0;
-       render_priv->state.org_x = 0;
-       render_priv->state.org_y = 0;
-       render_priv->state.have_origin = 0;
-       render_priv->state.clip_x0 = 0;
-       render_priv->state.clip_y0 = 0;
-       render_priv->state.clip_x1 = render_priv->track->PlayResX;
-       render_priv->state.clip_y1 = render_priv->track->PlayResY;
-       render_priv->state.detect_collisions = 1;
-       render_priv->state.fade = 0;
-       render_priv->state.drawing_mode = 0;
-       render_priv->state.effect_type = EF_NONE;
-       render_priv->state.effect_timing = 0;
-       render_priv->state.effect_skip_timing = 0;
-
-       apply_transition_effects(render_priv, event);
+    render_priv->state.event = event;
+    render_priv->state.style = render_priv->track->styles + event->Style;
+
+    reset_render_context(render_priv);
+
+    render_priv->state.evt_type = EVENT_NORMAL;
+    render_priv->state.alignment = render_priv->state.style->Alignment;
+    render_priv->state.pos_x = 0;
+    render_priv->state.pos_y = 0;
+    render_priv->state.org_x = 0;
+    render_priv->state.org_y = 0;
+    render_priv->state.have_origin = 0;
+    render_priv->state.clip_x0 = 0;
+    render_priv->state.clip_y0 = 0;
+    render_priv->state.clip_x1 = render_priv->track->PlayResX;
+    render_priv->state.clip_y1 = render_priv->track->PlayResY;
+    render_priv->state.detect_collisions = 1;
+    render_priv->state.fade = 0;
+    render_priv->state.drawing_mode = 0;
+    render_priv->state.effect_type = EF_NONE;
+    render_priv->state.effect_timing = 0;
+    render_priv->state.effect_skip_timing = 0;
+
+    apply_transition_effects(render_priv, event);
 }
 
 static void free_render_context(void)
@@ -1426,16 +1577,18 @@ static void free_render_context(void)
 }
 
 // Calculate the cbox of a series of points
-static void get_contour_cbox(FT_BBox *box, FT_Vector *points, int start, int end) {
+static void
+get_contour_cbox(FT_BBox * box, FT_Vector * points, int start, int end)
+{
     box->xMin = box->yMin = INT_MAX;
     box->xMax = box->yMax = INT_MIN;
     int i;
 
-    for (i=start; i<end; i++) {
-            box->xMin = (points[i].x < box->xMin) ? points[i].x : box->xMin;
-            box->xMax = (points[i].x > box->xMax) ? points[i].x : box->xMax;
-            box->yMin = (points[i].y < box->yMin) ? points[i].y : box->yMin;
-            box->yMax = (points[i].y > box->yMax) ? points[i].y : box->yMax;
+    for (i = start; i < end; i++) {
+        box->xMin = (points[i].x < box->xMin) ? points[i].x : box->xMin;
+        box->xMax = (points[i].x > box->xMax) ? points[i].x : box->xMax;
+        box->yMin = (points[i].y < box->yMin) ? points[i].y : box->yMin;
+        box->yMax = (points[i].y > box->yMax) ? points[i].y : box->yMax;
     }
 }
 
@@ -1443,7 +1596,8 @@ static void get_contour_cbox(FT_BBox *box, FT_Vector *points, int start, int end
  * \brief Fix-up stroker result for huge borders by removing the contours from
  * the outline that are harmful.
 */
-static void fix_freetype_stroker(FT_OutlineGlyph glyph, int border) {
+static void fix_freetype_stroker(FT_OutlineGlyph glyph, int border)
+{
     int nc = glyph->outline.n_contours;
     int begin, stop;
     char modified = 0;
@@ -1454,7 +1608,7 @@ static void fix_freetype_stroker(FT_OutlineGlyph glyph, int border) {
     int i, j;
 
     // Create a list of cboxes of the contours
-    for (i=0; i < nc; i++) {
+    for (i = 0; i < nc; i++) {
         start = end + 1;
         end = glyph->outline.contours[i];
         get_contour_cbox(&boxes[i], glyph->outline.points, start, end);
@@ -1464,32 +1618,34 @@ static void fix_freetype_stroker(FT_OutlineGlyph glyph, int border) {
     //    b) contour's height or width is smaller than the border*2
     // the contour can be safely removed.
     valid_cont = calloc(1, nc);
-    for (i=0; i < nc; i++) {
+    for (i = 0; i < nc; i++) {
         valid_cont[i] = 1;
-        for (j=0; j < nc; j++) {
-            if (i == j) continue;
+        for (j = 0; j < nc; j++) {
+            if (i == j)
+                continue;
             if (boxes[i].xMin >= boxes[j].xMin &&
                 boxes[i].xMax <= boxes[j].xMax &&
                 boxes[i].yMin >= boxes[j].yMin &&
                 boxes[i].yMax <= boxes[j].yMax) {
-                    int width = boxes[i].xMax - boxes[i].xMin;
-                    int height = boxes[i].yMax - boxes[i].yMin;
-                    if (width < border*2 || height < border*2) {
-                        valid_cont[i] = 0;
-                        modified = 1;
-                        break;
-                    }
+                int width = boxes[i].xMax - boxes[i].xMin;
+                int height = boxes[i].yMax - boxes[i].yMin;
+                if (width < border * 2 || height < border * 2) {
+                    valid_cont[i] = 0;
+                    modified = 1;
+                    break;
                 }
+            }
         }
     }
 
     // Zero-out contours that can be removed; much simpler than copying
     if (modified) {
-        for (i=0; i<nc; i++) {
-            if (valid_cont[i]) continue;
-            begin = (i == 0) ? 0 : glyph->outline.contours[i-1]+1;
+        for (i = 0; i < nc; i++) {
+            if (valid_cont[i])
+                continue;
+            begin = (i == 0) ? 0 : glyph->outline.contours[i - 1] + 1;
             stop = glyph->outline.contours[i];
-            for (j=begin; j<=stop; j++) {
+            for (j = begin; j <= stop; j++) {
                 glyph->outline.points[j].x = 0;
                 glyph->outline.points[j].y = 0;
                 glyph->outline.tags[j] = 0;
@@ -1511,61 +1667,74 @@ static void fix_freetype_stroker(FT_OutlineGlyph glyph, int border) {
  * and add them to cache.
  * The glyphs are returned in info->glyph and info->outline_glyph
  */
-static void get_outline_glyph(ass_renderer_t* render_priv, int symbol, glyph_info_t* info, FT_Vector* advance)
+static void
+get_outline_glyph(ass_renderer_t *render_priv, int symbol,
+                  glyph_info_t *info, FT_Vector * advance)
 {
-       int error;
-       glyph_hash_val_t* val;
-       glyph_hash_key_t key;
-       memset(&key, 0, sizeof(key));
-       key.font = render_priv->state.font;
-       key.size = render_priv->state.font_size;
-       key.ch = symbol;
-       key.scale_x = (render_priv->state.scale_x * 0xFFFF);
-       key.scale_y = (render_priv->state.scale_y * 0xFFFF);
-       key.advance = *advance;
-       key.bold = render_priv->state.bold;
-       key.italic = render_priv->state.italic;
-       key.outline = render_priv->state.border * 0xFFFF;
-
-       memset(info, 0, sizeof(glyph_info_t));
-
-       val = cache_find_glyph(render_priv->cache.glyph_cache, &key);
-       if (val) {
-               FT_Glyph_Copy(val->glyph, &info->glyph);
-               if (val->outline_glyph)
-                       FT_Glyph_Copy(val->outline_glyph, &info->outline_glyph);
-               info->bbox = val->bbox_scaled;
-               info->advance.x = val->advance.x;
-               info->advance.y = val->advance.y;
-       } else {
-               glyph_hash_val_t v;
-               info->glyph = ass_font_get_glyph(render_priv->fontconfig_priv, render_priv->state.font, symbol, render_priv->settings.hinting);
-               if (!info->glyph)
-                       return;
-               info->advance.x = d16_to_d6(info->glyph->advance.x);
-               info->advance.y = d16_to_d6(info->glyph->advance.y);
-               FT_Glyph_Get_CBox( info->glyph, FT_GLYPH_BBOX_PIXELS, &info->bbox);
-
-               if (render_priv->state.stroker) {
-                       FT_Glyph_Copy(info->glyph, &info->outline_glyph);
-                       fix_freetype_stroker((FT_OutlineGlyph) info->outline_glyph, double_to_d6(render_priv->state.border * render_priv->border_scale));
-                       error = FT_Glyph_StrokeBorder( &(info->outline_glyph), render_priv->state.stroker, 0 , 1);
-                       if (error) {
-                               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FT_Glyph_Stroke_Error, error);
-                       }
-               }
-
-               memset(&v, 0, sizeof(v));
-               FT_Glyph_Copy(info->glyph, &v.glyph);
-               if (info->outline_glyph)
-                       FT_Glyph_Copy(info->outline_glyph, &v.outline_glyph);
-               v.advance = info->advance;
-               v.bbox_scaled = info->bbox;
-               cache_add_glyph(render_priv->cache.glyph_cache, &key, &v);
-       }
+    int error;
+    glyph_hash_val_t *val;
+    glyph_hash_key_t key;
+    memset(&key, 0, sizeof(key));
+    key.font = render_priv->state.font;
+    key.size = render_priv->state.font_size;
+    key.ch = symbol;
+    key.scale_x = (render_priv->state.scale_x * 0xFFFF);
+    key.scale_y = (render_priv->state.scale_y * 0xFFFF);
+    key.advance = *advance;
+    key.bold = render_priv->state.bold;
+    key.italic = render_priv->state.italic;
+    key.outline = render_priv->state.border * 0xFFFF;
+
+    memset(info, 0, sizeof(glyph_info_t));
+
+    val = cache_find_glyph(render_priv->cache.glyph_cache, &key);
+    if (val) {
+        FT_Glyph_Copy(val->glyph, &info->glyph);
+        if (val->outline_glyph)
+            FT_Glyph_Copy(val->outline_glyph, &info->outline_glyph);
+        info->bbox = val->bbox_scaled;
+        info->advance.x = val->advance.x;
+        info->advance.y = val->advance.y;
+    } else {
+        glyph_hash_val_t v;
+        info->glyph =
+            ass_font_get_glyph(render_priv->fontconfig_priv,
+                               render_priv->state.font, symbol,
+                               render_priv->settings.hinting);
+        if (!info->glyph)
+            return;
+        info->advance.x = d16_to_d6(info->glyph->advance.x);
+        info->advance.y = d16_to_d6(info->glyph->advance.y);
+        FT_Glyph_Get_CBox(info->glyph, FT_GLYPH_BBOX_PIXELS, &info->bbox);
+
+        if (render_priv->state.stroker) {
+            FT_Glyph_Copy(info->glyph, &info->outline_glyph);
+            fix_freetype_stroker((FT_OutlineGlyph) info->outline_glyph,
+                                 double_to_d6(render_priv->state.
+                                              border *
+                                              render_priv->border_scale));
+            error =
+                FT_Glyph_StrokeBorder(&(info->outline_glyph),
+                                      render_priv->state.stroker, 0, 1);
+            if (error) {
+                mp_msg(MSGT_ASS, MSGL_WARN,
+                       MSGTR_LIBASS_FT_Glyph_Stroke_Error, error);
+            }
+        }
+
+        memset(&v, 0, sizeof(v));
+        FT_Glyph_Copy(info->glyph, &v.glyph);
+        if (info->outline_glyph)
+            FT_Glyph_Copy(info->outline_glyph, &v.outline_glyph);
+        v.advance = info->advance;
+        v.bbox_scaled = info->bbox;
+        cache_add_glyph(render_priv->cache.glyph_cache, &key, &v);
+    }
 }
 
-static void transform_3d(FT_Vector shift, FT_Glyph* glyph, FT_Glyph* glyph2, double frx, double fry, double frz);
+static void transform_3d(FT_Vector shift, FT_Glyph * glyph,
+                         FT_Glyph * glyph2, double frx, double fry,
+                         double frz);
 
 /**
  * \brief Get bitmaps for a glyph
@@ -1575,50 +1744,54 @@ static void transform_3d(FT_Vector shift, FT_Glyph* glyph, FT_Glyph* glyph2, dou
  * After that, bitmaps are added to the cache.
  * They are returned in info->bm (glyph), info->bm_o (outline) and info->bm_s (shadow).
  */
-static void get_bitmap_glyph(ass_renderer_t* render_priv, glyph_info_t* info)
+static void
+get_bitmap_glyph(ass_renderer_t *render_priv, glyph_info_t *info)
 {
-       bitmap_hash_val_t* val;
-       bitmap_hash_key_t* key = &info->hash_key;
-
-       val = cache_find_bitmap(render_priv->cache.bitmap_cache, key);
-/*     val = 0; */
-
-       if (val) {
-               info->bm = val->bm;
-               info->bm_o = val->bm_o;
-               info->bm_s = val->bm_s;
-       } else {
-               FT_Vector shift;
-               bitmap_hash_val_t hash_val;
-               int error;
-               info->bm = info->bm_o = info->bm_s = 0;
-               if (info->glyph && info->symbol != '\n' && info->symbol != 0) {
-                       // calculating rotation shift vector (from rotation origin to the glyph basepoint)
-                       shift.x = int_to_d6(info->hash_key.shift_x);
-                       shift.y = int_to_d6(info->hash_key.shift_y);
-                       // apply rotation
-                       transform_3d(shift, &info->glyph, &info->outline_glyph, info->frx, info->fry, info->frz);
-
-                       // render glyph
-                       error = glyph_to_bitmap(render_priv->synth_priv,
-                                       info->glyph, info->outline_glyph,
-                                       &info->bm, &info->bm_o,
-                                       &info->bm_s, info->be, info->blur * render_priv->border_scale);
-                       if (error)
-                               info->symbol = 0;
-
-                       // add bitmaps to cache
-                       hash_val.bm_o = info->bm_o;
-                       hash_val.bm = info->bm;
-                       hash_val.bm_s = info->bm_s;
-                       cache_add_bitmap(render_priv->cache.bitmap_cache, &(info->hash_key), &hash_val);
-               }
-       }
-       // deallocate glyphs
-       if (info->glyph)
-               FT_Done_Glyph(info->glyph);
-       if (info->outline_glyph)
-               FT_Done_Glyph(info->outline_glyph);
+    bitmap_hash_val_t *val;
+    bitmap_hash_key_t *key = &info->hash_key;
+
+    val = cache_find_bitmap(render_priv->cache.bitmap_cache, key);
+    /*  val = 0; */
+
+    if (val) {
+        info->bm = val->bm;
+        info->bm_o = val->bm_o;
+        info->bm_s = val->bm_s;
+    } else {
+        FT_Vector shift;
+        bitmap_hash_val_t hash_val;
+        int error;
+        info->bm = info->bm_o = info->bm_s = 0;
+        if (info->glyph && info->symbol != '\n' && info->symbol != 0) {
+            // calculating rotation shift vector (from rotation origin to the glyph basepoint)
+            shift.x = int_to_d6(info->hash_key.shift_x);
+            shift.y = int_to_d6(info->hash_key.shift_y);
+            // apply rotation
+            transform_3d(shift, &info->glyph, &info->outline_glyph,
+                         info->frx, info->fry, info->frz);
+
+            // render glyph
+            error = glyph_to_bitmap(render_priv->synth_priv,
+                                    info->glyph, info->outline_glyph,
+                                    &info->bm, &info->bm_o,
+                                    &info->bm_s, info->be,
+                                    info->blur * render_priv->border_scale);
+            if (error)
+                info->symbol = 0;
+
+            // add bitmaps to cache
+            hash_val.bm_o = info->bm_o;
+            hash_val.bm = info->bm;
+            hash_val.bm_s = info->bm_s;
+            cache_add_bitmap(render_priv->cache.bitmap_cache,
+                             &(info->hash_key), &hash_val);
+        }
+    }
+    // deallocate glyphs
+    if (info->glyph)
+        FT_Done_Glyph(info->glyph);
+    if (info->outline_glyph)
+        FT_Done_Glyph(info->outline_glyph);
 }
 
 /**
@@ -1629,29 +1802,31 @@ static void get_bitmap_glyph(ass_renderer_t* render_priv, glyph_info_t* info)
  *   lines[].asc
  *   lines[].desc
  */
-static void measure_text(ass_renderer_trender_priv)
+static void measure_text(ass_renderer_t *render_priv)
 {
-       text_info_t* text_info = &render_priv->text_info;
-       int cur_line = 0, max_asc = 0, max_desc = 0;
-       int i;
-       text_info->height = 0;
-       for (i = 0; i < text_info->length + 1; ++i) {
-               if ((i == text_info->length) || text_info->glyphs[i].linebreak) {
-                       text_info->lines[cur_line].asc = max_asc;
-                       text_info->lines[cur_line].desc = max_desc;
-                       text_info->height += max_asc + max_desc;
-                       cur_line ++;
-                       max_asc = max_desc = 0;
-               }
-               if (i < text_info->length) {
-                       glyph_info_t* cur = text_info->glyphs + i;
-                       if (cur->asc > max_asc)
-                               max_asc = cur->asc;
-                       if (cur->desc > max_desc)
-                               max_desc = cur->desc;
-               }
-       }
-       text_info->height += (text_info->n_lines - 1) * double_to_d6(render_priv->settings.line_spacing);
+    text_info_t *text_info = &render_priv->text_info;
+    int cur_line = 0, max_asc = 0, max_desc = 0;
+    int i;
+    text_info->height = 0;
+    for (i = 0; i < text_info->length + 1; ++i) {
+        if ((i == text_info->length) || text_info->glyphs[i].linebreak) {
+            text_info->lines[cur_line].asc = max_asc;
+            text_info->lines[cur_line].desc = max_desc;
+            text_info->height += max_asc + max_desc;
+            cur_line++;
+            max_asc = max_desc = 0;
+        }
+        if (i < text_info->length) {
+            glyph_info_t *cur = text_info->glyphs + i;
+            if (cur->asc > max_asc)
+                max_asc = cur->asc;
+            if (cur->desc > max_desc)
+                max_desc = cur->desc;
+        }
+    }
+    text_info->height +=
+        (text_info->n_lines -
+         1) * double_to_d6(render_priv->settings.line_spacing);
 }
 
 /**
@@ -1663,131 +1838,154 @@ static void measure_text(ass_renderer_t* render_priv)
  * the difference in lengths between this two lines.
  * The result may not be optimal, but usually is good enough.
  */
-static void wrap_lines_smart(ass_renderer_t* render_priv, int max_text_width)
+static void
+wrap_lines_smart(ass_renderer_t *render_priv, int max_text_width)
 {
-       int i, j;
-       glyph_info_t *cur, *s1, *e1, *s2, *s3, *w;
-       int last_space;
-       int break_type;
-       int exit;
-       int pen_shift_x;
-       int pen_shift_y;
-       int cur_line;
-       text_info_t* text_info = &render_priv->text_info;
-       
-       last_space = -1;
-       text_info->n_lines = 1;
-       break_type = 0;
-       s1 = text_info->glyphs; // current line start
-       for (i = 0; i < text_info->length; ++i) {
-               int break_at, s_offset, len;
-               cur = text_info->glyphs + i;
-               break_at = -1;
-               s_offset = s1->bbox.xMin + s1->pos.x;
-               len = (cur->bbox.xMax + cur->pos.x) - s_offset;
-
-               if (cur->symbol == '\n') {
-                       break_type = 2;
-                       break_at = i;
-                       mp_msg(MSGT_ASS, MSGL_DBG2, "forced line break at %d\n", break_at);
-               }
-
-               if ((len >= max_text_width) && (render_priv->track->WrapStyle != 2)) {
-                       break_type = 1;
-                       break_at = last_space;
-                       if (break_at == -1)
-                               break_at = i - 1;
-                       if (break_at == -1)
-                               break_at = 0;
-                       mp_msg(MSGT_ASS, MSGL_DBG2, "overfill at %d\n", i);
-                       mp_msg(MSGT_ASS, MSGL_DBG2, "line break at %d\n", break_at);
-               }
-
-               if (break_at != -1) {
-                       // need to use one more line
-                       // marking break_at+1 as start of a new line
-                       int lead = break_at + 1; // the first symbol of the new line
-                       if (text_info->n_lines >= text_info->max_lines) {
-                               // Raise maximum number of lines
-                               text_info->max_lines *= 2;
-                               text_info->lines = realloc(text_info->lines,
-                                       sizeof(line_info_t) * text_info->max_lines);
-                       }
-                       if (lead < text_info->length)
-                               text_info->glyphs[lead].linebreak = break_type;
-                       last_space = -1;
-                       s1 = text_info->glyphs + lead;
-                       s_offset = s1->bbox.xMin + s1->pos.x;
-                       text_info->n_lines ++;
-               }
-
-               if (cur->symbol == ' ')
-                       last_space = i;
-
-               // make sure the hard linebreak is not forgotten when
-               // there was a new soft linebreak just inserted
-               if (cur->symbol == '\n' && break_type == 1)
-                       i--;
-       }
+    int i, j;
+    glyph_info_t *cur, *s1, *e1, *s2, *s3, *w;
+    int last_space;
+    int break_type;
+    int exit;
+    int pen_shift_x;
+    int pen_shift_y;
+    int cur_line;
+    text_info_t *text_info = &render_priv->text_info;
+
+    last_space = -1;
+    text_info->n_lines = 1;
+    break_type = 0;
+    s1 = text_info->glyphs;     // current line start
+    for (i = 0; i < text_info->length; ++i) {
+        int break_at, s_offset, len;
+        cur = text_info->glyphs + i;
+        break_at = -1;
+        s_offset = s1->bbox.xMin + s1->pos.x;
+        len = (cur->bbox.xMax + cur->pos.x) - s_offset;
+
+        if (cur->symbol == '\n') {
+            break_type = 2;
+            break_at = i;
+            mp_msg(MSGT_ASS, MSGL_DBG2, "forced line break at %d\n",
+                   break_at);
+        }
+
+        if ((len >= max_text_width)
+            && (render_priv->track->WrapStyle != 2)) {
+            break_type = 1;
+            break_at = last_space;
+            if (break_at == -1)
+                break_at = i - 1;
+            if (break_at == -1)
+                break_at = 0;
+            mp_msg(MSGT_ASS, MSGL_DBG2, "overfill at %d\n", i);
+            mp_msg(MSGT_ASS, MSGL_DBG2, "line break at %d\n", break_at);
+        }
+
+        if (break_at != -1) {
+            // need to use one more line
+            // marking break_at+1 as start of a new line
+            int lead = break_at + 1;    // the first symbol of the new line
+            if (text_info->n_lines >= text_info->max_lines) {
+                // Raise maximum number of lines
+                text_info->max_lines *= 2;
+                text_info->lines = realloc(text_info->lines,
+                                           sizeof(line_info_t) *
+                                           text_info->max_lines);
+            }
+            if (lead < text_info->length)
+                text_info->glyphs[lead].linebreak = break_type;
+            last_space = -1;
+            s1 = text_info->glyphs + lead;
+            s_offset = s1->bbox.xMin + s1->pos.x;
+            text_info->n_lines++;
+        }
+
+        if (cur->symbol == ' ')
+            last_space = i;
+
+        // make sure the hard linebreak is not forgotten when
+        // there was a new soft linebreak just inserted
+        if (cur->symbol == '\n' && break_type == 1)
+            i--;
+    }
 #define DIFF(x,y) (((x) < (y)) ? (y - x) : (x - y))
-       exit = 0;
-       while (!exit) {
-               exit = 1;
-               w = s3 = text_info->glyphs;
-               s1 = s2 = 0;
-               for (i = 0; i <= text_info->length; ++i) {
-                       cur = text_info->glyphs + i;
-                       if ((i == text_info->length) || cur->linebreak) {
-                               s1 = s2;
-                               s2 = s3;
-                               s3 = cur;
-                               if (s1 && (s2->linebreak == 1)) { // have at least 2 lines, and linebreak is 'soft'
-                                       int l1, l2, l1_new, l2_new;
-
-                                       w = s2;
-                                       do { --w; } while ((w > s1) && (w->symbol == ' '));
-                                       while ((w > s1) && (w->symbol != ' ')) { --w; }
-                                       e1 = w;
-                                       while ((e1 > s1) && (e1->symbol == ' ')) { --e1; }
-                                       if (w->symbol == ' ') ++w;
-
-                                       l1 = ((s2-1)->bbox.xMax + (s2-1)->pos.x) - (s1->bbox.xMin + s1->pos.x);
-                                       l2 = ((s3-1)->bbox.xMax + (s3-1)->pos.x) - (s2->bbox.xMin + s2->pos.x);
-                                       l1_new = (e1->bbox.xMax + e1->pos.x) - (s1->bbox.xMin + s1->pos.x);
-                                       l2_new = ((s3-1)->bbox.xMax + (s3-1)->pos.x) - (w->bbox.xMin + w->pos.x);
-
-                                       if (DIFF(l1_new, l2_new) < DIFF(l1, l2)) {
-                                               w->linebreak = 1;
-                                               s2->linebreak = 0;
-                                               exit = 0;
-                                       }
-                               }
-                       }
-                       if (i == text_info->length)
-                               break;
-               }
-
-       }
-       assert(text_info->n_lines >= 1);
+    exit = 0;
+    while (!exit) {
+        exit = 1;
+        w = s3 = text_info->glyphs;
+        s1 = s2 = 0;
+        for (i = 0; i <= text_info->length; ++i) {
+            cur = text_info->glyphs + i;
+            if ((i == text_info->length) || cur->linebreak) {
+                s1 = s2;
+                s2 = s3;
+                s3 = cur;
+                if (s1 && (s2->linebreak == 1)) {       // have at least 2 lines, and linebreak is 'soft'
+                    int l1, l2, l1_new, l2_new;
+
+                    w = s2;
+                    do {
+                        --w;
+                    } while ((w > s1) && (w->symbol == ' '));
+                    while ((w > s1) && (w->symbol != ' ')) {
+                        --w;
+                    }
+                    e1 = w;
+                    while ((e1 > s1) && (e1->symbol == ' ')) {
+                        --e1;
+                    }
+                    if (w->symbol == ' ')
+                        ++w;
+
+                    l1 = ((s2 - 1)->bbox.xMax + (s2 - 1)->pos.x) -
+                        (s1->bbox.xMin + s1->pos.x);
+                    l2 = ((s3 - 1)->bbox.xMax + (s3 - 1)->pos.x) -
+                        (s2->bbox.xMin + s2->pos.x);
+                    l1_new =
+                        (e1->bbox.xMax + e1->pos.x) -
+                        (s1->bbox.xMin + s1->pos.x);
+                    l2_new =
+                        ((s3 - 1)->bbox.xMax + (s3 - 1)->pos.x) -
+                        (w->bbox.xMin + w->pos.x);
+
+                    if (DIFF(l1_new, l2_new) < DIFF(l1, l2)) {
+                        w->linebreak = 1;
+                        s2->linebreak = 0;
+                        exit = 0;
+                    }
+                }
+            }
+            if (i == text_info->length)
+                break;
+        }
+
+    }
+    assert(text_info->n_lines >= 1);
 #undef DIFF
 
-       measure_text(render_priv);
-
-       pen_shift_x = 0;
-       pen_shift_y = 0;
-       cur_line = 1;
-       for (i = 0; i < text_info->length; ++i) {
-               cur = text_info->glyphs + i;
-               if (cur->linebreak) {
-                       int height = text_info->lines[cur_line - 1].desc + text_info->lines[cur_line].asc;
-                       cur_line ++;
-                       pen_shift_x = - cur->pos.x;
-                       pen_shift_y += d6_to_int(height + double_to_d6(render_priv->settings.line_spacing));
-                       mp_msg(MSGT_ASS, MSGL_DBG2, "shifting from %d to %d by (%d, %d)\n", i, text_info->length - 1, pen_shift_x, pen_shift_y);
-               }
-               cur->pos.x += pen_shift_x;
-               cur->pos.y += pen_shift_y;
-       }
+    measure_text(render_priv);
+
+    pen_shift_x = 0;
+    pen_shift_y = 0;
+    cur_line = 1;
+    for (i = 0; i < text_info->length; ++i) {
+        cur = text_info->glyphs + i;
+        if (cur->linebreak) {
+            int height =
+                text_info->lines[cur_line - 1].desc +
+                text_info->lines[cur_line].asc;
+            cur_line++;
+            pen_shift_x = -cur->pos.x;
+            pen_shift_y +=
+                d6_to_int(height +
+                          double_to_d6(render_priv->settings.line_spacing));
+            mp_msg(MSGT_ASS, MSGL_DBG2,
+                   "shifting from %d to %d by (%d, %d)\n", i,
+                   text_info->length - 1, pen_shift_x, pen_shift_y);
+        }
+        cur->pos.x += pen_shift_x;
+        cur->pos.y += pen_shift_y;
+    }
 }
 
 /**
@@ -1801,60 +1999,63 @@ static void wrap_lines_smart(ass_renderer_t* render_priv, int max_text_width)
  * 2. sets effect_timing for all glyphs to x coordinate of the border line between the left and right karaoke parts
  * (left part is filled with PrimaryColour, right one - with SecondaryColour).
  */
-static void process_karaoke_effects(ass_renderer_trender_priv)
+static void process_karaoke_effects(ass_renderer_t *render_priv)
 {
-       glyph_info_t *cur, *cur2;
-       glyph_info_t *s1, *e1; // start and end of the current word
-       glyph_info_t *s2; // start of the next word
-       int i;
-       int timing; // current timing
-       int tm_start, tm_end; // timings at start and end of the current word
-       int tm_current;
-       double dt;
-       int x;
-       int x_start, x_end;
-
-       tm_current = render_priv->time - render_priv->state.event->Start;
-       timing = 0;
-       s1 = s2 = 0;
-       for (i = 0; i <= render_priv->text_info.length; ++i) {
-               cur = render_priv->text_info.glyphs + i;
-               if ((i == render_priv->text_info.length) || (cur->effect_type != EF_NONE)) {
-                       s1 = s2;
-                       s2 = cur;
-                       if (s1) {
-                               e1 = s2 - 1;
-                               tm_start = timing + s1->effect_skip_timing;
-                               tm_end = tm_start + s1->effect_timing;
-                               timing = tm_end;
-                               x_start = 1000000;
-                               x_end = -1000000;
-                               for (cur2 = s1; cur2 <= e1; ++cur2) {
-                                       x_start = FFMIN(x_start, cur2->bbox.xMin + cur2->pos.x);
-                                       x_end = FFMAX(x_end, cur2->bbox.xMax + cur2->pos.x);
-                               }
-
-                               dt = (tm_current - tm_start);
-                               if ((s1->effect_type == EF_KARAOKE) || (s1->effect_type == EF_KARAOKE_KO)) {
-                                       if (dt > 0)
-                                               x = x_end + 1;
-                                       else
-                                               x = x_start;
-                               } else if (s1->effect_type == EF_KARAOKE_KF) {
-                                       dt /= (tm_end - tm_start);
-                                       x = x_start + (x_end - x_start) * dt;
-                               } else {
-                                       mp_msg(MSGT_ASS, MSGL_ERR, MSGTR_LIBASS_UnknownEffectType_InternalError);
-                                       continue;
-                               }
-
-                               for (cur2 = s1; cur2 <= e1; ++cur2) {
-                                       cur2->effect_type = s1->effect_type;
-                                       cur2->effect_timing = x - cur2->pos.x;
-                               }
-                       }
-               }
-       }
+    glyph_info_t *cur, *cur2;
+    glyph_info_t *s1, *e1;      // start and end of the current word
+    glyph_info_t *s2;           // start of the next word
+    int i;
+    int timing;                 // current timing
+    int tm_start, tm_end;       // timings at start and end of the current word
+    int tm_current;
+    double dt;
+    int x;
+    int x_start, x_end;
+
+    tm_current = render_priv->time - render_priv->state.event->Start;
+    timing = 0;
+    s1 = s2 = 0;
+    for (i = 0; i <= render_priv->text_info.length; ++i) {
+        cur = render_priv->text_info.glyphs + i;
+        if ((i == render_priv->text_info.length)
+            || (cur->effect_type != EF_NONE)) {
+            s1 = s2;
+            s2 = cur;
+            if (s1) {
+                e1 = s2 - 1;
+                tm_start = timing + s1->effect_skip_timing;
+                tm_end = tm_start + s1->effect_timing;
+                timing = tm_end;
+                x_start = 1000000;
+                x_end = -1000000;
+                for (cur2 = s1; cur2 <= e1; ++cur2) {
+                    x_start = FFMIN(x_start, cur2->bbox.xMin + cur2->pos.x);
+                    x_end = FFMAX(x_end, cur2->bbox.xMax + cur2->pos.x);
+                }
+
+                dt = (tm_current - tm_start);
+                if ((s1->effect_type == EF_KARAOKE)
+                    || (s1->effect_type == EF_KARAOKE_KO)) {
+                    if (dt > 0)
+                        x = x_end + 1;
+                    else
+                        x = x_start;
+                } else if (s1->effect_type == EF_KARAOKE_KF) {
+                    dt /= (tm_end - tm_start);
+                    x = x_start + (x_end - x_start) * dt;
+                } else {
+                    mp_msg(MSGT_ASS, MSGL_ERR,
+                           MSGTR_LIBASS_UnknownEffectType_InternalError);
+                    continue;
+                }
+
+                for (cur2 = s1; cur2 <= e1; ++cur2) {
+                    cur2->effect_type = s1->effect_type;
+                    cur2->effect_timing = x - cur2->pos.x;
+                }
+            }
+        }
+    }
 }
 
 /**
@@ -1863,34 +2064,34 @@ static void process_karaoke_effects(ass_renderer_t* render_priv)
  * \param alignment alignment
  * \param bx, by out: base point coordinates
  */
-static void get_base_point(FT_BBox bbox, int alignment, int* bx, int* by)
+static void get_base_point(FT_BBox bbox, int alignment, int *bx, int *by)
 {
-       const int halign = alignment & 3;
-       const int valign = alignment & 12;
-       if (bx)
-               switch(halign) {
-               case HALIGN_LEFT:
-                       *bx = bbox.xMin;
-                       break;
-               case HALIGN_CENTER:
-                       *bx = (bbox.xMax + bbox.xMin) / 2;
-                       break;
-               case HALIGN_RIGHT:
-                       *bx = bbox.xMax;
-                       break;
-               }
-       if (by)
-               switch(valign) {
-               case VALIGN_TOP:
-                       *by = bbox.yMin;
-                       break;
-               case VALIGN_CENTER:
-                       *by = (bbox.yMax + bbox.yMin) / 2;
-                       break;
-               case VALIGN_SUB:
-                       *by = bbox.yMax;
-                       break;
-               }
+    const int halign = alignment & 3;
+    const int valign = alignment & 12;
+    if (bx)
+        switch (halign) {
+        case HALIGN_LEFT:
+            *bx = bbox.xMin;
+            break;
+        case HALIGN_CENTER:
+            *bx = (bbox.xMax + bbox.xMin) / 2;
+            break;
+        case HALIGN_RIGHT:
+            *bx = bbox.xMax;
+            break;
+        }
+    if (by)
+        switch (valign) {
+        case VALIGN_TOP:
+            *by = bbox.yMin;
+            break;
+        case VALIGN_CENTER:
+            *by = (bbox.yMax + bbox.yMin) / 2;
+            break;
+        case VALIGN_SUB:
+            *by = bbox.yMax;
+            break;
+        }
 }
 
 /**
@@ -1898,42 +2099,45 @@ static void get_base_point(FT_BBox bbox, int alignment, int* bx, int* by)
  * Applies rotations given by frx, fry and frz and projects the points back
  * onto the screen plane.
  */
-static void transform_3d_points(FT_Vector shift, FT_Glyph glyph, double frx, double fry, double frz) {
-       double sx = sin(frx);
-       double sy = sin(fry);
-       double sz = sin(frz);
-       double cx = cos(frx);
-       double cy = cos(fry);
-       double cz = cos(frz);
-       FT_Outline *outline = &((FT_OutlineGlyph) glyph)->outline;
-       FT_Vector* p = outline->points;
-       double x, y, z, xx, yy, zz;
-       int i;
-
-       for (i=0; i<outline->n_points; i++) {
-               x = p[i].x + shift.x;
-               y = p[i].y + shift.y;
-               z = 0.;
-
-               xx = x*cz + y*sz;
-               yy = -(x*sz - y*cz);
-               zz = z;
-
-               x = xx;
-               y = yy*cx + zz*sx;
-               z = yy*sx - zz*cx;
-
-               xx = x*cy + z*sy;
-               yy = y;
-               zz = x*sy - z*cy;
-
-               zz = FFMAX(zz, -19000);
-
-               x = (xx * 20000) / (zz + 20000);
-               y = (yy * 20000) / (zz + 20000);
-               p[i].x = x - shift.x + 0.5;
-               p[i].y = y - shift.y + 0.5;
-       }
+static void
+transform_3d_points(FT_Vector shift, FT_Glyph glyph, double frx,
+                    double fry, double frz)
+{
+    double sx = sin(frx);
+    double sy = sin(fry);
+    double sz = sin(frz);
+    double cx = cos(frx);
+    double cy = cos(fry);
+    double cz = cos(frz);
+    FT_Outline *outline = &((FT_OutlineGlyph) glyph)->outline;
+    FT_Vector *p = outline->points;
+    double x, y, z, xx, yy, zz;
+    int i;
+
+    for (i = 0; i < outline->n_points; i++) {
+        x = p[i].x + shift.x;
+        y = p[i].y + shift.y;
+        z = 0.;
+
+        xx = x * cz + y * sz;
+        yy = -(x * sz - y * cz);
+        zz = z;
+
+        x = xx;
+        y = yy * cx + zz * sx;
+        z = yy * sx - zz * cx;
+
+        xx = x * cy + z * sy;
+        yy = y;
+        zz = x * sy - z * cy;
+
+        zz = FFMAX(zz, -19000);
+
+        x = (xx * 20000) / (zz + 20000);
+        y = (yy * 20000) / (zz + 20000);
+        p[i].x = x - shift.x + 0.5;
+        p[i].y = y - shift.y + 0.5;
+    }
 }
 
 /**
@@ -1946,17 +2150,19 @@ static void transform_3d_points(FT_Vector shift, FT_Glyph glyph, double frx, dou
  * \param frz z-axis rotation angle
  * Rotates both glyphs by frx, fry and frz. Shift vector is added before rotation and subtracted after it.
  */
-static void transform_3d(FT_Vector shift, FT_Glyph* glyph, FT_Glyph* glyph2, double frx, double fry, double frz)
+static void
+transform_3d(FT_Vector shift, FT_Glyph * glyph, FT_Glyph * glyph2,
+             double frx, double fry, double frz)
 {
-       frx = - frx;
-       frz = - frz;
-       if (frx != 0. || fry != 0. || frz != 0.) {
-               if (glyph && *glyph)
-                       transform_3d_points(shift, *glyph, frx, fry, frz);
-
-               if (glyph2 && *glyph2)
-                       transform_3d_points(shift, *glyph2, frx, fry, frz);
-       }
+    frx = -frx;
+    frz = -frz;
+    if (frx != 0. || fry != 0. || frz != 0.) {
+        if (glyph && *glyph)
+            transform_3d_points(shift, *glyph, frx, fry, frz);
+
+        if (glyph2 && *glyph2)
+            transform_3d_points(shift, *glyph2, frx, fry, frz);
+    }
 }
 
 
@@ -1966,615 +2172,723 @@ static void transform_3d(FT_Vector shift, FT_Glyph* glyph, FT_Glyph* glyph2, dou
  * \param event_images struct containing resulting images, will also be initialized
  * Process event, appending resulting ass_image_t's to images_root.
  */
-static int ass_render_event(ass_renderer_t* render_priv, ass_event_t* event, event_images_t* event_images)
+static int
+ass_render_event(ass_renderer_t *render_priv, ass_event_t *event,
+                 event_images_t *event_images)
 {
-       char* p;
-       FT_UInt previous;
-       FT_UInt num_glyphs;
-       FT_Vector pen;
-       unsigned code;
-       FT_BBox bbox;
-       int i, j;
-       FT_Vector shift;
-       int MarginL, MarginR, MarginV;
-       int last_break;
-       int alignment, halign, valign;
-       int device_x = 0, device_y = 0;
-       ass_settings_t* settings_priv = &render_priv->settings;
-       text_info_t* text_info = &render_priv->text_info;
-
-       if (event->Style >= render_priv->track->n_styles) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NoStyleFound);
-               return 1;
-       }
-       if (!event->Text) {
-               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_EmptyEvent);
-               return 1;
-       }
-
-       init_render_context(render_priv, event);
-
-       text_info->length = 0;
-       pen.x = 0;
-       pen.y = 0;
-       previous = 0;
-       num_glyphs = 0;
-       p = event->Text;
-       // Event parsing.
-       while (1) {
-               // get next char, executing style override
-               // this affects render_context
-               do {
-                       code = get_next_char(render_priv, &p);
-               } while (code && render_priv->state.drawing_mode); // skip everything in drawing mode
-
-               // face could have been changed in get_next_char
-               if (!render_priv->state.font) {
-                       free_render_context();
-                       return 1;
-               }
-
-               if (code == 0)
-                       break;
-
-               if (text_info->length >= text_info->max_glyphs) {
-                       // Raise maximum number of glyphs
-                       text_info->max_glyphs *= 2;
-                       text_info->glyphs = realloc(text_info->glyphs, sizeof(glyph_info_t) * text_info->max_glyphs);
-               }
-
-               if ( previous && code ) {
-                       FT_Vector delta;
-                       delta = ass_font_get_kerning(render_priv->state.font, previous, code);
-                       pen.x += delta.x * render_priv->state.scale_x;
-                       pen.y += delta.y * render_priv->state.scale_y;
-               }
-
-               shift.x = pen.x & SUBPIXEL_MASK;
-               shift.y = pen.y & SUBPIXEL_MASK;
-
-               if (render_priv->state.evt_type == EVENT_POSITIONED) {
-                       shift.x += double_to_d6(x2scr_pos(render_priv, render_priv->state.pos_x)) & SUBPIXEL_MASK;
-                       shift.y -= double_to_d6(y2scr_pos(render_priv, render_priv->state.pos_y)) & SUBPIXEL_MASK;
-               }
-
-               ass_font_set_transform(render_priv->state.font,
-                                      render_priv->state.scale_x * render_priv->font_scale_x,
-                                      render_priv->state.scale_y,
-                                      &shift );
-
-               get_outline_glyph(render_priv, code, text_info->glyphs + text_info->length, &shift);
-
-               text_info->glyphs[text_info->length].pos.x = pen.x >> 6;
-               text_info->glyphs[text_info->length].pos.y = pen.y >> 6;
-
-               pen.x += text_info->glyphs[text_info->length].advance.x;
-               pen.x += double_to_d6(render_priv->state.hspacing);
-               pen.y += text_info->glyphs[text_info->length].advance.y;
-
-               previous = code;
-
-               text_info->glyphs[text_info->length].symbol = code;
-               text_info->glyphs[text_info->length].linebreak = 0;
-               for (i = 0; i < 4; ++i) {
-                       uint32_t clr = render_priv->state.c[i];
-                       change_alpha(&clr, mult_alpha(_a(clr), render_priv->state.fade), 1.);
-                       text_info->glyphs[text_info->length].c[i] = clr;
-               }
-               text_info->glyphs[text_info->length].effect_type = render_priv->state.effect_type;
-               text_info->glyphs[text_info->length].effect_timing = render_priv->state.effect_timing;
-               text_info->glyphs[text_info->length].effect_skip_timing = render_priv->state.effect_skip_timing;
-               text_info->glyphs[text_info->length].be = render_priv->state.be;
-               text_info->glyphs[text_info->length].blur = render_priv->state.blur;
-               text_info->glyphs[text_info->length].shadow = render_priv->state.shadow;
-               text_info->glyphs[text_info->length].frx = render_priv->state.frx;
-               text_info->glyphs[text_info->length].fry = render_priv->state.fry;
-               text_info->glyphs[text_info->length].frz = render_priv->state.frz;
-               ass_font_get_asc_desc(render_priv->state.font, code,
-                                     &text_info->glyphs[text_info->length].asc,
-                                     &text_info->glyphs[text_info->length].desc);
-               text_info->glyphs[text_info->length].asc *= render_priv->state.scale_y;
-               text_info->glyphs[text_info->length].desc *= render_priv->state.scale_y;
-
-               // fill bitmap_hash_key
-               text_info->glyphs[text_info->length].hash_key.font = render_priv->state.font;
-               text_info->glyphs[text_info->length].hash_key.size = render_priv->state.font_size;
-               text_info->glyphs[text_info->length].hash_key.outline = render_priv->state.border * 0xFFFF;
-               text_info->glyphs[text_info->length].hash_key.scale_x = render_priv->state.scale_x * 0xFFFF;
-               text_info->glyphs[text_info->length].hash_key.scale_y = render_priv->state.scale_y * 0xFFFF;
-               text_info->glyphs[text_info->length].hash_key.frx = render_priv->state.frx * 0xFFFF;
-               text_info->glyphs[text_info->length].hash_key.fry = render_priv->state.fry * 0xFFFF;
-               text_info->glyphs[text_info->length].hash_key.frz = render_priv->state.frz * 0xFFFF;
-               text_info->glyphs[text_info->length].hash_key.bold = render_priv->state.bold;
-               text_info->glyphs[text_info->length].hash_key.italic = render_priv->state.italic;
-               text_info->glyphs[text_info->length].hash_key.ch = code;
-               text_info->glyphs[text_info->length].hash_key.advance = shift;
-               text_info->glyphs[text_info->length].hash_key.be = render_priv->state.be;
-               text_info->glyphs[text_info->length].hash_key.blur = render_priv->state.blur;
-
-               text_info->length++;
-
-               render_priv->state.effect_type = EF_NONE;
-               render_priv->state.effect_timing = 0;
-               render_priv->state.effect_skip_timing = 0;
-       }
-
-       if (text_info->length == 0) {
-               // no valid symbols in the event; this can be smth like {comment}
-               free_render_context();
-               return 1;
-       }
-
-       // depends on glyph x coordinates being monotonous, so it should be done before line wrap
-       process_karaoke_effects(render_priv);
-
-       // alignments
-       alignment = render_priv->state.alignment;
-       halign = alignment & 3;
-       valign = alignment & 12;
-
-       MarginL = (event->MarginL) ? event->MarginL : render_priv->state.style->MarginL; 
-       MarginR = (event->MarginR) ? event->MarginR : render_priv->state.style->MarginR; 
-       MarginV = (event->MarginV) ? event->MarginV : render_priv->state.style->MarginV;
-
-       if (render_priv->state.evt_type != EVENT_HSCROLL) {
-               int max_text_width;
-
-               // calculate max length of a line
-               max_text_width = x2scr(render_priv, render_priv->track->PlayResX - MarginR) - x2scr(render_priv, MarginL);
-
-               // rearrange text in several lines
-               wrap_lines_smart(render_priv, max_text_width);
-
-               // align text
-               last_break = -1;
-               for (i = 1; i < text_info->length + 1; ++i) { // (text_info->length + 1) is the end of the last line
-                       if ((i == text_info->length) || text_info->glyphs[i].linebreak) {
-                               int width, shift = 0;
-                               glyph_info_t* first_glyph = text_info->glyphs + last_break + 1;
-                               glyph_info_t* last_glyph = text_info->glyphs + i - 1;
-
-                               while ((last_glyph > first_glyph) && ((last_glyph->symbol == '\n') || (last_glyph->symbol == 0)))
-                                       last_glyph --;
-
-                               width = last_glyph->pos.x + d6_to_int(last_glyph->advance.x) - first_glyph->pos.x;
-                               if (halign == HALIGN_LEFT) { // left aligned, no action
-                                       shift = 0;
-                               } else if (halign == HALIGN_RIGHT) { // right aligned
-                                       shift = max_text_width - width;
-                               } else if (halign == HALIGN_CENTER) { // centered
-                                       shift = (max_text_width - width) / 2;
-                               }
-                               for (j = last_break + 1; j < i; ++j) {
-                                       text_info->glyphs[j].pos.x += shift;
-                               }
-                               last_break = i - 1;
-                       }
-               }
-       } else { // render_priv->state.evt_type == EVENT_HSCROLL
-               measure_text(render_priv);
-       }
-
-       // determing text bounding box
-       compute_string_bbox(text_info, &bbox);
-
-       // determine device coordinates for text
-
-       // x coordinate for everything except positioned events
-       if (render_priv->state.evt_type == EVENT_NORMAL ||
-           render_priv->state.evt_type == EVENT_VSCROLL) {
-               device_x = x2scr(render_priv, MarginL);
-       } else if (render_priv->state.evt_type == EVENT_HSCROLL) {
-               if (render_priv->state.scroll_direction == SCROLL_RL)
-                       device_x = x2scr(render_priv, render_priv->track->PlayResX - render_priv->state.scroll_shift);
-               else if (render_priv->state.scroll_direction == SCROLL_LR)
-                       device_x = x2scr(render_priv, render_priv->state.scroll_shift) - (bbox.xMax - bbox.xMin);
-       }
-
-       // y coordinate for everything except positioned events
-       if (render_priv->state.evt_type == EVENT_NORMAL ||
-           render_priv->state.evt_type == EVENT_HSCROLL) {
-               if (valign == VALIGN_TOP) { // toptitle
-                       device_y = y2scr_top(render_priv, MarginV) + d6_to_int(text_info->lines[0].asc);
-               } else if (valign == VALIGN_CENTER) { // midtitle
-                       int scr_y = y2scr(render_priv, render_priv->track->PlayResY / 2);
-                       device_y = scr_y - (bbox.yMax - bbox.yMin) / 2;
-               } else { // subtitle
-                       int scr_y;
-                       if (valign != VALIGN_SUB)
-                               mp_msg(MSGT_ASS, MSGL_V, "Invalid valign, supposing 0 (subtitle)\n");
-                       scr_y = y2scr_sub(render_priv, render_priv->track->PlayResY - MarginV);
-                       device_y = scr_y;
-                       device_y -= d6_to_int(text_info->height);
-                       device_y += d6_to_int(text_info->lines[0].asc);
-               }
-       } else if (render_priv->state.evt_type == EVENT_VSCROLL) {
-               if (render_priv->state.scroll_direction == SCROLL_TB)
-                       device_y = y2scr(render_priv, render_priv->state.clip_y0 + render_priv->state.scroll_shift) - (bbox.yMax - bbox.yMin);
-               else if (render_priv->state.scroll_direction == SCROLL_BT)
-                       device_y = y2scr(render_priv, render_priv->state.clip_y1 - render_priv->state.scroll_shift);
-       }
-
-       // positioned events are totally different
-       if (render_priv->state.evt_type == EVENT_POSITIONED) {
-               int base_x = 0;
-               int base_y = 0;
-               mp_msg(MSGT_ASS, MSGL_DBG2, "positioned event at %f, %f\n", render_priv->state.pos_x, render_priv->state.pos_y);
-               get_base_point(bbox, alignment, &base_x, &base_y);
-               device_x = x2scr_pos(render_priv, render_priv->state.pos_x) - base_x;
-               device_y = y2scr_pos(render_priv, render_priv->state.pos_y) - base_y;
-       }
-
-       // fix clip coordinates (they depend on alignment)
-       if (render_priv->state.evt_type == EVENT_NORMAL ||
-           render_priv->state.evt_type == EVENT_HSCROLL ||
-           render_priv->state.evt_type == EVENT_VSCROLL) {
-               render_priv->state.clip_x0 = x2scr(render_priv, render_priv->state.clip_x0);
-               render_priv->state.clip_x1 = x2scr(render_priv, render_priv->state.clip_x1);
-               if (valign == VALIGN_TOP) {
-                       render_priv->state.clip_y0 = y2scr_top(render_priv, render_priv->state.clip_y0);
-                       render_priv->state.clip_y1 = y2scr_top(render_priv, render_priv->state.clip_y1);
-               } else if (valign == VALIGN_CENTER) {
-                       render_priv->state.clip_y0 = y2scr(render_priv, render_priv->state.clip_y0);
-                       render_priv->state.clip_y1 = y2scr(render_priv, render_priv->state.clip_y1);
-               } else if (valign == VALIGN_SUB) {
-                       render_priv->state.clip_y0 = y2scr_sub(render_priv, render_priv->state.clip_y0);
-                       render_priv->state.clip_y1 = y2scr_sub(render_priv, render_priv->state.clip_y1);
-               }
-       } else if (render_priv->state.evt_type == EVENT_POSITIONED) {
-               render_priv->state.clip_x0 = x2scr_pos(render_priv, render_priv->state.clip_x0);
-               render_priv->state.clip_x1 = x2scr_pos(render_priv, render_priv->state.clip_x1);
-               render_priv->state.clip_y0 = y2scr_pos(render_priv, render_priv->state.clip_y0);
-               render_priv->state.clip_y1 = y2scr_pos(render_priv, render_priv->state.clip_y1);
-       }
-
-       // calculate rotation parameters
-       {
-               FT_Vector center;
-
-               if (render_priv->state.have_origin) {
-                       center.x = x2scr(render_priv, render_priv->state.org_x);
-                       center.y = y2scr(render_priv, render_priv->state.org_y);
-               } else {
-                       int bx = 0, by = 0;
-                       get_base_point(bbox, alignment, &bx, &by);
-                       center.x = device_x + bx;
-                       center.y = device_y + by;
-               }
-
-               for (i = 0; i < text_info->length; ++i) {
-                       glyph_info_t* info = text_info->glyphs + i;
-
-                       if (info->hash_key.frx || info->hash_key.fry || info->hash_key.frz) {
-                               info->hash_key.shift_x = info->pos.x + device_x - center.x;
-                               info->hash_key.shift_y = - (info->pos.y + device_y - center.y);
-                       } else {
-                               info->hash_key.shift_x = 0;
-                               info->hash_key.shift_y = 0;
-                       }
-               }
-       }
-
-       // convert glyphs to bitmaps
-       for (i = 0; i < text_info->length; ++i)
-               get_bitmap_glyph(render_priv, text_info->glyphs + i);
-
-       memset(event_images, 0, sizeof(*event_images));
-       event_images->top = device_y - d6_to_int(text_info->lines[0].asc);
-       event_images->height = d6_to_int(text_info->height);
-       event_images->detect_collisions = render_priv->state.detect_collisions;
-       event_images->shift_direction = (valign == VALIGN_TOP) ? 1 : -1;
-       event_images->event = event;
-       event_images->imgs = render_text(render_priv, device_x, device_y);
-
-       free_render_context();
-
-       return 0;
+    char *p;
+    FT_UInt previous;
+    FT_UInt num_glyphs;
+    FT_Vector pen;
+    unsigned code;
+    FT_BBox bbox;
+    int i, j;
+    FT_Vector shift;
+    int MarginL, MarginR, MarginV;
+    int last_break;
+    int alignment, halign, valign;
+    int device_x = 0, device_y = 0;
+    ass_settings_t *settings_priv = &render_priv->settings;
+    text_info_t *text_info = &render_priv->text_info;
+
+    if (event->Style >= render_priv->track->n_styles) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NoStyleFound);
+        return 1;
+    }
+    if (!event->Text) {
+        mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_EmptyEvent);
+        return 1;
+    }
+
+    init_render_context(render_priv, event);
+
+    text_info->length = 0;
+    pen.x = 0;
+    pen.y = 0;
+    previous = 0;
+    num_glyphs = 0;
+    p = event->Text;
+    // Event parsing.
+    while (1) {
+        // get next char, executing style override
+        // this affects render_context
+        do {
+            code = get_next_char(render_priv, &p);
+        } while (code && render_priv->state.drawing_mode);      // skip everything in drawing mode
+
+        // face could have been changed in get_next_char
+        if (!render_priv->state.font) {
+            free_render_context();
+            return 1;
+        }
+
+        if (code == 0)
+            break;
+
+        if (text_info->length >= text_info->max_glyphs) {
+            // Raise maximum number of glyphs
+            text_info->max_glyphs *= 2;
+            text_info->glyphs =
+                realloc(text_info->glyphs,
+                        sizeof(glyph_info_t) * text_info->max_glyphs);
+        }
+
+        if (previous && code) {
+            FT_Vector delta;
+            delta =
+                ass_font_get_kerning(render_priv->state.font, previous,
+                                     code);
+            pen.x += delta.x * render_priv->state.scale_x;
+            pen.y += delta.y * render_priv->state.scale_y;
+        }
+
+        shift.x = pen.x & SUBPIXEL_MASK;
+        shift.y = pen.y & SUBPIXEL_MASK;
+
+        if (render_priv->state.evt_type == EVENT_POSITIONED) {
+            shift.x +=
+                double_to_d6(x2scr_pos
+                             (render_priv,
+                              render_priv->state.pos_x)) & SUBPIXEL_MASK;
+            shift.y -=
+                double_to_d6(y2scr_pos
+                             (render_priv,
+                              render_priv->state.pos_y)) & SUBPIXEL_MASK;
+        }
+
+        ass_font_set_transform(render_priv->state.font,
+                               render_priv->state.scale_x *
+                               render_priv->font_scale_x,
+                               render_priv->state.scale_y, &shift);
+
+        get_outline_glyph(render_priv, code,
+                          text_info->glyphs + text_info->length, &shift);
+
+        text_info->glyphs[text_info->length].pos.x = pen.x >> 6;
+        text_info->glyphs[text_info->length].pos.y = pen.y >> 6;
+
+        pen.x += text_info->glyphs[text_info->length].advance.x;
+        pen.x += double_to_d6(render_priv->state.hspacing);
+        pen.y += text_info->glyphs[text_info->length].advance.y;
+
+        previous = code;
+
+        text_info->glyphs[text_info->length].symbol = code;
+        text_info->glyphs[text_info->length].linebreak = 0;
+        for (i = 0; i < 4; ++i) {
+            uint32_t clr = render_priv->state.c[i];
+            change_alpha(&clr,
+                         mult_alpha(_a(clr), render_priv->state.fade), 1.);
+            text_info->glyphs[text_info->length].c[i] = clr;
+        }
+        text_info->glyphs[text_info->length].effect_type =
+            render_priv->state.effect_type;
+        text_info->glyphs[text_info->length].effect_timing =
+            render_priv->state.effect_timing;
+        text_info->glyphs[text_info->length].effect_skip_timing =
+            render_priv->state.effect_skip_timing;
+        text_info->glyphs[text_info->length].be = render_priv->state.be;
+        text_info->glyphs[text_info->length].blur = render_priv->state.blur;
+        text_info->glyphs[text_info->length].shadow =
+            render_priv->state.shadow;
+        text_info->glyphs[text_info->length].frx = render_priv->state.frx;
+        text_info->glyphs[text_info->length].fry = render_priv->state.fry;
+        text_info->glyphs[text_info->length].frz = render_priv->state.frz;
+        ass_font_get_asc_desc(render_priv->state.font, code,
+                              &text_info->glyphs[text_info->length].asc,
+                              &text_info->glyphs[text_info->length].desc);
+        text_info->glyphs[text_info->length].asc *=
+            render_priv->state.scale_y;
+        text_info->glyphs[text_info->length].desc *=
+            render_priv->state.scale_y;
+
+        // fill bitmap_hash_key
+        text_info->glyphs[text_info->length].hash_key.font =
+            render_priv->state.font;
+        text_info->glyphs[text_info->length].hash_key.size =
+            render_priv->state.font_size;
+        text_info->glyphs[text_info->length].hash_key.outline =
+            render_priv->state.border * 0xFFFF;
+        text_info->glyphs[text_info->length].hash_key.scale_x =
+            render_priv->state.scale_x * 0xFFFF;
+        text_info->glyphs[text_info->length].hash_key.scale_y =
+            render_priv->state.scale_y * 0xFFFF;
+        text_info->glyphs[text_info->length].hash_key.frx =
+            render_priv->state.frx * 0xFFFF;
+        text_info->glyphs[text_info->length].hash_key.fry =
+            render_priv->state.fry * 0xFFFF;
+        text_info->glyphs[text_info->length].hash_key.frz =
+            render_priv->state.frz * 0xFFFF;
+        text_info->glyphs[text_info->length].hash_key.bold =
+            render_priv->state.bold;
+        text_info->glyphs[text_info->length].hash_key.italic =
+            render_priv->state.italic;
+        text_info->glyphs[text_info->length].hash_key.ch = code;
+        text_info->glyphs[text_info->length].hash_key.advance = shift;
+        text_info->glyphs[text_info->length].hash_key.be =
+            render_priv->state.be;
+        text_info->glyphs[text_info->length].hash_key.blur =
+            render_priv->state.blur;
+
+        text_info->length++;
+
+        render_priv->state.effect_type = EF_NONE;
+        render_priv->state.effect_timing = 0;
+        render_priv->state.effect_skip_timing = 0;
+    }
+
+    if (text_info->length == 0) {
+        // no valid symbols in the event; this can be smth like {comment}
+        free_render_context();
+        return 1;
+    }
+    // depends on glyph x coordinates being monotonous, so it should be done before line wrap
+    process_karaoke_effects(render_priv);
+
+    // alignments
+    alignment = render_priv->state.alignment;
+    halign = alignment & 3;
+    valign = alignment & 12;
+
+    MarginL =
+        (event->MarginL) ? event->MarginL : render_priv->state.style->
+        MarginL;
+    MarginR =
+        (event->MarginR) ? event->MarginR : render_priv->state.style->
+        MarginR;
+    MarginV =
+        (event->MarginV) ? event->MarginV : render_priv->state.style->
+        MarginV;
+
+    if (render_priv->state.evt_type != EVENT_HSCROLL) {
+        int max_text_width;
+
+        // calculate max length of a line
+        max_text_width =
+            x2scr(render_priv,
+                  render_priv->track->PlayResX - MarginR) -
+            x2scr(render_priv, MarginL);
+
+        // rearrange text in several lines
+        wrap_lines_smart(render_priv, max_text_width);
+
+        // align text
+        last_break = -1;
+        for (i = 1; i < text_info->length + 1; ++i) {   // (text_info->length + 1) is the end of the last line
+            if ((i == text_info->length)
+                || text_info->glyphs[i].linebreak) {
+                int width, shift = 0;
+                glyph_info_t *first_glyph =
+                    text_info->glyphs + last_break + 1;
+                glyph_info_t *last_glyph = text_info->glyphs + i - 1;
+
+                while ((last_glyph > first_glyph)
+                       && ((last_glyph->symbol == '\n')
+                           || (last_glyph->symbol == 0)))
+                    last_glyph--;
+
+                width =
+                    last_glyph->pos.x +
+                    d6_to_int(last_glyph->advance.x) - first_glyph->pos.x;
+                if (halign == HALIGN_LEFT) {    // left aligned, no action
+                    shift = 0;
+                } else if (halign == HALIGN_RIGHT) {    // right aligned
+                    shift = max_text_width - width;
+                } else if (halign == HALIGN_CENTER) {   // centered
+                    shift = (max_text_width - width) / 2;
+                }
+                for (j = last_break + 1; j < i; ++j) {
+                    text_info->glyphs[j].pos.x += shift;
+                }
+                last_break = i - 1;
+            }
+        }
+    } else {                    // render_priv->state.evt_type == EVENT_HSCROLL
+        measure_text(render_priv);
+    }
+
+    // determing text bounding box
+    compute_string_bbox(text_info, &bbox);
+
+    // determine device coordinates for text
+
+    // x coordinate for everything except positioned events
+    if (render_priv->state.evt_type == EVENT_NORMAL ||
+        render_priv->state.evt_type == EVENT_VSCROLL) {
+        device_x = x2scr(render_priv, MarginL);
+    } else if (render_priv->state.evt_type == EVENT_HSCROLL) {
+        if (render_priv->state.scroll_direction == SCROLL_RL)
+            device_x =
+                x2scr(render_priv,
+                      render_priv->track->PlayResX -
+                      render_priv->state.scroll_shift);
+        else if (render_priv->state.scroll_direction == SCROLL_LR)
+            device_x =
+                x2scr(render_priv,
+                      render_priv->state.scroll_shift) - (bbox.xMax -
+                                                          bbox.xMin);
+    }
+    // y coordinate for everything except positioned events
+    if (render_priv->state.evt_type == EVENT_NORMAL ||
+        render_priv->state.evt_type == EVENT_HSCROLL) {
+        if (valign == VALIGN_TOP) {     // toptitle
+            device_y =
+                y2scr_top(render_priv,
+                          MarginV) + d6_to_int(text_info->lines[0].asc);
+        } else if (valign == VALIGN_CENTER) {   // midtitle
+            int scr_y =
+                y2scr(render_priv, render_priv->track->PlayResY / 2);
+            device_y = scr_y - (bbox.yMax - bbox.yMin) / 2;
+        } else {                // subtitle
+            int scr_y;
+            if (valign != VALIGN_SUB)
+                mp_msg(MSGT_ASS, MSGL_V,
+                       "Invalid valign, supposing 0 (subtitle)\n");
+            scr_y =
+                y2scr_sub(render_priv,
+                          render_priv->track->PlayResY - MarginV);
+            device_y = scr_y;
+            device_y -= d6_to_int(text_info->height);
+            device_y += d6_to_int(text_info->lines[0].asc);
+        }
+    } else if (render_priv->state.evt_type == EVENT_VSCROLL) {
+        if (render_priv->state.scroll_direction == SCROLL_TB)
+            device_y =
+                y2scr(render_priv,
+                      render_priv->state.clip_y0 +
+                      render_priv->state.scroll_shift) - (bbox.yMax -
+                                                          bbox.yMin);
+        else if (render_priv->state.scroll_direction == SCROLL_BT)
+            device_y =
+                y2scr(render_priv,
+                      render_priv->state.clip_y1 -
+                      render_priv->state.scroll_shift);
+    }
+    // positioned events are totally different
+    if (render_priv->state.evt_type == EVENT_POSITIONED) {
+        int base_x = 0;
+        int base_y = 0;
+        mp_msg(MSGT_ASS, MSGL_DBG2, "positioned event at %f, %f\n",
+               render_priv->state.pos_x, render_priv->state.pos_y);
+        get_base_point(bbox, alignment, &base_x, &base_y);
+        device_x =
+            x2scr_pos(render_priv, render_priv->state.pos_x) - base_x;
+        device_y =
+            y2scr_pos(render_priv, render_priv->state.pos_y) - base_y;
+    }
+    // fix clip coordinates (they depend on alignment)
+    if (render_priv->state.evt_type == EVENT_NORMAL ||
+        render_priv->state.evt_type == EVENT_HSCROLL ||
+        render_priv->state.evt_type == EVENT_VSCROLL) {
+        render_priv->state.clip_x0 =
+            x2scr(render_priv, render_priv->state.clip_x0);
+        render_priv->state.clip_x1 =
+            x2scr(render_priv, render_priv->state.clip_x1);
+        if (valign == VALIGN_TOP) {
+            render_priv->state.clip_y0 =
+                y2scr_top(render_priv, render_priv->state.clip_y0);
+            render_priv->state.clip_y1 =
+                y2scr_top(render_priv, render_priv->state.clip_y1);
+        } else if (valign == VALIGN_CENTER) {
+            render_priv->state.clip_y0 =
+                y2scr(render_priv, render_priv->state.clip_y0);
+            render_priv->state.clip_y1 =
+                y2scr(render_priv, render_priv->state.clip_y1);
+        } else if (valign == VALIGN_SUB) {
+            render_priv->state.clip_y0 =
+                y2scr_sub(render_priv, render_priv->state.clip_y0);
+            render_priv->state.clip_y1 =
+                y2scr_sub(render_priv, render_priv->state.clip_y1);
+        }
+    } else if (render_priv->state.evt_type == EVENT_POSITIONED) {
+        render_priv->state.clip_x0 =
+            x2scr_pos(render_priv, render_priv->state.clip_x0);
+        render_priv->state.clip_x1 =
+            x2scr_pos(render_priv, render_priv->state.clip_x1);
+        render_priv->state.clip_y0 =
+            y2scr_pos(render_priv, render_priv->state.clip_y0);
+        render_priv->state.clip_y1 =
+            y2scr_pos(render_priv, render_priv->state.clip_y1);
+    }
+    // calculate rotation parameters
+    {
+        FT_Vector center;
+
+        if (render_priv->state.have_origin) {
+            center.x = x2scr(render_priv, render_priv->state.org_x);
+            center.y = y2scr(render_priv, render_priv->state.org_y);
+        } else {
+            int bx = 0, by = 0;
+            get_base_point(bbox, alignment, &bx, &by);
+            center.x = device_x + bx;
+            center.y = device_y + by;
+        }
+
+        for (i = 0; i < text_info->length; ++i) {
+            glyph_info_t *info = text_info->glyphs + i;
+
+            if (info->hash_key.frx || info->hash_key.fry
+                || info->hash_key.frz) {
+                info->hash_key.shift_x = info->pos.x + device_x - center.x;
+                info->hash_key.shift_y =
+                    -(info->pos.y + device_y - center.y);
+            } else {
+                info->hash_key.shift_x = 0;
+                info->hash_key.shift_y = 0;
+            }
+        }
+    }
+
+    // convert glyphs to bitmaps
+    for (i = 0; i < text_info->length; ++i)
+        get_bitmap_glyph(render_priv, text_info->glyphs + i);
+
+    memset(event_images, 0, sizeof(*event_images));
+    event_images->top = device_y - d6_to_int(text_info->lines[0].asc);
+    event_images->height = d6_to_int(text_info->height);
+    event_images->detect_collisions = render_priv->state.detect_collisions;
+    event_images->shift_direction = (valign == VALIGN_TOP) ? 1 : -1;
+    event_images->event = event;
+    event_images->imgs = render_text(render_priv, device_x, device_y);
+
+    free_render_context();
+
+    return 0;
 }
 
 /**
  * \brief deallocate image list
  * \param img list pointer
  */
-static void ass_free_images(ass_image_timg)
+static void ass_free_images(ass_image_t *img)
 {
-       while (img) {
-               ass_image_t* next = img->next;
-               free(img);
-               img = next;
-       }
+    while (img) {
+        ass_image_t *next = img->next;
+        free(img);
+        img = next;
+    }
 }
 
-static void ass_reconfigure(ass_renderer_tpriv)
+static void ass_reconfigure(ass_renderer_t *priv)
 {
-       priv->render_id = ++last_render_id;
-       priv->cache.glyph_cache = ass_glyph_cache_reset(priv->cache.glyph_cache);
-       priv->cache.bitmap_cache = ass_bitmap_cache_reset(priv->cache.bitmap_cache);
-       priv->cache.composite_cache = ass_composite_cache_reset(priv->cache.composite_cache);
-       ass_free_images(priv->prev_images_root);
-       priv->prev_images_root = 0;
+    priv->render_id = ++last_render_id;
+    priv->cache.glyph_cache =
+        ass_glyph_cache_reset(priv->cache.glyph_cache);
+    priv->cache.bitmap_cache =
+        ass_bitmap_cache_reset(priv->cache.bitmap_cache);
+    priv->cache.composite_cache =
+        ass_composite_cache_reset(priv->cache.composite_cache);
+    ass_free_images(priv->prev_images_root);
+    priv->prev_images_root = 0;
 }
 
-void ass_set_frame_size(ass_renderer_tpriv, int w, int h)
+void ass_set_frame_size(ass_renderer_t *priv, int w, int h)
 {
-       if (priv->settings.frame_width != w || priv->settings.frame_height != h) {
-               priv->settings.frame_width = w;
-               priv->settings.frame_height = h;
-               if (priv->settings.aspect == 0.)
-                       priv->settings.aspect = ((double)w) / h;
-               ass_reconfigure(priv);
-       }
+    if (priv->settings.frame_width != w || priv->settings.frame_height != h) {
+        priv->settings.frame_width = w;
+        priv->settings.frame_height = h;
+        if (priv->settings.aspect == 0.)
+            priv->settings.aspect = ((double) w) / h;
+        ass_reconfigure(priv);
+    }
 }
 
-void ass_set_margins(ass_renderer_tpriv, int t, int b, int l, int r)
+void ass_set_margins(ass_renderer_t *priv, int t, int b, int l, int r)
 {
-       if (priv->settings.left_margin != l ||
-           priv->settings.right_margin != r ||
-           priv->settings.top_margin != t ||
-           priv->settings.bottom_margin != b) {
-               priv->settings.left_margin = l;
-               priv->settings.right_margin = r;
-               priv->settings.top_margin = t;
-               priv->settings.bottom_margin = b;
-               ass_reconfigure(priv);
-       }
+    if (priv->settings.left_margin != l ||
+        priv->settings.right_margin != r ||
+        priv->settings.top_margin != t
+        || priv->settings.bottom_margin != b) {
+        priv->settings.left_margin = l;
+        priv->settings.right_margin = r;
+        priv->settings.top_margin = t;
+        priv->settings.bottom_margin = b;
+        ass_reconfigure(priv);
+    }
 }
 
-void ass_set_use_margins(ass_renderer_tpriv, int use)
+void ass_set_use_margins(ass_renderer_t *priv, int use)
 {
-       priv->settings.use_margins = use;
+    priv->settings.use_margins = use;
 }
 
-void ass_set_aspect_ratio(ass_renderer_tpriv, double ar)
+void ass_set_aspect_ratio(ass_renderer_t *priv, double ar)
 {
-       if (priv->settings.aspect != ar) {
-               priv->settings.aspect = ar;
-               ass_reconfigure(priv);
-       }
+    if (priv->settings.aspect != ar) {
+        priv->settings.aspect = ar;
+        ass_reconfigure(priv);
+    }
 }
 
-void ass_set_font_scale(ass_renderer_tpriv, double font_scale)
+void ass_set_font_scale(ass_renderer_t *priv, double font_scale)
 {
-       if (priv->settings.font_size_coeff != font_scale) {
-               priv->settings.font_size_coeff = font_scale;
-               ass_reconfigure(priv);
-       }
+    if (priv->settings.font_size_coeff != font_scale) {
+        priv->settings.font_size_coeff = font_scale;
+        ass_reconfigure(priv);
+    }
 }
 
-void ass_set_hinting(ass_renderer_tpriv, ass_hinting_t ht)
+void ass_set_hinting(ass_renderer_t *priv, ass_hinting_t ht)
 {
-       if (priv->settings.hinting != ht) {
-               priv->settings.hinting = ht;
-               ass_reconfigure(priv);
-       }
+    if (priv->settings.hinting != ht) {
+        priv->settings.hinting = ht;
+        ass_reconfigure(priv);
+    }
 }
 
-void ass_set_line_spacing(ass_renderer_tpriv, double line_spacing)
+void ass_set_line_spacing(ass_renderer_t *priv, double line_spacing)
 {
-       priv->settings.line_spacing = line_spacing;
+    priv->settings.line_spacing = line_spacing;
 }
 
-static int ass_set_fonts_(ass_renderer_t* priv, const char* default_font, const char* default_family, int fc)
+static int
+ass_set_fonts_(ass_renderer_t *priv, const char *default_font,
+               const char *default_family, int fc)
 {
-       if (priv->settings.default_font)
-               free(priv->settings.default_font);
-       if (priv->settings.default_family)
-               free(priv->settings.default_family);
-
-       priv->settings.default_font = default_font ? strdup(default_font) : 0;
-       priv->settings.default_family = default_family ? strdup(default_family) : 0;
-
-       if (priv->fontconfig_priv)
-               fontconfig_done(priv->fontconfig_priv);
-       priv->fontconfig_priv = fontconfig_init(priv->library, priv->ftlibrary, default_family, default_font, fc);
-
-       return !!priv->fontconfig_priv;
+    if (priv->settings.default_font)
+        free(priv->settings.default_font);
+    if (priv->settings.default_family)
+        free(priv->settings.default_family);
+
+    priv->settings.default_font = default_font ? strdup(default_font) : 0;
+    priv->settings.default_family =
+        default_family ? strdup(default_family) : 0;
+
+    if (priv->fontconfig_priv)
+        fontconfig_done(priv->fontconfig_priv);
+    priv->fontconfig_priv =
+        fontconfig_init(priv->library, priv->ftlibrary, default_family,
+                        default_font, fc);
+
+    return !!priv->fontconfig_priv;
 }
 
-int ass_set_fonts(ass_renderer_t* priv, const char* default_font, const char* default_family)
+int
+ass_set_fonts(ass_renderer_t *priv, const char *default_font,
+              const char *default_family)
 {
-       return ass_set_fonts_(priv, default_font, default_family, 1);
+    return ass_set_fonts_(priv, default_font, default_family, 1);
 }
 
-int ass_set_fonts_nofc(ass_renderer_t* priv, const char* default_font, const char* default_family)
+int
+ass_set_fonts_nofc(ass_renderer_t *priv, const char *default_font,
+                   const char *default_family)
 {
-       return ass_set_fonts_(priv, default_font, default_family, 0);
+    return ass_set_fonts_(priv, default_font, default_family, 0);
 }
 
 /**
  * \brief Start a new frame
  */
-static int ass_start_frame(ass_renderer_t *render_priv, ass_track_t* track, long long now)
+static int
+ass_start_frame(ass_renderer_t *render_priv, ass_track_t *track,
+                long long now)
 {
-       ass_settings_t* settings_priv = &render_priv->settings;
-
-       if (!render_priv->settings.frame_width && !render_priv->settings.frame_height)
-               return 1; // library not initialized
-
-       if (track->n_events == 0)
-               return 1; // nothing to do
-
-       render_priv->width = settings_priv->frame_width;
-       render_priv->height = settings_priv->frame_height;
-       render_priv->orig_width = settings_priv->frame_width - settings_priv->left_margin - settings_priv->right_margin;
-       render_priv->orig_height = settings_priv->frame_height - settings_priv->top_margin - settings_priv->bottom_margin;
-       render_priv->orig_width_nocrop = settings_priv->frame_width -
-               FFMAX(settings_priv->left_margin, 0) -
-               FFMAX(settings_priv->right_margin, 0);
-       render_priv->orig_height_nocrop = settings_priv->frame_height -
-               FFMAX(settings_priv->top_margin, 0) -
-               FFMAX(settings_priv->bottom_margin, 0);
-       render_priv->track = track;
-       render_priv->time = now;
-
-       ass_lazy_track_init(render_priv);
-
-       render_priv->font_scale = settings_priv->font_size_coeff *
-                                  render_priv->orig_height / render_priv->track->PlayResY;
-       if (render_priv->track->ScaledBorderAndShadow)
-               render_priv->border_scale = ((double)render_priv->orig_height) / render_priv->track->PlayResY;
-       else
-               render_priv->border_scale = 1.;
-
-       render_priv->font_scale_x = 1.;
-
-       render_priv->prev_images_root = render_priv->images_root;
-       render_priv->images_root = 0;
-
-       return 0;
+    ass_settings_t *settings_priv = &render_priv->settings;
+
+    if (!render_priv->settings.frame_width
+        && !render_priv->settings.frame_height)
+        return 1;               // library not initialized
+
+    if (track->n_events == 0)
+        return 1;               // nothing to do
+
+    render_priv->width = settings_priv->frame_width;
+    render_priv->height = settings_priv->frame_height;
+    render_priv->orig_width =
+        settings_priv->frame_width - settings_priv->left_margin -
+        settings_priv->right_margin;
+    render_priv->orig_height =
+        settings_priv->frame_height - settings_priv->top_margin -
+        settings_priv->bottom_margin;
+    render_priv->orig_width_nocrop =
+        settings_priv->frame_width - FFMAX(settings_priv->left_margin,
+                                           0) -
+        FFMAX(settings_priv->right_margin, 0);
+    render_priv->orig_height_nocrop =
+        settings_priv->frame_height - FFMAX(settings_priv->top_margin,
+                                            0) -
+        FFMAX(settings_priv->bottom_margin, 0);
+    render_priv->track = track;
+    render_priv->time = now;
+
+    ass_lazy_track_init(render_priv);
+
+    render_priv->font_scale = settings_priv->font_size_coeff *
+        render_priv->orig_height / render_priv->track->PlayResY;
+    if (render_priv->track->ScaledBorderAndShadow)
+        render_priv->border_scale =
+            ((double) render_priv->orig_height) /
+            render_priv->track->PlayResY;
+    else
+        render_priv->border_scale = 1.;
+
+    render_priv->font_scale_x = 1.;
+
+    render_priv->prev_images_root = render_priv->images_root;
+    render_priv->images_root = 0;
+
+    return 0;
 }
 
-static int cmp_event_layer(const void* p1, const void* p2)
+static int cmp_event_layer(const void *p1, const void *p2)
 {
-       ass_event_t* e1 = ((event_images_t*)p1)->event;
-       ass_event_t* e2 = ((event_images_t*)p2)->event;
-       if (e1->Layer < e2->Layer)
-               return -1;
-       if (e1->Layer > e2->Layer)
-               return 1;
-       if (e1->ReadOrder < e2->ReadOrder)
-               return -1;
-       if (e1->ReadOrder > e2->ReadOrder)
-               return 1;
-       return 0;
+    ass_event_t *e1 = ((event_images_t *) p1)->event;
+    ass_event_t *e2 = ((event_images_t *) p2)->event;
+    if (e1->Layer < e2->Layer)
+        return -1;
+    if (e1->Layer > e2->Layer)
+        return 1;
+    if (e1->ReadOrder < e2->ReadOrder)
+        return -1;
+    if (e1->ReadOrder > e2->ReadOrder)
+        return 1;
+    return 0;
 }
 
 #define MAX_EVENTS 100
 
-static render_priv_t* get_render_priv(ass_renderer_t* render_priv, ass_event_t* event)
+static render_priv_t *get_render_priv(ass_renderer_t *render_priv,
+                                      ass_event_t *event)
 {
-       if (!event->render_priv)
-               event->render_priv = calloc(1, sizeof(render_priv_t));
-       // FIXME: check render_id
-       if (render_priv->render_id != event->render_priv->render_id) {
-               memset(event->render_priv, 0, sizeof(render_priv_t));
-               event->render_priv->render_id = render_priv->render_id;
-       }
-       return event->render_priv;
+    if (!event->render_priv)
+        event->render_priv = calloc(1, sizeof(render_priv_t));
+    // FIXME: check render_id
+    if (render_priv->render_id != event->render_priv->render_id) {
+        memset(event->render_priv, 0, sizeof(render_priv_t));
+        event->render_priv->render_id = render_priv->render_id;
+    }
+    return event->render_priv;
 }
 
 typedef struct segment_s {
-       int a, b; // top and height
+    int a, b;                   // top and height
 } segment_t;
 
-static int overlap(segment_t* s1, segment_t* s2)
+static int overlap(segment_t *s1, segment_t *s2)
 {
-       if (s1->a >= s2->b || s2->a >= s1->b)
-               return 0;
-       return 1;
+    if (s1->a >= s2->b || s2->a >= s1->b)
+        return 0;
+    return 1;
 }
 
-static int cmp_segment(const void* p1, const void* p2)
+static int cmp_segment(const void *p1, const void *p2)
 {
-       return ((segment_t*)p1)->a - ((segment_t*)p2)->a;
+    return ((segment_t *) p1)->a - ((segment_t *) p2)->a;
 }
 
-static void shift_event(ass_renderer_t* render_priv, event_images_t* ei, int shift)
+static void
+shift_event(ass_renderer_t *render_priv, event_images_t *ei, int shift)
 {
-       ass_image_t* cur = ei->imgs;
-       while (cur) {
-               cur->dst_y += shift;
-               // clip top and bottom
-               if (cur->dst_y < 0) {
-                       int clip = - cur->dst_y;
-                       cur->h -= clip;
-                       cur->bitmap += clip * cur->stride;
-                       cur->dst_y = 0;
-               }
-               if (cur->dst_y + cur->h >= render_priv->height) {
-                       int clip = cur->dst_y + cur->h - render_priv->height;
-                       cur->h -= clip;
-               }
-               if (cur->h <= 0) {
-                       cur->h = 0;
-                       cur->dst_y = 0;
-               }
-               cur = cur->next;
-       }
-       ei->top += shift;
+    ass_image_t *cur = ei->imgs;
+    while (cur) {
+        cur->dst_y += shift;
+        // clip top and bottom
+        if (cur->dst_y < 0) {
+            int clip = -cur->dst_y;
+            cur->h -= clip;
+            cur->bitmap += clip * cur->stride;
+            cur->dst_y = 0;
+        }
+        if (cur->dst_y + cur->h >= render_priv->height) {
+            int clip = cur->dst_y + cur->h - render_priv->height;
+            cur->h -= clip;
+        }
+        if (cur->h <= 0) {
+            cur->h = 0;
+            cur->dst_y = 0;
+        }
+        cur = cur->next;
+    }
+    ei->top += shift;
 }
 
 // dir: 1 - move down
 //      -1 - move up
-static int fit_segment(segment_t* s, segment_t* fixed, int* cnt, int dir)
+static int fit_segment(segment_t *s, segment_t *fixed, int *cnt, int dir)
 {
-       int i;
-       int shift = 0;
-
-       if (dir == 1) // move down
-               for (i = 0; i < *cnt; ++i) {
-                       if (s->b + shift <= fixed[i].a || s->a + shift >= fixed[i].b)
-                               continue;
-                       shift = fixed[i].b - s->a;
-               }
-       else // dir == -1, move up
-               for (i = *cnt-1; i >= 0; --i) {
-                       if (s->b + shift <= fixed[i].a || s->a + shift >= fixed[i].b)
-                               continue;
-                       shift = fixed[i].a - s->b;
-               }
-
-       fixed[*cnt].a = s->a + shift;
-       fixed[*cnt].b = s->b + shift;
-       (*cnt)++;
-       qsort(fixed, *cnt, sizeof(segment_t), cmp_segment);
-
-       return shift;
+    int i;
+    int shift = 0;
+
+    if (dir == 1)               // move down
+        for (i = 0; i < *cnt; ++i) {
+            if (s->b + shift <= fixed[i].a || s->a + shift >= fixed[i].b)
+                continue;
+            shift = fixed[i].b - s->a;
+    } else                      // dir == -1, move up
+        for (i = *cnt - 1; i >= 0; --i) {
+            if (s->b + shift <= fixed[i].a || s->a + shift >= fixed[i].b)
+                continue;
+            shift = fixed[i].a - s->b;
+        }
+
+    fixed[*cnt].a = s->a + shift;
+    fixed[*cnt].b = s->b + shift;
+    (*cnt)++;
+    qsort(fixed, *cnt, sizeof(segment_t), cmp_segment);
+
+    return shift;
 }
 
-static void fix_collisions(ass_renderer_t* render_priv, event_images_t* imgs, int cnt)
+static void
+fix_collisions(ass_renderer_t *render_priv, event_images_t *imgs, int cnt)
 {
-       segment_t used[MAX_EVENTS];
-       int cnt_used = 0;
-       int i, j;
-
-       // fill used[] with fixed events
-       for (i = 0; i < cnt; ++i) {
-               render_priv_t* priv;
-               if (!imgs[i].detect_collisions) continue;
-               priv = get_render_priv(render_priv, imgs[i].event);
-               if (priv->height > 0) { // it's a fixed event
-                       segment_t s;
-                       s.a = priv->top;
-                       s.b = priv->top + priv->height;
-                       if (priv->height != imgs[i].height) { // no, it's not
-                               mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_EventHeightHasChanged);
-                               priv->top = 0;
-                               priv->height = 0;
-                       }
-                       for (j = 0; j < cnt_used; ++j)
-                               if (overlap(&s, used + j)) { // no, it's not
-                                       priv->top = 0;
-                                       priv->height = 0;
-                               }
-                       if (priv->height > 0) { // still a fixed event
-                               used[cnt_used].a = priv->top;
-                               used[cnt_used].b = priv->top + priv->height;
-                               cnt_used ++;
-                               shift_event(render_priv, imgs + i, priv->top - imgs[i].top);
-                       }
-               }
-       }
-       qsort(used, cnt_used, sizeof(segment_t), cmp_segment);
-
-       // try to fit other events in free spaces
-       for (i = 0; i < cnt; ++i) {
-               render_priv_t* priv;
-               if (!imgs[i].detect_collisions) continue;
-               priv = get_render_priv(render_priv, imgs[i].event);
-               if (priv->height == 0) { // not a fixed event
-                       int shift;
-                       segment_t s;
-                       s.a = imgs[i].top;
-                       s.b = imgs[i].top + imgs[i].height;
-                       shift = fit_segment(&s, used, &cnt_used, imgs[i].shift_direction);
-                       if (shift) shift_event(render_priv, imgs + i, shift);
-                       // make it fixed
-                       priv->top = imgs[i].top;
-                       priv->height = imgs[i].height;
-               }
-
-       }
+    segment_t used[MAX_EVENTS];
+    int cnt_used = 0;
+    int i, j;
+
+    // fill used[] with fixed events
+    for (i = 0; i < cnt; ++i) {
+        render_priv_t *priv;
+        if (!imgs[i].detect_collisions)
+            continue;
+        priv = get_render_priv(render_priv, imgs[i].event);
+        if (priv->height > 0) { // it's a fixed event
+            segment_t s;
+            s.a = priv->top;
+            s.b = priv->top + priv->height;
+            if (priv->height != imgs[i].height) {       // no, it's not
+                mp_msg(MSGT_ASS, MSGL_WARN,
+                       MSGTR_LIBASS_EventHeightHasChanged);
+                priv->top = 0;
+                priv->height = 0;
+            }
+            for (j = 0; j < cnt_used; ++j)
+                if (overlap(&s, used + j)) {    // no, it's not
+                    priv->top = 0;
+                    priv->height = 0;
+                }
+            if (priv->height > 0) {     // still a fixed event
+                used[cnt_used].a = priv->top;
+                used[cnt_used].b = priv->top + priv->height;
+                cnt_used++;
+                shift_event(render_priv, imgs + i, priv->top - imgs[i].top);
+            }
+        }
+    }
+    qsort(used, cnt_used, sizeof(segment_t), cmp_segment);
+
+    // try to fit other events in free spaces
+    for (i = 0; i < cnt; ++i) {
+        render_priv_t *priv;
+        if (!imgs[i].detect_collisions)
+            continue;
+        priv = get_render_priv(render_priv, imgs[i].event);
+        if (priv->height == 0) {        // not a fixed event
+            int shift;
+            segment_t s;
+            s.a = imgs[i].top;
+            s.b = imgs[i].top + imgs[i].height;
+            shift =
+                fit_segment(&s, used, &cnt_used, imgs[i].shift_direction);
+            if (shift)
+                shift_event(render_priv, imgs + i, shift);
+            // make it fixed
+            priv->top = imgs[i].top;
+            priv->height = imgs[i].height;
+        }
+
+    }
 }
 
 /**
@@ -2585,15 +2899,21 @@ static void fix_collisions(ass_renderer_t* render_priv, event_images_t* imgs, in
  */
 static int ass_image_compare(ass_image_t *i1, ass_image_t *i2)
 {
-       if (i1->w != i2->w) return 2;
-       if (i1->h != i2->h) return 2;
-       if (i1->stride != i2->stride) return 2;
-       if (i1->color != i2->color) return 2;
-       if (i1->bitmap != i2->bitmap)
-               return 2;
-       if (i1->dst_x != i2->dst_x) return 1;
-       if (i1->dst_y != i2->dst_y) return 1;
-       return 0;
+    if (i1->w != i2->w)
+        return 2;
+    if (i1->h != i2->h)
+        return 2;
+    if (i1->stride != i2->stride)
+        return 2;
+    if (i1->color != i2->color)
+        return 2;
+    if (i1->bitmap != i2->bitmap)
+        return 2;
+    if (i1->dst_x != i2->dst_x)
+        return 1;
+    if (i1->dst_y != i2->dst_y)
+        return 1;
+    return 0;
 }
 
 /**
@@ -2603,33 +2923,34 @@ static int ass_image_compare(ass_image_t *i1, ass_image_t *i2)
  */
 static int ass_detect_change(ass_renderer_t *priv)
 {
-       ass_image_t* img, *img2;
-       int diff;
-
-       img = priv->prev_images_root;
-       img2 = priv->images_root;
-       diff = 0;
-       while (img && diff < 2) {
-               ass_image_t* next, *next2;
-               next = img->next;
-               if (img2) {
-                       int d = ass_image_compare(img, img2);
-                       if (d > diff) diff = d;
-                       next2 = img2->next;
-               } else {
-                       // previous list is shorter
-                       diff = 2;
-                       break;
-               }
-               img = next;
-               img2 = next2;
-       }
-
-       // is the previous list longer?
-       if (img2)
-               diff = 2;
-
-       return diff;
+    ass_image_t *img, *img2;
+    int diff;
+
+    img = priv->prev_images_root;
+    img2 = priv->images_root;
+    diff = 0;
+    while (img && diff < 2) {
+        ass_image_t *next, *next2;
+        next = img->next;
+        if (img2) {
+            int d = ass_image_compare(img, img2);
+            if (d > diff)
+                diff = d;
+            next2 = img2->next;
+        } else {
+            // previous list is shorter
+            diff = 2;
+            break;
+        }
+        img = next;
+        img2 = next2;
+    }
+
+    // is the previous list longer?
+    if (img2)
+        diff = 2;
+
+    return diff;
 }
 
 /**
@@ -2641,62 +2962,66 @@ static int ass_detect_change(ass_renderer_t *priv)
  *        0 if identical, 1 if different positions, 2 if different content.
  *        Can be NULL, in that case no detection is performed.
  */
-ass_image_t* ass_render_frame(ass_renderer_t *priv, ass_track_t* track, long long now, int* detect_change)
+ass_image_t *ass_render_frame(ass_renderer_t *priv, ass_track_t *track,
+                              long long now, int *detect_change)
 {
-       int i, cnt, rc;
-       event_images_t* last;
-       ass_image_t** tail;
-
-       // init frame
-       rc = ass_start_frame(priv, track, now);
-       if (rc != 0)
-               return 0;
-
-       // render events separately
-       cnt = 0;
-       for (i = 0; i < track->n_events; ++i) {
-               ass_event_t* event = track->events + i;
-               if ( (event->Start <= now) && (now < (event->Start + event->Duration)) ) {
-                       if (cnt >= priv->eimg_size) {
-                               priv->eimg_size += 100;
-                               priv->eimg = realloc(priv->eimg, priv->eimg_size * sizeof(event_images_t));
-                       }
-                       rc = ass_render_event(priv, event, priv->eimg + cnt);
-                       if (!rc) ++cnt;
-               }
-       }
-
-       // sort by layer
-       qsort(priv->eimg, cnt, sizeof(event_images_t), cmp_event_layer);
-
-       // call fix_collisions for each group of events with the same layer
-       last = priv->eimg;
-       for (i = 1; i < cnt; ++i)
-               if (last->event->Layer != priv->eimg[i].event->Layer) {
-                       fix_collisions(priv, last, priv->eimg + i - last);
-                       last = priv->eimg + i;
-               }
-       if (cnt > 0)
-               fix_collisions(priv, last, priv->eimg + cnt - last);
-
-       // concat lists
-       tail = &priv->images_root;
-       for (i = 0; i < cnt; ++i) {
-               ass_image_t* cur = priv->eimg[i].imgs;
-               while (cur) {
-                       *tail = cur;
-                       tail = &cur->next;
-                       cur = cur->next;
-               }
-       }
-
-       if (detect_change)
-               *detect_change = ass_detect_change(priv);
-
-       // free the previous image list
-       ass_free_images(priv->prev_images_root);
-       priv->prev_images_root = 0;
-
-       return priv->images_root;
-}
+    int i, cnt, rc;
+    event_images_t *last;
+    ass_image_t **tail;
+
+    // init frame
+    rc = ass_start_frame(priv, track, now);
+    if (rc != 0)
+        return 0;
+
+    // render events separately
+    cnt = 0;
+    for (i = 0; i < track->n_events; ++i) {
+        ass_event_t *event = track->events + i;
+        if ((event->Start <= now)
+            && (now < (event->Start + event->Duration))) {
+            if (cnt >= priv->eimg_size) {
+                priv->eimg_size += 100;
+                priv->eimg =
+                    realloc(priv->eimg,
+                            priv->eimg_size * sizeof(event_images_t));
+            }
+            rc = ass_render_event(priv, event, priv->eimg + cnt);
+            if (!rc)
+                ++cnt;
+        }
+    }
+
+    // sort by layer
+    qsort(priv->eimg, cnt, sizeof(event_images_t), cmp_event_layer);
 
+    // call fix_collisions for each group of events with the same layer
+    last = priv->eimg;
+    for (i = 1; i < cnt; ++i)
+        if (last->event->Layer != priv->eimg[i].event->Layer) {
+            fix_collisions(priv, last, priv->eimg + i - last);
+            last = priv->eimg + i;
+        }
+    if (cnt > 0)
+        fix_collisions(priv, last, priv->eimg + cnt - last);
+
+    // concat lists
+    tail = &priv->images_root;
+    for (i = 0; i < cnt; ++i) {
+        ass_image_t *cur = priv->eimg[i].imgs;
+        while (cur) {
+            *tail = cur;
+            tail = &cur->next;
+            cur = cur->next;
+        }
+    }
+
+    if (detect_change)
+        *detect_change = ass_detect_change(priv);
+
+    // free the previous image list
+    ass_free_images(priv->prev_images_root);
+    priv->prev_images_root = 0;
+
+    return priv->images_root;
+}
index d43fef3137fcdaa83de860a191904e360fdbdfc5..cdea14ef44af0eb30b8e46d0ec14f61cc9078f9b 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 
 /// ass Style: line
 typedef struct ass_style_s {
-       char* Name;
-       char* FontName;
-       double FontSize;
-       uint32_t PrimaryColour;
-       uint32_t SecondaryColour;
-       uint32_t OutlineColour;
-       uint32_t BackColour;
-       int Bold;
-       int Italic;
-       int Underline;
-       int StrikeOut;
-       double ScaleX;
-       double ScaleY;
-       double Spacing;
-       int Angle;
-       int BorderStyle;
-       double Outline;
-       double Shadow;
-       int Alignment;
-       int MarginL;
-       int MarginR;
-       int MarginV;
+    char *Name;
+    char *FontName;
+    double FontSize;
+    uint32_t PrimaryColour;
+    uint32_t SecondaryColour;
+    uint32_t OutlineColour;
+    uint32_t BackColour;
+    int Bold;
+    int Italic;
+    int Underline;
+    int StrikeOut;
+    double ScaleX;
+    double ScaleY;
+    double Spacing;
+    int Angle;
+    int BorderStyle;
+    double Outline;
+    double Shadow;
+    int Alignment;
+    int MarginL;
+    int MarginR;
+    int MarginV;
 //        int AlphaLevel;
-       int Encoding;
-       int treat_fontname_as_pattern;
+    int Encoding;
+    int treat_fontname_as_pattern;
 } ass_style_t;
 
 typedef struct render_priv_s render_priv_t;
@@ -66,20 +64,20 @@ typedef struct render_priv_s render_priv_t;
 /// ass_event_t corresponds to a single Dialogue line
 /// Text is stored as-is, style overrides will be parsed later
 typedef struct ass_event_s {
-       long long Start; // ms
-       long long Duration; // ms
-
-       int ReadOrder;
-       int Layer;
-       int Style;
-       char* Name;
-       int MarginL;
-       int MarginR;
-       int MarginV;
-       char* Effect;
-       char* Text;
-
-       render_priv_t* render_priv;
+    long long Start;            // ms
+    long long Duration;         // ms
+
+    int ReadOrder;
+    int Layer;
+    int Style;
+    char *Name;
+    int MarginL;
+    int MarginR;
+    int MarginV;
+    char *Effect;
+    char *Text;
+
+    render_priv_t *render_priv;
 } ass_event_t;
 
 typedef struct parser_priv_s parser_priv_t;
@@ -89,31 +87,32 @@ typedef struct ass_library_s ass_library_t;
 /// ass track represent either an external script or a matroska subtitle stream (no real difference between them)
 /// it can be used in rendering after the headers are parsed (i.e. events format line read)
 typedef struct ass_track_s {
-       int n_styles; // amount used
-       int max_styles; // amount allocated
-       int n_events;
-       int max_events;
-       ass_style_t* styles; // array of styles, max_styles length, n_styles used
-       ass_event_t* events; // the same as styles
+    int n_styles;               // amount used
+    int max_styles;             // amount allocated
+    int n_events;
+    int max_events;
+    ass_style_t *styles;        // array of styles, max_styles length, n_styles used
+    ass_event_t *events;        // the same as styles
 
-       char* style_format; // style format line (everything after "Format: ")
-       char* event_format; // event format line
+    char *style_format;         // style format line (everything after "Format: ")
+    char *event_format;         // event format line
 
-       enum {TRACK_TYPE_UNKNOWN = 0, TRACK_TYPE_ASS, TRACK_TYPE_SSA} track_type;
+    enum { TRACK_TYPE_UNKNOWN =
+            0, TRACK_TYPE_ASS, TRACK_TYPE_SSA } track_type;
 
-       // script header fields
-       int PlayResX;
-       int PlayResY;
-       double Timer;
-       int WrapStyle;
-       char ScaledBorderAndShadow;
+    // script header fields
+    int PlayResX;
+    int PlayResY;
+    double Timer;
+    int WrapStyle;
+    char ScaledBorderAndShadow;
 
 
-       int default_style; // index of default style
-       char* name; // file name in case of external subs, 0 for streams
+    int default_style;          // index of default style
+    char *name;                 // file name in case of external subs, 0 for streams
 
-       ass_library_t* library;
-       parser_priv_t* parser_priv;
+    ass_library_t *library;
+    parser_priv_t *parser_priv;
 } ass_track_t;
 
-#endif /* LIBASS_TYPES_H */
+#endif                          /* LIBASS_TYPES_H */
index 9a89e8afae426622fb90f60fbe22dd3b0d877eea..73e7433f96cb42c94fcef8c97719146baba67d51 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 #include "mputils.h"
 #include "ass_utils.h"
 
-int mystrtoi(char** p, int* res)
+int mystrtoi(char **p, int *res)
 {
-       // NOTE: base argument is ignored, but not used in libass anyway
-       double temp_res;
-       char* start = *p;
-       temp_res = strtod(*p, p);
-       *res = (int) (temp_res + 0.5);
-       if (*p != start) return 1;
-       else return 0;
+    // NOTE: base argument is ignored, but not used in libass anyway
+    double temp_res;
+    char *start = *p;
+    temp_res = strtod(*p, p);
+    *res = (int) (temp_res + 0.5);
+    if (*p != start)
+        return 1;
+    else
+        return 0;
 }
 
-int mystrtoll(char** p, long long* res)
+int mystrtoll(char **p, long long *res)
 {
-       double temp_res;
-       char* start = *p;
-       temp_res = strtod(*p, p);
-       *res = (long long) (temp_res + 0.5);
-       if (*p != start) return 1;
-       else return 0;
+    double temp_res;
+    char *start = *p;
+    temp_res = strtod(*p, p);
+    *res = (long long) (temp_res + 0.5);
+    if (*p != start)
+        return 1;
+    else
+        return 0;
 }
 
-int mystrtou32(char** p, int base, uint32_t* res)
+int mystrtou32(char **p, int base, uint32_t *res)
 {
-       char* start = *p;
-       *res = strtoll(*p, p, base);
-       if (*p != start) return 1;
-       else return 0;
+    char *start = *p;
+    *res = strtoll(*p, p, base);
+    if (*p != start)
+        return 1;
+    else
+        return 0;
 }
 
-int mystrtod(char** p, double* res)
+int mystrtod(char **p, double *res)
 {
-       char* start = *p;
-       *res = strtod(*p, p);
-       if (*p != start) return 1;
-       else return 0;
+    char *start = *p;
+    *res = strtod(*p, p);
+    if (*p != start)
+        return 1;
+    else
+        return 0;
 }
 
-int strtocolor(char** q, uint32_t* res)
+int strtocolor(char **q, uint32_t *res)
 {
-       uint32_t color = 0;
-       int result;
-       char* p = *q;
+    uint32_t color = 0;
+    int result;
+    char *p = *q;
 
-       if (*p == '&') ++p;
-       else mp_msg(MSGT_ASS, MSGL_DBG2, "suspicious color format: \"%s\"\n", p);
+    if (*p == '&')
+        ++p;
+    else
+        mp_msg(MSGT_ASS, MSGL_DBG2, "suspicious color format: \"%s\"\n", p);
 
-       if (*p == 'H' || *p == 'h') {
-               ++p;
-               result = mystrtou32(&p, 16, &color);
-       } else {
-               result = mystrtou32(&p, 0, &color);
-       }
+    if (*p == 'H' || *p == 'h') {
+        ++p;
+        result = mystrtou32(&p, 16, &color);
+    } else {
+        result = mystrtou32(&p, 0, &color);
+    }
 
-       {
-               unsigned char* tmp = (unsigned char*)(&color);
-               unsigned char b;
-               b = tmp[0]; tmp[0] = tmp[3]; tmp[3] = b;
-               b = tmp[1]; tmp[1] = tmp[2]; tmp[2] = b;
-       }
-       if (*p == '&') ++p;
-       *q = p;
+    {
+        unsigned char *tmp = (unsigned char *) (&color);
+        unsigned char b;
+        b = tmp[0];
+        tmp[0] = tmp[3];
+        tmp[3] = b;
+        b = tmp[1];
+        tmp[1] = tmp[2];
+        tmp[2] = b;
+    }
+    if (*p == '&')
+        ++p;
+    *q = p;
 
-       *res = color;
-       return result;
+    *res = color;
+    return result;
 }
 
 // Return a boolean value for a string
-char parse_bool(char* str) {
-       while (*str == ' ' || *str == '\t')
-               str++;
-       if (!strncasecmp(str, "yes", 3))
-               return 1;
-       else if (strtol(str, NULL, 10) > 0)
-               return 1;
-       return 0;
+char parse_bool(char *str)
+{
+    while (*str == ' ' || *str == '\t')
+        str++;
+    if (!strncasecmp(str, "yes", 3))
+        return 1;
+    else if (strtol(str, NULL, 10) > 0)
+        return 1;
+    return 0;
 }
 
 #if 0
-static void sprint_tag(uint32_t tag, chardst)
+static void sprint_tag(uint32_t tag, char *dst)
 {
-       dst[0] = (tag >> 24) & 0xFF;
-       dst[1] = (tag >> 16) & 0xFF;
-       dst[2] = (tag >> 8) & 0xFF;
-       dst[3] = tag & 0xFF;
-       dst[4] = 0;
+    dst[0] = (tag >> 24) & 0xFF;
+    dst[1] = (tag >> 16) & 0xFF;
+    dst[2] = (tag >> 8) & 0xFF;
+    dst[3] = tag & 0xFF;
+    dst[4] = 0;
 }
 
 void dump_glyph(FT_Glyph g)
 {
-       char tag[5];
-       int i;
-       FT_OutlineGlyph og = (FT_OutlineGlyph)g;
-       FT_Outline* o = &(og->outline);
-       sprint_tag(g->format, tag);
-       printf("glyph: %p \n", g);
-       printf("format: %s \n", tag);
-       printf("outline: %p \n", o);
-       printf("contours: %d, points: %d, points ptr: %p \n", o->n_contours, o->n_points, o->points);
-       for (i = 0; i < o->n_points; ++i) {
-               printf("  point %f, %f \n", d6_to_double(o->points[i].x), d6_to_double(o->points[i].y));
-       }
+    char tag[5];
+    int i;
+    FT_OutlineGlyph og = (FT_OutlineGlyph) g;
+    FT_Outline *o = &(og->outline);
+    sprint_tag(g->format, tag);
+    printf("glyph: %p \n", g);
+    printf("format: %s \n", tag);
+    printf("outline: %p \n", o);
+    printf("contours: %d, points: %d, points ptr: %p \n", o->n_contours,
+           o->n_points, o->points);
+    for (i = 0; i < o->n_points; ++i) {
+        printf("  point %f, %f \n", d6_to_double(o->points[i].x),
+               d6_to_double(o->points[i].y));
+    }
 }
 #endif
index 8c5f3e8f49a1cee3f446c050b415cee4a9a36f9e..54c8fe0e2979eba8238b954cb664189ef313398f 100644 (file)
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
  *
 
 #include <stdint.h>
 
-int mystrtoi(char** p, int* res);
-int mystrtoll(char** p, long long* res);
-int mystrtou32(char** p, int base, uint32_t* res);
-int mystrtod(char** p, double* res);
-int strtocolor(char** q, uint32_t* res);
-char parse_bool(charstr);
+int mystrtoi(char **p, int *res);
+int mystrtoll(char **p, long long *res);
+int mystrtou32(char **p, int base, uint32_t *res);
+int mystrtod(char **p, double *res);
+int strtocolor(char **q, uint32_t *res);
+char parse_bool(char *str);
 
-static inline int d6_to_int(int x) {
-       return (x + 32) >> 6;
+static inline int d6_to_int(int x)
+{
+    return (x + 32) >> 6;
 }
-static inline int d16_to_int(int x) {
-       return (x + 32768) >> 16;
+static inline int d16_to_int(int x)
+{
+    return (x + 32768) >> 16;
 }
-static inline int int_to_d6(int x) {
-       return x << 6;
+static inline int int_to_d6(int x)
+{
+    return x << 6;
 }
-static inline int int_to_d16(int x) {
-       return x << 16;
+static inline int int_to_d16(int x)
+{
+    return x << 16;
 }
-static inline int d16_to_d6(int x) {
-       return (x + 512) >> 10;
+static inline int d16_to_d6(int x)
+{
+    return (x + 512) >> 10;
 }
-static inline int d6_to_d16(int x) {
-       return x << 10;
+static inline int d6_to_d16(int x)
+{
+    return x << 10;
 }
-static inline double d6_to_double(int x) {
-       return x / 64.;
+static inline double d6_to_double(int x)
+{
+    return x / 64.;
 }
-static inline int double_to_d6(double x) {
-       return (int)(x * 64);
+static inline int double_to_d6(double x)
+{
+    return (int) (x * 64);
 }
-static inline double d16_to_double(int x) {
-       return ((double)x) / 0x10000;
+static inline double d16_to_double(int x)
+{
+    return ((double) x) / 0x10000;
 }
-static inline int double_to_d16(double x) {
-       return (int)(x * 0x10000);
+static inline int double_to_d16(double x)
+{
+    return (int) (x * 0x10000);
 }
 
-#endif /* LIBASS_UTILS_H */
+#endif                          /* LIBASS_UTILS_H */
index d926ffcf7d8c1692611b07b8d2c9506f6f430610..4e235f4c33790464e4d5f85b20aa3c7c1deea77c 100644 (file)
@@ -53,4 +53,3 @@
 #define MSGTR_LIBASS_NoCharmaps "[ass] font face with no charmaps\n"
 #define MSGTR_LIBASS_NoCharmapAutodetected "[ass] no charmap autodetected, trying the first one\n"
 #endif
-
index 085317810f4622e119babfc3ff16121ddbbf3f9d..a4a5a9f1a9f1b58de540ce9134fdcd481d375b30 100644 (file)
 #include <enca.h>
 #endif
 
-void my_mp_msg(int lvl, char *lvl_str, char *fmt, ...) {
-       va_list va;
-       if(lvl > MSGL_INFO) return;
-       va_start(va, fmt);
-       vprintf(fmt, va);
-       va_end(va);
+void my_mp_msg(int lvl, char *lvl_str, char *fmt, ...)
+{
+    va_list va;
+    if (lvl > MSGL_INFO)
+        return;
+    va_start(va, fmt);
+    vprintf(fmt, va);
+    va_end(va);
 }
 
-unsigned utf8_get_char(char **str) {
-  uint8_t *strp = (uint8_t *)*str;
-  unsigned c = *strp++;
-  unsigned mask = 0x80;
-  int len = -1;
-  while (c & mask) {
-    mask >>= 1;
-    len++;
-  }
-  if (len <= 0 || len > 4)
-    goto no_utf8;
-  c &= mask - 1;
-  while ((*strp & 0xc0) == 0x80) {
-    if (len-- <= 0)
-      goto no_utf8;
-    c = (c << 6) | (*strp++ & 0x3f);
-  }
-  if (len)
-    goto no_utf8;
-  *str = (char *)strp;
-  return c;
-
-no_utf8:
-  strp = (uint8_t *)*str;
-  c = *strp++;
-  *str = (char *)strp;
-  return c;
+unsigned utf8_get_char(char **str)
+{
+    uint8_t *strp = (uint8_t *) * str;
+    unsigned c = *strp++;
+    unsigned mask = 0x80;
+    int len = -1;
+    while (c & mask) {
+        mask >>= 1;
+        len++;
+    }
+    if (len <= 0 || len > 4)
+        goto no_utf8;
+    c &= mask - 1;
+    while ((*strp & 0xc0) == 0x80) {
+        if (len-- <= 0)
+            goto no_utf8;
+        c = (c << 6) | (*strp++ & 0x3f);
+    }
+    if (len)
+        goto no_utf8;
+    *str = (char *) strp;
+    return c;
+
+  no_utf8:
+    strp = (uint8_t *) * str;
+    c = *strp++;
+    *str = (char *) strp;
+    return c;
 }
 
 // gaussian blur
-void blur(
-       unsigned char *buffer,
-       unsigned short *tmp2,
-       int width,
-       int height,
-       int stride,
-       int *m2,
-       int r,
-       int mwidth) {
+void blur(unsigned char *buffer,
+          unsigned short *tmp2,
+          int width, int height, int stride, int *m2, int r, int mwidth)
+{
 
     int x, y;
 
-    unsigned char  *s = buffer;
-    unsigned short *t = tmp2+1;
-    for(y=0; y<height; y++){
-       memset(t-1, 0, (width+1)*sizeof(short));
-
-       for(x=0; x<r; x++){
-           const int src= s[x];
-           if(src){
-               register unsigned short *dstp= t + x-r;
-               int mx;
-               unsigned *m3= m2 + src*mwidth;
-               for(mx=r-x; mx<mwidth; mx++){
-                   dstp[mx]+= m3[mx];
-               }
-           }
-       }
-
-       for(; x<width-r; x++){
-           const int src= s[x];
-           if(src){
-               register unsigned short *dstp= t + x-r;
-               int mx;
-               unsigned *m3= m2 + src*mwidth;
-               for(mx=0; mx<mwidth; mx++){
-                   dstp[mx]+= m3[mx];
-               }
-           }
-       }
-
-       for(; x<width; x++){
-           const int src= s[x];
-           if(src){
-               register unsigned short *dstp= t + x-r;
-               int mx;
-               const int x2= r+width -x;
-               unsigned *m3= m2 + src*mwidth;
-               for(mx=0; mx<x2; mx++){
-                   dstp[mx]+= m3[mx];
-               }
-           }
-       }
-
-       s+= stride;
-       t+= width + 1;
+    unsigned char *s = buffer;
+    unsigned short *t = tmp2 + 1;
+    for (y = 0; y < height; y++) {
+        memset(t - 1, 0, (width + 1) * sizeof(short));
+
+        for (x = 0; x < r; x++) {
+            const int src = s[x];
+            if (src) {
+                register unsigned short *dstp = t + x - r;
+                int mx;
+                unsigned *m3 = m2 + src * mwidth;
+                for (mx = r - x; mx < mwidth; mx++) {
+                    dstp[mx] += m3[mx];
+                }
+            }
+        }
+
+        for (; x < width - r; x++) {
+            const int src = s[x];
+            if (src) {
+                register unsigned short *dstp = t + x - r;
+                int mx;
+                unsigned *m3 = m2 + src * mwidth;
+                for (mx = 0; mx < mwidth; mx++) {
+                    dstp[mx] += m3[mx];
+                }
+            }
+        }
+
+        for (; x < width; x++) {
+            const int src = s[x];
+            if (src) {
+                register unsigned short *dstp = t + x - r;
+                int mx;
+                const int x2 = r + width - x;
+                unsigned *m3 = m2 + src * mwidth;
+                for (mx = 0; mx < x2; mx++) {
+                    dstp[mx] += m3[mx];
+                }
+            }
+        }
+
+        s += stride;
+        t += width + 1;
     }
 
     t = tmp2;
-    for(x=0; x<width; x++){
-       for(y=0; y<r; y++){
-           unsigned short *srcp= t + y*(width+1) + 1;
-           int src= *srcp;
-           if(src){
-               register unsigned short *dstp= srcp - 1 + width+1;
-               const int src2= (src + 128)>>8;
-               unsigned *m3= m2 + src2*mwidth;
-
-               int mx;
-               *srcp= 128;
-               for(mx=r-1; mx<mwidth; mx++){
-                   *dstp += m3[mx];
-                   dstp+= width+1;
-               }
-           }
-       }
-       for(; y<height-r; y++){
-           unsigned short *srcp= t + y*(width+1) + 1;
-           int src= *srcp;
-           if(src){
-               register unsigned short *dstp= srcp - 1 - r*(width+1);
-               const int src2= (src + 128)>>8;
-               unsigned *m3= m2 + src2*mwidth;
-
-               int mx;
-               *srcp= 128;
-               for(mx=0; mx<mwidth; mx++){
-                   *dstp += m3[mx];
-                   dstp+= width+1;
-               }
-           }
-       }
-       for(; y<height; y++){
-           unsigned short *srcp= t + y*(width+1) + 1;
-           int src= *srcp;
-           if(src){
-               const int y2=r+height-y;
-               register unsigned short *dstp= srcp - 1 - r*(width+1);
-               const int src2= (src + 128)>>8;
-               unsigned *m3= m2 + src2*mwidth;
-
-               int mx;
-               *srcp= 128;
-               for(mx=0; mx<y2; mx++){
-                   *dstp += m3[mx];
-                   dstp+= width+1;
-               }
-           }
-       }
-       t++;
+    for (x = 0; x < width; x++) {
+        for (y = 0; y < r; y++) {
+            unsigned short *srcp = t + y * (width + 1) + 1;
+            int src = *srcp;
+            if (src) {
+                register unsigned short *dstp = srcp - 1 + width + 1;
+                const int src2 = (src + 128) >> 8;
+                unsigned *m3 = m2 + src2 * mwidth;
+
+                int mx;
+                *srcp = 128;
+                for (mx = r - 1; mx < mwidth; mx++) {
+                    *dstp += m3[mx];
+                    dstp += width + 1;
+                }
+            }
+        }
+        for (; y < height - r; y++) {
+            unsigned short *srcp = t + y * (width + 1) + 1;
+            int src = *srcp;
+            if (src) {
+                register unsigned short *dstp = srcp - 1 - r * (width + 1);
+                const int src2 = (src + 128) >> 8;
+                unsigned *m3 = m2 + src2 * mwidth;
+
+                int mx;
+                *srcp = 128;
+                for (mx = 0; mx < mwidth; mx++) {
+                    *dstp += m3[mx];
+                    dstp += width + 1;
+                }
+            }
+        }
+        for (; y < height; y++) {
+            unsigned short *srcp = t + y * (width + 1) + 1;
+            int src = *srcp;
+            if (src) {
+                const int y2 = r + height - y;
+                register unsigned short *dstp = srcp - 1 - r * (width + 1);
+                const int src2 = (src + 128) >> 8;
+                unsigned *m3 = m2 + src2 * mwidth;
+
+                int mx;
+                *srcp = 128;
+                for (mx = 0; mx < y2; mx++) {
+                    *dstp += m3[mx];
+                    dstp += width + 1;
+                }
+            }
+        }
+        t++;
     }
 
     t = tmp2;
     s = buffer;
-    for(y=0; y<height; y++){
-       for(x=0; x<width; x++){
-           s[x]= t[x]>>8;
-       }
-       s+= stride;
-       t+= width + 1;
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++) {
+            s[x] = t[x] >> 8;
+        }
+        s += stride;
+        t += width + 1;
     }
 }
 
 #ifdef CONFIG_ENCA
-void* guess_buffer_cp(unsigned char* buffer, int buflen, char *preferred_language, char *fallback)
+void *guess_buffer_cp(unsigned char *buffer, int buflen,
+                      char *preferred_language, char *fallback)
 {
     const char **languages;
     size_t langcnt;
@@ -187,29 +186,31 @@ void* guess_buffer_cp(unsigned char* buffer, int buflen, char *preferred_languag
     languages = enca_get_languages(&langcnt);
     mp_msg(MSGT_ASS, MSGL_V, "ENCA supported languages: ");
     for (i = 0; i < langcnt; i++) {
-       mp_msg(MSGT_ASS, MSGL_V, "%s ", languages[i]);
+        mp_msg(MSGT_ASS, MSGL_V, "%s ", languages[i]);
     }
     mp_msg(MSGT_ASS, MSGL_V, "\n");
-    
+
     for (i = 0; i < langcnt; i++) {
-       const char *tmp;
-       
-       if (strcasecmp(languages[i], preferred_language) != 0) continue;
-       analyser = enca_analyser_alloc(languages[i]);
-       encoding = enca_analyse_const(analyser, buffer, buflen);
-       tmp = enca_charset_name(encoding.charset, ENCA_NAME_STYLE_ICONV);
-       if (tmp && encoding.charset != ENCA_CS_UNKNOWN) {
-           detected_sub_cp = strdup(tmp);
-           mp_msg(MSGT_ASS, MSGL_INFO, "ENCA detected charset: %s\n", tmp);
-       }
-       enca_analyser_free(analyser);
+        const char *tmp;
+
+        if (strcasecmp(languages[i], preferred_language) != 0)
+            continue;
+        analyser = enca_analyser_alloc(languages[i]);
+        encoding = enca_analyse_const(analyser, buffer, buflen);
+        tmp = enca_charset_name(encoding.charset, ENCA_NAME_STYLE_ICONV);
+        if (tmp && encoding.charset != ENCA_CS_UNKNOWN) {
+            detected_sub_cp = strdup(tmp);
+            mp_msg(MSGT_ASS, MSGL_INFO, "ENCA detected charset: %s\n", tmp);
+        }
+        enca_analyser_free(analyser);
     }
-    
+
     free(languages);
 
     if (!detected_sub_cp) {
-       detected_sub_cp = strdup(fallback);
-       mp_msg(MSGT_ASS, MSGL_INFO, "ENCA detection failed: fallback to %s\n", fallback);
+        detected_sub_cp = strdup(fallback);
+        mp_msg(MSGT_ASS, MSGL_INFO,
+               "ENCA detection failed: fallback to %s\n", fallback);
     }
 
     return detected_sub_cp;
index 6f0e33217ab37236ddb1204c5e40d276d07d8325..a68f8a4b7d40ce69f2e712853b3c82c40787e5e2 100644 (file)
@@ -8,8 +8,9 @@ unsigned utf8_get_char(char **str);
 void my_mp_msg(int lvl, char *lvl_str, char *fmt, ...);
 
 #ifdef __VISUALC__
-static void mp_msg(int mod, int level, const char *fmt, ...) {
-       // MSVC doesn't like the # used all around for mp_msg, so it breaks va_arg
+static void mp_msg(int mod, int level, const char *fmt, ...)
+{
+    // MSVC doesn't like the # used all around for mp_msg, so it breaks va_arg
 }
 #else
 #define mp_msg(mod, level, args...) my_mp_msg(level, #level, args)
@@ -24,10 +25,11 @@ static void mp_msg(int mod, int level, const char *fmt, ...) {
 #define MSGL_V 6
 #define MSGL_DBG2 7
 
-void blur(unsigned char *buffer, unsigned short *tmp2, int width, int height,
-          int stride, int *m2, int r, int mwidth);
+void blur(unsigned char *buffer, unsigned short *tmp2, int width,
+          int height, int stride, int *m2, int r, int mwidth);
 
-void* guess_buffer_cp(unsigned char* buffer, int buflen, char *preferred_language, char *fallback);
+void *guess_buffer_cp(unsigned char *buffer, int buflen,
+                      char *preferred_language, char *fallback);
 
 #define FFMAX(a,b) ((a) > (b) ? (a) : (b))
 #define FFMIN(a,b) ((a) > (b) ? (b) : (a))