static void fill_plaintext(struct sd *sd, double pts) { struct sd_ass_priv *ctx = sd->priv; ASS_Track *track = ctx->shadow_track; ass_flush_events(track); char *text = get_text(sd, pts); if (!text) return; bstr dst = {0}; while (*text) { if (*text == '{') bstr_xappend(NULL, &dst, bstr0("\\")); bstr_xappend(NULL, &dst, (bstr){text, 1}); // Break ASS escapes with U+2060 WORD JOINER if (*text == '\\') mp_append_utf8_bstr(NULL, &dst, 0x2060); text++; } if (!dst.start || !dst.start[0]) return; int n = ass_alloc_event(track); ASS_Event *event = track->events + n; event->Start = 0; event->Duration = INT_MAX; event->Style = track->default_style; event->Text = strdup(dst.start); if (track->default_style < track->n_styles) track->styles[track->default_style].Alignment = ctx->on_top ? 6 : 2; }
static void add_indent(bstr *b, int indent) { if (indent < 0) return; bstr_xappend(NULL, b, bstr0("\n")); for (int n = 0; n < indent; n++) bstr_xappend(NULL, b, bstr0(" ")); }
static void write_arg(bstr *cmdline, char *arg) { // Empty args must be represented as an empty quoted string if (!arg[0]) { bstr_xappend(NULL, cmdline, bstr0("\"\"")); return; } // If the string doesn't have characters that need to be escaped, it's best // to leave it alone for the sake of Windows programs that don't process // quoted args correctly. if (!strpbrk(arg, " \t\"")) { bstr_xappend(NULL, cmdline, bstr0(arg)); return; } // If there are characters that need to be escaped, write a quoted string bstr_xappend(NULL, cmdline, bstr0("\"")); // Escape the argument. To match the behavior of CommandLineToArgvW, // backslashes are only escaped if they appear before a quote or the end of // the string. int num_slashes = 0; for (int pos = 0; arg[pos]; pos++) { switch (arg[pos]) { case '\\': // Count consecutive backslashes num_slashes++; break; case '"': // Write the argument up to the point before the quote bstr_xappend(NULL, cmdline, (struct bstr){arg, pos}); arg += pos; pos = 0; // Double backslashes preceding the quote for (int i = 0; i < num_slashes; i++) bstr_xappend(NULL, cmdline, bstr0("\\")); num_slashes = 0; // Escape the quote itself bstr_xappend(NULL, cmdline, bstr0("\\")); break; default: num_slashes = 0; } }
static void write_json_str(bstr *b, unsigned char *str) { APPEND(b, "\""); while (1) { unsigned char *cur = str; while (cur[0] >= 32 && cur[0] != '"' && cur[0] != '\\') cur++; if (!cur[0]) break; bstr_xappend(NULL, b, (bstr){str, cur - str}); if (cur[0] == '\"') { bstr_xappend(NULL, b, (bstr){"\\\"", 2}); } else if (cur[0] == '\\') { bstr_xappend(NULL, b, (bstr){"\\\\", 2}); } else if (cur[0] < sizeof(special_escape) && special_escape[cur[0]]) { bstr_xappend_asprintf(NULL, b, "\\%c", special_escape[cur[0]]); } else { bstr_xappend_asprintf(NULL, b, "\\u%04x", (unsigned char)cur[0]); } str = cur + 1; } APPEND(b, str); APPEND(b, "\""); }
static void write_json_str(bstr *b, char *str) { APPEND(b, "\""); while (1) { char *cur = str; while (cur[0] && cur[0] >= 32 && cur[0] != '"' && cur[0] != '\\') cur++; if (!cur[0]) break; bstr_xappend(NULL, b, (bstr){str, cur - str}); bstr_xappend_asprintf(NULL, b, "\\u%04x", (unsigned char)cur[0]); str = cur + 1; } APPEND(b, str); APPEND(b, "\""); }