summary refs log tree commit diff
path: root/term.c
diff options
context:
space:
mode:
Diffstat (limited to 'term.c')
-rw-r--r--term.c130
1 files changed, 73 insertions, 57 deletions
diff --git a/term.c b/term.c
index 5d7a918..426cd7f 100644
--- a/term.c
+++ b/term.c
@@ -138,26 +138,29 @@ static char updateESC(wchar_t ch) {
 
 enum {
 	Reset,
-	Bold,
-	Italic = 3,
-	Underline,
-	Reverse = 7,
-	NotBold = 22,
-	NotItalic,
-	NotUnderline,
-	NotReverse,
-	Fg0 = 30,
-	Fg7 = 37,
-	Fg,
-	FgDefault,
-	Bg0,
-	Bg7 = 47,
-	Bg,
-	BgDefault,
-	Fg8 = 90,
-	Fg15 = 97,
-	Bg8 = 100,
-	Bg15 = 107,
+	SetBold,
+	SetDim,
+	SetItalic,
+	SetUnderline,
+	SetBlink,
+	SetReverse = 7,
+	UnsetBoldDim = 22,
+	UnsetItalic,
+	UnsetUnderline,
+	UnsetBlink,
+	UnsetReverse = 27,
+	SetFg0 = 30,
+	SetFg7 = 37,
+	SetFg,
+	ResetFg,
+	SetBg0,
+	SetBg7 = 47,
+	SetBg,
+	ResetBg,
+	SetFg8 = 90,
+	SetFg15 = 97,
+	SetBg8 = 100,
+	SetBg15 = 107,
 	Color256 = 5,
 };
 
@@ -166,39 +169,42 @@ static void updateSGR(uint ps[], uint n) {
 		switch (ps[i]) {
 			break; case Reset: style = Default;
 
-			break; case Bold:      style.bold = true;
-			break; case Italic:    style.italic = true;
-			break; case Underline: style.underline = true;
-			break; case Reverse:   style.reverse = true;
+			break; case SetBold: style.attr &= ~Dim; style.attr |= Bold;
+			break; case SetDim:  style.attr &= ~Bold; style.attr |= Dim;
+			break; case SetItalic:    style.attr |= Italic;
+			break; case SetUnderline: style.attr |= Underline;
+			break; case SetBlink:     style.attr |= Blink;
+			break; case SetReverse:   style.attr |= Reverse;
 
-			break; case NotBold:      style.bold = false;
-			break; case NotItalic:    style.italic = false;
-			break; case NotUnderline: style.underline = false;
-			break; case NotReverse:   style.reverse = false;
+			break; case UnsetBoldDim:   style.attr &= ~(Bold | Dim);
+			break; case UnsetItalic:    style.attr &= ~Italic;
+			break; case UnsetUnderline: style.attr &= ~Underline;
+			break; case UnsetBlink:     style.attr &= ~Blink;
+			break; case UnsetReverse:   style.attr &= ~Reverse;
 
-			break; case Fg: {
+			break; case SetFg: {
 				if (++i < n && ps[i] == Color256) {
 					if (++i < n) style.fg = ps[i];
 				}
 			}
-			break; case Bg: {
+			break; case SetBg: {
 				if (++i < n && ps[i] == Color256) {
 					if (++i < n) style.bg = ps[i];
 				}
 			}
 
-			break; case FgDefault: style.fg = -1;
-			break; case BgDefault: style.bg = -1;
+			break; case ResetFg: style.fg = -1;
+			break; case ResetBg: style.bg = -1;
 
 			break; default: {
-				if (ps[i] >= Fg0 && ps[i] <= Fg7) {
-					style.fg = ps[i] - Fg0;
-				} else if (ps[i] >= Bg0 && ps[i] <= Bg7) {
-					style.bg = ps[i] - Bg0;
-				} else if (ps[i] >= Fg8 && ps[i] <= Fg15) {
-					style.fg = 8 + ps[i] - Fg8;
-				} else if (ps[i] >= Bg8 && ps[i] <= Bg15) {
-					style.bg = 8 + ps[i] - Bg8;
+				if (ps[i] >= SetFg0 && ps[i] <= SetFg7) {
+					style.fg = ps[i] - SetFg0;
+				} else if (ps[i] >= SetBg0 && ps[i] <= SetBg7) {
+					style.bg = ps[i] - SetBg0;
+				} else if (ps[i] >= SetFg8 && ps[i] <= SetFg15) {
+					style.fg = 8 + ps[i] - SetFg8;
+				} else if (ps[i] >= SetBg8 && ps[i] <= SetBg15) {
+					style.bg = 8 + ps[i] - SetBg8;
 				}
 			}
 		}
@@ -206,7 +212,7 @@ static void updateSGR(uint ps[], uint n) {
 }
 
 // SGR toggling all attributes and setting both colors in 256 palette.
-enum { PSCap = 4 + 2 * 3 };
+enum { PSCap = 5 + 2 * 3 };
 
 enum {
 	DEC = '?',
@@ -377,40 +383,50 @@ styleDiff(FILE *file, const struct Style *prev, const struct Style *next) {
 
 	uint ps[PSCap];
 	uint n = 0;
-	if (next->bold != prev->bold) {
-		ps[n++] = (next->bold ? Bold : NotBold);
+
+	enum Attr diff = prev->attr ^ next->attr;
+	if (diff & (Bold | Dim)) {
+		ps[n++] = (
+			next->attr & Bold ? SetBold
+			: next->attr & Dim ? SetDim
+			: UnsetBoldDim
+		);
+	}
+	if (diff & Italic) {
+		ps[n++] = (next->attr & Italic ? SetItalic : UnsetItalic);
 	}
-	if (next->italic != prev->italic) {
-		ps[n++] = (next->italic ? Italic : NotItalic);
+	if (diff & Underline) {
+		ps[n++] = (next->attr & Underline ? SetUnderline : UnsetUnderline);
 	}
-	if (next->underline != prev->underline) {
-		ps[n++] = (next->underline ? Underline : NotUnderline);
+	if (diff & Blink) {
+		ps[n++] = (next->attr & Blink ? SetBlink : UnsetBlink);
 	}
-	if (next->reverse != prev->reverse) {
-		ps[n++] = (next->reverse ? Reverse : NotReverse);
+	if (diff & Reverse) {
+		ps[n++] = (next->attr & Reverse ? SetReverse : UnsetReverse);
 	}
+
 	if (next->bg != prev->bg) {
 		if (next->bg == -1) {
-			ps[n++] = BgDefault;
+			ps[n++] = ResetBg;
 		} else if (next->bg < 8) {
-			ps[n++] = Bg0 + next->bg;
+			ps[n++] = SetBg0 + next->bg;
 		} else if (next->bg < 16) {
-			ps[n++] = Bg8 + next->bg - 8;
+			ps[n++] = SetBg8 + next->bg - 8;
 		} else {
-			ps[n++] = Bg;
+			ps[n++] = SetBg;
 			ps[n++] = Color256;
 			ps[n++] = next->bg;
 		}
 	}
 	if (next->fg != prev->fg) {
 		if (next->fg == -1) {
-			ps[n++] = FgDefault;
+			ps[n++] = ResetFg;
 		} else if (next->fg < 8) {
-			ps[n++] = Fg0 + next->fg;
+			ps[n++] = SetFg0 + next->fg;
 		} else if (next->fg < 16) {
-			ps[n++] = Fg8 + next->fg - 8;
+			ps[n++] = SetFg8 + next->fg - 8;
 		} else {
-			ps[n++] = Fg;
+			ps[n++] = SetFg;
 			ps[n++] = Color256;
 			ps[n++] = next->fg;
 		}