xref: /haiku/src/apps/terminal/TerminalLine.h (revision 18d6122240d1fc5cb29561ad710c5b29d1fdb36e)
14c9d4b02SIngo Weinhold /*
25b41331fSSiarzhuk Zharski  * Copyright 2013, Haiku, Inc. All rights reserved.
34c9d4b02SIngo Weinhold  * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
44c9d4b02SIngo Weinhold  * Distributed under the terms of the MIT License.
55b41331fSSiarzhuk Zharski  *
65b41331fSSiarzhuk Zharski  * Authors:
75b41331fSSiarzhuk Zharski  *		Ingo Weinhold, ingo_weinhold@gmx.de
85b41331fSSiarzhuk Zharski  *		Siarzhuk Zharski, zharik@gmx.li
94c9d4b02SIngo Weinhold  */
104c9d4b02SIngo Weinhold #ifndef TERMINAL_LINE_H
114c9d4b02SIngo Weinhold #define TERMINAL_LINE_H
124c9d4b02SIngo Weinhold 
13c0b591c5SJessica Hamilton #include <GraphicsDefs.h>
144c9d4b02SIngo Weinhold #include <SupportDefs.h>
154c9d4b02SIngo Weinhold 
16627ced12SAdrien Destugues #include "TermConst.h"
17627ced12SAdrien Destugues 
184c9d4b02SIngo Weinhold #include "UTF8Char.h"
194c9d4b02SIngo Weinhold 
204c9d4b02SIngo Weinhold 
21c0b591c5SJessica Hamilton struct Attributes {
22c0b591c5SJessica Hamilton 	uint32 state;
23c0b591c5SJessica Hamilton 	uint32 foreground;
24c0b591c5SJessica Hamilton 	uint32 background;
25*18d61222SJérôme Duval 	uint32 underline;
26*18d61222SJérôme Duval 	int underlineStyle;
27c0b591c5SJessica Hamilton 
AttributesAttributes28*18d61222SJérôme Duval 	Attributes() : state(0), foreground(0), background(0), underline(0), underlineStyle(0) {}
29c0b591c5SJessica Hamilton 
ResetAttributes30*18d61222SJérôme Duval 	inline void Reset()
31*18d61222SJérôme Duval 	{
32*18d61222SJérôme Duval 		state = 0;
33*18d61222SJérôme Duval 		foreground = 0;
34*18d61222SJérôme Duval 		background = 0;
35*18d61222SJérôme Duval 		underline = 0;
36*18d61222SJérôme Duval 		underlineStyle = 0;
37*18d61222SJérôme Duval 	}
38c0b591c5SJessica Hamilton 
IsWidthAttributes39c0b591c5SJessica Hamilton 	inline bool IsWidth() const { return (state & A_WIDTH) == A_WIDTH; }
IsBoldAttributes40c0b591c5SJessica Hamilton 	inline bool IsBold() const { return (state & BOLD) == BOLD; }
IsUnderAttributes41c0b591c5SJessica Hamilton 	inline bool IsUnder() const { return (state & UNDERLINE) == UNDERLINE; }
IsInverseAttributes42c0b591c5SJessica Hamilton 	inline bool IsInverse() const { return (state & INVERSE) == INVERSE; }
IsMouseAttributes43c0b591c5SJessica Hamilton 	inline bool IsMouse() const { return (state & MOUSE) == MOUSE; }
IsForeSetAttributes44c0b591c5SJessica Hamilton 	inline bool IsForeSet() const { return (state & FORESET) == FORESET; }
IsBackSetAttributes45c0b591c5SJessica Hamilton 	inline bool IsBackSet() const { return (state & BACKSET) == BACKSET; }
IsUnderSetAttributes46*18d61222SJérôme Duval 	inline bool IsUnderSet() const { return (state & UNDERSET) == UNDERSET; }
IsFontAttributes47c0b591c5SJessica Hamilton 	inline bool IsFont() const { return (state & FONT) == FONT; }
IsCRAttributes48c0b591c5SJessica Hamilton 	inline bool IsCR() const { return (state & DUMPCR) == DUMPCR; }
49c0b591c5SJessica Hamilton 
SetDirectForegroundAttributes50c0b591c5SJessica Hamilton 	inline void SetDirectForeground(uint8 red, uint8 green, uint8 blue)
51c0b591c5SJessica Hamilton 	{
52c0b591c5SJessica Hamilton 		foreground = 0x80000000 | (red << 16) | (green << 8) | blue;
53c0b591c5SJessica Hamilton 		state &= ~FORECOLOR;
54c0b591c5SJessica Hamilton 		state |= FORESET;
55c0b591c5SJessica Hamilton 	}
56c0b591c5SJessica Hamilton 
SetDirectBackgroundAttributes57c0b591c5SJessica Hamilton 	inline void SetDirectBackground(uint8 red, uint8 green, uint8 blue)
58c0b591c5SJessica Hamilton 	{
59c0b591c5SJessica Hamilton 		background = 0x80000000 | (red << 16) | (green << 8) | blue;
60c0b591c5SJessica Hamilton 		state &= ~BACKCOLOR;
61c0b591c5SJessica Hamilton 		state |= BACKSET;
62c0b591c5SJessica Hamilton 	}
63c0b591c5SJessica Hamilton 
SetDirectUnderlineAttributes64*18d61222SJérôme Duval 	inline void SetDirectUnderline(uint8 red, uint8 green, uint8 blue)
65*18d61222SJérôme Duval 	{
66*18d61222SJérôme Duval 		underline = 0x80000000 | (red << 16) | (green << 8) | blue;
67*18d61222SJérôme Duval 		state |= UNDERSET;
68*18d61222SJérôme Duval 	}
69*18d61222SJérôme Duval 
SetIndexedForegroundAttributes70c0b591c5SJessica Hamilton 	inline void SetIndexedForeground(uint32 index)
71c0b591c5SJessica Hamilton 	{
72c0b591c5SJessica Hamilton 		state &= ~FORECOLOR;
73c0b591c5SJessica Hamilton 		state |= FORESET;
74c0b591c5SJessica Hamilton 		state |= FORECOLORED(index);
75c0b591c5SJessica Hamilton 		foreground = 0;
76c0b591c5SJessica Hamilton 	}
77c0b591c5SJessica Hamilton 
SetIndexedBackgroundAttributes78c0b591c5SJessica Hamilton 	inline void SetIndexedBackground(uint32 index)
79c0b591c5SJessica Hamilton 	{
80c0b591c5SJessica Hamilton 		state &= ~BACKCOLOR;
81c0b591c5SJessica Hamilton 		state |= BACKSET;
82c0b591c5SJessica Hamilton 		state |= BACKCOLORED(index);
83c0b591c5SJessica Hamilton 		background = 0;
84c0b591c5SJessica Hamilton 	}
85c0b591c5SJessica Hamilton 
SetIndexedUnderlineAttributes86*18d61222SJérôme Duval 	inline void SetIndexedUnderline(uint32 index)
87*18d61222SJérôme Duval 	{
88*18d61222SJérôme Duval 		state |= UNDERSET;
89*18d61222SJérôme Duval 		underline = index;
90*18d61222SJérôme Duval 	}
91*18d61222SJérôme Duval 
SetUnderAttributes92*18d61222SJérôme Duval 	inline void SetUnder(int style)
93*18d61222SJérôme Duval 	{
94*18d61222SJérôme Duval 		underlineStyle = style;
95*18d61222SJérôme Duval 		state |= UNDERLINE;
96*18d61222SJérôme Duval 	}
97*18d61222SJérôme Duval 
UnsetForegroundAttributes98c0b591c5SJessica Hamilton 	inline void UnsetForeground()
99c0b591c5SJessica Hamilton 	{
100c0b591c5SJessica Hamilton 		state &= ~FORESET;
101c0b591c5SJessica Hamilton 		foreground = 0;
102c0b591c5SJessica Hamilton 	}
103c0b591c5SJessica Hamilton 
UnsetBackgroundAttributes104c0b591c5SJessica Hamilton 	inline void UnsetBackground()
105c0b591c5SJessica Hamilton 	{
106c0b591c5SJessica Hamilton 		state &= ~BACKSET;
107c0b591c5SJessica Hamilton 		background = 0;
108c0b591c5SJessica Hamilton 	}
109c0b591c5SJessica Hamilton 
UnsetUnderlineAttributes110*18d61222SJérôme Duval 	inline void UnsetUnderline()
111*18d61222SJérôme Duval 	{
112*18d61222SJérôme Duval 		state &= ~UNDERSET;
113*18d61222SJérôme Duval 		underline = 0;
114*18d61222SJérôme Duval 	}
115*18d61222SJérôme Duval 
UnsetUnderAttributes116*18d61222SJérôme Duval 	inline void UnsetUnder()
117*18d61222SJérôme Duval 	{
118*18d61222SJérôme Duval 		underlineStyle = 0;
119*18d61222SJérôme Duval 		state &= ~UNDERLINE;
120*18d61222SJérôme Duval 	}
121*18d61222SJérôme Duval 
122c0b591c5SJessica Hamilton 	inline rgb_color
ForegroundColorAttributes123c0b591c5SJessica Hamilton 	ForegroundColor(const rgb_color* indexedColors) const
124c0b591c5SJessica Hamilton 	{
125c0b591c5SJessica Hamilton 		if ((foreground & 0x80000000) != 0)
126c0b591c5SJessica Hamilton 			return make_color((foreground >> 16) & 0xFF,
127c0b591c5SJessica Hamilton 				(foreground >> 8) & 0xFF,
128c0b591c5SJessica Hamilton 				foreground & 0xFF);
129c0b591c5SJessica Hamilton 		else
130c0b591c5SJessica Hamilton 			return indexedColors[(state & FORECOLOR) >> 16];
131c0b591c5SJessica Hamilton 	}
132c0b591c5SJessica Hamilton 
133c0b591c5SJessica Hamilton 	inline rgb_color
BackgroundColorAttributes134c0b591c5SJessica Hamilton 	BackgroundColor(const rgb_color* indexedColors) const
135c0b591c5SJessica Hamilton 	{
136c0b591c5SJessica Hamilton 		if ((background & 0x80000000) != 0)
137c0b591c5SJessica Hamilton 			return make_color((background >> 16) & 0xFF,
138c0b591c5SJessica Hamilton 				(background >> 8) & 0xFF,
139c0b591c5SJessica Hamilton 				background & 0xFF);
140c0b591c5SJessica Hamilton 		else
141c0b591c5SJessica Hamilton 			return indexedColors[(state & BACKCOLOR) >> 24];
142c0b591c5SJessica Hamilton 	}
143c0b591c5SJessica Hamilton 
144*18d61222SJérôme Duval 	inline rgb_color
UnderlineColorAttributes145*18d61222SJérôme Duval 	UnderlineColor(const rgb_color* indexedColors) const
146*18d61222SJérôme Duval 	{
147*18d61222SJérôme Duval 		if ((underline & 0x80000000) != 0)
148*18d61222SJérôme Duval 			return make_color((underline >> 16) & 0xFF,
149*18d61222SJérôme Duval 				(underline >> 8) & 0xFF,
150*18d61222SJérôme Duval 				underline & 0xFF);
151*18d61222SJérôme Duval 		else
152*18d61222SJérôme Duval 			return indexedColors[underline];
153*18d61222SJérôme Duval 	}
154*18d61222SJérôme Duval 
155*18d61222SJérôme Duval 	inline int
UnderlineStyleAttributes156*18d61222SJérôme Duval 	UnderlineStyle() const
157*18d61222SJérôme Duval 	{
158*18d61222SJérôme Duval 		return underlineStyle;
159*18d61222SJérôme Duval 	}
160*18d61222SJérôme Duval 
161c0b591c5SJessica Hamilton 	inline Attributes&
162c0b591c5SJessica Hamilton 	operator&=(uint32 value) { state &= value; return *this; }
163c0b591c5SJessica Hamilton 
164c0b591c5SJessica Hamilton 	inline Attributes&
165c0b591c5SJessica Hamilton 	operator|=(uint32 value) { state |= value; return *this; }
166c0b591c5SJessica Hamilton 
167c0b591c5SJessica Hamilton 	inline uint32
168c0b591c5SJessica Hamilton 	operator|(uint32 value) { return state | value; }
169c0b591c5SJessica Hamilton 
170c0b591c5SJessica Hamilton 	inline uint32
171c0b591c5SJessica Hamilton 	operator&(uint32 value) { return state & value; }
172c0b591c5SJessica Hamilton 
173c0b591c5SJessica Hamilton 	inline bool
174c0b591c5SJessica Hamilton 	operator==(const Attributes& other) const
175c0b591c5SJessica Hamilton 	{
176c0b591c5SJessica Hamilton 		return state == other.state
177c0b591c5SJessica Hamilton 			&& foreground == other.foreground
178*18d61222SJérôme Duval 			&& background == other.background
179*18d61222SJérôme Duval 			&& underline == other.underline
180*18d61222SJérôme Duval 			&& underlineStyle == other.underlineStyle;
181c0b591c5SJessica Hamilton 	}
182c0b591c5SJessica Hamilton 
183c0b591c5SJessica Hamilton 	inline bool
184c0b591c5SJessica Hamilton 	operator!=(const Attributes& other) const
185c0b591c5SJessica Hamilton 	{
186c0b591c5SJessica Hamilton 		return state != other.state
187c0b591c5SJessica Hamilton 			|| foreground != other.foreground
188*18d61222SJérôme Duval 			|| background != other.background
189*18d61222SJérôme Duval 			|| underline != other.underline
190*18d61222SJérôme Duval 			|| underlineStyle != other.underlineStyle;
191c0b591c5SJessica Hamilton 	}
192c0b591c5SJessica Hamilton };
193c0b591c5SJessica Hamilton 
194c0b591c5SJessica Hamilton 
1954c9d4b02SIngo Weinhold struct TerminalCell {
1964c9d4b02SIngo Weinhold 	UTF8Char			character;
197c0b591c5SJessica Hamilton 	Attributes			attributes;
198a43a4e9fSJessica Hamilton 
199a43a4e9fSJessica Hamilton 	inline bool
200a43a4e9fSJessica Hamilton 	operator!=(const Attributes& other) const
201a43a4e9fSJessica Hamilton 	{
202a43a4e9fSJessica Hamilton 		return (attributes.state & CHAR_ATTRIBUTES)
203a43a4e9fSJessica Hamilton 				!= (other.state & CHAR_ATTRIBUTES)
204a43a4e9fSJessica Hamilton 			|| attributes.foreground != other.foreground
205a43a4e9fSJessica Hamilton 			|| attributes.background != other.background;
206a43a4e9fSJessica Hamilton 	}
2074c9d4b02SIngo Weinhold };
2084c9d4b02SIngo Weinhold 
2094c9d4b02SIngo Weinhold 
2104c9d4b02SIngo Weinhold struct TerminalLine {
21117b889deSIngo Weinhold 	uint16			length;
2124c9d4b02SIngo Weinhold 	bool			softBreak;	// soft line break
213c0b591c5SJessica Hamilton 	Attributes		attributes;
2144c9d4b02SIngo Weinhold 	TerminalCell	cells[1];
2154c9d4b02SIngo Weinhold 
ClearTerminalLine216c0b591c5SJessica Hamilton 	inline void Clear()
217c0b591c5SJessica Hamilton 	{
218c0b591c5SJessica Hamilton 		Clear(Attributes());
219c0b591c5SJessica Hamilton 	}
220c0b591c5SJessica Hamilton 
ClearTerminalLine221c0b591c5SJessica Hamilton 	inline void Clear(size_t count)
222c0b591c5SJessica Hamilton 	{
223c0b591c5SJessica Hamilton 		Clear(Attributes(), count);
224c0b591c5SJessica Hamilton 	}
225c0b591c5SJessica Hamilton 
226c0b591c5SJessica Hamilton 	inline void Clear(Attributes attr, size_t count = 0)
2274c9d4b02SIngo Weinhold 	{
2284c9d4b02SIngo Weinhold 		length = 0;
229b512213bSSiarzhuk Zharski 		attributes = attr;
2304c9d4b02SIngo Weinhold 		softBreak = false;
231b512213bSSiarzhuk Zharski 		for (size_t i = 0; i < count; i++)
232b512213bSSiarzhuk Zharski 			cells[i].attributes = attr;
2334c9d4b02SIngo Weinhold 	}
2344c9d4b02SIngo Weinhold };
2354c9d4b02SIngo Weinhold 
2364c9d4b02SIngo Weinhold 
2374c9d4b02SIngo Weinhold struct AttributesRun {
238c0b591c5SJessica Hamilton 	Attributes	attributes;
2394c9d4b02SIngo Weinhold 	uint16	offset;			// character offset
2404c9d4b02SIngo Weinhold 	uint16	length;			// length of the run in characters
2414c9d4b02SIngo Weinhold };
2424c9d4b02SIngo Weinhold 
2434c9d4b02SIngo Weinhold 
2444c9d4b02SIngo Weinhold struct HistoryLine {
2454c9d4b02SIngo Weinhold 	AttributesRun*	attributesRuns;
2464c9d4b02SIngo Weinhold 	uint16			attributesRunCount;	// number of attribute runs
2474c9d4b02SIngo Weinhold 	uint16			byteLength : 15;	// number of bytes in the line
2484c9d4b02SIngo Weinhold 	bool			softBreak : 1;		// soft line break;
249c0b591c5SJessica Hamilton 	Attributes		attributes;
2504c9d4b02SIngo Weinhold 
AttributesRunsHistoryLine2514c9d4b02SIngo Weinhold 	AttributesRun* AttributesRuns() const
2524c9d4b02SIngo Weinhold 	{
2534c9d4b02SIngo Weinhold 		return attributesRuns;
2544c9d4b02SIngo Weinhold 	}
2554c9d4b02SIngo Weinhold 
CharsHistoryLine2564c9d4b02SIngo Weinhold 	char* Chars() const
2574c9d4b02SIngo Weinhold 	{
2584c9d4b02SIngo Weinhold 		return (char*)(attributesRuns + attributesRunCount);
2594c9d4b02SIngo Weinhold 	}
2604c9d4b02SIngo Weinhold 
BufferSizeHistoryLine2614c9d4b02SIngo Weinhold 	int32 BufferSize() const
2624c9d4b02SIngo Weinhold 	{
2634c9d4b02SIngo Weinhold 		return attributesRunCount * sizeof(AttributesRun) + byteLength;
2644c9d4b02SIngo Weinhold 	}
2654c9d4b02SIngo Weinhold };
2664c9d4b02SIngo Weinhold 
2674c9d4b02SIngo Weinhold 
2684c9d4b02SIngo Weinhold #endif	// TERMINAL_LINE_H
269