libass分析8-源码分析-libass处理event中{}的逻辑

Author: wencoo
Blog:https://wencoo.blog.csdn.net/
Date: 22/03/2024
Email: jianwen056@aliyun.com
Wechat:wencoo824
QQ:1419440391
Details:

文章目录

目录

正文 或 背景

语法示例

Dialogue: 0,0:00:02.31,0:00:03.31,,Default,0,0,0,,{\fnAlibaba_PuHuiTi_2.0_75_SemiBold_75_SemiBold.ttf\fs250\an7\bord5\xshad5\yshad-5\3c&5151e4&\4c&3131ab&\fade(00,ff,00,3000,6000,7000,8000)\move(0,0,500,500,3000,8000)}测试测试

这个在最后文字前加{}内容来改变参数的逻辑在下面的函数中

parse_events

实现

// Parse event text. 解析事件文本。
// Fill render_priv->text_info. 填补render_priv - > text_info。
static bool parse_events(RenderContext *state, ASS_Event *event)
{
    TextInfo *text_info = state->text_info;
    ASS_Renderer *render_priv = state->renderer;

    char *p = event->Text, *q;

    // Event parsing. 事件解析。
    while (true) {
        ASS_StringView drawing_text = {NULL, 0};

        // get next char, executing style override 获取下一个字符,执行样式重写
        // this affects render_context 这影响render_context
        unsigned code = 0;
        while (*p) {
            if ((*p == '{') && (q = strchr(p, '}'))) {
                p = ass_parse_tags(state, p, q, 1., false);
                assert(*p == '}');
                p++;
            } else if (state->drawing_scale) {
                q = p;
                if (*p == '{')
                    q++;
                while ((*q != '{') && (*q != 0))
                    q++;
                drawing_text.str = p;
                drawing_text.len = q - p;
                code = 0xfffc; // object replacement character  对象替换字符
                p = q;
                break;
            } else {
                code = ass_get_next_char(state, &p);
                break;
            }
        }

        if (code == 0)
            break;

        // face could have been changed in get_next_char  Face可以在get_next_char中更改
        if (!state->font)
            goto fail;

        if (text_info->length >= text_info->max_glyphs) {
            // Raise maximum number of glyphs  提高字形的最大数量
            int new_max = 2 * FFMIN(FFMAX(text_info->max_glyphs, text_info->length / 2 + 1),
                                    INT_MAX / 2);
            if (text_info->length >= new_max)
                goto fail;
            if (!ASS_REALLOC_ARRAY(text_info->glyphs, new_max) ||
                    !ASS_REALLOC_ARRAY(text_info->event_text, new_max) ||
                    !ASS_REALLOC_ARRAY(text_info->breaks, new_max))
                goto fail;
            text_info->max_glyphs = new_max;
        }

        GlyphInfo *info = &text_info->glyphs[text_info->length];

        // Clear current GlyphInfo  清除当前的GlyphInfo
        memset(info, 0, sizeof(GlyphInfo));

        // Parse drawing 解析图
        if (drawing_text.str) {
            info->drawing_text = drawing_text;
            info->drawing_scale = state->drawing_scale;
            info->drawing_pbo = state->pbo;
        }

        // Fill glyph information  填写字形信息
        info->symbol = code;
        info->font = state->font;
        if (!drawing_text.str)
            ass_cache_inc_ref(info->font);
        for (int i = 0; i < 4; i++) {
            uint32_t clr = state->c[i];
            info->a_pre_fade[i] = _a(clr);
            ass_apply_fade(&clr, state->fade);
            info->c[i] = clr;
        }

        info->effect_type = state->effect_type;
        info->effect_timing = state->effect_timing;
        info->effect_skip_timing = state->effect_skip_timing;
        info->reset_effect = state->reset_effect;
        // VSFilter compatibility: font glyphs use PlayResY scaling in both dimensions  VSFilter兼容性:字体在两个维度上都使用PlayResY缩放
        info->font_size =
            fabs(state->font_size * state->screen_scale_y);
        info->be = state->be;
        info->blur = state->blur;
        info->shadow_x = state->shadow_x;
        info->shadow_y = state->shadow_y;
        info->scale_x = state->scale_x;
        info->scale_y = state->scale_y;
        info->border_style = state->border_style;
        info->border_x = state->border_x;
        info->border_y = state->border_y;
        info->hspacing = state->hspacing;
        info->bold = state->bold;
        info->italic = state->italic;
        info->flags = state->flags;
        if (info->font->desc.vertical && code >= VERTICAL_LOWER_BOUND)
            info->flags |= DECO_ROTATE;
        info->frx = state->frx;
        info->fry = state->fry;
        info->frz = state->frz;
        info->fax = state->fax;
        info->fay = state->fay;
        info->fade = state->fade;

        info->hspacing_scaled = 0;
        info->scale_fix = 1;

        if (!drawing_text.str) {
            info->hspacing_scaled = double_to_d6(info->hspacing *
                    state->screen_scale_x / render_priv->par_scale_x *
                    info->scale_x);
            fix_glyph_scaling(render_priv, info);
        }

        text_info->length++;

        state->effect_type = EF_NONE;
        state->effect_timing = 0;
        state->effect_skip_timing = 0;
        state->reset_effect = false;
    }

    return true;

fail:
    free_render_context(state);
    return false;
}

参考

  • <>

由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 wencoo824。QQ:1419440391。

技术交流

欢迎加微信,搜索"wencoo824",进行技术交流,备注"博客音视频技术交流"

音视频领域其他技术文章的链接

opengl相关文章

ffmpeg相关文章

ffmpeg原理相关文章

ffmpeg源码分析相关文章

ffmpeg指令相关文章

ffmpeg报错相关文章

c/c++相关文章

linux相关文章

后面都是一些废话,不用看,刷分的

推广一个AI学习网站

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

中国软件行业倡议书

精简软件开发,电脑性能越来越好,打出的程序安装包越来越大,磁盘,内存越吃越多,这不是好现象,大家觉得呢,欢迎发表看法,各抒己见。

作者有话说

个人简介:多年工作工程经验,擅长linux下软件开发,qt,ffmpeg音视频二次开发。

欢迎各位叨扰作者,如果有什么项目合作,创业合伙需要研发,网站推广等等,尽管来联系,对于能挣钱的事,作者可是很感兴趣的哦。

关于内卷

劝大家一句,不要内卷,内卷只能害了别人,害了自己。

相关推荐
小屁孩大帅-杨一凡1 分钟前
java后端请求想接收多个对象入参的数据
java·开发语言
java1234_小锋8 分钟前
使用 RabbitMQ 有什么好处?
java·开发语言
TangKenny21 分钟前
计算网络信号
java·算法·华为
肘击鸣的百k路22 分钟前
Java 代理模式详解
java·开发语言·代理模式
Hsu_kk27 分钟前
MySQL 批量删除海量数据的几种方法
数据库·mysql
编程学无止境28 分钟前
第02章 MySQL环境搭建
数据库·mysql
城南vision28 分钟前
Docker学习—Docker核心概念总结
java·学习·docker
wyh要好好学习35 分钟前
SpringMVC快速上手
java·spring
尢词37 分钟前
SpringMVC
java·spring·java-ee·tomcat·maven
knight-n39 分钟前
MYSQL库的操作
数据库·mysql