diff options
| author | Po Lu | 2021-12-12 01:17:00 +0000 |
|---|---|---|
| committer | Po Lu | 2021-12-12 01:19:57 +0000 |
| commit | c6cf446894a3d1eb1679de2a278fba9d4804952a (patch) | |
| tree | 9622edb2d8cffbe26d1c512216a5f3f29bd62273 /src | |
| parent | 8716f21d94bfda0072843e087833fedb38dcf13e (diff) | |
| download | emacs-c6cf446894a3d1eb1679de2a278fba9d4804952a.tar.gz emacs-c6cf446894a3d1eb1679de2a278fba9d4804952a.zip | |
Fix drawing overlines on top of stretch glyphs when there is a box
* src/haikuterm.c (haiku_draw_string_box): Also draw text
decorations if the clipping is to be set.
(haiku_draw_glyph_string): Only draw text decorations if
the box will not be drawn with clipping.
Diffstat (limited to 'src')
| -rw-r--r-- | src/haikuterm.c | 321 |
1 files changed, 160 insertions, 161 deletions
diff --git a/src/haikuterm.c b/src/haikuterm.c index f3c37b0258e..f95a013867f 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c | |||
| @@ -536,162 +536,6 @@ haiku_draw_relief_rect (struct glyph_string *s, | |||
| 536 | } | 536 | } |
| 537 | 537 | ||
| 538 | static void | 538 | static void |
| 539 | haiku_draw_string_box (struct glyph_string *s, int clip_p) | ||
| 540 | { | ||
| 541 | int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x; | ||
| 542 | bool raised_p, left_p, right_p; | ||
| 543 | struct glyph *last_glyph; | ||
| 544 | struct haiku_rect clip_rect; | ||
| 545 | |||
| 546 | struct face *face = s->face; | ||
| 547 | |||
| 548 | last_x = ((s->row->full_width_p && !s->w->pseudo_window_p) | ||
| 549 | ? WINDOW_RIGHT_EDGE_X (s->w) | ||
| 550 | : window_box_right (s->w, s->area)); | ||
| 551 | |||
| 552 | /* The glyph that may have a right box line. For static | ||
| 553 | compositions and images, the right-box flag is on the first glyph | ||
| 554 | of the glyph string; for other types it's on the last glyph. */ | ||
| 555 | if (s->cmp || s->img) | ||
| 556 | last_glyph = s->first_glyph; | ||
| 557 | else if (s->first_glyph->type == COMPOSITE_GLYPH | ||
| 558 | && s->first_glyph->u.cmp.automatic) | ||
| 559 | { | ||
| 560 | /* For automatic compositions, we need to look up the last glyph | ||
| 561 | in the composition. */ | ||
| 562 | struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area]; | ||
| 563 | struct glyph *g = s->first_glyph; | ||
| 564 | for (last_glyph = g++; | ||
| 565 | g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id | ||
| 566 | && g->slice.cmp.to < s->cmp_to; | ||
| 567 | last_glyph = g++) | ||
| 568 | ; | ||
| 569 | } | ||
| 570 | else | ||
| 571 | last_glyph = s->first_glyph + s->nchars - 1; | ||
| 572 | |||
| 573 | vwidth = eabs (face->box_vertical_line_width); | ||
| 574 | hwidth = eabs (face->box_horizontal_line_width); | ||
| 575 | raised_p = face->box == FACE_RAISED_BOX; | ||
| 576 | left_x = s->x; | ||
| 577 | right_x = (s->row->full_width_p && s->extends_to_end_of_line_p | ||
| 578 | ? last_x - 1 | ||
| 579 | : min (last_x, s->x + s->background_width) - 1); | ||
| 580 | |||
| 581 | top_y = s->y; | ||
| 582 | bottom_y = top_y + s->height - 1; | ||
| 583 | |||
| 584 | left_p = (s->first_glyph->left_box_line_p | ||
| 585 | || (s->hl == DRAW_MOUSE_FACE | ||
| 586 | && (s->prev == NULL | ||
| 587 | || s->prev->hl != s->hl))); | ||
| 588 | right_p = (last_glyph->right_box_line_p | ||
| 589 | || (s->hl == DRAW_MOUSE_FACE | ||
| 590 | && (s->next == NULL | ||
| 591 | || s->next->hl != s->hl))); | ||
| 592 | |||
| 593 | get_glyph_string_clip_rect (s, &clip_rect); | ||
| 594 | |||
| 595 | if (face->box == FACE_SIMPLE_BOX) | ||
| 596 | haiku_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth, | ||
| 597 | vwidth, left_p, right_p, &clip_rect); | ||
| 598 | else | ||
| 599 | haiku_draw_relief_rect (s, left_x, top_y, right_x, bottom_y, hwidth, | ||
| 600 | vwidth, raised_p, true, true, left_p, right_p, | ||
| 601 | &clip_rect, 1); | ||
| 602 | |||
| 603 | if (clip_p) | ||
| 604 | { | ||
| 605 | void *view = FRAME_HAIKU_VIEW (s->f); | ||
| 606 | BView_ClipToInverseRect (view, left_x, top_y, right_x - left_x + 1, hwidth); | ||
| 607 | if (left_p) | ||
| 608 | BView_ClipToInverseRect (view, left_x, top_y, vwidth, bottom_y - top_y + 1); | ||
| 609 | BView_ClipToInverseRect (view, left_x, bottom_y - hwidth + 1, | ||
| 610 | right_x - left_x + 1, hwidth); | ||
| 611 | if (right_p) | ||
| 612 | BView_ClipToInverseRect (view, right_x - vwidth + 1, | ||
| 613 | top_y, vwidth, bottom_y - top_y + 1); | ||
| 614 | } | ||
| 615 | } | ||
| 616 | |||
| 617 | static void | ||
| 618 | haiku_draw_plain_background (struct glyph_string *s, struct face *face, | ||
| 619 | int box_line_hwidth, int box_line_vwidth) | ||
| 620 | { | ||
| 621 | void *view = FRAME_HAIKU_VIEW (s->f); | ||
| 622 | BView_StartClip (view); | ||
| 623 | if (s->hl == DRAW_CURSOR) | ||
| 624 | BView_SetHighColor (view, FRAME_CURSOR_COLOR (s->f).pixel); | ||
| 625 | else | ||
| 626 | BView_SetHighColor (view, face->background_defaulted_p ? | ||
| 627 | FRAME_BACKGROUND_PIXEL (s->f) : | ||
| 628 | face->background); | ||
| 629 | |||
| 630 | BView_FillRectangle (view, s->x, | ||
| 631 | s->y + box_line_hwidth, | ||
| 632 | s->background_width, | ||
| 633 | s->height - 2 * box_line_hwidth); | ||
| 634 | BView_EndClip (view); | ||
| 635 | } | ||
| 636 | |||
| 637 | static void | ||
| 638 | haiku_draw_stipple_background (struct glyph_string *s, struct face *face, | ||
| 639 | int box_line_hwidth, int box_line_vwidth) | ||
| 640 | { | ||
| 641 | } | ||
| 642 | |||
| 643 | static void | ||
| 644 | haiku_maybe_draw_background (struct glyph_string *s, int force_p) | ||
| 645 | { | ||
| 646 | if ((s->first_glyph->type != IMAGE_GLYPH) && !s->background_filled_p) | ||
| 647 | { | ||
| 648 | struct face *face = s->face; | ||
| 649 | int box_line_width = max (face->box_horizontal_line_width, 0); | ||
| 650 | int box_vline_width = max (face->box_vertical_line_width, 0); | ||
| 651 | |||
| 652 | if (FONT_HEIGHT (s->font) < s->height - 2 * box_vline_width | ||
| 653 | || FONT_TOO_HIGH (s->font) | ||
| 654 | || s->font_not_found_p || s->extends_to_end_of_line_p || force_p) | ||
| 655 | { | ||
| 656 | if (!face->stipple) | ||
| 657 | haiku_draw_plain_background (s, face, box_line_width, | ||
| 658 | box_vline_width); | ||
| 659 | else | ||
| 660 | haiku_draw_stipple_background (s, face, box_line_width, | ||
| 661 | box_vline_width); | ||
| 662 | s->background_filled_p = 1; | ||
| 663 | } | ||
| 664 | } | ||
| 665 | } | ||
| 666 | |||
| 667 | static void | ||
| 668 | haiku_mouse_face_colors (struct glyph_string *s, uint32_t *fg, | ||
| 669 | uint32_t *bg) | ||
| 670 | { | ||
| 671 | int face_id; | ||
| 672 | struct face *face; | ||
| 673 | |||
| 674 | /* What face has to be used last for the mouse face? */ | ||
| 675 | face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id; | ||
| 676 | face = FACE_FROM_ID_OR_NULL (s->f, face_id); | ||
| 677 | if (face == NULL) | ||
| 678 | face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); | ||
| 679 | |||
| 680 | if (s->first_glyph->type == CHAR_GLYPH) | ||
| 681 | face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil); | ||
| 682 | else | ||
| 683 | face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil); | ||
| 684 | |||
| 685 | face = FACE_FROM_ID (s->f, face_id); | ||
| 686 | prepare_face_for_display (s->f, s->face); | ||
| 687 | |||
| 688 | if (fg) | ||
| 689 | *fg = face->foreground; | ||
| 690 | if (bg) | ||
| 691 | *bg = face->background; | ||
| 692 | } | ||
| 693 | |||
| 694 | static void | ||
| 695 | haiku_draw_underwave (struct glyph_string *s, int width, int x) | 539 | haiku_draw_underwave (struct glyph_string *s, int width, int x) |
| 696 | { | 540 | { |
| 697 | int wave_height = 3, wave_length = 2; | 541 | int wave_height = 3, wave_length = 2; |
| @@ -876,6 +720,164 @@ haiku_draw_text_decoration (struct glyph_string *s, struct face *face, | |||
| 876 | } | 720 | } |
| 877 | 721 | ||
| 878 | static void | 722 | static void |
| 723 | haiku_draw_string_box (struct glyph_string *s, int clip_p) | ||
| 724 | { | ||
| 725 | int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x; | ||
| 726 | bool raised_p, left_p, right_p; | ||
| 727 | struct glyph *last_glyph; | ||
| 728 | struct haiku_rect clip_rect; | ||
| 729 | |||
| 730 | struct face *face = s->face; | ||
| 731 | |||
| 732 | last_x = ((s->row->full_width_p && !s->w->pseudo_window_p) | ||
| 733 | ? WINDOW_RIGHT_EDGE_X (s->w) | ||
| 734 | : window_box_right (s->w, s->area)); | ||
| 735 | |||
| 736 | /* The glyph that may have a right box line. For static | ||
| 737 | compositions and images, the right-box flag is on the first glyph | ||
| 738 | of the glyph string; for other types it's on the last glyph. */ | ||
| 739 | if (s->cmp || s->img) | ||
| 740 | last_glyph = s->first_glyph; | ||
| 741 | else if (s->first_glyph->type == COMPOSITE_GLYPH | ||
| 742 | && s->first_glyph->u.cmp.automatic) | ||
| 743 | { | ||
| 744 | /* For automatic compositions, we need to look up the last glyph | ||
| 745 | in the composition. */ | ||
| 746 | struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area]; | ||
| 747 | struct glyph *g = s->first_glyph; | ||
| 748 | for (last_glyph = g++; | ||
| 749 | g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id | ||
| 750 | && g->slice.cmp.to < s->cmp_to; | ||
| 751 | last_glyph = g++) | ||
| 752 | ; | ||
| 753 | } | ||
| 754 | else | ||
| 755 | last_glyph = s->first_glyph + s->nchars - 1; | ||
| 756 | |||
| 757 | vwidth = eabs (face->box_vertical_line_width); | ||
| 758 | hwidth = eabs (face->box_horizontal_line_width); | ||
| 759 | raised_p = face->box == FACE_RAISED_BOX; | ||
| 760 | left_x = s->x; | ||
| 761 | right_x = (s->row->full_width_p && s->extends_to_end_of_line_p | ||
| 762 | ? last_x - 1 | ||
| 763 | : min (last_x, s->x + s->background_width) - 1); | ||
| 764 | |||
| 765 | top_y = s->y; | ||
| 766 | bottom_y = top_y + s->height - 1; | ||
| 767 | |||
| 768 | left_p = (s->first_glyph->left_box_line_p | ||
| 769 | || (s->hl == DRAW_MOUSE_FACE | ||
| 770 | && (s->prev == NULL | ||
| 771 | || s->prev->hl != s->hl))); | ||
| 772 | right_p = (last_glyph->right_box_line_p | ||
| 773 | || (s->hl == DRAW_MOUSE_FACE | ||
| 774 | && (s->next == NULL | ||
| 775 | || s->next->hl != s->hl))); | ||
| 776 | |||
| 777 | get_glyph_string_clip_rect (s, &clip_rect); | ||
| 778 | |||
| 779 | if (face->box == FACE_SIMPLE_BOX) | ||
| 780 | haiku_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth, | ||
| 781 | vwidth, left_p, right_p, &clip_rect); | ||
| 782 | else | ||
| 783 | haiku_draw_relief_rect (s, left_x, top_y, right_x, bottom_y, hwidth, | ||
| 784 | vwidth, raised_p, true, true, left_p, right_p, | ||
| 785 | &clip_rect, 1); | ||
| 786 | |||
| 787 | if (clip_p) | ||
| 788 | { | ||
| 789 | void *view = FRAME_HAIKU_VIEW (s->f); | ||
| 790 | |||
| 791 | haiku_draw_text_decoration (s, face, face->foreground, s->width, s->x); | ||
| 792 | BView_ClipToInverseRect (view, left_x, top_y, right_x - left_x + 1, hwidth); | ||
| 793 | if (left_p) | ||
| 794 | BView_ClipToInverseRect (view, left_x, top_y, vwidth, bottom_y - top_y + 1); | ||
| 795 | BView_ClipToInverseRect (view, left_x, bottom_y - hwidth + 1, | ||
| 796 | right_x - left_x + 1, hwidth); | ||
| 797 | if (right_p) | ||
| 798 | BView_ClipToInverseRect (view, right_x - vwidth + 1, | ||
| 799 | top_y, vwidth, bottom_y - top_y + 1); | ||
| 800 | } | ||
| 801 | } | ||
| 802 | |||
| 803 | static void | ||
| 804 | haiku_draw_plain_background (struct glyph_string *s, struct face *face, | ||
| 805 | int box_line_hwidth, int box_line_vwidth) | ||
| 806 | { | ||
| 807 | void *view = FRAME_HAIKU_VIEW (s->f); | ||
| 808 | BView_StartClip (view); | ||
| 809 | if (s->hl == DRAW_CURSOR) | ||
| 810 | BView_SetHighColor (view, FRAME_CURSOR_COLOR (s->f).pixel); | ||
| 811 | else | ||
| 812 | BView_SetHighColor (view, face->background_defaulted_p ? | ||
| 813 | FRAME_BACKGROUND_PIXEL (s->f) : | ||
| 814 | face->background); | ||
| 815 | |||
| 816 | BView_FillRectangle (view, s->x, | ||
| 817 | s->y + box_line_hwidth, | ||
| 818 | s->background_width, | ||
| 819 | s->height - 2 * box_line_hwidth); | ||
| 820 | BView_EndClip (view); | ||
| 821 | } | ||
| 822 | |||
| 823 | static void | ||
| 824 | haiku_draw_stipple_background (struct glyph_string *s, struct face *face, | ||
| 825 | int box_line_hwidth, int box_line_vwidth) | ||
| 826 | { | ||
| 827 | } | ||
| 828 | |||
| 829 | static void | ||
| 830 | haiku_maybe_draw_background (struct glyph_string *s, int force_p) | ||
| 831 | { | ||
| 832 | if ((s->first_glyph->type != IMAGE_GLYPH) && !s->background_filled_p) | ||
| 833 | { | ||
| 834 | struct face *face = s->face; | ||
| 835 | int box_line_width = max (face->box_horizontal_line_width, 0); | ||
| 836 | int box_vline_width = max (face->box_vertical_line_width, 0); | ||
| 837 | |||
| 838 | if (FONT_HEIGHT (s->font) < s->height - 2 * box_vline_width | ||
| 839 | || FONT_TOO_HIGH (s->font) | ||
| 840 | || s->font_not_found_p || s->extends_to_end_of_line_p || force_p) | ||
| 841 | { | ||
| 842 | if (!face->stipple) | ||
| 843 | haiku_draw_plain_background (s, face, box_line_width, | ||
| 844 | box_vline_width); | ||
| 845 | else | ||
| 846 | haiku_draw_stipple_background (s, face, box_line_width, | ||
| 847 | box_vline_width); | ||
| 848 | s->background_filled_p = 1; | ||
| 849 | } | ||
| 850 | } | ||
| 851 | } | ||
| 852 | |||
| 853 | static void | ||
| 854 | haiku_mouse_face_colors (struct glyph_string *s, uint32_t *fg, | ||
| 855 | uint32_t *bg) | ||
| 856 | { | ||
| 857 | int face_id; | ||
| 858 | struct face *face; | ||
| 859 | |||
| 860 | /* What face has to be used last for the mouse face? */ | ||
| 861 | face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id; | ||
| 862 | face = FACE_FROM_ID_OR_NULL (s->f, face_id); | ||
| 863 | if (face == NULL) | ||
| 864 | face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); | ||
| 865 | |||
| 866 | if (s->first_glyph->type == CHAR_GLYPH) | ||
| 867 | face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil); | ||
| 868 | else | ||
| 869 | face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil); | ||
| 870 | |||
| 871 | face = FACE_FROM_ID (s->f, face_id); | ||
| 872 | prepare_face_for_display (s->f, s->face); | ||
| 873 | |||
| 874 | if (fg) | ||
| 875 | *fg = face->foreground; | ||
| 876 | if (bg) | ||
| 877 | *bg = face->background; | ||
| 878 | } | ||
| 879 | |||
| 880 | static void | ||
| 879 | haiku_draw_glyph_string_foreground (struct glyph_string *s) | 881 | haiku_draw_glyph_string_foreground (struct glyph_string *s) |
| 880 | { | 882 | { |
| 881 | struct face *face = s->face; | 883 | struct face *face = s->face; |
| @@ -1557,14 +1559,11 @@ haiku_draw_glyph_string (struct glyph_string *s) | |||
| 1557 | 1559 | ||
| 1558 | if (!box_filled_p && face->box != FACE_NO_BOX) | 1560 | if (!box_filled_p && face->box != FACE_NO_BOX) |
| 1559 | haiku_draw_string_box (s, 1); | 1561 | haiku_draw_string_box (s, 1); |
| 1562 | else | ||
| 1563 | haiku_draw_text_decoration (s, face, face->foreground, s->width, s->x); | ||
| 1560 | 1564 | ||
| 1561 | if (!s->for_overlaps) | 1565 | if (!s->for_overlaps) |
| 1562 | { | 1566 | { |
| 1563 | uint32_t dcol; | ||
| 1564 | dcol = face->foreground; | ||
| 1565 | |||
| 1566 | haiku_draw_text_decoration (s, face, dcol, s->width, s->x); | ||
| 1567 | |||
| 1568 | if (s->prev) | 1567 | if (s->prev) |
| 1569 | { | 1568 | { |
| 1570 | struct glyph_string *prev; | 1569 | struct glyph_string *prev; |