unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Text shadows
@ 2023-03-12  4:06 Kai Ma
  2023-03-12  4:18 ` Kai Ma
  2023-03-12  7:12 ` Eli Zaretskii
  0 siblings, 2 replies; 12+ messages in thread
From: Kai Ma @ 2023-03-12  4:06 UTC (permalink / raw)
  To: emacs-devel

Hi emacs

Recently, I implemented the “text shadows” feature for Cairo-powered windowing systems, including X11 and Wayland.  See [1] if you wonder what that looks like.

This feature adds a new face attribute :shadow, and accepts values like:

- FLOAT                 how much blurring?
- (FLOAT . COLOR)       additionally, specifies a color for the shadow
- (FLOAT COLOR OFFSET)  additionally, specifies an offset (x . y)

This was first implemented for the NS port three years ago (also by me), and seems to have sparked some interest and was discussed on emacs-devel [2].  (I didn’t follow the discussion on emacs-devel back then.)

I’m writing to ask if the community is interested in accepting this feature into mainline Emacs?  If so, I will improve things and make a formal patch.

Also, I’d like some feedback on the design and the implementation [3].  The Gaussian blurring function used GCC vector extensions.  Is this allowed in the Emacs code?

There is also a known issue regarding text extents (?), and I’d like to know what is the correct path forward:

1. The shadows sometimes should be drawn outside the glyph extents, but they aren’t drawn.
2. Previously drawn shadows are not cleared, and they even accumulate.  This can be observed with blink-cursor-mode enabled.

Any input would be greatly appreciated!

[1] https://github.com/ksqsf/emacsmoe/pull/1#issuecomment-1465072298
[2] https://lists.gnu.org/archive/html/emacs-devel/2020-05/msg02921.html
[3] https://github.com/ksqsf/emacsmoe/pull/1/files 

— Kai




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Text shadows
  2023-03-12  4:06 Text shadows Kai Ma
@ 2023-03-12  4:18 ` Kai Ma
  2023-03-12  7:12 ` Eli Zaretskii
  1 sibling, 0 replies; 12+ messages in thread
From: Kai Ma @ 2023-03-12  4:18 UTC (permalink / raw)
  To: emacs-devel

Let me try to make it more clear…

> 1. The shadows sometimes should be drawn outside the glyph extents, but they aren’t drawn.

The shadows usually extend beyond the glyph extents, but sometimes they are limited to the glyph extents, and aren’t drawn.

For example, when the user is inputing new characters.

> 2. Previously drawn shadows are not cleared, and they even accumulate.  This can be observed with blink-cursor-mode enabled.

Shadows drawn outside a glyph extent are sometimes not cleared, and they accumulate.  For example, put the cursor over a character C, which initially had less shadows around it, but after a few blinks, the shadows accumulate:

   .C.
   :C:
   ;C;
   |C|
   #C#




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Text shadows
  2023-03-12  4:06 Text shadows Kai Ma
  2023-03-12  4:18 ` Kai Ma
@ 2023-03-12  7:12 ` Eli Zaretskii
  2023-03-12  8:24   ` Kai Ma
  1 sibling, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2023-03-12  7:12 UTC (permalink / raw)
  To: Kai Ma; +Cc: emacs-devel

> From: Kai Ma <justksqsf@gmail.com>
> Date: Sun, 12 Mar 2023 12:06:28 +0800
> 
> Recently, I implemented the “text shadows” feature for Cairo-powered windowing systems, including X11 and Wayland.  See [1] if you wonder what that looks like.

Which parts of the feature implementation really require Cairo?  IOW,
why cannot this be available to non-Cairo builds as well?

> This feature adds a new face attribute :shadow, and accepts values like:
> 
> - FLOAT                 how much blurring?
> - (FLOAT . COLOR)       additionally, specifies a color for the shadow
> - (FLOAT COLOR OFFSET)  additionally, specifies an offset (x . y)

I think at least in some GUI systems the offset is specified as radius
and angle.

> I’m writing to ask if the community is interested in accepting this feature into mainline Emacs?  If so, I will improve things and make a formal patch.

Yes, I think we'd like to support this feature.  But it looks to me
like the current WIP is incomplete, as it doesn't handle the change in
glyph metrics due to the shadowing, see below.

It is best to submit a feature-request bug report using
report-emacs-bug, and then continue the discussion on our issue
tracker.

> 1. The shadows sometimes should be drawn outside the glyph extents, but they aren’t drawn.
> 2. Previously drawn shadows are not cleared, and they even accumulate.  This can be observed with blink-cursor-mode enabled.

This probably means you need further changes in the layout part of the
display code, in xdisp.c, to account for the changes in the glyph
metrics due to the shadow attribute.  See, for example, how the 'box'
face attribute is handled there.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Text shadows
  2023-03-12  7:12 ` Eli Zaretskii
@ 2023-03-12  8:24   ` Kai Ma
  2023-03-12  8:46     ` Po Lu
  2023-03-12  9:14     ` Eli Zaretskii
  0 siblings, 2 replies; 12+ messages in thread
From: Kai Ma @ 2023-03-12  8:24 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel


> On Mar 12, 2023, at 15:12, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Kai Ma <justksqsf@gmail.com>
>> Date: Sun, 12 Mar 2023 12:06:28 +0800
>> 
>> Recently, I implemented the “text shadows” feature for Cairo-powered windowing systems, including X11 and Wayland.  See [1] if you wonder what that looks like.
> 
> Which parts of the feature implementation really require Cairo?  IOW,
> why cannot this be available to non-Cairo builds as well?

Theoretically, nothing.  I targeted Cairo because (I think) it is the most popular option on GNU/Linux.

Speaking of this specific implementation, gaussian_blur() relies on a specific Cairo image format ARGB32, (this assumption could be easily removed), and then it is used by ftcrfont_draw() to generate shadows.

I don’t know whether non-Cairo builds (non-cairo X, win32) can/should use gaussian_blur() though, since I’m not familiar with them.

>> This feature adds a new face attribute :shadow, and accepts values like:
>> 
>> - FLOAT                 how much blurring?
>> - (FLOAT . COLOR)       additionally, specifies a color for the shadow
>> - (FLOAT COLOR OFFSET)  additionally, specifies an offset (x . y)
> 
> I think at least in some GUI systems the offset is specified as radius
> and angle.

The shadow is generated by this process:

- draw glyphs (in the shadow color) onto a blank canvas;
- apply the blurring function;
- copy the “shadow” back to the original canvas at the specified x-y coordinate.

So I don’t think radius and angle is relevant here.

>> I’m writing to ask if the community is interested in accepting this feature into mainline Emacs?  If so, I will improve things and make a formal patch.
> 
> Yes, I think we'd like to support this feature.  But it looks to me
> like the current WIP is incomplete, as it doesn't handle the change in
> glyph metrics due to the shadowing, see below.

Thanks!

> It is best to submit a feature-request bug report using
> report-emacs-bug, and then continue the discussion on our issue
> tracker.

Will do after I fix the glyph metrics.

>> 1. The shadows sometimes should be drawn outside the glyph extents, but they aren’t drawn.
>> 2. Previously drawn shadows are not cleared, and they even accumulate.  This can be observed with blink-cursor-mode enabled.
> 
> This probably means you need further changes in the layout part of the
> display code, in xdisp.c, to account for the changes in the glyph
> metrics due to the shadow attribute.  See, for example, how the 'box'
> face attribute is handled there.

Thanks for this pointer.  I will work this out first, and then let’s continue the discussion on the bug tracker.

— Kai




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Text shadows
  2023-03-12  8:24   ` Kai Ma
@ 2023-03-12  8:46     ` Po Lu
  2023-03-12  9:23       ` Kai Ma
  2023-03-12  9:14     ` Eli Zaretskii
  1 sibling, 1 reply; 12+ messages in thread
From: Po Lu @ 2023-03-12  8:46 UTC (permalink / raw)
  To: Kai Ma; +Cc: Eli Zaretskii, emacs-devel

Kai Ma <justksqsf@gmail.com> writes:

>> On Mar 12, 2023, at 15:12, Eli Zaretskii <eliz@gnu.org> wrote:
>> 
>>> From: Kai Ma <justksqsf@gmail.com>
>>> Date: Sun, 12 Mar 2023 12:06:28 +0800
>>> 
>>> Recently, I implemented the “text shadows” feature for Cairo-powered windowing systems, including X11 and Wayland.  See [1] if you wonder what that looks like.
>> 
>> Which parts of the feature implementation really require Cairo?  IOW,
>> why cannot this be available to non-Cairo builds as well?
>
> Theoretically, nothing.  I targeted Cairo because (I think) it is the most popular option on GNU/Linux.
>
> Speaking of this specific implementation, gaussian_blur() relies on a specific Cairo image format ARGB32, (this assumption could be easily removed), and then it is used by ftcrfont_draw() to generate shadows.
>
> I don’t know whether non-Cairo builds (non-cairo X, win32) can/should use gaussian_blur() though, since I’m not familiar with them.

Non-Cairo builds and Cairo builds alike should use the X Rendering
Extension, where an arbitrary blur kernel is a standard picture filter.
Cairo builds on X should as well.

P.S: the GNU project rejects the Unix convention that `foo()' refers to
the function `foo': `foo()' is a function declarator that returns int
and takes any number of arguments, or alternatively a function call to
`foo' with no arguments.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Text shadows
  2023-03-12  8:24   ` Kai Ma
  2023-03-12  8:46     ` Po Lu
@ 2023-03-12  9:14     ` Eli Zaretskii
  2023-03-12  9:55       ` Kai Ma
  1 sibling, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2023-03-12  9:14 UTC (permalink / raw)
  To: Kai Ma; +Cc: emacs-devel

> From: Kai Ma <justksqsf@gmail.com>
> Date: Sun, 12 Mar 2023 16:24:17 +0800
> Cc: emacs-devel@gnu.org
> 
> > Which parts of the feature implementation really require Cairo?  IOW,
> > why cannot this be available to non-Cairo builds as well?
> 
> Theoretically, nothing.  I targeted Cairo because (I think) it is the most popular option on GNU/Linux.
> 
> Speaking of this specific implementation, gaussian_blur() relies on a specific Cairo image format ARGB32, (this assumption could be easily removed), and then it is used by ftcrfont_draw() to generate shadows.
> 
> I don’t know whether non-Cairo builds (non-cairo X, win32) can/should use gaussian_blur() though, since I’m not familiar with them.

Would you please investigate that aspect?  E.g., does Firefox support
this without Cairo, and if so, how?

At worst, perhaps it would be good enough not to support blurring on
some platforms, or support it by some minor modification of the color?
Or maybe we could implement the equivalent of gaussian_blur in our
code?

> >> This feature adds a new face attribute :shadow, and accepts values like:
> >> 
> >> - FLOAT                 how much blurring?
> >> - (FLOAT . COLOR)       additionally, specifies a color for the shadow
> >> - (FLOAT COLOR OFFSET)  additionally, specifies an offset (x . y)
> > 
> > I think at least in some GUI systems the offset is specified as radius
> > and angle.
> 
> The shadow is generated by this process:
> 
> - draw glyphs (in the shadow color) onto a blank canvas;
> - apply the blurring function;
> - copy the “shadow” back to the original canvas at the specified x-y coordinate.
> 
> So I don’t think radius and angle is relevant here.

The radius and angle are just polar specifications of the Cartesian
X-offset and Y-offset, that's all.  If the API needs Cartesian
specification, it should be trivial to convert polar to Cartesian
before calling the API.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Text shadows
  2023-03-12  8:46     ` Po Lu
@ 2023-03-12  9:23       ` Kai Ma
  2023-03-12 10:33         ` Po Lu
  0 siblings, 1 reply; 12+ messages in thread
From: Kai Ma @ 2023-03-12  9:23 UTC (permalink / raw)
  To: Po Lu; +Cc: Eli Zaretskii, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1498 bytes --]


> On Mar 12, 2023, at 16:46, Po Lu <luangruo@yahoo.com> wrote:
>> Theoretically, nothing.  I targeted Cairo because (I think) it is the most popular option on GNU/Linux.
>> 
>> Speaking of this specific implementation, gaussian_blur() relies on a specific Cairo image format ARGB32, (this assumption could be easily removed), and then it is used by ftcrfont_draw() to generate shadows.
>> 
>> I don’t know whether non-Cairo builds (non-cairo X, win32) can/should use gaussian_blur() though, since I’m not familiar with them.
> 
> Non-Cairo builds and Cairo builds alike should use the X Rendering
> Extension, where an arbitrary blur kernel is a standard picture filter.
> Cairo builds on X should as well.


I agree XRender should be used for non-Cairo X builds (when XRender is available).

But it’s probably not a good idea to use XRender on X+Cairo.  In this setting, cairo_show_glyphs is used to draw glyphs, but Cairo does not expose any interface to the underlying Picture object.  So it would require additional memory copies between X and Cairo just for blurring.  I guess it would be slower as the image to blur is usually small.  I will do the benchmarks once I get XRender blurring working.

> P.S: the GNU project rejects the Unix convention that `foo()' refers to
> the function `foo': `foo()' is a function declarator that returns int
> and takes any number of arguments, or alternatively a function call to
> `foo' with no arguments.


Point taken.


[-- Attachment #2: Type: text/html, Size: 6878 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Text shadows
  2023-03-12  9:14     ` Eli Zaretskii
@ 2023-03-12  9:55       ` Kai Ma
  2023-03-12 11:33         ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Kai Ma @ 2023-03-12  9:55 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1916 bytes --]


> On Mar 12, 2023, at 17:14, Eli Zaretskii <eliz@gnu.org> wrote:
> 
> Would you please investigate that aspect?  E.g., does Firefox support
> this without Cairo, and if so, how?

From what I read, Firefox currently has two set of 2D graphics APIs, Moz2D and Thebes.

Moz2D contained their own implementations for an approximation of Gaussian blurring using the box blur [1].

Thebes defines an interface named DrawSurfaceWithShadow [2], and provides implementations in terms of Cairo [3] (based on a custom blurring function [4]), Direct2D [5], and Skia [6].

So it appears that, with Cairo, one has to implement their own blurring function.

[1] https://searchfox.org/mozilla-central/rev/2ede53e39955988f98db4369f7ce09614b22104a/gfx/2d/Blur.cpp#876 
[2] https://searchfox.org/mozilla-central/rev/2ede53e39955988f98db4369f7ce09614b22104a/gfx/2d/2D.h#1447 
[3] https://searchfox.org/mozilla-central/rev/2ede53e39955988f98db4369f7ce09614b22104a/gfx/2d/DrawTargetCairo.cpp#936 
[4] https://searchfox.org/mozilla-central/source/gfx/2d/Blur.cpp#581
[5] https://searchfox.org/mozilla-central/rev/2ede53e39955988f98db4369f7ce09614b22104a/gfx/2d/DrawTargetD2D1.cpp#306 
[6] https://searchfox.org/mozilla-central/rev/2ede53e39955988f98db4369f7ce09614b22104a/gfx/2d/DrawTargetSkia.cpp#765 

> At worst, perhaps it would be good enough not to support blurring on
> some platforms, or support it by some minor modification of the color?
> Or maybe we could implement the equivalent of gaussian_blur in our
> code?

This is already the case: Cairo does not provide a Gaussian blurring function, so I wrote one (named gaussian_blur) in xcairo.c.  It is an approximation, not the “True Gaussian Blur”, like Moz2D’s implementation.  It only uses one CPU core, but is fast enough for me.

I don’t have objections to simply making the background slightly different on some difficult platforms.


[-- Attachment #2: Type: text/html, Size: 7824 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Text shadows
  2023-03-12  9:23       ` Kai Ma
@ 2023-03-12 10:33         ` Po Lu
  0 siblings, 0 replies; 12+ messages in thread
From: Po Lu @ 2023-03-12 10:33 UTC (permalink / raw)
  To: Kai Ma; +Cc: Eli Zaretskii, emacs-devel

Kai Ma <justksqsf@gmail.com> writes:

>  On Mar 12, 2023, at 16:46, Po Lu <luangruo@yahoo.com> wrote:
>
>  Theoretically, nothing.  I targeted Cairo because (I think) it is the most popular option on GNU/Linux.
>
>  Speaking of this specific implementation, gaussian_blur() relies on a specific Cairo image format ARGB32, (this assumption could be
>  easily removed), and then it is used by ftcrfont_draw() to generate shadows.
>
>  I don’t know whether non-Cairo builds (non-cairo X, win32) can/should use gaussian_blur() though, since I’m not familiar with them.
>
>  Non-Cairo builds and Cairo builds alike should use the X Rendering
>  Extension, where an arbitrary blur kernel is a standard picture filter.
>  Cairo builds on X should as well.
>
> I agree XRender should be used for non-Cairo X builds (when XRender is available).

You can create a scratch Cairo surface backed by the drawable and
suitable picture format.

Temporary drawable and GC allocation is usually very fast in X servers
descending from the MIT sample server because they internally use many
different kinds of ``scratch pixmaps'' and ``scratch GCs'', but if you
worry about this kind of thing you can reuse the surface if you want
too.

Then, place a filter on that surface's picture and composite its
contents to FRAME_X_PICTURE (f).

Any code which involves Emacs writing to memory is unacceptable under X.
The reason is that the shared memory extension is not always available,
and is slower.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Text shadows
  2023-03-12  9:55       ` Kai Ma
@ 2023-03-12 11:33         ` Eli Zaretskii
  2023-03-12 11:49           ` Kai Ma
  0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2023-03-12 11:33 UTC (permalink / raw)
  To: Kai Ma; +Cc: emacs-devel

> From: Kai Ma <justksqsf@gmail.com>
> Date: Sun, 12 Mar 2023 17:55:01 +0800
> Cc: emacs-devel@gnu.org
> 
>  At worst, perhaps it would be good enough not to support blurring on
>  some platforms, or support it by some minor modification of the color?
>  Or maybe we could implement the equivalent of gaussian_blur in our
>  code?
> 
> This is already the case: Cairo does not provide a Gaussian blurring function, so I wrote one (named
> gaussian_blur) in xcairo.c.  It is an approximation, not the “True Gaussian Blur”, like Moz2D’s
> implementation.  It only uses one CPU core, but is fast enough for me.

I thought you said gaussian_blur required some Cairo-only extension?
That's why I wrote the above.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Text shadows
  2023-03-12 11:33         ` Eli Zaretskii
@ 2023-03-12 11:49           ` Kai Ma
  2023-03-12 12:36             ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Kai Ma @ 2023-03-12 11:49 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel



> On Mar 12, 2023, at 19:33, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Kai Ma <justksqsf@gmail.com>
>> Date: Sun, 12 Mar 2023 17:55:01 +0800
>> Cc: emacs-devel@gnu.org
>> 
>> At worst, perhaps it would be good enough not to support blurring on
>> some platforms, or support it by some minor modification of the color?
>> Or maybe we could implement the equivalent of gaussian_blur in our
>> code?
>> 
>> This is already the case: Cairo does not provide a Gaussian blurring function, so I wrote one (named
>> gaussian_blur) in xcairo.c.  It is an approximation, not the “True Gaussian Blur”, like Moz2D’s
>> implementation.  It only uses one CPU core, but is fast enough for me.
> 
> I thought you said gaussian_blur required some Cairo-only extension?
> That's why I wrote the above.

Sorry if my words were misleading.  I didn’t intend to say that.

gaussian_blur right now only works on Cairo surfaces, but it’s easy to change.




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Text shadows
  2023-03-12 11:49           ` Kai Ma
@ 2023-03-12 12:36             ` Eli Zaretskii
  0 siblings, 0 replies; 12+ messages in thread
From: Eli Zaretskii @ 2023-03-12 12:36 UTC (permalink / raw)
  To: Kai Ma; +Cc: emacs-devel

> From: Kai Ma <justksqsf@gmail.com>
> Date: Sun, 12 Mar 2023 19:49:40 +0800
> Cc: emacs-devel@gnu.org
> 
> 
> 
> > On Mar 12, 2023, at 19:33, Eli Zaretskii <eliz@gnu.org> wrote:
> > 
> >> This is already the case: Cairo does not provide a Gaussian blurring function, so I wrote one (named
> >> gaussian_blur) in xcairo.c.  It is an approximation, not the “True Gaussian Blur”, like Moz2D’s
> >> implementation.  It only uses one CPU core, but is fast enough for me.
> > 
> > I thought you said gaussian_blur required some Cairo-only extension?
> > That's why I wrote the above.
> 
> Sorry if my words were misleading.  I didn’t intend to say that.
> 
> gaussian_blur right now only works on Cairo surfaces, but it’s easy to change.

Great, then I think we'd love to see it working in non-Cairo builds as
well.



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-03-12 12:36 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-12  4:06 Text shadows Kai Ma
2023-03-12  4:18 ` Kai Ma
2023-03-12  7:12 ` Eli Zaretskii
2023-03-12  8:24   ` Kai Ma
2023-03-12  8:46     ` Po Lu
2023-03-12  9:23       ` Kai Ma
2023-03-12 10:33         ` Po Lu
2023-03-12  9:14     ` Eli Zaretskii
2023-03-12  9:55       ` Kai Ma
2023-03-12 11:33         ` Eli Zaretskii
2023-03-12 11:49           ` Kai Ma
2023-03-12 12:36             ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).