Stipple support for MS Windows (bug#71159)
* src/w32term.c (w32_fill_stipple_pattern): New function. (w32_draw_glyph_string_bg_rect w32_draw_stretch_glyph_string) (w32_draw_glyph_string_background): Use new stipple function. * src/w32term.h (w32_bitmap_record): Add stipple value. * src/image.c (image_create_bitmap_from_data): Create stipple bitmap. (image_create_bitmap_from_file): Add suuport for pixmap and create stipple bitmap. (free_bitmap_record): Release stipple. * etc/NEWS: Announce support for stipples in MS-Windows.
This commit is contained in:
parent
5ad8ebe6e2
commit
48bb25c0e3
4 changed files with 124 additions and 37 deletions
3
etc/NEWS
3
etc/NEWS
|
@ -2852,6 +2852,9 @@ thumbnail images and show them in the thumbnail buffer. Unlike with
|
|||
using 'convert', this fallback method is synchronous, so Emacs will wait
|
||||
until all the thumbnails are created and displayed, before showing them.
|
||||
|
||||
---
|
||||
*** Emacs on MS-Windows now supports the ':stipple' face attribute.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
This file is part of GNU Emacs.
|
||||
|
|
102
src/image.c
102
src/image.c
|
@ -130,6 +130,12 @@ typedef struct w32_bitmap_record Bitmap_Record;
|
|||
#define PIX_MASK_RETAIN 0
|
||||
#define PIX_MASK_DRAW 1
|
||||
|
||||
#define XBM_BIT_SHUFFLE(b) (~(b))
|
||||
|
||||
#else
|
||||
|
||||
#define XBM_BIT_SHUFFLE(b) (b)
|
||||
|
||||
#endif /* HAVE_NTGUI */
|
||||
|
||||
#ifdef HAVE_NS
|
||||
|
@ -214,6 +220,11 @@ static void free_color_table (void);
|
|||
static unsigned long *colors_in_color_table (int *n);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NTGUI
|
||||
static HBITMAP w32_create_pixmap_from_bitmap_data (int, int, char *);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_WEBP) || defined (HAVE_GIF)
|
||||
static void anim_prune_animation_cache (Lisp_Object);
|
||||
#endif
|
||||
|
@ -596,13 +607,31 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
|
|||
#endif /* HAVE_ANDROID && !defined ANDROID_STUBIFY */
|
||||
|
||||
#ifdef HAVE_NTGUI
|
||||
Lisp_Object frame UNINIT; /* The value is not used. */
|
||||
Emacs_Pixmap bitmap;
|
||||
bitmap = CreateBitmap (width, height,
|
||||
FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes,
|
||||
FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits,
|
||||
bits);
|
||||
if (! bitmap)
|
||||
Emacs_Pixmap stipple;
|
||||
Emacs_Pixmap bitmap = CreateBitmap (width, height, dpyinfo->n_planes,
|
||||
dpyinfo->n_cbits, bits);
|
||||
|
||||
/* Convert X bitmap to W32 bitmap. */
|
||||
/* Windows mono bitmaps are reversed compared with X. */
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
{
|
||||
char *invertedBits;
|
||||
int nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height, i;
|
||||
|
||||
invertedBits = bits;
|
||||
|
||||
SAFE_NALLOCA (bits, 1, nbytes);
|
||||
|
||||
for (i = 0; i < nbytes; i++)
|
||||
bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]);
|
||||
}
|
||||
|
||||
stipple = w32_create_pixmap_from_bitmap_data (width, height, bits);
|
||||
|
||||
SAFE_FREE ();
|
||||
|
||||
if (!bitmap || !stipple)
|
||||
return -1;
|
||||
#endif /* HAVE_NTGUI */
|
||||
|
||||
|
@ -681,6 +710,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
|
|||
|
||||
#ifdef HAVE_NTGUI
|
||||
dpyinfo->bitmaps[id - 1].pixmap = bitmap;
|
||||
dpyinfo->bitmaps[id - 1].stipple = stipple;
|
||||
dpyinfo->bitmaps[id - 1].hinst = NULL;
|
||||
dpyinfo->bitmaps[id - 1].depth = 1;
|
||||
#endif /* HAVE_NTGUI */
|
||||
|
@ -699,7 +729,7 @@ typedef int image_fd;
|
|||
#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
|
||||
|
||||
#if defined HAVE_HAIKU || defined HAVE_NS || defined HAVE_PGTK \
|
||||
|| defined HAVE_ANDROID
|
||||
|| defined HAVE_ANDROID || defined HAVE_NTGUI
|
||||
static char *slurp_file (image_fd, ptrdiff_t *);
|
||||
static Lisp_Object image_find_image_fd (Lisp_Object, image_fd *);
|
||||
static bool xbm_read_bitmap_data (struct frame *, char *, char *,
|
||||
|
@ -711,10 +741,53 @@ static bool xbm_read_bitmap_data (struct frame *, char *, char *,
|
|||
ptrdiff_t
|
||||
image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
|
||||
{
|
||||
#if defined (HAVE_NTGUI)
|
||||
return -1; /* W32_TODO : bitmap support */
|
||||
#else
|
||||
Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
|
||||
|
||||
#ifdef HAVE_NTGUI
|
||||
ptrdiff_t id, size;
|
||||
int width, height, rc;
|
||||
image_fd fd;
|
||||
char *contents, *data;
|
||||
Emacs_Pixmap 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;
|
||||
}
|
||||
|
||||
{
|
||||
/* Windows mono bitmaps are reversed compared with X. */
|
||||
|
||||
int nbytes, i;
|
||||
nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height;
|
||||
|
||||
for (i = 0; i < nbytes; i++)
|
||||
data[i] = XBM_BIT_SHUFFLE (data[i]);
|
||||
}
|
||||
|
||||
id = image_allocate_bitmap_record (f);
|
||||
bitmap = w32_create_pixmap_from_bitmap_data (width, height, data);
|
||||
|
||||
dpyinfo->bitmaps[id - 1].height = width;
|
||||
dpyinfo->bitmaps[id - 1].width = height;
|
||||
dpyinfo->bitmaps[id - 1].stipple = bitmap;
|
||||
dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
|
||||
|
||||
xfree (contents);
|
||||
xfree (data);
|
||||
return id;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NS
|
||||
|
@ -1037,6 +1110,7 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm)
|
|||
|
||||
#ifdef HAVE_NTGUI
|
||||
DeleteObject (bm->pixmap);
|
||||
DeleteObject (bm->stipple);
|
||||
#endif /* HAVE_NTGUI */
|
||||
|
||||
#ifdef HAVE_NS
|
||||
|
@ -4800,12 +4874,6 @@ convert_mono_to_color_image (struct frame *f, struct image *img,
|
|||
img->pixmap = new_pixmap;
|
||||
}
|
||||
|
||||
#define XBM_BIT_SHUFFLE(b) (~(b))
|
||||
|
||||
#else
|
||||
|
||||
#define XBM_BIT_SHUFFLE(b) (b)
|
||||
|
||||
#endif /* HAVE_NTGUI */
|
||||
|
||||
|
||||
|
|
|
@ -1248,6 +1248,34 @@ w32_clear_glyph_string_rect (struct glyph_string *s,
|
|||
real_w, real_h);
|
||||
}
|
||||
|
||||
/* Fill background with bitmap pattern from S at specified position
|
||||
given by X and Y. WIDTH and HEIGHT specifies bitmap size, GC is
|
||||
used to get foreground and background color context and HDC where
|
||||
fill it. */
|
||||
|
||||
static void
|
||||
w32_fill_stipple_pattern (HDC hdc, struct glyph_string *s, Emacs_GC *gc,
|
||||
int x, int y, unsigned int width, unsigned int height)
|
||||
{
|
||||
SetTextColor (hdc, gc->foreground);
|
||||
SetBkColor (hdc, gc->background);
|
||||
|
||||
RECT r;
|
||||
Emacs_Pixmap bm;
|
||||
HBRUSH hb;
|
||||
|
||||
r.left = x;
|
||||
r.top = y;
|
||||
r.right = x + width;
|
||||
r.bottom = y + height;
|
||||
|
||||
bm = FRAME_DISPLAY_INFO (s->f)->bitmaps[s->face->stipple - 1].stipple;
|
||||
|
||||
hb = CreatePatternBrush (bm);
|
||||
FillRect (hdc, &r, hb);
|
||||
|
||||
DeleteObject (hb);
|
||||
}
|
||||
|
||||
/* Draw the background of glyph_string S. If S->background_filled_p
|
||||
is non-zero don't draw it. FORCE_P non-zero means draw the
|
||||
|
@ -1264,21 +1292,16 @@ w32_draw_glyph_string_background (struct glyph_string *s, bool force_p)
|
|||
{
|
||||
int box_line_width = max (s->face->box_horizontal_line_width, 0);
|
||||
|
||||
#if 0 /* TODO: stipple */
|
||||
if (s->stippled_p)
|
||||
{
|
||||
/* Fill background with a stipple pattern. */
|
||||
XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
|
||||
XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, s->x,
|
||||
s->y + box_line_width,
|
||||
s->background_width,
|
||||
s->height - 2 * box_line_width);
|
||||
XSetFillStyle (s->display, s->gc, FillSolid);
|
||||
w32_fill_stipple_pattern (s->hdc, s, s->gc, s->x,
|
||||
s->y + box_line_width,
|
||||
s->background_width,
|
||||
s->height - 2 * box_line_width);
|
||||
s->background_filled_p = true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
|
||||
else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
|
||||
/* When xdisp.c ignores FONT_HEIGHT, we cannot trust
|
||||
font dimensions, since the actual glyphs might be
|
||||
much smaller. So in that case we always clear the
|
||||
|
@ -2286,16 +2309,12 @@ w32_draw_image_foreground_1 (struct glyph_string *s, HBITMAP pixmap)
|
|||
static void
|
||||
w32_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
|
||||
{
|
||||
#if 0 /* TODO: stipple */
|
||||
if (s->stippled_p)
|
||||
{
|
||||
/* Fill background with a stipple pattern. */
|
||||
XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
|
||||
XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, x, y, w, h);
|
||||
XSetFillStyle (s->display, s->gc, FillSolid);
|
||||
w32_fill_stipple_pattern (s->hdc, s, s->gc, x, y, w, h);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
w32_clear_glyph_string_rect (s, x, y, w, h);
|
||||
}
|
||||
|
||||
|
@ -2500,16 +2519,12 @@ w32_draw_stretch_glyph_string (struct glyph_string *s)
|
|||
get_glyph_string_clip_rect (s, &r);
|
||||
w32_set_clip_rectangle (hdc, &r);
|
||||
|
||||
#if 0 /* TODO: stipple */
|
||||
if (s->face->stipple)
|
||||
{
|
||||
/* Fill background with a stipple pattern. */
|
||||
XSetFillStyle (s->display, gc, FillOpaqueStippled);
|
||||
XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), gc, x, y, w, h);
|
||||
XSetFillStyle (s->display, gc, FillSolid);
|
||||
w32_fill_stipple_pattern (s->hdc, s, gc, x, y, w, h);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ struct w32_bitmap_record
|
|||
{
|
||||
Emacs_Pixmap pixmap;
|
||||
char *file;
|
||||
Emacs_Pixmap stipple;
|
||||
HINSTANCE hinst; /* Used to load the file */
|
||||
int refcount;
|
||||
/* Record some info about this pixmap. */
|
||||
|
|
Loading…
Add table
Reference in a new issue