@@ -171,6 +171,28 @@ Line::append(const char *p)
171
171
}
172
172
}
173
173
174
+ void
175
+ Line::set_fgcolour (unsigned char clr)
176
+ {
177
+ Cell *p = cells_, *end = cells_ + length_;
178
+ for (; p != end; p++)
179
+ {
180
+ p->fgcolour = clr;
181
+ p->attribute |= Cell::FGCOLOUR;
182
+ }
183
+ }
184
+
185
+ void
186
+ Line::set_bgcolour (unsigned char clr)
187
+ {
188
+ Cell *p = cells_, *end = cells_ + length_;
189
+ for (; p != end; p++)
190
+ {
191
+ p->bgcolour = clr;
192
+ p->attribute |= Cell::BGCOLOUR;
193
+ }
194
+ }
195
+
174
196
void
175
197
Line::add_attribute (char addition)
176
198
{
@@ -180,7 +202,11 @@ Line::add_attribute(char addition)
180
202
p++->attribute |= addition;
181
203
}
182
204
183
- bool Area::use_backspaces = true ;
205
+ bool Area::use_backspaces = false ;
206
+ bool Area::use_ansi = true ;
207
+
208
+ Area::size_type Area::widthsize = 6 ; /* px */
209
+ Area::size_type Area::heightsize = 16 ; /* px, default fontsize */
184
210
185
211
Area::Area () :
186
212
width_(0 ),
@@ -466,6 +492,32 @@ Area::fill(char c, size_type x, size_type y, size_type w, size_type h)
466
492
}
467
493
}
468
494
495
+ void
496
+ Area::set_bgcolour (unsigned char clr)
497
+ {
498
+ for (size_type y = 0 ; y < height (); y++) {
499
+ Cell *p = cells_[y], *end = p + width ();
500
+ while (p != end) {
501
+ p->bgcolour = clr;
502
+ p->attribute |= Cell::BGCOLOUR;
503
+ p++;
504
+ }
505
+ }
506
+ }
507
+
508
+ void
509
+ Area::set_fgcolour (unsigned char clr)
510
+ {
511
+ for (size_type y = 0 ; y < height (); y++) {
512
+ Cell *p = cells_[y], *end = p + width ();
513
+ while (p != end) {
514
+ p->fgcolour = clr;
515
+ p->attribute |= Cell::FGCOLOUR;
516
+ p++;
517
+ }
518
+ }
519
+ }
520
+
469
521
void
470
522
Area::add_attribute (char addition)
471
523
{
@@ -506,62 +558,113 @@ iconvstream &
506
558
operator <<(iconvstream& os, const Area &a)
507
559
{
508
560
for (Area::size_type y = 0 ; y < a.height (); y++) {
509
- const Cell *cell = a.cells_ [y];
510
- const Cell *end = cell + a.width ();
511
- while (
512
- end != cell && end[-1 ].character == ' ' &&
513
- (end[-1 ].attribute &
514
- (Cell::UNDERLINE | Cell::STRIKETHROUGH)) == 0
515
- )
561
+ /* compute visible part */
562
+ const Cell *cell = a.cells_ [y];
563
+ const Cell *end = cell + a.width ();
564
+ char attrs = Cell::NONE;
565
+ unsigned char fgcolour = Cell::BLACK;
566
+ unsigned char bgcolour = Cell::WHITE;
567
+
568
+ /* trim off trailing spaces when they are not "visible" due to
569
+ * attributes (underline/strikethrough) */
570
+ while (end != cell &&
571
+ end[-1 ].character == ' ' &&
572
+ (end[-1 ].attribute & (Cell::UNDERLINE |
573
+ Cell::STRIKETHROUGH)) == 0 )
516
574
end--;
517
575
518
576
for (const Cell *p = cell; p != end; p++) {
519
- int c = p->character ;
520
- char a = p->attribute ;
577
+ int c = p->character ;
578
+ char a = p->attribute ;
521
579
char u[5 ] = {0 , 0 , 0 , 0 , 0 };
522
580
581
+ /* compute codepoint, this is a bit unfortunate and should
582
+ * go away once we use wchar_t */
523
583
u[0 ] = c & 0xFF ;
524
584
if ((c >> 7 ) & 1 ) {
525
- unsigned int d = c;
585
+ unsigned int d = c;
526
586
unsigned char point = 1 ;
527
587
while ((c >> (7 - point++)) & 1 ) {
528
588
d >>= 8 ;
529
589
u[point - 1 ] = d & 0xFF ;
530
- };
590
+ }
531
591
}
532
592
533
- if (a == Cell::NONE) {
593
+ if (Area::use_ansi) {
594
+ /* use ANSI escape sequences to produce colours, bold
595
+ * and underline */
596
+
597
+ /* see if there's something that needs disabling */
598
+ if (attrs != a ||
599
+ (a & Cell::COLOUR &&
600
+ (p->fgcolour != fgcolour ||
601
+ p->bgcolour != bgcolour)))
602
+ {
603
+ /* reset all properties, rebuild afterwards
604
+ * we do this also because it's the only way to
605
+ * unset something :) */
606
+ os << " \e[0" ;
607
+
608
+ attrs = a;
609
+ fgcolour = p->fgcolour ;
610
+ bgcolour = p->bgcolour ;
611
+
612
+ /* enable needed properties */
613
+ if (attrs & Cell::UNDERLINE) {
614
+ os << " ;4" ;
615
+ }
616
+ if (attrs & Cell::BOLD) {
617
+ os << " ;1" ;
618
+ }
619
+ /* ignore strikethrough, can't represent it */
620
+
621
+ if (attrs & Cell::FGCOLOUR) {
622
+ os << " ;38;5;" << std::to_string (fgcolour);
623
+ }
624
+ if (attrs & Cell::BGCOLOUR) {
625
+ os << " ;48;5;" << std::to_string (bgcolour);
626
+ }
627
+
628
+ /* finish sequence */
629
+ os << " m" ;
630
+ }
631
+ os << u;
632
+ } else if (Area::use_backspaces &&
633
+ a != Cell::NONE)
634
+ {
635
+ /* old method of producing bold and underline */
636
+
637
+ /* No LESS / terminal combination that I know of
638
+ * supports dash-backspace-character as
639
+ * "strikethrough". Pity.
640
+ * (For historical reasons we're still doing it though.) */
641
+ if (a & Cell::STRIKETHROUGH)
642
+ os << ' -' << backspace;
643
+
644
+ /* No LESS that I know of can combine underlining
645
+ * and boldface. In practice, boldface always takes
646
+ * precedence.
647
+ *
648
+ * It's not a good idea to optimize an underlined
649
+ * space as a single underscore (as opposed to
650
+ * underscore-backspace-space) -- this would not
651
+ * look nice next to an underlined character. */
652
+ if ((a & Cell::UNDERLINE))
653
+ os << ' _' << backspace;
654
+ if ((a & Cell::BOLD ) && c != ' ' )
655
+ os << u << backspace;
534
656
os << u;
535
657
} else {
536
- if (Area::use_backspaces) {
537
- /*
538
- * No LESS / terminal combination that I know of
539
- * supports dash-backspace-character as
540
- * "strikethrough". Pity.
541
- */
542
- if (a & Cell::STRIKETHROUGH)
543
- os << ' -' << backspace;
544
-
545
- /*
546
- * No LESS that I know of can combine underlining
547
- * and boldface. In practice, boldface always takes
548
- * precedence.
549
- *
550
- * It's not a good idea to optimize an underlined
551
- * space as a single underscore (as opposed to
552
- * underscore-backspace-space) -- this would not
553
- * look nice next to an underlined character.
554
- */
555
- if ((a & Cell::UNDERLINE))
556
- os << ' _' << backspace;
557
- if ((a & Cell::BOLD ) && c != ' ' )
558
- os << c << backspace;
559
- os << u;
560
- } else {
561
- os << (c == ' ' && (a & Cell::UNDERLINE) ? " _" : u);
562
- }
658
+ /* no rendering, historical behaviour to turn spaces
659
+ * into underscores when the input is underlined */
660
+ os << (c == ' ' && (a & Cell::UNDERLINE) ? " _" : u);
563
661
}
564
662
}
663
+
664
+ /* if we haven't yet, unset all features */
665
+ if (Area::use_ansi && attrs != Cell::NONE)
666
+ os << " \e[0;m" ;
667
+
565
668
os << endl;
566
669
}
567
670
0 commit comments