From: Po Lu Date: Mon, 27 Jun 2022 06:16:52 +0000 (+0000) Subject: Implement stipples for images on Haiku X-Git-Tag: emacs-29.0.90~1447^2~1431 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=d1f63b2b0683a18d9b39faf7a825b89459754a8f;p=emacs.git Implement stipples for images on Haiku * src/haiku_draw_support.cc (be_draw_bitmap_with_mask): New function. * src/haiku_support.h: Add prototype. * src/haikuterm.c (haiku_draw_image_glyph_string): Draw stipple correctly. (haiku_draw_glyph_string): Fix conditions under which row->stipple_p is set. --- diff --git a/src/haiku_draw_support.cc b/src/haiku_draw_support.cc index e2025ed68d4..8e911dd1843 100644 --- a/src/haiku_draw_support.cc +++ b/src/haiku_draw_support.cc @@ -475,3 +475,62 @@ be_draw_cross_on_pixmap (void *bitmap, int x, int y, int width, be_draw_cross_on_pixmap_1 (target, x, y, width, height, color); } + +void +be_draw_bitmap_with_mask (void *view, void *bitmap, void *mask, + int dx, int dy, int width, int height, + int vx, int vy, int vwidth, int vheight, + bool use_bilinear_filtering) +{ + BBitmap *source ((BBitmap *) bitmap); + BBitmap combined (source->Bounds (), B_RGBA32); + BRect bounds; + int x, y, bit; + BView *vw; + uint32_t source_mask; + unsigned long pixel; + + if (combined.InitCheck () != B_OK) + return; + + if (combined.ImportBits (source) != B_OK) + return; + + bounds = source->Bounds (); + + if (source->ColorSpace () == B_RGB32) + source_mask = 255u << 24; + else + source_mask = 0; + + for (y = 0; y < BE_RECT_HEIGHT (bounds); ++y) + { + for (x = 0; x < BE_RECT_WIDTH (bounds); ++x) + { + bit = haiku_get_pixel (mask, x, y); + + if (bit) + { + pixel = haiku_get_pixel (bitmap, x, y); + haiku_put_pixel ((void *) &combined, x, y, + source_mask | pixel); + } + else + haiku_put_pixel ((void *) &combined, x, y, 0); + } + } + + vw = get_view (view); + + vw->SetDrawingMode (B_OP_OVER); + if (!use_bilinear_filtering) + vw->DrawBitmap (&combined, + BRect (dx, dy, dx + width - 1, dy + height - 1), + BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1)); + else + vw->DrawBitmap (&combined, + BRect (dx, dy, dx + width - 1, dy + height - 1), + BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1), + B_FILTER_BITMAP_BILINEAR); + vw->SetDrawingMode (B_OP_COPY); +} diff --git a/src/haiku_support.h b/src/haiku_support.h index 7585b62a064..6260b35cbc1 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -575,6 +575,8 @@ extern void be_apply_affine_transform (void *, double, double, double, extern void be_apply_inverse_transform (double (*)[3], int, int, int *, int *); extern void be_draw_image_mask (void *, void *, int, int, int, int, int, int, int, int, uint32_t); +extern void be_draw_bitmap_with_mask (void *, void *, void *, int, int, int, + int, int, int, int, int, bool); extern void be_get_display_resolution (double *, double *); extern void be_get_screen_dimensions (int *, int *); diff --git a/src/haikuterm.c b/src/haikuterm.c index f50f6b34bda..9e84dec1593 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -1672,7 +1672,6 @@ haiku_draw_image_glyph_string (struct glyph_string *s) view = FRAME_HAIKU_VIEW (s->f); bitmap = s->img->pixmap; - /* TODO: implement stipples for images with masks. */ s->stippled_p = face->stipple != 0; if (s->hl == DRAW_CURSOR) @@ -1680,8 +1679,8 @@ haiku_draw_image_glyph_string (struct glyph_string *s) else background = face->background; - BView_SetHighColor (view, background); - BView_FillRectangle (view, x, y, width, height); + haiku_draw_background_rect (s, face, x, y, + width, height); if (bitmap) { @@ -1733,22 +1732,36 @@ haiku_draw_image_glyph_string (struct glyph_string *s) image_transform[1][1], image_transform[1][2]); - BView_DrawBitmap (view, bitmap, 0, 0, - s->img->original_width, - s->img->original_height, - 0, 0, - s->img->original_width, - s->img->original_height, - s->img->use_bilinear_filtering); - - if (mask) - be_draw_image_mask (mask, view, 0, 0, + if (!s->stippled_p || !mask) + { + BView_DrawBitmap (view, bitmap, 0, 0, s->img->original_width, s->img->original_height, 0, 0, s->img->original_width, s->img->original_height, - face->background); + s->img->use_bilinear_filtering); + + if (mask) + be_draw_image_mask (mask, view, 0, 0, + s->img->original_width, + s->img->original_height, + 0, 0, + s->img->original_width, + s->img->original_height, + face->background); + } + else + /* In order to make sure the stipple background remains + visible, use the mask for the alpha channel of BITMAP + and composite it onto the view instead. */ + be_draw_bitmap_with_mask (view, bitmap, mask, 0, 0, + s->img->original_width, + s->img->original_height, + 0, 0, + s->img->original_width, + s->img->original_height, + s->img->use_bilinear_filtering); if (s->slice.x != x || s->slice.y != y || s->slice.width != s->img->width @@ -1949,10 +1962,8 @@ haiku_draw_glyph_string (struct glyph_string *s) /* Set the stipple_p flag indicating whether or not a stipple was drawn in s->row. That is the case either when s is a stretch glyph string and s->face->stipple is not NULL, or when - s->face->stipple exists and s->hl is not DRAW_CURSOR, and s is - not an image. This is different from X. */ - if (s->first_glyph->type != IMAGE_GLYPH - && s->face->stipple + s->face->stipple exists and s->hl is not DRAW_CURSOR. */ + if (s->face->stipple && (s->first_glyph->type == STRETCH_GLYPH || s->hl != DRAW_CURSOR)) s->row->stipple_p = true;