unsigned int get_line_encoded(struct encoder_ctx *ctx, unsigned char *buffer, int line_num, struct eia608_screen *data)
{
	unsigned char *orig = buffer; // Keep for debugging
	unsigned char *line = data->characters[line_num];
	for (int i = 0; i < 33; i++)
	{
		int bytes = 0;
		switch (ctx->encoding)
		{
		case CCX_ENC_UTF_8:
			bytes = get_char_in_utf_8(buffer, line[i]);
			break;
		case CCX_ENC_LATIN_1:
			get_char_in_latin_1(buffer, line[i]);
			bytes = 1;
			break;
		case CCX_ENC_UNICODE:
			get_char_in_unicode(buffer, line[i]);
			bytes = 2;
		case CCX_ENC_ASCII:
		    *buffer = line[i];
			bytes = 1;
			break;
		}
		buffer += bytes;
	}
	return (unsigned int)(buffer - orig); // Return length
}
int change_ascii_encoding(unsigned char* dest, unsigned char* src, int len, enum ccx_encoding_type out_enc)
{
	unsigned char *orig = dest; // Keep for calculating length
	int bytes = 0;
	for (int i = 0; i < len; i++)
	{
		char c = src[i];
		switch (out_enc)
		{
		case CCX_ENC_UTF_8:
			bytes = get_char_in_utf_8(dest, c);
			break;
		case CCX_ENC_LATIN_1:
			get_char_in_latin_1(dest, c);
			bytes = 1;
			break;
		case CCX_ENC_UNICODE:
			get_char_in_unicode(dest, c);
			bytes = 2;
			break;
		case CCX_ENC_ASCII:
			memcpy(dest, src, len);
			return len;
		default:
			return CCX_ENOSUPP;
		}
		dest += bytes;
	}
	*dest = 0;
	return (dest - orig); // Return length
}
void draw_row(struct eia608_screen* data, int row, uint8_t * canvas, int rowstride)
{
	int column;
	int unicode = 0;
	uint8_t pen[2];
	uint8_t* cell;
	int first = -1;
	int last = 0;

	pen[0] = COL_BLACK;

	for (column = 0; column < COLUMNS ; column++) {

		if (COL_TRANSPARENT != data->colors[row][column])
		{
			cell = canvas + ((column+1) * CCW);
			get_char_in_unicode((unsigned char*)&unicode, data->characters[row][column]);
			pen[1] = data->colors[row][column];

			int attr = data->fonts[row][column];
			draw_char_indexed(cell, rowstride, pen, unicode, (attr & FONT_ITALICS) != 0, (attr & FONT_UNDERLINED) != 0);
			if (first < 0)
			{
				// draw a printable space before the first non-space char
				first = column;
				if (unicode != 0x20)
				{
					cell = canvas + ((first) * CCW);
					draw_char_indexed(cell, rowstride, pen, 0x20, 0, 0);
				}
			}
			last = column;
		}
	}
	// draw a printable space after the last non-space char
	// unicode should still contain the last character
	// check whether it is a space
	if (unicode != 0x20)
	{
		cell = canvas + ((last+2) * CCW);
		draw_char_indexed(cell, rowstride, pen, 0x20, 0, 0);
	}
}
unsigned get_decoder_line_basic(unsigned char *buffer, int line_num, struct eia608_screen *data, int trim_subs, enum ccx_encoding_type encoding)
{
	unsigned char *line = data->characters[line_num];
	int last_non_blank = -1;
	int first_non_blank = -1;
	unsigned char *orig = buffer; // Keep for debugging
	find_limit_characters(line, &first_non_blank, &last_non_blank);
	if (!trim_subs)
		first_non_blank = 0;

	if (first_non_blank == -1)
	{
		*buffer = 0;
		return 0;
	}

	int bytes = 0;
	for (int i = first_non_blank; i <= last_non_blank; i++)
	{
		char c = line[i];
		switch (encoding)
		{
		case CCX_ENC_UTF_8:
			bytes = get_char_in_utf_8(buffer, c);
			break;
		case CCX_ENC_LATIN_1:
			get_char_in_latin_1(buffer, c);
			bytes = 1;
			break;
		case CCX_ENC_UNICODE:
			get_char_in_unicode(buffer, c);
			bytes = 2;
			break;
		}
		buffer += bytes;
	}
	*buffer = 0;
	return (unsigned)(buffer - orig); // Return length
}
unsigned get_decoder_line_encoded(unsigned char *buffer, int line_num, struct eia608_screen *data)
{
	int col = COL_WHITE;
	int underlined = 0;
	int italics = 0;
	int changed_font = 0;
	char tagstack[128] = ""; // Keep track of opening/closing tags

	unsigned char *line = data->characters[line_num];
	unsigned char *orig = buffer; // Keep for debugging
	int first = 0, last = 31;
	if (ccx_encoders_helpers_settings.trim_subs)
		find_limit_characters(line, &first, &last);
	for (int i = first; i <= last; i++)
	{
		// Handle color
		int its_col = data->colors[line_num][i];
		if (its_col != col  && !ccx_encoders_helpers_settings.no_font_color &&
			!(col == COL_USERDEFINED && its_col == COL_WHITE)) // Don't replace user defined with white
		{
			if (changed_font)
				buffer = close_tag(buffer, tagstack, 'F', &underlined, &italics, &changed_font);
			// Add new font tag
			buffer += encode_line(buffer, (unsigned char*)color_text[its_col][1]);
			if (its_col == COL_USERDEFINED)
			{
				// The previous sentence doesn't copy the whole
				// <font> tag, just up to the quote before the color
				buffer += encode_line(buffer, (unsigned char*)usercolor_rgb);
				buffer += encode_line(buffer, (unsigned char*) "\">");
			}
			if (color_text[its_col][1][0]) // That means a <font> was added to the buffer
			{
				strcat(tagstack, "F");
				changed_font++;
			}
			col = its_col;
		}
		// Handle underlined
		int is_underlined = data->fonts[line_num][i] & FONT_UNDERLINED;
		if (is_underlined && underlined == 0 && !ccx_encoders_helpers_settings.no_type_setting) // Open underline
		{
			buffer += encode_line(buffer, (unsigned char *) "<u>");
			strcat(tagstack, "U");
			underlined++;
		}
		if (is_underlined == 0 && underlined && !ccx_encoders_helpers_settings.no_type_setting) // Close underline
		{
			buffer = close_tag(buffer, tagstack, 'U', &underlined, &italics, &changed_font);
		}
		// Handle italics
		int has_ita = data->fonts[line_num][i] & FONT_ITALICS;
		if (has_ita && italics == 0 && !ccx_encoders_helpers_settings.no_type_setting) // Open italics
		{
			buffer += encode_line(buffer, (unsigned char *) "<i>");
			strcat(tagstack, "I");
			italics++;
		}
		if (has_ita == 0 && italics && !ccx_encoders_helpers_settings.no_type_setting) // Close italics
		{
			buffer = close_tag(buffer, tagstack, 'I', &underlined, &italics, &changed_font);
		}
		int bytes = 0;
		switch (ccx_encoders_helpers_settings.encoding)
		{
		case CCX_ENC_UTF_8:
			bytes = get_char_in_utf_8(buffer, line[i]);
			break;
		case CCX_ENC_LATIN_1:
			get_char_in_latin_1(buffer, line[i]);
			bytes = 1;
			break;
		case CCX_ENC_UNICODE:
			get_char_in_unicode(buffer, line[i]);
			bytes = 2;
			break;
		}
		buffer += bytes;
	}
	buffer = close_tag(buffer, tagstack, 'A', &underlined, &italics, &changed_font);
	if (underlined || italics || changed_font)
		ccx_common_logging.fatal_ftn(CCX_COMMON_EXIT_BUG_BUG, "Not all tags closed in encoding, this is a bug, please report.\n");
	*buffer = 0;
	return (unsigned)(buffer - orig); // Return length
}