From: Po Lu Date: Sun, 8 May 2022 04:42:11 +0000 (+0000) Subject: Fully implement stipples for text on Haiku X-Git-Tag: emacs-29.0.90~1910^2~918 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=b205d67f8c92593f8e170419d677a70e535a3a19;p=emacs.git Fully implement stipples for text on Haiku * src/haikufont.c (haikufont_draw): Use `haiku_draw_background_rect' instead. * src/haikuterm.c (haiku_draw_plain_background): Change arguments to accept rect manually. (haiku_get_bitmap): Delete function. (haiku_get_bitmap_rec): New function. (haiku_draw_stipple_background): Accept rect instead of box sizes. (haiku_draw_background_rect): New function. (haiku_maybe_draw_background): Use that instead. (haiku_draw_image_glyph_string): Add notice. (haiku_draw_glyph_string): Set `stippled_p' correctly. * src/haikuterm.h (struct haiku_bitmap_record): New fields for keeping track of stipple state. * src/image.c (image_create_bitmap_from_data) (image_create_bitmap_from_file, free_bitmap_record): Free and set them accordingly. --- diff --git a/src/haikufont.c b/src/haikufont.c index e0db086aa00..54f11c6e413 100644 --- a/src/haikufont.c +++ b/src/haikufont.c @@ -1084,8 +1084,8 @@ haikufont_draw (struct glyph_string *s, int from, int to, s->first_glyph->slice.glyphless.lower_yoff - s->first_glyph->slice.glyphless.upper_yoff; - BView_SetHighColor (view, background); - BView_FillRectangle (view, x, y - ascent, s->width, height); + haiku_draw_background_rect (s, s->face, x, y - ascent, + s->width, height); s->background_filled_p = 1; } diff --git a/src/haikuterm.c b/src/haikuterm.c index 46ea5f90277..93af5c8e435 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -971,10 +971,11 @@ haiku_draw_string_box (struct glyph_string *s) static void haiku_draw_plain_background (struct glyph_string *s, struct face *face, - int box_line_hwidth, int box_line_vwidth) + int x, int y, int width, int height) { void *view = FRAME_HAIKU_VIEW (s->f); unsigned long cursor_color; + if (s->hl == DRAW_CURSOR) { haiku_merge_cursor_foreground (s, NULL, &cursor_color); @@ -983,38 +984,86 @@ haiku_draw_plain_background (struct glyph_string *s, struct face *face, else BView_SetHighColor (view, face->background_defaulted_p ? FRAME_BACKGROUND_PIXEL (s->f) : - face->background); + face->background); - BView_FillRectangle (view, s->x, - s->y + box_line_hwidth, - s->background_width, - s->height - 2 * box_line_hwidth); + BView_FillRectangle (view, x, y, width, height); } -static void * -haiku_get_bitmap (struct frame *f, ptrdiff_t id) +static struct haiku_bitmap_record * +haiku_get_bitmap_rec (struct frame *f, ptrdiff_t id) { - return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].img; + return &FRAME_DISPLAY_INFO (f)->bitmaps[id - 1]; +} + +static void +haiku_update_bitmap_rec (struct haiku_bitmap_record *rec, + uint32_t new_foreground, + uint32_t new_background) +{ + char *bits; + int x, y, bytes_per_line; + + if (new_foreground == rec->stipple_foreground + && new_background == rec->stipple_background) + return; + + bits = rec->stipple_bits; + bytes_per_line = (rec->width + 7) / 8; + + for (y = 0; y < rec->height; y++) + { + for (x = 0; x < rec->width; x++) + haiku_put_pixel (rec->img, x, y, + ((bits[x / 8] >> (x % 8)) & 1 + ? new_foreground : new_background)); + + bits += bytes_per_line; + } + + rec->stipple_foreground = new_foreground; + rec->stipple_background = new_background; } static void haiku_draw_stipple_background (struct glyph_string *s, struct face *face, - int box_line_hwidth, int box_line_vwidth) + int x, int y, int width, int height) { + struct haiku_bitmap_record *rec; + unsigned long foreground, background; void *view; view = FRAME_HAIKU_VIEW (s->f); + rec = haiku_get_bitmap_rec (s->f, s->face->stipple); + + if (s->hl == DRAW_CURSOR) + haiku_merge_cursor_foreground (s, &foreground, &background); + else + { + foreground = s->face->foreground; + background = s->face->background; + } + + haiku_update_bitmap_rec (rec, foreground, background); + BView_StartClip (view); haiku_clip_to_string (s); - BView_ClipToRect (view, s->x, s->y + box_line_hwidth, - s->background_width, - s->height - 2 * box_line_hwidth); - BView_DrawBitmapTiled (view, haiku_get_bitmap (s->f, face->stipple), - 0, 0, -1, -1, 0, 0, FRAME_PIXEL_WIDTH (s->f), + BView_ClipToRect (view, x, y, width, height); + BView_DrawBitmapTiled (view, rec->img, 0, 0, -1, -1, + 0, 0, FRAME_PIXEL_WIDTH (s->f), FRAME_PIXEL_HEIGHT (s->f)); BView_EndClip (view); } +void +haiku_draw_background_rect (struct glyph_string *s, struct face *face, + int x, int y, int width, int height) +{ + if (!s->stippled_p) + haiku_draw_plain_background (s, face, x, y, width, height); + else + haiku_draw_stipple_background (s, face, x, y, width, height); +} + static void haiku_maybe_draw_background (struct glyph_string *s, int force_p) { @@ -1028,12 +1077,10 @@ haiku_maybe_draw_background (struct glyph_string *s, int force_p) || FONT_TOO_HIGH (s->font) || s->font_not_found_p || s->extends_to_end_of_line_p || force_p) { - if (!face->stipple) - haiku_draw_plain_background (s, face, box_line_width, - box_vline_width); - else - haiku_draw_stipple_background (s, face, box_line_width, - box_vline_width); + haiku_draw_background_rect (s, s->face, s->x, s->y + box_line_width, + s->background_width, + s->height - 2 * box_line_width); + s->background_filled_p = 1; } } @@ -1286,17 +1333,8 @@ haiku_draw_stretch_glyph_string (struct glyph_string *s) } if (background_width > 0) - { - void *view = FRAME_HAIKU_VIEW (s->f); - unsigned long bkg; - if (s->hl == DRAW_CURSOR) - haiku_merge_cursor_foreground (s, NULL, &bkg); - else - bkg = s->face->background; - - BView_SetHighColor (view, bkg); - BView_FillRectangle (view, x, s->y, background_width, s->height); - } + haiku_draw_background_rect (s, s->face, s->y, + background_width, s->height); } s->background_filled_p = 1; } @@ -1566,6 +1604,7 @@ haiku_draw_image_glyph_string (struct glyph_string *s) void *view = FRAME_HAIKU_VIEW (s->f); void *bitmap = s->img->pixmap; + /* TODO: implement stipples for images with masks. */ s->stippled_p = face->stipple != 0; BView_SetHighColor (view, face->background); @@ -1648,16 +1687,14 @@ haiku_draw_image_glyph_string (struct glyph_string *s) static void haiku_draw_glyph_string (struct glyph_string *s) { - void *view; + void *view = FRAME_HAIKU_VIEW (s->f);; + struct face *face = s->face; block_input (); - view = FRAME_HAIKU_VIEW (s->f); BView_draw_lock (view, false, 0, 0, 0, 0); prepare_face_for_display (s->f, s->face); - struct face *face = s->face; - if (face != s->face) - prepare_face_for_display (s->f, face); + s->stippled_p = s->hl != DRAW_CURSOR && face->stipple; if (s->next && s->right_overhang && !s->for_overlaps) { diff --git a/src/haikuterm.h b/src/haikuterm.h index 1bff03ae39e..cc032d03892 100644 --- a/src/haikuterm.h +++ b/src/haikuterm.h @@ -52,6 +52,10 @@ struct haiku_bitmap_record char *file; int refcount; int height, width, depth; + + uint32_t stipple_foreground; + uint32_t stipple_background; + void *stipple_bits; }; struct haiku_display_info @@ -325,6 +329,9 @@ extern int haiku_load_image (struct frame *, struct image *, extern void syms_of_haikuimage (void); #endif +extern void haiku_draw_background_rect (struct glyph_string *, struct face *, + int, int, int, int); + #ifdef USE_BE_CAIRO extern cairo_t *haiku_begin_cr_clip (struct frame *, struct glyph_string *); diff --git a/src/image.c b/src/image.c index 757e1250066..f3b47f7cccb 100644 --- a/src/image.c +++ b/src/image.c @@ -542,20 +542,24 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #endif /* HAVE_PGTK */ #ifdef HAVE_HAIKU - void *bitmap; + void *bitmap, *stipple; int bytes_per_line, x, y; - bitmap = BBitmap_new (width, height, 1); + bitmap = BBitmap_new (width, height, false); if (!bitmap) return -1; bytes_per_line = (width + 7) / 8; + stipple = xmalloc (height * bytes_per_line); + memcpy (stipple, bits, height * bytes_per_line); for (y = 0; y < height; y++) { for (x = 0; x < width; x++) - PUT_PIXEL (bitmap, x, y, (bits[8] >> (x % 8)) & 1); + PUT_PIXEL (bitmap, x, y, ((bits[8] >> (x % 8)) & 1 + ? f->foreground_pixel + : f->background_pixel)); bits += bytes_per_line; } #endif @@ -577,6 +581,11 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #ifdef HAVE_HAIKU dpyinfo->bitmaps[id - 1].img = bitmap; dpyinfo->bitmaps[id - 1].depth = 1; + dpyinfo->bitmaps[id - 1].stipple_bits = stipple; + dpyinfo->bitmaps[id - 1].stipple_foreground + = f->foreground_pixel & 0xffffffff; + dpyinfo->bitmaps[id - 1].stipple_background + = f->background_pixel & 0xffffffff; #endif dpyinfo->bitmaps[id - 1].file = NULL; @@ -731,7 +740,7 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) return -1; } - bitmap = BBitmap_new (width, height, 1); + bitmap = BBitmap_new (width, height, false); if (!bitmap) { @@ -748,6 +757,11 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) dpyinfo->bitmaps[id - 1].height = height; dpyinfo->bitmaps[id - 1].width = width; dpyinfo->bitmaps[id - 1].refcount = 1; + dpyinfo->bitmaps[id - 1].stipple_foreground + = f->foreground_pixel & 0xffffffff; + dpyinfo->bitmaps[id - 1].stipple_background + = f->background_pixel & 0xffffffff; + dpyinfo->bitmaps[id - 1].stipple_bits = data; bytes_per_line = (width + 7) / 8; tmp = data; @@ -755,13 +769,14 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) for (y = 0; y < height; y++) { for (x = 0; x < width; x++) - PUT_PIXEL (bitmap, x, y, (tmp[x / 8] >> (x % 8)) & 1); + PUT_PIXEL (bitmap, x, y, ((tmp[x / 8] >> (x % 8)) & 1 + ? f->foreground_pixel + : f->background_pixel)); tmp += bytes_per_line; } xfree (contents); - xfree (data); return id; #endif } @@ -796,6 +811,9 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm) #ifdef HAVE_HAIKU BBitmap_free (bm->img); + + if (bm->stipple_bits) + xfree (bm->stipple_bits); #endif if (bm->file)