emacs-diffs
[Top][All Lists]
Advanced

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

master faa342c794: Implement bitmap loading for faces on Haiku


From: Po Lu
Subject: master faa342c794: Implement bitmap loading for faces on Haiku
Date: Sat, 7 May 2022 23:09:12 -0400 (EDT)

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

    Implement bitmap loading for faces on Haiku
    
    Stipples don't completely work yet.
    
    * lisp/faces.el (face-valid-attribute-values): Enable `:stipple'
    on Haiku.
    * src/haiku_draw_support.cc (BView_DrawBitmap)
    (BView_DrawBitmapWithEraseOp, BView_DrawMask): Don't push and
    pop states.
    (BView_DrawBitmapTiled): New function.
    
    * src/haiku_support.cc (BBitmap_import_mono_bits): Delete
    function.
    * src/haiku_support.h: Update prototypes.
    * src/haikuterm.c (get_string_resource): Fix coding style.
    (haiku_get_bitmap, haiku_draw_stipple_background): Implement
    partially.
    (haiku_set_scroll_bar_default_width)
    (haiku_set_scroll_bar_default_height, haiku_scroll_bar_create)
    (haiku_set_horizontal_scroll_bar, haiku_set_vertical_scroll_bar)
    (haiku_create_terminal, haiku_scroll_bar_remove): Fix coding
    style.
    
    * src/image.c (image_create_bitmap_from_data)
    (image_create_bitmap_from_file): Implement on Haiku.
---
 lisp/faces.el             |   2 +-
 src/haiku_draw_support.cc |  46 ++++++++++++++++----
 src/haiku_support.cc      |  11 -----
 src/haiku_support.h       |   4 +-
 src/haikuterm.c           | 106 +++++++++++++++++++++++++++++++---------------
 src/image.c               |  82 ++++++++++++++++++++++++++++++++---
 6 files changed, 188 insertions(+), 63 deletions(-)

diff --git a/lisp/faces.el b/lisp/faces.el
index 12a386c8f6..395ea315ba 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -1202,7 +1202,7 @@ an integer value."
            (:height
             'integerp)
            (:stipple
-            (and (memq (window-system frame) '(x ns pgtk)) ; No stipple on w32 
or haiku
+            (and (memq (window-system frame) '(x ns pgtk haiku)) ; No stipple 
on w32
                  (mapcar #'list
                          (apply #'nconc
                                 (mapcar (lambda (dir)
diff --git a/src/haiku_draw_support.cc b/src/haiku_draw_support.cc
index a8d46d000a..551af51d7c 100644
--- a/src/haiku_draw_support.cc
+++ b/src/haiku_draw_support.cc
@@ -285,11 +285,32 @@ BView_DrawBitmap (void *view, void *bitmap, int x, int y,
   BView *vw = get_view (view);
   BBitmap *bm = (BBitmap *) bitmap;
 
-  vw->PushState ();
   vw->SetDrawingMode (B_OP_OVER);
   vw->DrawBitmap (bm, BRect (x, y, x + width - 1, y + height - 1),
                  BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1));
-  vw->PopState ();
+  vw->SetDrawingMode (B_OP_COPY);
+}
+
+void
+BView_DrawBitmapTiled (void *view, void *bitmap, int x, int y,
+                      int width, int height, int vx, int vy,
+                      int vwidth, int vheight)
+{
+  BView *vw = get_view (view);
+  BBitmap *bm = (BBitmap *) bitmap;
+  BRect bounds = bm->Bounds ();
+
+  if (width == -1)
+    width = BE_RECT_WIDTH (bounds);
+
+  if (height == -1)
+    height = BE_RECT_HEIGHT (bounds);
+
+  vw->SetDrawingMode (B_OP_OVER);
+  vw->DrawBitmap (bm, BRect (x, y, x + width - 1, y + height - 1),
+                 BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1),
+                 B_TILE_BITMAP);
+  vw->SetDrawingMode (B_OP_COPY);
 }
 
 void
@@ -300,17 +321,22 @@ BView_DrawBitmapWithEraseOp (void *view, void *bitmap, 
int x,
   BBitmap *bm = (BBitmap *) bitmap;
   BBitmap bc (bm->Bounds (), B_RGBA32);
   BRect rect (x, y, x + width - 1, y + height - 1);
+  uint32_t *bits;
+  size_t stride;
+  rgb_color low_color;
+  BRect bounds;
 
   if (bc.InitCheck () != B_OK || bc.ImportBits (bm) != B_OK)
     return;
 
-  uint32_t *bits = (uint32_t *) bc.Bits ();
-  size_t stride = bc.BytesPerRow ();
+  bits = (uint32_t *) bc.Bits ();
+  stride = bc.BytesPerRow ();
 
   if (bm->ColorSpace () == B_GRAY1)
     {
-      rgb_color low_color = vw->LowColor ();
-      BRect bounds = bc.Bounds ();
+      low_color = vw->LowColor ();
+      bounds = bc.Bounds ();
+
       for (int y = 0; y < BE_RECT_HEIGHT (bounds); ++y)
        {
          for (int x = 0; x < BE_RECT_WIDTH (bounds); ++x)
@@ -323,10 +349,11 @@ BView_DrawBitmapWithEraseOp (void *view, void *bitmap, 
int x,
        }
     }
 
-  vw->PushState ();
-  vw->SetDrawingMode (bm->ColorSpace () == B_GRAY1 ? B_OP_OVER : B_OP_ERASE);
+  vw->SetDrawingMode ((bm->ColorSpace ()
+                      == B_GRAY1)
+                     ? B_OP_OVER : B_OP_ERASE);
   vw->DrawBitmap (&bc, rect);
-  vw->PopState ();
+  vw->SetDrawingMode (B_OP_COPY);
 }
 
 void
@@ -357,6 +384,7 @@ BView_DrawMask (void *src, void *view,
   vw->SetDrawingMode (B_OP_OVER);
   vw->DrawBitmap (&bm, BRect (x, y, x + width - 1, y + height - 1),
                  BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1));
+  vw->SetDrawingMode (B_OP_COPY);
 }
 
 static BBitmap *
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 5dfb25d6dd..27a676dd31 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -3599,17 +3599,6 @@ BBitmap_import_fringe_bitmap (void *bitmap, unsigned 
short *bits, int wd, int h)
     }
 }
 
-void
-BBitmap_import_mono_bits (void *bitmap, void *bits, int wd, int h)
-{
-  BBitmap *bmp = (BBitmap *) bitmap;
-
-  if (wd % 8)
-    wd += 8 - (wd % 8);
-
-  bmp->ImportBits (bits, wd / 8 * h, wd / 8, 0, B_GRAY1);
-}
-
 /* Make a scrollbar at X, Y known to the view VIEW.  */
 void
 BView_publish_scroll_bar (void *view, int x, int y, int width, int height)
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 5ded9300d8..eaca7a9bad 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -541,6 +541,8 @@ extern void BView_DrawBitmap (void *, void *, int, int, 
int, int, int, int,
 extern void BView_DrawBitmapWithEraseOp (void *, void *, int, int, int, int);
 extern void BView_DrawMask (void *, void *, int, int, int, int,        int, 
int,
                            int, int, uint32_t);
+extern void BView_DrawBitmapTiled (void *, void *, int, int,
+                                  int, int, int, int, int, int);
 
 extern void BView_resize_to (void *, int, int);
 extern void BView_set_view_cursor (void *, void *);
@@ -570,9 +572,7 @@ extern void BView_invalidate (void *);
 extern void BView_draw_lock (void *, bool, int, int, int, int);
 extern void BView_invalidate_region (void *, int, int, int, int);
 extern void BView_draw_unlock (void *);
-
 extern void BBitmap_import_fringe_bitmap (void *, unsigned short *, int, int);
-extern void BBitmap_import_mono_bits (void *, void *, int, int);
 
 extern void haiku_font_pattern_free (struct haiku_font_pattern *);
 
diff --git a/src/haikuterm.c b/src/haikuterm.c
index f08fe68187..46ea5f9027 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -122,7 +122,8 @@ haiku_delete_terminal (struct terminal *terminal)
 }
 
 static const char *
-get_string_resource (void *ignored, const char *name, const char *class)
+haiku_get_string_resource (void *ignored, const char *name,
+                          const char *class)
 {
   const char *native;
 
@@ -990,10 +991,28 @@ haiku_draw_plain_background (struct glyph_string *s, 
struct face *face,
                       s->height - 2 * box_line_hwidth);
 }
 
+static void *
+haiku_get_bitmap (struct frame *f, ptrdiff_t id)
+{
+  return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].img;
+}
+
 static void
 haiku_draw_stipple_background (struct glyph_string *s, struct face *face,
                               int box_line_hwidth, int box_line_vwidth)
 {
+  void *view;
+
+  view = FRAME_HAIKU_VIEW (s->f);
+  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),
+                        FRAME_PIXEL_HEIGHT (s->f));
+  BView_EndClip (view);
 }
 
 static void
@@ -2079,19 +2098,25 @@ haiku_draw_vertical_window_border (struct window *w,
 static void
 haiku_set_scroll_bar_default_width (struct frame *f)
 {
-  int unit = FRAME_COLUMN_WIDTH (f);
-  FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = BScrollBar_default_size (0) + 1;
-  FRAME_CONFIG_SCROLL_BAR_COLS (f) =
-    (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
+  int unit, size;
+
+  unit = FRAME_COLUMN_WIDTH (f);
+  size = BScrollBar_default_size (0) + 1;
+
+  FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = size;
+  FRAME_CONFIG_SCROLL_BAR_COLS (f) = (size + unit - 1) / unit;
 }
 
 static void
 haiku_set_scroll_bar_default_height (struct frame *f)
 {
-  int height = FRAME_LINE_HEIGHT (f);
-  FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = BScrollBar_default_size (1) + 1;
-  FRAME_CONFIG_SCROLL_BAR_LINES (f) =
-    (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) + height - 1) / height;
+  int height, size;
+
+  height = FRAME_LINE_HEIGHT (f);
+  size = BScrollBar_default_size (true) + 1;
+
+  FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = size;
+  FRAME_CONFIG_SCROLL_BAR_LINES (f) = (size + height - 1) / height;
 }
 
 static void
@@ -2273,15 +2298,17 @@ static struct scroll_bar *
 haiku_scroll_bar_create (struct window *w, int left, int top,
                         int width, int height, bool horizontal_p)
 {
-  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct frame *f;
   Lisp_Object barobj;
+  struct scroll_bar *bar;
+  void *scroll_bar;
+  void *view;
 
-  void *sb = NULL;
-  void *vw = FRAME_HAIKU_VIEW (f);
+  f = XFRAME (WINDOW_FRAME (w));
+  view = FRAME_HAIKU_VIEW (f);
 
   block_input ();
-  struct scroll_bar *bar
-    = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, prev, PVEC_OTHER);
+  bar = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, prev, PVEC_OTHER);
 
   XSETWINDOW (bar->window, w);
   bar->top = top;
@@ -2294,15 +2321,14 @@ haiku_scroll_bar_create (struct window *w, int left, 
int top,
   bar->update = -1;
   bar->horizontal = horizontal_p;
 
-  sb = BScrollBar_make_for_view (vw, horizontal_p,
-                                left, top, left + width - 1,
-                                top + height - 1, bar);
-
-  BView_publish_scroll_bar (vw, left, top, width, height);
+  scroll_bar = BScrollBar_make_for_view (view, horizontal_p,
+                                        left, top, left + width - 1,
+                                        top + height - 1, bar);
+  BView_publish_scroll_bar (view, left, top, width, height);
 
   bar->next = FRAME_SCROLL_BARS (f);
   bar->prev = Qnil;
-  bar->scroll_bar = sb;
+  bar->scroll_bar = scroll_bar;
   XSETVECTOR (barobj, bar);
   fset_scroll_bars (f, barobj);
 
@@ -2316,18 +2342,20 @@ haiku_scroll_bar_create (struct window *w, int left, 
int top,
 static void
 haiku_set_horizontal_scroll_bar (struct window *w, int portion, int whole, int 
position)
 {
-  eassert (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w));
   Lisp_Object barobj;
   struct scroll_bar *bar;
   int top, height, left, width;
   int window_x, window_width;
+  void *view;
 
+  eassert (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w));
   /* Get window dimensions.  */
   window_box (w, ANY_AREA, &window_x, 0, &window_width, 0);
   left = window_x;
   width = window_width;
   top = WINDOW_SCROLL_BAR_AREA_Y (w);
   height = WINDOW_CONFIG_SCROLL_BAR_HEIGHT (w);
+  view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (w));
 
   block_input ();
 
@@ -2342,15 +2370,15 @@ haiku_set_horizontal_scroll_bar (struct window *w, int 
portion, int whole, int p
     {
       bar = XSCROLL_BAR (w->horizontal_scroll_bar);
 
-      if (bar->left != left || bar->top != top ||
-         bar->width != width || bar->height != height)
+      if (bar->left != left || bar->top != top
+         || bar->width != width || bar->height != height)
        {
-         void *view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (w));
          BView_forget_scroll_bar (view, bar->left, bar->top,
                                   bar->width, bar->height);
          BView_move_frame (bar->scroll_bar, left, top,
                            left + width - 1, top + height - 1);
          BView_publish_scroll_bar (view, left, top, width, height);
+
          bar->left = left;
          bar->top = top;
          bar->width = width;
@@ -2367,14 +2395,15 @@ haiku_set_horizontal_scroll_bar (struct window *w, int 
portion, int whole, int p
 }
 
 static void
-haiku_set_vertical_scroll_bar (struct window *w,
-                              int portion, int whole, int position)
+haiku_set_vertical_scroll_bar (struct window *w, int portion, int whole, int 
position)
 {
-  eassert (WINDOW_HAS_VERTICAL_SCROLL_BAR (w));
   Lisp_Object barobj;
   struct scroll_bar *bar;
   int top, height, left, width;
   int window_y, window_height;
+  void *view;
+
+  eassert (WINDOW_HAS_VERTICAL_SCROLL_BAR (w));
 
   /* Get window dimensions.  */
   window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
@@ -2384,8 +2413,10 @@ haiku_set_vertical_scroll_bar (struct window *w,
   /* Compute the left edge and the width of the scroll bar area.  */
   left = WINDOW_SCROLL_BAR_AREA_X (w);
   width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
-  block_input ();
 
+  view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (w));
+
+  block_input ();
   if (NILP (w->vertical_scroll_bar))
     {
       bar = haiku_scroll_bar_create (w, left, top, width, height, false);
@@ -2396,15 +2427,15 @@ haiku_set_vertical_scroll_bar (struct window *w,
     {
       bar = XSCROLL_BAR (w->vertical_scroll_bar);
 
-      if (bar->left != left || bar->top != top ||
-         bar->width != width || bar->height != height)
+      if (bar->left != left || bar->top != top
+         || bar->width != width || bar->height != height)
        {
-         void *view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (w));
          BView_forget_scroll_bar (view, bar->left, bar->top,
                                   bar->width, bar->height);
          BView_move_frame (bar->scroll_bar, left, top,
                            left + width - 1, top + height - 1);
          BView_publish_scroll_bar (view, left, top, width, height);
+
          bar->left = left;
          bar->top = top;
          bar->width = width;
@@ -3880,7 +3911,7 @@ haiku_create_terminal (struct haiku_display_info *dpyinfo)
   terminal->frame_visible_invisible_hook = haiku_set_frame_visible_invisible;
   terminal->set_frame_offset_hook = haiku_set_offset;
   terminal->delete_terminal_hook = haiku_delete_terminal;
-  terminal->get_string_resource_hook = get_string_resource;
+  terminal->get_string_resource_hook = haiku_get_string_resource;
   terminal->set_new_font_hook = haiku_new_font;
   terminal->defined_color_hook = haiku_defined_color;
   terminal->set_window_size_hook = haiku_set_window_size;
@@ -4089,9 +4120,15 @@ mark_haiku_display (void)
 void
 haiku_scroll_bar_remove (struct scroll_bar *bar)
 {
+  void *view;
+  struct frame *f;
+
+  f = WINDOW_XFRAME (XWINDOW (bar->window));
+  view = FRAME_HAIKU_VIEW (f);
+
   block_input ();
-  void *view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (XWINDOW (bar->window)));
-  BView_forget_scroll_bar (view, bar->left, bar->top, bar->width, bar->height);
+  BView_forget_scroll_bar (view, bar->left, bar->top,
+                          bar->width, bar->height);
   BScrollBar_delete (bar->scroll_bar);
   expose_frame (WINDOW_XFRAME (XWINDOW (bar->window)),
                bar->left, bar->top, bar->width, bar->height);
@@ -4100,7 +4137,6 @@ haiku_scroll_bar_remove (struct scroll_bar *bar)
     wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil);
   else
     wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
-
   unblock_input ();
 };
 
diff --git a/src/image.c b/src/image.c
index e4b56e29cf..757e125006 100644
--- a/src/image.c
+++ b/src/image.c
@@ -542,12 +542,22 @@ image_create_bitmap_from_data (struct frame *f, char 
*bits,
 #endif /* HAVE_PGTK */
 
 #ifdef HAVE_HAIKU
-  void *bitmap = BBitmap_new (width, height, 1);
+  void *bitmap;
+  int bytes_per_line, x, y;
+
+  bitmap = BBitmap_new (width, height, 1);
 
   if (!bitmap)
     return -1;
 
-  BBitmap_import_mono_bits (bitmap, bits, width, height);
+  bytes_per_line = (width + 7) / 8;
+
+  for (y = 0; y < height; y++)
+    {
+      for (x = 0; x < width; x++)
+       PUT_PIXEL (bitmap, x, y, (bits[8] >> (x % 8)) & 1);
+      bits += bytes_per_line;
+    }
 #endif
 
   id = image_allocate_bitmap_record (f);
@@ -592,12 +602,19 @@ image_create_bitmap_from_data (struct frame *f, char 
*bits,
   return id;
 }
 
+#ifdef HAVE_HAIKU
+static char *slurp_file (int, ptrdiff_t *);
+static Lisp_Object image_find_image_fd (Lisp_Object, int *);
+static bool xbm_read_bitmap_data (struct frame *, char *, char *,
+                                 int *, int *, char **, bool);
+#endif
+
 /* Create bitmap from file FILE for frame F.  */
 
 ptrdiff_t
 image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
 {
-#if defined (HAVE_NTGUI) || defined (HAVE_HAIKU)
+#if defined (HAVE_NTGUI)
   return -1;  /* W32_TODO : bitmap support */
 #else
   Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
@@ -610,7 +627,6 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object 
file)
   if (!bitmap)
       return -1;
 
-
   id = image_allocate_bitmap_record (f);
   dpyinfo->bitmaps[id - 1].img = bitmap;
   dpyinfo->bitmaps[id - 1].refcount = 1;
@@ -637,7 +653,6 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object 
file)
   dpyinfo->bitmaps[id - 1].img = bitmap;
   dpyinfo->bitmaps[id - 1].refcount = 1;
   dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
-  //dpyinfo->bitmaps[id - 1].depth = 1;
   dpyinfo->bitmaps[id - 1].height = gdk_pixbuf_get_width (bitmap);
   dpyinfo->bitmaps[id - 1].width = gdk_pixbuf_get_height (bitmap);
   dpyinfo->bitmaps[id - 1].pattern
@@ -692,6 +707,63 @@ image_create_bitmap_from_file (struct frame *f, 
Lisp_Object file)
 
   return id;
 #endif /* HAVE_X_WINDOWS */
+
+#ifdef HAVE_HAIKU
+  ptrdiff_t id, size;
+  int fd, width, height, rc, bytes_per_line, x, y;
+  char *contents, *data, *tmp;
+  void *bitmap;
+
+  if (!STRINGP (image_find_image_fd (file, &fd)))
+    return -1;
+
+  contents = slurp_file (fd, &size);
+
+  if (!contents)
+    return -1;
+
+  rc = xbm_read_bitmap_data (f, contents, contents + size,
+                            &width, &height, &data, 0);
+
+  if (!rc)
+    {
+      xfree (contents);
+      return -1;
+    }
+
+  bitmap = BBitmap_new (width, height, 1);
+
+  if (!bitmap)
+    {
+      xfree (contents);
+      xfree (data);
+      return -1;
+    }
+
+  id = image_allocate_bitmap_record (f);
+
+  dpyinfo->bitmaps[id - 1].img = bitmap;
+  dpyinfo->bitmaps[id - 1].depth = 1;
+  dpyinfo->bitmaps[id - 1].file = NULL;
+  dpyinfo->bitmaps[id - 1].height = height;
+  dpyinfo->bitmaps[id - 1].width = width;
+  dpyinfo->bitmaps[id - 1].refcount = 1;
+
+  bytes_per_line = (width + 7) / 8;
+  tmp = data;
+
+  for (y = 0; y < height; y++)
+    {
+      for (x = 0; x < width; x++)
+       PUT_PIXEL (bitmap, x, y, (tmp[x / 8] >> (x % 8)) & 1);
+
+      tmp += bytes_per_line;
+    }
+
+  xfree (contents);
+  xfree (data);
+  return id;
+#endif
 }
 
 /* Free bitmap B.  */



reply via email to

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