Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
2fa898a
Add README for the EmacsMoe patchset
ksqsf Jan 9, 2020
5516504
Proof of concept: text with shadows
ksqsf Jan 9, 2020
962206e
Initial implementation for macOS
ksqsf Jan 14, 2020
749eeea
Fix punctuation in README.
ksqsf Jan 15, 2020
dcd69b2
add travis ci
ksqsf Jan 20, 2020
4535bbe
add linux support to travis
ksqsf Jan 20, 2020
538a83b
Merge branch 'master' into feature/shadow
ksqsf Jan 20, 2020
6d80bf6
Initial implementation for Cairo.
ksqsf May 23, 2020
4586472
PoC of GNU/Linux support
ksqsf May 23, 2020
8be5965
Plug in values
ksqsf May 24, 2020
0274e0e
Format must have alpha channel
ksqsf May 24, 2020
afabd01
My box blur is even slower than Gaussian blur...
ksqsf May 24, 2020
f4dcdae
Merge remote-tracking branch 'upstream/master' into master
ksqsf Oct 22, 2020
7190f26
Merge branch 'master' into feature/shadow
ksqsf Oct 22, 2020
3223675
Merge remote-tracking branch 'upstream/master'
ksqsf Mar 3, 2023
d9ddcbf
Merge branch 'master' into feature/shadow
ksqsf Mar 3, 2023
a513c89
; Fix merge errors.
ksqsf Mar 3, 2023
3b38343
Add test drivers to see text shadow effects
ksqsf Mar 3, 2023
cac87a4
Optimize the Gaussian blur on Linux
ksqsf Mar 3, 2023
abf2b6a
Optimize
ksqsf Mar 3, 2023
0435b23
Import OpenCV for Gaussian blur.
ksqsf Mar 6, 2023
c5e5533
Do not blur the whole clip.
ksqsf Mar 7, 2023
16fe8b8
Revert "Import OpenCV for Gaussian blur."
ksqsf Mar 7, 2023
f3659c2
Remove OpenMP from the Gaussian blur
ksqsf Mar 7, 2023
d64b98e
Revert "Revert "Import OpenCV for Gaussian blur.""
ksqsf Mar 7, 2023
437b050
Implement color support for Linux
ksqsf Mar 7, 2023
3c2dd74
Fix build.
ksqsf Mar 7, 2023
47ed5af
Fix build.
ksqsf Mar 7, 2023
66e9fd8
Show info about :shadow in describe-face
ksqsf Mar 11, 2023
a5318be
Linux: Support offset
ksqsf Mar 11, 2023
fa3d418
Linux: specify the blur in pixels
ksqsf Mar 11, 2023
df5dcc7
Mac: Fix offset.
ksqsf Mar 11, 2023
5f1c378
Linux: fix out-of-bounds access
ksqsf Mar 11, 2023
dc56e34
Linux: expand the bounding box
ksqsf Mar 11, 2023
cbcdcc4
Remove OpenCV.
ksqsf Mar 11, 2023
c9b4fea
; Fix last commit
ksqsf Mar 11, 2023
7dccc51
Fix pgtk build
ksqsf Mar 12, 2023
a38a6dc
Mac: fix color
ksqsf Mar 12, 2023
1029cb8
Add a more comprehensive demo
ksqsf Mar 12, 2023
3e1f57b
Merge branch 'feature/shadow' of github.com:ksqsf/emacsmoe into ksqsf…
jakeprime Oct 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
language: c
compiler: clang

addons:
apt:
update: true
packages:
- libxml2-dev
- libgtk-3-dev
- libxpm-dev
- libgif-dev
- libgnutls-dev

jobs:
include:
- os: osx
before_script: ./autogen.sh && ./configure --without-makeinfo --with-ns --without-xml2
script: make -j8
- os: linux
before_script: ./autogen.sh && ./configure --without-makeinfo --with-x --with-x-toolkit=gtk3
script: make -j8
File renamed without changes.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# EmacsMoe Patchset

The original README is `README.emacs`.

This patchset tries to introduce modern visual effects to Emacs. Like
them or not, implementing them is a fun weekend project.

## Help wanted!

1. As you know, Emacs supports a variety of GUI platforms. I'm familiar
with none of them! Right now, I have only Linux and macOS
environments, so at least someone with Windows expertise is wanted.
2. There may be design flaws. Please don't hesitate to bring forth
your idea.

## Implemented features

Nothing so far.

## WIP

- Colorful Shadows. [Like this one.](https://marketplace.visualstudio.com/items?itemName=webrender.synthwave-x-fluoromachine)

## Planned

- Background images.
7 changes: 7 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -4383,6 +4383,7 @@ if test "${HAVE_X11}" = "yes"; then
fi

HAVE_CAIRO=no
CAIRO_OBJ=""
if test "${HAVE_X11}" = "yes"; then
if test "${with_cairo}" != "no"; then
CAIRO_REQUIRED=1.8.0
Expand All @@ -4400,8 +4401,10 @@ if test "${HAVE_X11}" = "yes"; then
AC_DEFINE([USE_CAIRO], [1], [Define to 1 if using cairo.])
CFLAGS="$CFLAGS $CAIRO_CFLAGS"
LIBS="$LIBS $CAIRO_LIBS"
CAIRO_OBJ="xcairo.o"
AC_SUBST([CAIRO_CFLAGS])
AC_SUBST([CAIRO_LIBS])
AC_SUBST([CAIRO_OBJ])
else
AC_MSG_WARN([cairo requested but not found.])
fi
Expand Down Expand Up @@ -4469,8 +4472,10 @@ if test "$window_system" = "pgtk"; then

CFLAGS="$CFLAGS $CAIRO_CFLAGS"
LIBS="$LIBS $CAIRO_LIBS"
CAIRO_OBJ="xcairo.o"
AC_SUBST([CAIRO_CFLAGS])
AC_SUBST([CAIRO_LIBS])
AC_SUBST([CAIRO_OBJ])
fi

if test "${HAVE_BE_APP}" = "yes"; then
Expand All @@ -4482,8 +4487,10 @@ if test "${HAVE_BE_APP}" = "yes"; then
AC_DEFINE([USE_BE_CAIRO], [1], [Define to 1 if using cairo on Haiku.])
CFLAGS="$CFLAGS $CAIRO_CFLAGS"
LIBS="$LIBS $CAIRO_LIBS"
CAIRO_OBJ="xcairo.o"
AC_SUBST([CAIRO_CFLAGS])
AC_SUBST([CAIRO_LIBS])
AC_SUBST([CAIRO_OBJ])
else
AC_MSG_WARN([cairo requested but not found.])
fi
Expand Down
1 change: 1 addition & 0 deletions lisp/faces.el
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,7 @@ an integer value."
(:height . "height in 1/10 pt")
(:weight . "weight")
(:slant . "slant")
(:shadow . "shadow")
(:underline . "underline")
(:overline . "overline")
(:extend . "extend")
Expand Down
1 change: 1 addition & 0 deletions lisp/help-fns.el
Original file line number Diff line number Diff line change
Expand Up @@ -1835,6 +1835,7 @@ If FRAME is omitted or nil, use the selected frame."
(:foreground . "Foreground")
(:distant-foreground . "DistantForeground")
(:background . "Background")
(:shadow . "Shadow")
(:underline . "Underline")
(:overline . "Overline")
(:strike-through . "Strike-through")
Expand Down
8 changes: 8 additions & 0 deletions moe/shadow-demo.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
;; To see the effect of text shadows, use the command:
;; emacs -q -l moe/shadow-demo.el

(set-face-attribute 'font-lock-function-name-face nil :shadow '(5.0 . "red"))
(set-face-attribute 'font-lock-variable-name-face nil :shadow '(5.0 . "green"))
(set-face-attribute 'font-lock-keyword-face nil :shadow '(5.0 . "yellow"))
(set-face-attribute 'font-lock-type-face nil :shadow '5.0)
(set-face-attribute 'default nil :shadow '(5.0 nil 2 . 2))
3 changes: 2 additions & 1 deletion src/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ WEBKIT_CFLAGS= @WEBKIT_CFLAGS@

CAIRO_LIBS= @CAIRO_LIBS@
CAIRO_CFLAGS= @CAIRO_CFLAGS@
CAIRO_OBJ= @CAIRO_OBJ@

IMAGEMAGICK_LIBS= @IMAGEMAGICK_LIBS@
IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@
Expand Down Expand Up @@ -480,7 +481,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
$(if $(HYBRID_MALLOC),sheap.o) \
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
$(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ) \
$(HAIKU_OBJ) $(PGTK_OBJ) $(ANDROID_OBJ)
$(HAIKU_OBJ) $(PGTK_OBJ) $(ANDROID_OBJ) $(CAIRO_OBJ)
doc_obj = $(base_obj) $(NS_OBJC_OBJ)
obj = $(doc_obj) $(HAIKU_CXX_OBJ)

Expand Down
14 changes: 12 additions & 2 deletions src/dispextern.h
Original file line number Diff line number Diff line change
Expand Up @@ -1652,6 +1652,7 @@ enum lface_attribute_index
LFACE_HEIGHT_INDEX,
LFACE_WEIGHT_INDEX,
LFACE_SLANT_INDEX,
LFACE_SHADOW_INDEX,
LFACE_UNDERLINE_INDEX,
LFACE_INVERSE_INDEX,
LFACE_FOREGROUND_INDEX,
Expand Down Expand Up @@ -1737,11 +1738,12 @@ struct face
unsigned long background;

/* Pixel value or color index of underline, overlined,
strike-through, or box color. */
strike-through, box color, or shadow color. */
unsigned long underline_color;
unsigned long overline_color;
unsigned long strike_through_color;
unsigned long box_color;
unsigned long shadow_color;

struct font *font;

Expand Down Expand Up @@ -1783,9 +1785,16 @@ struct face
bool_bf use_box_color_for_shadows_p : 1;

/* Non-zero if text in this face should be underlined, overlined,
strike-through or have a box drawn around it. */
strike-through, have a box drawn around it, or have shadows. */
bool_bf overline_p : 1;
bool_bf strike_through_p : 1;
bool_bf shadow_p : 1;

/* The blur parameter of the shadow. */
double shadow_blur;

/* Shadow offset. In most cases, both fields are taken to be zero. */
struct { short x, y; } shadow_offset;

/* True means that the colors specified for this face could not be
loaded, and were replaced by default colors, so they shouldn't be
Expand All @@ -1800,6 +1809,7 @@ struct face
bool_bf overline_color_defaulted_p : 1;
bool_bf strike_through_color_defaulted_p : 1;
bool_bf box_color_defaulted_p : 1;
bool_bf shadow_color_defaulted_p : 1;

/* True means the underline should be drawn at the descent line. */
bool_bf underline_at_descent_line_p : 1;
Expand Down
145 changes: 112 additions & 33 deletions src/ftcrfont.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */

#include <time.h>

#include <config.h>
#include <math.h>
Expand All @@ -41,11 +42,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "xsettings.h"
#endif

#ifdef USE_BE_CAIRO
#include "xcairo.h"

#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
#define BLUE_FROM_ULONG(color) ((color) & 0xff)
#endif

#define METRICS_NCOLS_PER_ROW (128)

Expand Down Expand Up @@ -529,16 +530,11 @@ ftcrfont_variation_glyphs (struct font *font, int c, unsigned variations[256])
}
#endif /* HAVE_OTF_GET_VARIATION_GLYPHS || HAVE_FT_FACE_GETCHARVARIANTINDEX */

static int
ftcrfont_draw (struct glyph_string *s,
int from, int to, int x, int y, bool with_background)
static void
ftcrfont_select_foreground_color (struct frame *f,
cairo_t *cr,
struct glyph_string *s)
{
struct frame *f = s->f;
struct font_info *ftcrfont_info = (struct font_info *) s->font;
cairo_t *cr;
cairo_glyph_t *glyphs;
int len = to - from;
int i;
#ifdef USE_BE_CAIRO
unsigned long be_foreground, be_background;

Expand All @@ -552,6 +548,101 @@ ftcrfont_draw (struct glyph_string *s,
&be_background);
#endif

#ifndef USE_BE_CAIRO
#ifdef HAVE_X_WINDOWS
x_set_other_cr_source_with_gc_foreground (f, s->gc, cr, false);
#else
pgtk_set_other_cr_source_with_color (f, cr, s->xgcv.foreground, false);
#endif
#else
uint32_t col = be_foreground;

cairo_set_source_rgb (cr, RED_FROM_ULONG (col) / 255.0,
GREEN_FROM_ULONG (col) / 255.0,
BLUE_FROM_ULONG (col) / 255.0);
#endif
}

/* Select the proper foreground color (source) before calling this. */
static void
ftcrfont_show_glyphs (struct glyph_string *s, cairo_t *cr,
int from, int to, int x, int y)
{
struct font_info *ftcrfont_info = (struct font_info *) s->font;
int len = to - from;
cairo_glyph_t *glyphs;
int i;

glyphs = alloca (sizeof (cairo_glyph_t) * len);
for (i = 0; i < len; i++)
{
glyphs[i].index = s->char2b[from + i];
glyphs[i].x = x;
glyphs[i].y = y;
x += (s->padding_p ? 1 : ftcrfont_glyph_extents (s->font,
glyphs[i].index,
NULL));
}

cairo_set_scaled_font (cr, ftcrfont_info->cr_scaled_font);
cairo_show_glyphs (cr, glyphs, len);
}

static void
ftcrfont_draw_shadow (struct glyph_string *s, cairo_t *frame_cr,
int from, int to, int x, int y, bool save)
{
cairo_surface_t *surface;
cairo_t *dc;

int x1, y1, w1, h1;
unsigned long col;
int margin;

margin = (int) ceil (s->face->shadow_blur);
w1 = s->width + margin;
h1 = FONT_HEIGHT (s->font) + margin;

surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w1, h1);
dc = cairo_create (surface);

if (s->face->shadow_color_defaulted_p)
col = s->face->foreground;
else
col = s->face->shadow_color;

cairo_set_source_rgb (dc,
RED_FROM_ULONG (col) / 255.0,
GREEN_FROM_ULONG (col) / 255.0,
BLUE_FROM_ULONG (col) / 255.0);
cairo_set_operator (dc, CAIRO_OPERATOR_OVER);

ftcrfont_show_glyphs (s, dc, from, to, margin, FONT_BASE(s->font) + margin);
gaussian_blur (surface, w1, h1, s->face->shadow_blur / 2.0);

x1 = x + s->face->shadow_offset.x - margin;
y1 = y - FONT_BASE (s->font) + s->face->shadow_offset.y - margin;

if (save)
cairo_save (frame_cr);
cairo_set_source_surface (frame_cr, surface, x1, y1);
cairo_rectangle (frame_cr, x1, y1, w1, h1);
cairo_fill (frame_cr);
if (save)
cairo_restore (frame_cr);

cairo_destroy (dc);
cairo_surface_destroy (surface);
}

static int
ftcrfont_draw (struct glyph_string *s,
int from, int to, int x, int y, bool with_background)
{
struct frame *f = s->f;
cairo_t *cr;
int len = to - from;

block_input ();

#ifndef USE_BE_CAIRO
Expand Down Expand Up @@ -595,31 +686,19 @@ ftcrfont_draw (struct glyph_string *s,
cairo_fill (cr);
}

glyphs = alloca (sizeof (cairo_glyph_t) * len);
for (i = 0; i < len; i++)
{
glyphs[i].index = s->char2b[from + i];
glyphs[i].x = x;
glyphs[i].y = y;
x += (s->padding_p ? 1 : ftcrfont_glyph_extents (s->font,
glyphs[i].index,
NULL));
}
#ifndef USE_BE_CAIRO
#ifdef HAVE_X_WINDOWS
x_set_cr_source_with_gc_foreground (f, s->gc, false);
#if defined(HAVE_PGTK)
/* PGTK requires the foreground color to be selected BEFORE creating
the shadow layer. Hence we need to save and restore cairo_t. */
ftcrfont_select_foreground_color (f, cr, s);
if (s->face->shadow_p)
ftcrfont_draw_shadow (s, cr, from, to, x, y, true);
#else
pgtk_set_cr_source_with_color (f, s->xgcv.foreground, false);
if (s->face->shadow_p)
ftcrfont_draw_shadow (s, cr, from, to, x, y, false);
ftcrfont_select_foreground_color (f, cr, s);
#endif
#else
uint32_t col = be_foreground;
ftcrfont_show_glyphs (s, cr, from, to, x, y);

cairo_set_source_rgb (cr, RED_FROM_ULONG (col) / 255.0,
GREEN_FROM_ULONG (col) / 255.0,
BLUE_FROM_ULONG (col) / 255.0);
#endif
cairo_set_scaled_font (cr, ftcrfont_info->cr_scaled_font);
cairo_show_glyphs (cr, glyphs, len);
#ifndef USE_BE_CAIRO
#ifdef HAVE_X_WINDOWS
x_end_cr_clip (f);
Expand Down
Loading