|
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.
v2-0001-Improve-FT_Outline_Embolden-for-the-unintended-ar.patch
Description: Text Data
k_plot.png
Description: PNG image
k_0.0.png
Description: PNG image
k_0.5.png
Description: PNG image
k_1.0.png
Description: PNG image
k_1.4.png
Description: PNG image
k_1.8.png
Description: PNG image
k_2.0.png
Description: PNG image
k_2.3.png
Description: PNG image
[Prev in Thread] | Current Thread | [Next in Thread] |