emacs-diffs
[Top][All Lists]
Advanced

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

master b205d67f8c 1/2: Fully implement stipples for text on Haiku


From: Po Lu
Subject: master b205d67f8c 1/2: Fully implement stipples for text on Haiku
Date: Sun, 8 May 2022 01:10:40 -0400 (EDT)

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

    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.
---
 src/haikufont.c |   4 +-
 src/haikuterm.c | 111 +++++++++++++++++++++++++++++++++++++-------------------
 src/haikuterm.h |   7 ++++
 src/image.c     |  30 ++++++++++++---
 4 files changed, 107 insertions(+), 45 deletions(-)

diff --git a/src/haikufont.c b/src/haikufont.c
index e0db086aa0..54f11c6e41 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 46ea5f9027..93af5c8e43 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 1bff03ae39..cc032d0389 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 757e125006..f3b47f7ccc 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)



reply via email to

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