emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master d1f63b2b06 1/2: Implement stipples for images on Haiku


From: Po Lu
Subject: master d1f63b2b06 1/2: Implement stipples for images on Haiku
Date: Mon, 27 Jun 2022 02:23:58 -0400 (EDT)

branch: master
commit d1f63b2b0683a18d9b39faf7a825b89459754a8f
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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.
---
 src/haiku_draw_support.cc | 59 +++++++++++++++++++++++++++++++++++++++++++++++
 src/haiku_support.h       |  2 ++
 src/haikuterm.c           | 47 ++++++++++++++++++++++---------------
 3 files changed, 90 insertions(+), 18 deletions(-)

diff --git a/src/haiku_draw_support.cc b/src/haiku_draw_support.cc
index e2025ed68d..8e911dd184 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 7585b62a06..6260b35cbc 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 f50f6b34bd..9e84dec159 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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]