freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ft-devel] [PATCH v2] Improve FT_Outline_Embolden for the unintended


From: Byeongsik Jeon
Subject: Re: [ft-devel] [PATCH v2] Improve FT_Outline_Embolden for the unintended artifacts problem (#45596).
Date: Tue, 9 Oct 2018 08:53:29 +0900
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.0

On Fri, 5 Oct 2018 10:47:05 -0400, Alexei Podtelezhnikov <address@hidden> wrote:
I'm sorry.
I think I fell into a fixed idea because of my good looking results.

Now, I'm trying to combine the advantages of both codes. I think I will reuse
the idea of a lot of existing code.

A few important things to keep in mind before I go into algorithmic
ideas. The strength in the FreeType sense is how many pixels are added
to a stem, half a pixel on each side, measured in 1/64 of a pixel.
This is documented and expected. We cannot change that. You refer to
MS implementation. Is it documented somewhere? Also you should be
careful with modifying  metrics. So that you do not surprise people
who use this functionality.

I doubt that there is an easy way to solve artifacts with a simple cap
on shift. This mathematical problem has a proper rigorous solution:

1) Emboldening does not change the orientation of segments, it only
changes their lengths. The "cross" situation is when the length
becomes "negative" or the segment points in the opposite direction.
Such segments should be removed from the *original* outline: two
original adjacent segments should be shortcut at their intersection.
This process might be recursive until all "cross" conditions are
removed.
2) Shift the remaining simplified outline points.
3) Deal with sharp angles: use round or bevel line join.

Of course this is easier said than done. I put that on hold a long
time ago. You welcome to work on this. This might be a cool summer
GSoC project.

Regards,
Alexei

Thank you.

I have tried to solve this problem in the past few days, but I have not got a satisfactory solution. In short, it was like playing a mole-catching game.

So I thought in another direction. I tried to find a solution to the problem, but I was worried about the cause of the problem.

Is it because the shift vector is too big in the sharpen edge?

rot( in + out ) / ( 1 + inner_product( in, out ) )

The sharper the corner, the more this value converges to infinity.
The code below is avoiding this problem.

          /* shift only if turn is less than ~160 degrees */
          if ( d > -0xF000L )
          {
            d = d + 0x10000L;
            ...
          }
          else
            shift.x = shift.y = 0;

However, this code causes another artifact to be created. This is because the shift value suddenly becomes zero unlike the neighbor points.

I thought about using another equation to get a shift vector. The direction can be obtained as "normalize( rot( in + out ) ). The length induced an expression that satisfies certain conditions as follows.

        /* deg = in.x * out.x + in.y * out.y = -cos(theta)
         * f(deg) = a * deg^2 + b * deg + d
         * f(1)  = 1       , theta = 180
         * f(0)  = sqrt(2) , theta = 90, 270
         * f(-1) = k       , theta = 0, 360
         */

k_plot.png is a graph of the equations with the original expression.

The k value controls the shift value. The actual results are stable because they maintain the correct value at 90, 180, 270 degrees. Even the results of k = 0.0 are noteworthy.

I want to hear your opinion on this approach.

Attachment: v2-0001-Improve-FT_Outline_Embolden-for-the-unintended-ar.patch
Description: Text Data

Attachment: k_plot.png
Description: PNG image

Attachment: k_0.0.png
Description: PNG image

Attachment: k_0.5.png
Description: PNG image

Attachment: k_1.0.png
Description: PNG image

Attachment: k_1.4.png
Description: PNG image

Attachment: k_1.8.png
Description: PNG image

Attachment: k_2.0.png
Description: PNG image

Attachment: k_2.3.png
Description: PNG image


reply via email to

[Prev in Thread] Current Thread [Next in Thread]