+static const char *ttml_get_display_alignment(int alignment)
+{
+ switch (alignment) {
+ case 1:
+ case 2:
+ case 3:
+ return "after";
+ case 4:
+ case 5:
+ case 6:
+ return "center";
+ case 7:
+ case 8:
+ case 9:
+ return "before";
+ default:
+ return NULL;
+ }
+}
+
+static const char *ttml_get_text_alignment(int alignment)
+{
+ switch (alignment) {
+ case 1:
+ case 4:
+ case 7:
+ return "left";
+ case 2:
+ case 5:
+ case 8:
+ return "center";
+ case 3:
+ case 6:
+ case 9:
+ return "right";
+ default:
+ return NULL;
+ }
+}
+
+static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf,
+ ASSStyle style)
+{
+ const char *display_alignment = NULL;
+ const char *text_alignment = NULL;
+
+ if (!style.name) {
+ av_log(avctx, AV_LOG_ERROR, "Subtitle style name not set!\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (style.font_size < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid font size for TTML: %d!\n",
+ style.font_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ display_alignment = ttml_get_display_alignment(style.alignment);
+ text_alignment = ttml_get_text_alignment(style.alignment);
+ if (!display_alignment || !text_alignment) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to convert ASS style alignment %d of style %s to "
+ "TTML display and text alignment!\n",
+ style.alignment,
+ style.name);
+ return AVERROR_INVALIDDATA;
+ }
+
+ av_bprintf(buf, " <region xml:id=\"");
+ av_bprint_escape(buf, style.name, NULL, AV_ESCAPE_MODE_XML,
+ AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
+ av_bprintf(buf, "\"\n");
+
+ av_bprintf(buf, " tts:displayAlign=\"");
+ av_bprint_escape(buf, display_alignment, NULL, AV_ESCAPE_MODE_XML,
+ AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
+ av_bprintf(buf, "\"\n");
+
+ av_bprintf(buf, " tts:textAlign=\"");
+ av_bprint_escape(buf, text_alignment, NULL, AV_ESCAPE_MODE_XML,
+ AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
+ av_bprintf(buf, "\"\n");
+
+ // if we set cell resolution to our script reference resolution,
+ // then a single line is a single "point" on our canvas. Thus, by setting
+ // our font size to font size in cells, we should gain a similar enough
+ // scale without resorting to explicit pixel based font sizing, which is
+ // frowned upon in the TTML community.
+ av_bprintf(buf, " tts:fontSize=\"%dc\"\n",
+ style.font_size);
+
+ if (style.font_name) {
+ av_bprintf(buf, " tts:fontFamily=\"");
+ av_bprint_escape(buf, style.font_name, NULL, AV_ESCAPE_MODE_XML,
+ AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
+ av_bprintf(buf, "\"\n");
+ }
+
+ av_bprintf(buf, " tts:overflow=\"visible\" />\n");
+
+ return 0;
+}
+