[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)