Add Stipple support for PGTK
* ../src/pgtkterm.c (create_background_surface_by_face) (create_background_surface, x_draw_glyph_string_background) (x_draw_glyph_string_bg_rect, x_draw_image_glyph_string) (x_draw_stretch_glyph_string, pgtk_draw_fringe_bitmap): handle stipple * ../src/image.c (image_create_bitmap_from_file, ) (syms_of_image): Add pgtk support * ../lisp/faces.el (face-valid-attribute-values): add pgtk support stipple 対応。 stipple がまともに動いてなかったので修正。
This commit is contained in:
parent
1d549fa069
commit
85441c96d7
3 changed files with 130 additions and 84 deletions
|
@ -1151,13 +1151,14 @@ an integer value."
|
|||
(:height
|
||||
'integerp)
|
||||
(:stipple
|
||||
(and (memq (window-system frame) '(x ns)) ; No stipple on w32
|
||||
(mapcar #'list
|
||||
(and (memq (window-system frame) '(x ns pgtk)) ; No stipple on w32
|
||||
(mapcar (lambda (f)
|
||||
(cons (file-name-base f) f))
|
||||
(apply #'nconc
|
||||
(mapcar (lambda (dir)
|
||||
(and (file-readable-p dir)
|
||||
(file-directory-p dir)
|
||||
(directory-files dir)))
|
||||
(directory-files dir 'full)))
|
||||
x-bitmap-file-path)))))
|
||||
(:inherit
|
||||
(cons '("none" . nil)
|
||||
|
|
|
@ -507,12 +507,14 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_PGTK
|
||||
GError *err;
|
||||
GError *err = NULL;
|
||||
ptrdiff_t id;
|
||||
void * bitmap = gdk_pixbuf_new_from_file(SSDATA(file), &err);
|
||||
|
||||
if (!bitmap)
|
||||
if (!bitmap) {
|
||||
g_error_free(err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
id = image_allocate_bitmap_record(f);
|
||||
|
||||
|
@ -10698,7 +10700,7 @@ non-numeric, there is no explicit limit on the size of images. */);
|
|||
DEFSYM (Qxbm, "xbm");
|
||||
add_image_type (Qxbm);
|
||||
|
||||
#if defined (HAVE_XPM) || defined (HAVE_NS)
|
||||
#if defined (HAVE_XPM) || defined (HAVE_NS) || defined (USE_CAIRO)
|
||||
DEFSYM (Qxpm, "xpm");
|
||||
add_image_type (Qxpm);
|
||||
#endif
|
||||
|
|
199
src/pgtkterm.c
199
src/pgtkterm.c
|
@ -984,6 +984,66 @@ x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
|
|||
}
|
||||
|
||||
|
||||
static cairo_surface_t *
|
||||
create_background_surface_by_face (struct frame *f, struct face *face, int x, int y, int width, int height)
|
||||
{
|
||||
cairo_surface_t *surface = cairo_surface_create_similar (FRAME_CR_SURFACE (f),
|
||||
CAIRO_CONTENT_COLOR,
|
||||
width,
|
||||
height);
|
||||
|
||||
{
|
||||
cairo_t *cr = cairo_create (surface);
|
||||
|
||||
double r = ((face->background >> 16) & 0xff) / 255.0;
|
||||
double g = ((face->background >> 8) & 0xff) / 255.0;
|
||||
double b = ((face->background >> 0) & 0xff) / 255.0;
|
||||
cairo_set_source_rgb (cr, r, g, b);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
if (face->stipple != 0) {
|
||||
GdkPixbuf *pixbuf = FRAME_DISPLAY_INFO (f)->bitmaps[face->stipple - 1].img;
|
||||
GdkPixbuf *pb = gdk_pixbuf_add_alpha (pixbuf, TRUE, 255, 255, 255);
|
||||
cairo_surface_t *mask = cairo_surface_create_similar_image (FRAME_CR_SURFACE (f),
|
||||
CAIRO_FORMAT_A1,
|
||||
width,
|
||||
height);
|
||||
|
||||
{
|
||||
cairo_t *cr = cairo_create (mask);
|
||||
gdk_cairo_set_source_pixbuf (cr, pb, 0, 0);
|
||||
cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
{
|
||||
cairo_t *cr = cairo_create (surface);
|
||||
double r = ((face->foreground >> 16) & 0xff) / 255.0;
|
||||
double g = ((face->foreground >> 8) & 0xff) / 255.0;
|
||||
double b = ((face->foreground >> 0) & 0xff) / 255.0;
|
||||
cairo_set_source_rgb (cr, r, g, b);
|
||||
cairo_mask_surface (cr, mask, 0, 0);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
cairo_surface_destroy (mask);
|
||||
g_object_unref (pb);
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
create_background_surface (struct glyph_string *s, int x, int y, int width, int height)
|
||||
{
|
||||
return create_background_surface_by_face (s->f, s->face, x, y, width, height);
|
||||
}
|
||||
|
||||
/* 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
|
||||
background even if it wouldn't be drawn normally. This is used
|
||||
|
@ -1007,20 +1067,28 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
|
|||
PGTK_TRACE("x_draw_glyph_string_background: 2. %d.", s->font_not_found_p);
|
||||
PGTK_TRACE("x_draw_glyph_string_background: 2. %d.", s->extends_to_end_of_line_p);
|
||||
PGTK_TRACE("x_draw_glyph_string_background: 2. %d.", force_p);
|
||||
#if 0
|
||||
|
||||
if (s->stippled_p)
|
||||
{
|
||||
/* Fill background with a stipple pattern. */
|
||||
XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
|
||||
x_fill_rectangle (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);
|
||||
|
||||
cairo_surface_t *bg = create_background_surface (s,
|
||||
s->x, s->y + box_line_width,
|
||||
s->background_width, s->height - 2 * box_line_width);
|
||||
|
||||
cairo_t *cr = pgtk_begin_cr_clip (s->f);
|
||||
cairo_set_source_surface (cr, bg, s->x, s->y + box_line_width);
|
||||
cairo_rectangle (cr,
|
||||
s->x, s->y + box_line_width,
|
||||
s->background_width, s->height - 2 * box_line_width);
|
||||
cairo_fill (cr);
|
||||
pgtk_end_cr_clip (s->f);
|
||||
|
||||
cairo_surface_destroy (bg);
|
||||
|
||||
s->background_filled_p = true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
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
|
||||
|
@ -1821,16 +1889,21 @@ x_draw_image_relief (struct glyph_string *s)
|
|||
static void
|
||||
x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
|
||||
{
|
||||
#if 0
|
||||
if (s->stippled_p)
|
||||
{
|
||||
/* Fill background with a stipple pattern. */
|
||||
XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
|
||||
x_fill_rectangle (s->f, s->gc, x, y, w, h);
|
||||
XSetFillStyle (s->display, s->gc, FillSolid);
|
||||
|
||||
cairo_surface_t *bg = create_background_surface (s, x, y, w, h);
|
||||
|
||||
cairo_t *cr = pgtk_begin_cr_clip (s->f);
|
||||
cairo_set_source_surface (cr, bg, x, y);
|
||||
cairo_rectangle (cr, x, y, w, h);
|
||||
cairo_fill (cr);
|
||||
pgtk_end_cr_clip (s->f);
|
||||
|
||||
cairo_surface_destroy (bg);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
x_clear_glyph_string_rect (s, x, y, w, h);
|
||||
}
|
||||
|
||||
|
@ -1881,7 +1954,6 @@ x_draw_image_glyph_string (struct glyph_string *s)
|
|||
int box_line_hwidth = eabs (s->face->box_line_width);
|
||||
int box_line_vwidth = max (s->face->box_line_width, 0);
|
||||
int height;
|
||||
cairo_surface_t *surface = NULL;
|
||||
|
||||
height = s->height;
|
||||
if (s->slice.y == 0)
|
||||
|
@ -1903,43 +1975,15 @@ x_draw_image_glyph_string (struct glyph_string *s)
|
|||
{
|
||||
if (s->img->mask)
|
||||
{
|
||||
/* Create a pixmap as large as the glyph string. Fill it
|
||||
with the background color. Copy the image to it, using
|
||||
its mask. Copy the temporary pixmap to the display. */
|
||||
cairo_surface_t *bg = create_background_surface (s, s->x, s->y, s->background_width, s->height);
|
||||
|
||||
/* Create a pixmap as large as the glyph string. */
|
||||
surface = cairo_surface_create_similar(FRAME_CR_SURFACE(s->f), CAIRO_CONTENT_COLOR_ALPHA,
|
||||
s->background_width,
|
||||
s->height);
|
||||
cairo_t *cr = pgtk_begin_cr_clip (s->f);
|
||||
cairo_set_source_surface (cr, bg, s->x, s->y);
|
||||
cairo_rectangle (cr, s->x, s->y, s->background_width, s->height);
|
||||
cairo_fill (cr);
|
||||
pgtk_end_cr_clip (s->f);
|
||||
|
||||
/* Don't clip in the following because we're working on the
|
||||
pixmap. */
|
||||
// XSetClipMask (s->display, s->gc, None);
|
||||
|
||||
/* Fill the pixmap with the background color/stipple. */
|
||||
#if 0
|
||||
if (s->stippled_p)
|
||||
{
|
||||
/* Fill background with a stipple pattern. */
|
||||
XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
|
||||
XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
|
||||
XFillRectangle (s->display, pixmap, s->gc,
|
||||
0, 0, s->background_width, s->height);
|
||||
XSetFillStyle (s->display, s->gc, FillSolid);
|
||||
XSetTSOrigin (s->display, s->gc, 0, 0);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
cairo_t *cr = cairo_create(surface);
|
||||
int red = (s->xgcv.background >> 16) & 0xff;
|
||||
int green = (s->xgcv.background >> 8) & 0xff;
|
||||
int blue = (s->xgcv.background >> 0) & 0xff;
|
||||
cairo_set_source_rgb (cr, red / 255.0, green / 255.0, blue / 255.0);
|
||||
cairo_rectangle(cr, 0, 0, s->background_width, s->height);
|
||||
cairo_fill(cr);
|
||||
cairo_destroy(cr);
|
||||
}
|
||||
cairo_surface_destroy (bg);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1957,7 +2001,15 @@ x_draw_image_glyph_string (struct glyph_string *s)
|
|||
if (s->slice.y == 0)
|
||||
y += box_line_vwidth;
|
||||
|
||||
x_draw_glyph_string_bg_rect (s, x, y, width, height);
|
||||
cairo_surface_t *bg = create_background_surface (s, x, y, width, height);
|
||||
|
||||
cairo_t *cr = pgtk_begin_cr_clip (s->f);
|
||||
cairo_set_source_surface (cr, bg, x, y);
|
||||
cairo_rectangle (cr, x, y, width, height);
|
||||
cairo_fill (cr);
|
||||
pgtk_end_cr_clip (s->f);
|
||||
|
||||
cairo_surface_destroy (bg);
|
||||
}
|
||||
|
||||
s->background_filled_p = true;
|
||||
|
@ -1978,18 +2030,6 @@ x_draw_image_glyph_string (struct glyph_string *s)
|
|||
cairo_fill (cr);
|
||||
pgtk_end_cr_clip (s->f);
|
||||
}
|
||||
else
|
||||
if (surface != NULL)
|
||||
{
|
||||
cairo_t *cr = pgtk_begin_cr_clip(s->f);
|
||||
|
||||
x_draw_image_foreground_1 (s, surface);
|
||||
x_set_glyph_string_clipping (s, cr);
|
||||
|
||||
cairo_set_source_surface(cr, surface, 0, 0);
|
||||
cairo_rectangle(cr, s->x, s->y, s->background_width, s->height);
|
||||
pgtk_end_cr_clip(s->f);
|
||||
}
|
||||
else
|
||||
x_draw_image_foreground (s);
|
||||
|
||||
|
@ -1998,9 +2038,6 @@ x_draw_image_glyph_string (struct glyph_string *s)
|
|||
|| s->hl == DRAW_IMAGE_RAISED
|
||||
|| s->hl == DRAW_IMAGE_SUNKEN)
|
||||
x_draw_image_relief (s);
|
||||
|
||||
if (surface != NULL)
|
||||
cairo_surface_destroy(surface);
|
||||
}
|
||||
|
||||
/* Draw stretch glyph string S. */
|
||||
|
@ -2071,16 +2108,18 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
|
|||
get_glyph_string_clip_rect (s, &r);
|
||||
x_set_clip_rectangles (s->f, cr, &r, 1);
|
||||
|
||||
#if 0
|
||||
if (s->face->stipple)
|
||||
{
|
||||
/* Fill background with a stipple pattern. */
|
||||
XSetFillStyle (s->display, gc, FillOpaqueStippled);
|
||||
x_fill_rectangle (s->f, gc, x, y, w, h);
|
||||
XSetFillStyle (s->display, gc, FillSolid);
|
||||
cairo_surface_t *bg = create_background_surface (s, x, y, w, h);
|
||||
cairo_t *cr = pgtk_begin_cr_clip (s->f);
|
||||
cairo_set_source_surface (cr, bg, x, y);
|
||||
cairo_rectangle (cr, x, y, w, h);
|
||||
cairo_fill (cr);
|
||||
pgtk_end_cr_clip (s->f);
|
||||
cairo_surface_destroy (bg);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
pgtk_fill_rectangle(s->f, color, x, y, w, h);
|
||||
}
|
||||
|
@ -3195,15 +3234,19 @@ pgtk_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fr
|
|||
for something displayed in the text (e.g. face `region' on
|
||||
mono-displays, the fill style may have been changed to
|
||||
FillSolid in x_draw_glyph_string_background. */
|
||||
#if 0
|
||||
if (face->stipple)
|
||||
XSetFillStyle (display, face->gc, FillOpaqueStippled);
|
||||
else
|
||||
#endif
|
||||
if (face->stipple) {
|
||||
cairo_surface_t *bg = create_background_surface_by_face(f, face, p->bx, p->by, p->nx, p->ny);
|
||||
cairo_t *cr = pgtk_begin_cr_clip (f);
|
||||
cairo_set_source_surface (cr, bg, p->bx, p->by);
|
||||
cairo_rectangle (cr, p->bx, p->by, p->nx, p->ny);
|
||||
cairo_fill (cr);
|
||||
pgtk_end_cr_clip (f);
|
||||
cairo_surface_destroy (bg);
|
||||
} else {
|
||||
pgtk_set_cr_source_with_color(f, face->background);
|
||||
|
||||
cairo_rectangle(cr, p->bx, p->by, p->nx, p->ny);
|
||||
cairo_fill(cr);
|
||||
cairo_rectangle(cr, p->bx, p->by, p->nx, p->ny);
|
||||
cairo_fill(cr);
|
||||
}
|
||||
}
|
||||
|
||||
PGTK_TRACE("which: %d, max_fringe_bmp: %d.", p->which, max_fringe_bmp);
|
||||
|
|
Loading…
Add table
Reference in a new issue