protected void paintChars(JComponent c, Graphics g, int x, int y, VtAttributes attrs, int start,
			int end) {
		char[] ch = line.getCharBuffer();
		int descent = metrics.getDescent();
		int height = metrics.getHeight();
		int left = x + start * em;
		int width = em * (end - start);
		Color bg = attrs.resolveBackground(colors);
		if (bg != null) {
			g.setColor(bg);
			g.fillRect(left, descent - height, width, height);
		}
		g.setColor(attrs.resolveForeground(colors));
		// I don't really intend to implement blinking.
		// We still use metrics from DEFAULT_FONT_ID
		Font font = Gui.getFont(switch (attrs.intensity()) {
			case NORMAL -> switch (attrs.font()) {
				case NORMAL -> TerminalPanel.DEFAULT_FONT_ID;
				case ITALIC -> TerminalPanel.DEFAULT_ITALIC_FONT_ID;
				case BLACK_LETTER -> TerminalPanel.DEFAULT_FRAKTUR_FONT_ID;
			};
			case BOLD -> switch (attrs.font()) {
				case NORMAL -> TerminalPanel.BRIGHT_FONT_ID;
				case ITALIC -> TerminalPanel.BRIGHT_ITALIC_FONT_ID;
				case BLACK_LETTER -> TerminalPanel.BRIGHT_FRAKTUR_FONT_ID;
			};
			case DIM -> switch (attrs.font()) {
				case NORMAL -> TerminalPanel.DIM_FONT_ID;
				case ITALIC -> TerminalPanel.DIM_ITALIC_FONT_ID;
				case BLACK_LETTER -> TerminalPanel.DIM_FRAKTUR_FONT_ID;
			};
		});
		font = font.deriveFont(font.getSize2D() + fontSizeAdjustment);
		g.setFont(font);

		if (!attrs.hidden()) {
			switch (attrs.underline()) {
				case DOUBLE:
					g.fillRect(left, descent - UNDERLINE_HEIGHT * 3, width, UNDERLINE_HEIGHT);
					// Yes, fall through
				case SINGLE:
					g.fillRect(left, descent - UNDERLINE_HEIGHT, width, UNDERLINE_HEIGHT);
				case NONE:
			}

			for (int i = start; i < end; i++) {
				/**
				 * HACK: The default monospaced font selected by Java may not have glyphs for the
				 * box-drawing characters, so it may choose glyphs from a different font.
				 * Alternatively, the default monospaced font's box-drawing glyphs are not, in fact,
				 * monospaced. This is not acceptable. To deal with that, when we find a glyph whose
				 * width does not match, we'll scale it horizontally so that it does.
				 */
				int chW = metrics.charWidth(ch[i]);
				if (chW != em) {
					try (SaveTransform st = new SaveTransform(g)) {
						st.g.translate(x + em * i, 0);
						st.g.scale((double) em / chW, 1.0);
						st.g.drawChars(ch, i, 1, 0, 0);
					}
				}
				else {
					g.drawChars(ch, i, 1, x + em * i, 0);
				}
			}
			if (attrs.strikeThrough()) {
				g.fillRect(left, height * 2 / 3, width, UNDERLINE_HEIGHT);
			}
		}
		// TODO: What is proportionalSpacing?
	}
Get the number of columns (total width, not just the used by the line)

@return the column count
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalTextFieldElement.java