Ticket #2076: libass-de409235f4a3.patch

File libass-de409235f4a3.patch, 14.4 KB (added by subjunk@…, 14 years ago)

Patch

  • ass.c

     
    191191    style->MarginL = style->MarginR = style->MarginV = 20;
    192192}
    193193
    194 /**
    195  * \brief find style by name
    196  * \param track track
    197  * \param name style name
    198  * \return index in track->styles
    199  * Returnes 0 if no styles found => expects at least 1 style.
    200  * Parsing code always adds "Default" style in the end.
    201  */
    202 static int lookup_style(ASS_Track *track, char *name)
    203 {
    204     int i;
    205     if (*name == '*')
    206         ++name;                 // FIXME: what does '*' really mean ?
    207     for (i = track->n_styles - 1; i >= 0; --i) {
    208         if (strcmp(track->styles[i].Name, name) == 0)
    209             return i;
    210     }
    211     i = track->default_style;
    212     ass_msg(track->library, MSGL_WARN,
    213             "[%p]: Warning: no style named '%s' found, using '%s'",
    214             track, name, track->styles[i].Name);
    215     return i;                   // use the first style
    216 }
    217 
    218194static uint32_t string2color(ASS_Library *library, char *p)
    219195{
    220196    uint32_t tmp;
  • ass_parse.c

     
    105105}
    106106
    107107/**
    108  * \brief Change border width
    109  * negative value resets border to style value
     108 * \brief Calculate valid border size. Makes sure the border sizes make sense.
     109 *
     110 * \param priv renderer state object
     111 * \param border_x requested x border size
     112 * \param border_y requested y border size
    110113 */
    111 void change_border(ASS_Renderer *render_priv, double border_x,
    112                    double border_y)
     114void calc_border(ASS_Renderer *priv, double border_x, double border_y)
    113115{
    114     int bord;
    115     if (!render_priv->state.font)
    116         return;
    117 
    118116    if (border_x < 0 && border_y < 0) {
    119         if (render_priv->state.style->BorderStyle == 1 ||
    120             render_priv->state.style->BorderStyle == 3)
    121             border_x = border_y = render_priv->state.style->Outline;
     117        if (priv->state.style->BorderStyle == 1 ||
     118            priv->state.style->BorderStyle == 3)
     119            border_x = border_y = priv->state.style->Outline;
    122120        else
    123121            border_x = border_y = 1.;
    124122    }
    125123
    126     render_priv->state.border_x = border_x;
    127     render_priv->state.border_y = border_y;
     124    priv->state.border_x = border_x;
     125    priv->state.border_y = border_y;
     126}
    128127
    129     bord = 64 * border_x * render_priv->border_scale;
     128/**
     129 * \brief Change border width
     130 *
     131 * \param render_priv renderer state object
     132 * \param info glyph state object
     133 */
     134void change_border(ASS_Renderer *render_priv, double border_x, double border_y)
     135{
     136    int bord = 64 * border_x * render_priv->border_scale;
    130137    if (bord > 0 && border_x == border_y) {
    131138        if (!render_priv->state.stroker) {
    132139            int error;
     
    138145                        "failed to get stroker");
    139146                render_priv->state.stroker = 0;
    140147            }
    141         }
    142         if (render_priv->state.stroker)
     148            render_priv->state.stroker_radius = -1.0;
     149        }
     150        if (render_priv->state.stroker && render_priv->state.stroker_radius != bord) {
    143151            FT_Stroker_Set(render_priv->state.stroker, bord,
    144152                           FT_STROKER_LINECAP_ROUND,
    145153                           FT_STROKER_LINEJOIN_ROUND, 0);
     154            render_priv->state.stroker_radius = bord;
     155        }
    146156    } else {
    147157        FT_Stroker_Done(render_priv->state.stroker);
    148158        render_priv->state.stroker = 0;
     
    256266            val = render_priv->state.border_x * (1 - pwr) + val * pwr;
    257267        else
    258268            val = -1.;
    259         change_border(render_priv, val, render_priv->state.border_y);
     269        calc_border(render_priv, val, render_priv->state.border_y);
    260270        render_priv->state.bm_run_id++;
    261271    } else if (mystrcmp(&p, "ybord")) {
    262272        double val;
     
    264274            val = render_priv->state.border_y * (1 - pwr) + val * pwr;
    265275        else
    266276            val = -1.;
    267         change_border(render_priv, render_priv->state.border_x, val);
     277        calc_border(render_priv, render_priv->state.border_x, val);
     278        render_priv->state.bm_run_id++;
    268279    } else if (mystrcmp(&p, "xshad")) {
    269280        double val;
    270281        if (mystrtod(&p, &val))
     
    388399    } else if (mystrcmp(&p, "bord")) {
    389400        double val;
    390401        if (mystrtod(&p, &val)) {
    391             if (render_priv->state.border_x == render_priv->state.border_y)
    392402                val = render_priv->state.border_x * (1 - pwr) + val * pwr;
    393403        } else
    394404            val = -1.;          // reset to default
    395         change_border(render_priv, val, val);
     405        calc_border(render_priv, val, val);
    396406        render_priv->state.bm_run_id++;
    397407    } else if (mystrcmp(&p, "move")) {
    398408        double x1, x2, y1, y2;
     
    730740        ass_msg(render_priv->library, MSGL_DBG2, "single c/a at %f: %c%c = %X",
    731741               pwr, n, cmd, render_priv->state.c[cidx]);
    732742    } else if (mystrcmp(&p, "r")) {
    733         reset_render_context(render_priv);
     743        char *start = p;
     744        char *style;
     745        skip_to('\\');
     746        if (p > start) {
     747            style = malloc(p - start + 1);
     748            strncpy(style, start, p - start);
     749            style[p - start] = '\0';
     750            reset_render_context(render_priv,
     751                    render_priv->track->styles + lookup_style(render_priv->track, style));
     752            free(style);
     753        } else
     754            reset_render_context(render_priv, NULL);
    734755    } else if (mystrcmp(&p, "be")) {
    735756        int val;
    736757        if (mystrtoi(&p, &val)) {
  • ass_parse.h

     
    2828
    2929void update_font(ASS_Renderer *render_priv);
    3030double ensure_font_size(ASS_Renderer *priv, double size);
     31void calc_border(ASS_Renderer *priv, double border_x, double border_y);
    3132void change_border(ASS_Renderer *render_priv, double border_x,
    3233                   double border_y);
    3334void apply_transition_effects(ASS_Renderer *render_priv, ASS_Event *event);
  • ass_render.c

     
    841841 * \brief partially reset render_context to style values
    842842 * Works like {\r}: resets some style overrides
    843843 */
    844 void reset_render_context(ASS_Renderer *render_priv)
     844void reset_render_context(ASS_Renderer *render_priv, ASS_Style *style)
    845845{
    846     render_priv->state.c[0] = render_priv->state.style->PrimaryColour;
    847     render_priv->state.c[1] = render_priv->state.style->SecondaryColour;
    848     render_priv->state.c[2] = render_priv->state.style->OutlineColour;
    849     render_priv->state.c[3] = render_priv->state.style->BackColour;
     846    if (!style)
     847        style = render_priv->state.style;
     848
     849    render_priv->state.c[0] = style->PrimaryColour;
     850    render_priv->state.c[1] = style->SecondaryColour;
     851    render_priv->state.c[2] = style->OutlineColour;
     852    render_priv->state.c[3] = style->BackColour;
    850853    render_priv->state.flags =
    851         (render_priv->state.style->Underline ? DECO_UNDERLINE : 0) |
    852         (render_priv->state.style->StrikeOut ? DECO_STRIKETHROUGH : 0);
    853     render_priv->state.font_size = render_priv->state.style->FontSize;
     854        (style->Underline ? DECO_UNDERLINE : 0) |
     855        (style->StrikeOut ? DECO_STRIKETHROUGH : 0);
     856    render_priv->state.font_size = style->FontSize;
    854857
    855858    free(render_priv->state.family);
    856859    render_priv->state.family = NULL;
    857     render_priv->state.family = strdup(render_priv->state.style->FontName);
     860    render_priv->state.family = strdup(style->FontName);
    858861    render_priv->state.treat_family_as_pattern =
    859         render_priv->state.style->treat_fontname_as_pattern;
    860     render_priv->state.bold = render_priv->state.style->Bold;
    861     render_priv->state.italic = render_priv->state.style->Italic;
     862        style->treat_fontname_as_pattern;
     863    render_priv->state.bold = style->Bold;
     864    render_priv->state.italic = style->Italic;
    862865    update_font(render_priv);
    863866
    864     change_border(render_priv, -1., -1.);
    865     render_priv->state.scale_x = render_priv->state.style->ScaleX;
    866     render_priv->state.scale_y = render_priv->state.style->ScaleY;
    867     render_priv->state.hspacing = render_priv->state.style->Spacing;
     867    calc_border(render_priv, style->Outline, style->Outline);
     868    change_border(render_priv, render_priv->state.border_x, render_priv->state.border_y);
     869    render_priv->state.scale_x = style->ScaleX;
     870    render_priv->state.scale_y = style->ScaleY;
     871    render_priv->state.hspacing = style->Spacing;
    868872    render_priv->state.be = 0;
    869873    render_priv->state.blur = 0.0;
    870     render_priv->state.shadow_x = render_priv->state.style->Shadow;
    871     render_priv->state.shadow_y = render_priv->state.style->Shadow;
     874    render_priv->state.shadow_x = style->Shadow;
     875    render_priv->state.shadow_y = style->Shadow;
    872876    render_priv->state.frx = render_priv->state.fry = 0.;
    873     render_priv->state.frz = M_PI * render_priv->state.style->Angle / 180.;
     877    render_priv->state.frz = M_PI * style->Angle / 180.;
    874878    render_priv->state.fax = render_priv->state.fay = 0.;
    875879    render_priv->state.wrap_style = render_priv->track->WrapStyle;
    876     render_priv->state.font_encoding = render_priv->state.style->Encoding;
     880    render_priv->state.font_encoding = style->Encoding;
    877881}
    878882
    879883/**
     
    886890    render_priv->state.style = render_priv->track->styles + event->Style;
    887891    render_priv->state.parsed_tags = 0;
    888892
    889     reset_render_context(render_priv);
     893    reset_render_context(render_priv, render_priv->state.style);
    890894
    891895    render_priv->state.evt_type = EVENT_NORMAL;
    892896    render_priv->state.alignment = render_priv->state.style->Alignment;
     
    11411145        } else if ((info->border_x > 0 || info->border_y > 0)
    11421146                && double_to_d6(info->scale_x) && double_to_d6(info->scale_y)) {
    11431147
    1144             outline_copy(priv->ftlibrary, v.outline, &v.border);
     1148            change_border(priv, info->border_x, info->border_y);
     1149            outline_copy(priv->ftlibrary, v.outline, &v.border);
    11451150            stroke_outline(priv, v.border,
    11461151                    double_to_d6(info->border_x * priv->border_scale),
    11471152                    double_to_d6(info->border_y * priv->border_scale));
     
    17721777        glyphs[text_info->length].scale_y = render_priv->state.scale_y;
    17731778        glyphs[text_info->length].border_x= render_priv->state.border_x;
    17741779        glyphs[text_info->length].border_y = render_priv->state.border_y;
     1780        glyphs[text_info->length].hspacing = render_priv->state.hspacing;
    17751781        glyphs[text_info->length].bold = render_priv->state.bold;
    17761782        glyphs[text_info->length].italic = render_priv->state.italic;
    17771783        glyphs[text_info->length].flags = render_priv->state.flags;
     
    18291835        }
    18301836
    18311837        // add horizontal letter spacing
    1832         info->cluster_advance.x += double_to_d6(render_priv->state.hspacing *
     1838        info->cluster_advance.x += double_to_d6(info->hspacing *
    18331839                render_priv->font_scale * info->scale_x);
    18341840
    18351841        // add displacement for vertical shearing
  • ass_render.h

     
    134134    double fax, fay;            // text shearing
    135135    double scale_x, scale_y;
    136136    double border_x, border_y;
     137    double hspacing;
    137138    unsigned italic;
    138139    unsigned bold;
    139140    int flags;
     
    174175    int flags;                  // decoration flags (underline/strike-through)
    175176
    176177    FT_Stroker stroker;
     178    int stroker_radius;         // last stroker radius, for caching stroker objects
    177179    int alignment;              // alignment overrides go here; if zero, style value will be used
    178180    double frx, fry, frz;
    179181    double fax, fay;            // text shearing
     
    289291    int ha, hb;                 // left and width
    290292} Segment;
    291293
    292 void reset_render_context(ASS_Renderer *render_priv);
     294void reset_render_context(ASS_Renderer *render_priv, ASS_Style *style);
    293295void ass_free_images(ASS_Image *img);
    294296
    295297// XXX: this is actually in ass.c, includes should be fixed later on
  • ass_shaper.c

     
    655655        // Skip direction override control characters
    656656        // NOTE: Behdad said HarfBuzz is supposed to remove these, but this hasn't
    657657        // been implemented yet
    658         if (glyphs[i].symbol <= 0x202F && glyphs[i].symbol >= 0x202a) {
     658        if ((glyphs[i].symbol <= 0x202e && glyphs[i].symbol >= 0x202a)
     659                || (glyphs[i].symbol <= 0x200f && glyphs[i].symbol >= 0x200c)) {
    659660            glyphs[i].symbol = 0;
    660661            glyphs[i].skip++;
    661662        }
  • ass_utils.c

     
    160160    return c;
    161161}
    162162
     163/**
     164 * \brief find style by name
     165 * \param track track
     166 * \param name style name
     167 * \return index in track->styles
     168 * Returnes 0 if no styles found => expects at least 1 style.
     169 * Parsing code always adds "Default" style in the end.
     170 */
     171int lookup_style(ASS_Track *track, char *name)
     172{
     173    int i;
     174    if (*name == '*')
     175        ++name;                 // FIXME: what does '*' really mean ?
     176    for (i = track->n_styles - 1; i >= 0; --i) {
     177        if (strcmp(track->styles[i].Name, name) == 0)
     178            return i;
     179    }
     180    i = track->default_style;
     181    ass_msg(track->library, MSGL_WARN,
     182            "[%p]: Warning: no style named '%s' found, using '%s'",
     183            track, name, track->styles[i].Name);
     184    return i;                   // use the first style
     185}
     186
    163187#ifdef CONFIG_ENCA
    164188void *ass_guess_buffer_cp(ASS_Library *library, unsigned char *buffer,
    165189                          int buflen, char *preferred_language,
  • ass_utils.h

     
    5151char parse_bool(char *str);
    5252unsigned ass_utf8_get_char(char **str);
    5353void ass_msg(ASS_Library *priv, int lvl, char *fmt, ...);
     54int lookup_style(ASS_Track *track, char *name);
    5455#ifdef CONFIG_ENCA
    5556void *ass_guess_buffer_cp(ASS_Library *library, unsigned char *buffer,
    5657                          int buflen, char *preferred_language,