[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. */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master faa342c794: Implement bitmap loading for faces on Haiku,
Po Lu <=