Re: [ft-devel] [autohint] improved handling of serif fonts
于 07/04/2012 11:28 PM, Werner LEMBERG 写道: please test the current git. I have slightly changed the code in the auto-hinter which recognizes flat segments; it now accepts a broader group of shapes. As a consequence, handling of serif fonts like Palatino or Quattrocento should be much improved. I have also imported this code to ttfautohint. Cf. this bug report: https://savannah.nongnu.org/bugs/index.php?func=detailitem&item_id=36091 This remind me of the problem where stroke with a slight curvature at the end. The segment at the end cannot be detected in that case. See the thread: http://lists.gnu.org/archive/html/freetype-devel/2011-05/msg00013.html ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] [Patch] Compensate blue zone rounding after scale
On 05/14/2011 02:46 AM, Just Fill Bugs wrote: The 主,些,它,生,里 are not adjusted by the blue zone because their bottom line were too high in the original design. With compensation, the distance between blue zone to the un-adjust bottom line increased by 1px. To conclude, if we cannot catch the bottom line of ALL the glyphs into the blue zones, adding extra 1px to the bottom might not be a good idea in practice. To think how to benefit glyphs that escaped from blue zone, I wonder if we can change the scale and the delta of the whole metrics according to the calculated blue zone. Maybe only apply when shoot == ref. Scale origin height to fit height, then shift bottom ref.orig to ref.fit. It's more like the "warper" code but instead base on blue zone and applied to the global metrics as a whole. Maybe not, if the escaped glyphs can escape the blue zone, they might as well not be affected much by the small scaling and shifting changes. Anyway, the global metrics change should somehow affect none blue zone edges and reduce the deformation brought in by the blue zone alignment. Basically eliminated the anchor_drift from aflatin2.c. Make sense? ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] [Patch] Compensate blue zone rounding after scale
On 05/13/2011 09:32 PM, Werner LEMBERG wrote: In af_cjk_metrics_scale_dim(), when we scale the blue zone to the font size, the blue zone is also rounded to pixel grid. The offset introduced in the rounding at both the bottom and top could have undesirable effect on the glyph height at certain font size. [...] Again, it would be great if you can provide images which demonstrate the usefulness of your change. It seems that such a fix must be applied to the latin hinter also for consistency... The result is a mix. Attached a comparison for wqy-zenhei.ttc at 11.5pt. I actually have to patch ftstring to make it increase font size by half a point to reach 11.5pt. The lines are: 1. without height compensation. 2. with height compensation. As can be seem, some chars does benefit from a height glyph size, like 置,道,裡. However, the whole line looked worse with the compensation in height. It's because of chars which are outside the bottom blue zone displayed a bigger gap toward the chars adjusted with blue zone. The 主,些,它,生,里 are not adjusted by the blue zone because their bottom line were too high in the original design. With compensation, the distance between blue zone to the un-adjust bottom line increased by 1px. To conclude, if we cannot catch the bottom line of ALL the glyphs into the blue zones, adding extra 1px to the bottom might not be a good idea in practice. <>___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] [Patch] Compensate blue zone rounding after scale
On 05/13/2011 09:01 PM, Алексей Подтележников wrote: Why do you even create and calculate temporary shoot_delta? You can explicitly increment/decrement blue->shoot.fit the same way you do blue->ref.fit. Like this: +AF_CJKBlue blue; + +if ( delta_t>= delta_b ) +{ + blue =&axis->blues[AF_CJK_BLUE_TOP]; + blue->ref.fit += 64; + blue->shoot.fit += 64; +} +else +{ + blue =&axis->blues[AF_CJK_BLUE_BOTTOM]; + blue->ref.fit -= 64; + blue->shoot -= 64; +} Actually, there was an bug. My intention was to only update shoot.fit value if it is the same with the ref.fit. Otherwise, if shoot and ref don't merge, we don't know if shoot should be compensate. But in the code, it's somehow messed up and simply always update the shoot value. It should be: +if (shoot_delta == 0) + blue->shoot.fit = blue->ref.fit; As for the redundancy of the test on delta_sum <= 64, you are also right. I remove that too in the updated patch. diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c index 513b0c0..9d2 100644 --- a/src/autofit/afcjk.c +++ b/src/autofit/afcjk.c @@ -607,7 +607,7 @@ delta2 = FT_MulFix( delta2, scale ); FT_TRACE5(( "delta: %d", delta1 )); -if ( delta2 < 32 ) +if ( delta2 <= 32 ) delta2 = 0; /* else if ( delta2 < 64 ) @@ -632,6 +632,75 @@ blue->flags |= AF_CJK_BLUE_ACTIVE; } } + +/* Compensate glyph height from top and bottom blue zone offsets. */ +/* There are 4 states for the sum of top and bottom fit offset: +* +* 1. top + bottom >= 1.5 pxRound to 2 px +* +* 2. top + bottom >= 1.0 pxRound to 1 px +* Bad Result: 0.5 + 0.5 => 1 + 1 = 2px > 1px +* +* 3. top + bottom >= 0.5 pxRound to 1 px +* Bad Result: 0.4 + 0.4 => 0 + 0 = 0px < 1px +* +* 4. top + bottom < 0.5 pxRound to 0 px +* +* For the 2 bad result, +* +* 1st bad is OK, since we are OK with a pixel increase in size at small +* font size. +* +* 2nd bad is not OK. It shrink our already limited space by 1px at small +* fonr size. So we should compensate 1px in that situation. +*/ +{ + FT_Pos delta_t, delta_b; + AF_CJKBlue blue_t, blue_b; + + blue_t = &axis->blues[AF_CJK_BLUE_TOP]; + blue_b = &axis->blues[AF_CJK_BLUE_BOTTOM]; + + + delta_t =blue_t->ref.cur - blue_t->ref.fit; + delta_b = -( blue_b->ref.cur - blue_b->ref.fit ); + + FT_TRACE6(( "COMPEN: ref.cur: %li, ref.fit: %li, %li\n", +blue_t->ref.cur, blue_t->ref.fit, delta_t )); + FT_TRACE6(( "COMPEN: ref.cur: %li, ref.fit: %li, %li, sum: %li\n", +blue_b->ref.cur, blue_b->ref.fit, delta_b, delta_t + delta_b )); + + if ( delta_t > 0 && delta_b > 0&& /* rounded to floor. */ + ( delta_t + delta_b ) >= 32 && + delta_t <= 32&& delta_b <= 32 ) + { +FT_Pos shoot_delta; +AF_CJKBlue blue; + +if ( delta_t >= delta_b ) +{ + blue = &axis->blues[AF_CJK_BLUE_TOP]; + shoot_delta = blue->shoot.fit - blue->ref.fit; + blue->ref.fit += 64; +} +else +{ + blue = &axis->blues[AF_CJK_BLUE_BOTTOM]; + shoot_delta = blue->shoot.fit - blue->ref.fit; + blue->ref.fit -= 64; +} + +if (shoot_delta == 0) + blue->shoot.fit = blue->ref.fit; + +FT_TRACE5(( ">> compensated cjk blue zone %c%d[%ld/%ld]: " + "ref: cur=%.2f fit=%.2f shoot: cur=%.2f fit=%.2f\n", + ( dim == AF_DIMENSION_HORZ ) ? 'H':'V', + nn, blue->ref.org, blue->shoot.org, + blue->ref.cur/64.0, blue->ref.fit/64.0, + blue->shoot.cur/64.0, blue->shoot.fit/64.0 )); + } +} } ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
[ft-devel] [Patch] Compensate blue zone rounding after scale
In af_cjk_metrics_scale_dim(), when we scale the blue zone to the font size, the blue zone is also rounded to pixel grid. The offset introduced in the rounding at both the bottom and top could have undesirable effect on the glyph height at certain font size. There are 4 states for the sum of top and bottom fit offset: 1. top + bottom >= 1.5 pxRound to 2 px 2. top + bottom >= 1.0 pxRound to 1 px Bad Case: 0.5 + 0.5 => 1 + 1 = 2px > 1px 3. top + bottom >= 0.5 pxRound to 1 px Bad Case: 0.4 + 0.4 => 0 + 0 = 0px < 1px 4. top + bottom < 0.5 pxRound to 0 px For the 2 bad results: 1st bad is OK, since we are OK with a pixel increase in size at small font size. 2nd bad is not OK. It shrink our already limited space by 1px at small font size. So we should compensate 1px in that situation. The patch only tried to fix the ref blue zone. The compensation kicked in at 11.5pt and 10pt and add 1px to the glyph height for wqy-zenhei.ttc. diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c index 513b0c0..d3d8cdc 100644 --- a/src/autofit/afcjk.c +++ b/src/autofit/afcjk.c @@ -607,7 +607,7 @@ delta2 = FT_MulFix( delta2, scale ); FT_TRACE5(( "delta: %d", delta1 )); -if ( delta2 < 32 ) +if ( delta2 <= 32 ) delta2 = 0; /* else if ( delta2 < 64 ) @@ -632,6 +632,76 @@ blue->flags |= AF_CJK_BLUE_ACTIVE; } } + +/* Compensate glyph height from top and bottom blue zone offsets. */ +/* There are 4 states for the sum of top and bottom fit offset: +* +* 1. top + bottom >= 1.5 pxRound to 2 px +* +* 2. top + bottom >= 1.0 pxRound to 1 px +* Bad Result: 0.5 + 0.5 => 1 + 1 = 2px > 1px +* +* 3. top + bottom >= 0.5 pxRound to 1 px +* Bad Result: 0.4 + 0.4 => 0 + 0 = 0px < 1px +* +* 4. top + bottom < 0.5 pxRound to 0 px +* +* For the 2 bad result, +* +* 1st bad is OK, since we are OK with a pixel increase in size at small +* font size. +* +* 2nd bad is not OK. It shrink our already limited space by 1px at small +* fonr size. So we should compensate 1px in that situation. +*/ +{ + FT_Pos delta_t, delta_b, delta_sum; + AF_CJKBlue blue_t, blue_b; + + blue_t = &axis->blues[AF_CJK_BLUE_TOP]; + blue_b = &axis->blues[AF_CJK_BLUE_BOTTOM]; + + + delta_t =blue_t->ref.cur - blue_t->ref.fit; + delta_b = -( blue_b->ref.cur - blue_b->ref.fit ); + + delta_sum = delta_t + delta_b; + + FT_TRACE6(( "COMPEN: ref.cur: %li, ref.fit: %li, %li\n", +blue_t->ref.cur, blue_t->ref.fit, delta_t )); + FT_TRACE6(( "COMPEN: ref.cur: %li, ref.fit: %li, %li, sum: %li\n", +blue_b->ref.cur, blue_b->ref.fit, delta_b, delta_sum )); + + if ( delta_t > 0 && delta_b > 0&& /* rounded to floor. */ + delta_sum >= 32 && delta_sum <= 64 && + delta_t <= 32&& delta_b <= 32 ) + { +FT_Pos shoot_delta; +AF_CJKBlue blue; + +if ( delta_t >= delta_b ) +{ + blue = &axis->blues[AF_CJK_BLUE_TOP]; + shoot_delta = blue->shoot.fit - blue->ref.fit; + blue->ref.fit += 64; +} +else +{ + blue = &axis->blues[AF_CJK_BLUE_BOTTOM]; + shoot_delta = blue->shoot.fit - blue->ref.fit; + blue->ref.fit -= 64; +} + +blue->shoot.fit = blue->ref.fit + shoot_delta; + +FT_TRACE5(( ">> compensated cjk blue zone %c%d[%ld/%ld]: " + "ref: cur=%.2f fit=%.2f shoot: cur=%.2f fit=%.2f\n", + ( dim == AF_DIMENSION_HORZ ) ? 'H':'V', + nn, blue->ref.org, blue->shoot.org, + blue->ref.cur/64.0, blue->ref.fit/64.0, + blue->shoot.cur/64.0, blue->shoot.fit/64.0 )); + } +} } ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] Tweak CJK Blue zone parameters
On 05/12/2011 01:02 AM, suzuki toshiya wrote: > I attached 3 pictures comparing 4 cases for Japanese hi quality commercial > PostScript fonts (Ryumin-Light, GothicBBB-Medium and Shuei-Min. Ryumin-Light > and GothicBBB-Medium would be the most referential font in Japanese market > because they are bundled to most PostScript printers). Thanks for generating this sample for comparison. > > The autohinter improves the contrast of the strokes. > In my understanding, CJK bluezone is designed to improve the strokes > around the square boundaries, but it improves the contrast of the > internal strokes too. For example, please find "口" in "吉" or "合" > glyph in Ryumin-Light picture. I did not see anything that indicate the blue zone would effect middle stems in the code. You might want to trace af_cjk_hint_edges() with the given character to see why the alignment was skipped at the middle without blue zone. > The improvement by the proposed tweak for 16pt or smaller seems to be subtle. > Here's the characters I can see the 16pt tweak made differences. GothicBBB: 旦, 吉 Ryumin-Light: 品 ShueiMin: 占 Actually, these characters are the main targets of the patch. These chars have less strokes so they are normally designed to be shorter than the normal characters, i.e. their bottom lines are outside of a smaller blue zone. The patch try to catch these chars at the small font size. ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] Tweak CJK Blue zone parameters
On 05/09/2011 08:21 AM, mpsuz...@hiroshima-u.ac.jp wrote: If further tweak is needed for CJK bluezone, the code would be unmatured, I will disable it by default. In fact, the original demonstration was given by 11pt glyph of WenQuanYi-ZenHei, but your new tweak seems to change the dist value for the glyphs smaller than 17pt I think 17pt is unstable/temporal tuning value and not determined deducively. It makes me afraid that the code includes some ad-hoc parameters and they are not tested well. You don't have to include it. It's just some my brain storms I want to share with the list. The numbers are just some guess of mine. It is less aggressive than the numbers I tried at the beginning. When I test it, I meanly focused on 11pt, and tried to not over optimize it. One effect is that for 意 11pt, it raised the top horizontal edge to the top blue zone. Effectively pushed the dot over the blue zone. Limiting to 17pt is because I felt that, larger than 16pt, my eyes were more tolerant to the small even bottom line. Also around 15pt, the best_dist0 raised to 38 and was turned down to 36 by the safe guard in place. wqy-zenhei has an EM of 1024. How long do you need to find stable values for the tunable parameters? If it is difficult to estimate, I will propose new API to manipulate the parameters by FT2 clients. That's even better. Just don't know how many clients will use the API. Maybe through fontconfig? ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
[ft-devel] Tweak CJK Blue zone parameters
Now that the CJK blue zone code are in the freetype repository, further tweak on the parameters can be performed. One thing that I can think of is that the threshold of best_dist0 used in the af_cjk_hints_compute_blue_edges(). best_dist0 is used to initialize the snap distant from edges to one of the blue zones. It's initially set to 1/40 of EM, and scaled to the rendering size. That means any edge that is closer to 1/40 of the EM (1024 or something) points toward a blue zone will snap to the blue zone. At smaller rendering size, we can have much less possible different edges in limited space. For example, at 16 pixel, we can only have 1/16 different edges, less than the 1/40. (more different edges when considering anti-alias rendering, but that's fuzzy.) Therefore, we can force a bigger snap distance so that we can have more uneven edges aligned. Especially when we deliberately merge some glyph features at the smaller font size. What's the suitable snap distance will vary over fonts. I wrote a patch to set the distance at 1/24 for 16px or smaller font size. Different numbers can be used to experiment with all kind of fonts. More dynamic adjustment can be archived by linking the best_dist0 value to the delta between filled/unfilled blue zones. diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c index 101e668..513b0c0 100644 --- a/src/autofit/afcjk.c +++ b/src/autofit/afcjk.c @@ -1155,8 +1155,15 @@ FT_Posbest_dist0; /* initial threshold */ +FT_Fixed point_size = FT_MulFix( metrics->units_per_em / 64, scale ); + /* compute the initial threshold as a fraction of the EM size */ -best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale ); +/* 16px or smaller font use bigger dist. */ +if ( point_size < 17 ) + best_dist0 = FT_MulFix( metrics->units_per_em / 24, scale ); +else + best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale ); +FT_TRACE6(( "point_size: %li, best_dist0: %li\n", point_size, best_dist0 )); if ( best_dist0 > 64 / 2 ) /* Maximum 1/2 pixel */ best_dist0 = 64 / 2; ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] [Patch] CJK autofit/autohint blue zones
On 05/08/2011 06:32 PM, suzuki toshiya wrote: > I'm sorry for long long delay after your first post of blue zone patch. > Just I've committed your patch to git head. > Thanks for your review and commit work. ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] ttfautohint: fun with assembler code
On 05/07/2011 01:35 PM, Werner LEMBERG wrote: Thanks for you suggestions! Working with bytecode instructions must be actively trained, like any other programming language, then the obstacles diminish. Just for the fun of it, I installed the xgridfit. Learnt and wrote a xgridfit version of the compute_stem_width() function. Porting the pseudo code was fairly straight forward. Xgridfit has quite a rich set of APIs. But the generated code is much longer than your hand craft version, 400+ lines vs 150 lines. A lot of stack management codes. Xgridfit lost in code size... http://xgridfit.sourceforge.net/Xgridfit2";> empty.sfd empty2.sfd PUSHB_1 4 FDEF DEPTH PUSHB_1 17 SWAP WS PUSHB_1 19 PUSHB_1 18 RS PUSHB_1 2 ADD WS PUSHB_2 4 0 WS DEPTH PUSHB_1 17 RS SUB PUSHB_1 1 ADD CINDEX ABS PUSHB_1 18 RS PUSHB_1 1 ADD SWAP WS DEPTH PUSHB_1 17 RS SUB PUSHB_1 2 ADD CINDEX PUSHB_1 18 RS PUSHB_1 1 ADD RS PUSHB_1 3 PUSHB_1 64 MUL LT AND IF DEPTH PUSHB_1 17 RS SUB PUSHB_1 1 ADD CINDEX PUSHB_1 4 SWAP WS ELSE DEPTH PUSHB_1 17 RS SUB PUSHB_1 3 ADD CINDEX IF PUSHB_1 64 PUSHB_1 18 RS PUSHB_1 1 ADD SWAP WS ELSE PUSHB_1 56 PUSHB_1 18 RS PUSHB_1 1 ADD RS MIN PUSHB_1 18 RS PUSHB_1 1 ADD SWAP WS EIF EIF PUSHB_1 18 RS PUSHB_1 1 ADD RS PUSHB_1 0 RCVT SUB ABS PUSHB_1 18 RS PUSHB_1 2 ADD SWAP WS PUSHB_1 18 RS PUSHB_1 2 ADD RS PUSHB_1 40 LT IF PUSHB_1 48 PUSHB_1 0 RCVT MIN PUSHB_1 18 RS PUSHB_1 1 ADD SWAP WS ELSE PUSHB_1 18 RS PUSHB_1 1 ADD RS PUSHB_1 3 PUSHB_1 64 MUL LT IF PUSHB_1 18 RS PUSHB_1 1 ADD RS PUSHB_1 18 RS PUSHB_1 2 ADD SWAP WS PUSHB_1 18 RS PUSHB_1 1 ADD RS FLOOR PUSHB_1 18 RS PUSHB_1 1 ADD SWAP WS PUSHB_1 18 RS PUSHB_1 2 ADD RS PUSHB_1 18 RS PUSHB_1 1 ADD RS SUB PUSHB_1 18 RS PUSHB_1 2 ADD SWAP WS PUSHB_1 18 RS PUSHB_1 2 ADD RS PUSHB_1 10 LT IF PUSHB_1 18 RS PUSHB_1 1 ADD RS PUSHB_1 18 RS PUSHB_1 2 ADD RS ADD PUSHB_1 18 RS PUSHB_1 1 ADD SWAP WS ELSE PUSHB_1 18 RS PUSHB_1 2 ADD RS PUSHB_1 32 LT IF PUSHB_1 18 RS PUSHB_1 1 ADD RS PUSHB_1 10 ADD PUSHB_1 18 RS PUSHB_1 1 ADD SWAP WS ELSE PUSHB_1 18 RS PUSHB_1 2 ADD RS PUSHB_1 54 LT IF PUSHB_1 18 RS PUSHB_1 1 ADD RS PUSHB_1 54 ADD PUSHB_1 18 RS PUSHB_1 1 ADD SWAP WS ELSE PUSHB_1 18 RS PUSHB_1 1 ADD RS PUSHB_1 18 RS PUSHB_1 2 ADD RS ADD PUSHB_1 18 RS PUSHB_1 1 ADD SWAP WS EIF EIF EIF ELSE PUSHB_1 18 RS PUSHB_1 1 ADD RS PUSHB_1 32 ADD FLOOR PUSHB_1 18 RS PUSHB_1 1 ADD SWAP WS EIF EIF DEPTH PUSHB_1 17 RS SUB PUSHB_1 1 ADD CINDEX PUSHB_1 0 LT IF PUSHB_1 18 RS PUSHB_1 1 ADD RS NEG PUSHB_1 18 RS PUSHB_1 1 ADD SWAP WS EIF PUSHB_1 18 RS PUSHB_1 1 ADD RS PUSHB_1 4 SWAP WS POP POP POP ENDF ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] ttfautohint: fun with assembler code
On 04/30/2011 04:07 AM, Werner LEMBERG wrote: I've had some hope to show working bytecode stuff at the beginning of May, but things are a bit more complicated, unfortunately: While the library has been extended to support generated bytecode already, I have first to define some auxiliary bytecode functions to support hinting similar to FreeType's autohinter. . Here an example. The following code is taken from `af_latin_compute_stem_width', transformed into some pseudo code which can be easier converted to bytecode: Function: compute_stem_width ... This corresponds to the following (still untested) bytecode: // In the comments below, the top of the stack (`s:') // is the rightmost element. // Function 0: compute_stem_width // // in: width // is_serif // is_round // out: new_width // CVT: std_width 0xB0, // PUSHB_1 0x00, // 0 0x59, // EIF 0x2D, // ENDF It took me three hours to write that small bit of code, but meanwhile it's getting much faster :-) Those look really mind boggling. Maybe you can make use of the xgridfit tool to semi auto-gen the TT instructions. 1. map the pseudo code to xgridfit xml 2. generate .sfd from the xgridfit with an empty font. 3. ripoff the TT instruction from .sfd 4. edit the TT instruction further to fit ttfautohint. You can even write a script to automatic the 2, 3 steps. ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] [Patch] ftgrid: Add option to display a given UTF-8 character.
On 04/29/2011 02:01 PM, Just Fill Bugs wrote: This patch adds the -s and -u options to start ftgrid for a given UTF-8 character or unicode code in a font. Ping? ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] Culprit for missing segment at the ends of stems.
On 05/05/2011 03:37 AM, Werner LEMBERG wrote: >> It turned out that the culprit was, that the surrounding anchor points >> have no 'out direction' when searching for segments. [...] >> >> Cross out that part will solve the problem for "一" , of cause might >> also screw up some other parts. It's there to keep the tangent small. >> >> Any suggestion on how to fix it properly? > > I can imagine to take the segment length into account: The longer the > segment, the steeper the accepted tangent. > Came up with a patch. I don't know what function should be used to guide the angle against the segment length. diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c index be832ab..a0bc4a2 100644 --- a/src/autofit/afhints.c +++ b/src/autofit/afhints.c @@ -453,7 +453,8 @@ FT_LOCAL_DEF( AF_Direction ) af_direction_compute( FT_Pos dx, -FT_Pos dy ) +FT_Pos dy, +FT_Int dir_scale ) { FT_Posll, ss; /* long and short arm lengths */ AF_Direction dir; /* candidate direction*/ @@ -492,7 +493,7 @@ /* return no direction if arm lengths differ too much */ /* (value 14 is heuristic)*/ -ss *= 14; +ss *= dir_scale; if ( FT_ABS( ll ) <= FT_ABS( ss ) ) dir = AF_DIR_NONE; @@ -560,6 +561,55 @@ } + /* Find a suitable dir_scale based on distant from next on curve point. */ + + FT_LOCAL_DEF( FT_Int ) + find_dir_scale( AF_Point point, + AF_Point point_limit, + AF_Point head ) + { +FT_Pos dx, dy, ss, ll; +AF_Pointnext_on; +FT_Int dir_scale = 14; + +/* FIXME: 100 is obviously arbitrary picked. should + * be something like 1.5 ~ 2 times of stem width. */ +FT_Pos stem_width = 100*2; + +if ( point->flags & AF_FLAG_CONTROL ) + return dir_scale; + +for ( next_on = point->next; next_on < point_limit; next_on++ ) +{ + if ( ! ( next_on->flags & AF_FLAG_CONTROL ) ) + { +break; + } +} +/*printf( "%p, %p, %p\n", + * (void*)next_on, (void*)point_limit, (void*)head ); + */ +if ( next_on >= point_limit ) + next_on = head; /* return to first point. */ + +dx = FT_ABS( point->fx - next_on->fx ); +dy = FT_ABS( point->fy - next_on->fy ); +ss = FT_MIN( dx, dy ); +ll = FT_MAX( dx, dy ); + +if ( ss*14 < ll && ll < stem_width ) +{ + dir_scale = 4; /* 1/4 ~= tan(14 degree) */ +} + +printf( "dir_scale: %2i x,y: %4i,%4i, nx,ny: %4i,%4i ss,ll: %li,%li\n", +dir_scale, point->fx, point->fy, +next_on->fx, next_on->fy, ss, ll ); + +return dir_scale; + } + + /* Recompute all AF_Point in AF_GlyphHints from the definitions */ /* in a source outline. */ @@ -713,6 +763,7 @@ FT_Posin_x = 0; FT_Posin_y = 0; AF_Direction in_dir = AF_DIR_NONE; +FT_Intdir_scale = 14; /* 5 degree of direction slop */ for ( point = points; point < point_limit; point++ ) @@ -723,20 +774,34 @@ if ( point == first ) { +AF_Point prev_on; +for ( prev_on = point->prev; prev_on > point; prev_on-- ) +{ + if ( ! ( prev_on->flags & AF_FLAG_CONTROL ) ) + { +break; + } +} +dir_scale = find_dir_scale( prev_on, point_limit, points ); + prev = first->prev; in_x = first->fx - prev->fx; in_y = first->fy - prev->fy; -in_dir = af_direction_compute( in_x, in_y ); +in_dir = af_direction_compute( in_x, in_y, dir_scale ); first = prev + 1; } point->in_dir = (FT_Char)in_dir; + /* Use the same dir_scale between on curve points. */ + if ( ! ( point->flags & AF_FLAG_CONTROL ) ) +dir_scale = find_dir_scale( point, point_limit, points ); + next = point->next; out_x = next->fx - point->fx; out_y = next->fy - point->fy; - in_dir = af_direction_compute( out_x, out_y ); + in_dir = af_direction_compute( out_x, out_y, dir_scale ); point->out_dir = (FT_Char)in_dir; /* check for weak points */ ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
[ft-devel] Culprit for missing segment at the ends of stems.
I traced the autofit a bit to find out why some segments were missed at the ends of stems. like the vertical segments at the end of 一 of wqy-zenhei.ttc It turned out that the culprit was, that the surrounding anchor points have no 'out direction' when searching for segments. The code in afhints.c[1] has the following lines: af_direction_compute( FT_Pos dx, FT_Pos dy ) { FT_Posll, ss; /* long and short arm lengths */ ... /* return no direction if arm lengths differ too much */ /* (value 14 is heuristic)*/ ss *= 14; if ( FT_ABS( ll ) <= FT_ABS( ss ) ) dir = AF_DIR_NONE; For 一 in wqy-zenhei, ss = -5, and ll = -50 or something for a end point. Hence AF_DIR_NONE. Cross out that part will solve the problem for "一" , of cause might also screw up some other parts. It's there to keep the tangent small. Any suggestion on how to fix it properly? [1] http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/autofit/afhints.c#n455 <>___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
[ft-devel] AutoFit: Treat extrema of contours as edges for CJK glyph?
On 05/01/2011 03:27 PM, Just Fill Bugs wrote: > On 04/29/2011 01:22 AM, mpsuz...@hiroshima-u.ac.jp wrote: >> About the other bluezones, it's difficult for me to recognize >> remarkable improvement. Talking about the height/width proportion >> of "想意", the non-autofitted results look like same size, but >> both (old/new) autofitted results look like different size >> (rather, "想" looks like as taller than "意"). > > That's obviously because we failed to detect a top segment/edge for > the 2 glyphs. Therefore we cannot 'lift' the top edges of the glyphs. > At the same time, the first detected horizontal edges are grid-fit > to the lower grid. The result is a pressed down perception on the > top of the glyphs. > > Cannot do much with blue zone before we can detect all the ending of a > stem and also the extrema of a diagonal stem. It's not a problem of > the blue zone fitting. > For CJK glyph, There are alway many diagonal stems that needed to be fit with blue zones. However, since we cannot produce a horizontal or vertical segment out of a diagonal stem, the stem cannot be blue zoned, e.g. the top and the bottom of 户. To solute the problem, I suggest to treat the extremas of every contours in a glyph as edge lines. Then we can blue zone the edges so that diagonal stems can also be aligned at top and bottom. What do you think? <>___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] [Patch] CJK autofit/autohint blue zones
On 04/29/2011 01:22 AM, mpsuz...@hiroshima-u.ac.jp wrote: > Looking at "想意理生當着" of afoff-afold-afnew_gray_wqyzh0945.png, > I think that your patch removes the bumps of surplus vertical stems > crossing the lowest horizontal stems of "當着" and lifts the lowest > stems of "想意" to align to the lowest stems of other glyphs. > > I think the bumps of surplus vertical stems crossing the lower > horizontal stem (lower-right and lower-left of "口" ) is very > popular design of CJK Ideographs, and they are expected to be > ignored in low resolution rasterization. So the lower bluezone > implementation is good to include. BTW, I'm not sure if lower > bluezone should have filled/unfilled distinction. If you have > any example showing the requirement, please let me know. Well, the filled and unfilled distinction cannot be shown in wqy-zenhei with the current state of the freetype2 stem detection. Some of the filled stem terminal can be detected, some cannot. As can be seem from '林' with my visual segment patch for ftgrid. Initially, I was trying to keep vertical stems and horizontal stems to align to their own bluezone when the bluezone are different enough. maybe at 20pt or 24pt, the 2 blue zones could differ more than 1 pixel. 2ndly, since glyphs end with vertical stem has different bottom from those end with horizontal stem, By using both filled and unfilled blue zones, we can have a bigger range to snap nearby edges. Since the matched blue zone is calculated from the absolute distance before a blue zone to an edge, when the 2 blue zones are different, we effectively can have a reasonable larger blue zone to match more candidate stems. see 林 and 置. Now I think the 2nd reason overweight the 1st because blue zone is most useful at smaller size. > > About the other bluezones, it's difficult for me to recognize > remarkable improvement. Talking about the height/width proportion > of "想意", the non-autofitted results look like same size, but > both (old/new) autofitted results look like different size > (rather, "想" looks like as taller than "意"). That's obviously because we failed to detect a top segment/edge for the 2 glyphs. Therefore we cannot 'lift' the top edges of the glyphs. At the same time, the first detected horizontal edges are grid-fit to the lower grid. The result is a pressed down perception on the top of the glyphs. Cannot do much with blue zone before we can detect all the ending of a stem and also the extrema of a diagonal stem. It's not a problem of the blue zone fitting. Well, maybe for the 想, if we can relax the threshold for finding matching blue zone, the top of 目 will be matched to top blue zone and be lifted. Don't know how much false positive will get if we relax the threshold. It will look bad if the horizontal stem of 木 in 想 also matches the top blue zone. :( > Also the legibility > of upper parts of "它" and "當" gets worse than old autofitter. That is the horizontal blue zone effect. Since you planned to turn horizontal blue zone off, it should not be a problem. The other solution is to always expand the blue zones at smaller point so we can be guaranteed to have greater or equal sized glyph. At lease we can use a 1/4 pixel as threshold for rounding blue zones instead of 1/2 pixel we are currently used. The threshold for detecting matched blue zone can also be changed for smaller font. But that can be done once the blue zone code is in place. > > In summary, I think the lower bluezone would be worth to include > in next release, but others are questionable, if my samples > are appropriate to understand your proposals. Anyway, I think > your approach is very good and I want to decide after complete > reproduction of the demonstration. If GNU/Linux binary is acceptable, > I will upload my ftstring binaries. > It's ok with me. The bottom line zig-zag is an immediate problem for CJK font at small size. Others are just bonus. <><><>___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
[ft-devel] [Patch] ftgrid: Add option to display a given UTF-8 character.
This patch adds the -s and -u options to start ftgrid for a given UTF-8 character or unicode code in a font. diff --git a/src/ftgrid.c b/src/ftgrid.c index 711da2b..7860c7e 100644 --- a/src/ftgrid.c +++ b/src/ftgrid.c @@ -66,6 +66,7 @@ typedef struct status_ int ptsize; int res; int Num; /* glyph index */ + FT_UInt32charcode; /* unicode index */ int font_index; double scale; @@ -127,6 +128,7 @@ grid_status_init( GridStatus st, st->do_outline= 1; st->Num= 0; + st->charcode = 0; st->gamma = 1.0; st->header = ""; } @@ -909,6 +911,8 @@ grid_status_draw_outline( GridStatus st, fprintf( stderr, "\n" ); fprintf( stderr, " -r R use resolution R dpi (default: 72 dpi)\n" ); fprintf( stderr, " -f index specify first index to display\n" ); +fprintf( stderr, " -c char specify first UTF-8 Character to display\n" ); +fprintf( stderr, " -u char specify first unicode number to display\n" ); fprintf( stderr, "\n" ); exit( 1 ); @@ -921,13 +925,14 @@ grid_status_draw_outline( GridStatus st, { char* execname; intoption; +const char* Text; execname = ft_basename( (*argv)[0] ); while ( 1 ) { - option = getopt( *argc, *argv, "f:r:" ); + option = getopt( *argc, *argv, "f:r:c:u:" ); if ( option == -1 ) break; @@ -944,6 +949,15 @@ grid_status_draw_outline( GridStatus st, usage( execname ); break; + case 'c': +Text = (const char*)optarg; +status.charcode = utf8_next(&Text, Text + strlen(Text)); +break; + + case 'u': +status.charcode = atoi( optarg ); +break; + default: usage( execname ); break; @@ -1001,6 +1015,12 @@ grid_status_draw_outline( GridStatus st, event_font_change( 0 ); +if ( status.Num == 0 && status.charcode != 0 ) { + status.Num = FTDemo_Get_Index( handle, status.charcode ); + if ( status.Num == 0 ) +printf( "Could not found the given character in the font.\n" ); +} + grid_status_rescale_initial( &status, handle ); for ( ;; ) ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] Any tool that visually present segments of autofit module?
On 04/24/2011 02:05 PM, Werner LEMBERG wrote: I very much dislike the use of afhints.h and aftypes.h within the user space. Could you instead add debug hooks to afhints.c which can be used for communication? The simplest form could be something like these two functions: FT_Error af_glyph_hints_get_num_segments(AF_GlyphHints hints, int dimension, FT_Int* num_segments); FT_Error af_glyph_hints_get_segment_offset(AF_GlyphHints hints, int dimension, FT_Int idx, FT_Pos* offset); Okey, I add the accessor functions to afhint.c. I also made the segment drawing independent of the force autofit mode. I found that the segment lines are useful reference with or without autofit turned on. One observation I had is that in order to have the outlines merge with the segments into one, I have to 1. turn on force autofit (f) 2. turn of Horizontal and Vertical Hinting (H and V) 3. turn on hinting (h) Otherwise, there are always some offset between the outlines and the segments. diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c index 70c1054..22092b0 100644 --- a/src/autofit/afhints.c +++ b/src/autofit/afhints.c @@ -276,6 +276,55 @@ } #endif + /* Fetch number of segments */ +#ifdef __cplusplus + extern "C" { +#endif + FT_Error + af_glyph_hints_get_num_segments( AF_GlyphHints hints, + int dimension, + FT_Int* num_segments ) + { +FT_Error error= AF_Err_Ok; +AF_AxisHints axis = &hints->axis[dimension]; + +*num_segments = axis->num_segments; + +return error; + } +#ifdef __cplusplus + } +#endif + + /* fetch offset of segments. User supply the offset array. */ +#ifdef __cplusplus + extern "C" { +#endif + FT_Error + af_glyph_hints_get_segment_offset( AF_GlyphHints hints, + int dimension, + FT_Int idx, + FT_Pos* offset ) + { +FT_Error error= AF_Err_Ok; +AF_AxisHints axis = &hints->axis[dimension]; +AF_Segmentsegments = axis->segments; +AF_Segmentlimit= segments + idx; +AF_Segmentseg; + + +for ( seg = segments; seg < limit; seg++ ) +{ + *offset = dimension == AF_DIMENSION_HORZ ? (int)seg->first->ox + : (int)seg->first->oy; + offset++; +} + +return error; + } +#ifdef __cplusplus + } +#endif /* Dump the array of linked edges. */ @@ -348,6 +397,27 @@ FT_UNUSED( hints ); } + FT_Error + af_glyph_hints_get_num_segments( AF_GlyphHints hints, + int dimension, + FT_Int* num_segments ) + { +FT_UNUSED( hints ); +FT_UNUSED( dimension ); +FT_UNUSED( num_segments ); + } + + FT_Error + af_glyph_hints_get_segment_offset( AF_GlyphHints hints, + int dimension, + FT_Int idx, + FT_Pos* offset ) + { +FT_UNUSED( hints ); +FT_UNUSED( dimension ); +FT_UNUSED( idx ); +FT_UNUSED( offset ); + } void af_glyph_hints_dump_edges( AF_GlyphHints hints ) diff --git a/src/ftgrid.c b/src/ftgrid.c index 711da2b..ed3a77a 100644 --- a/src/ftgrid.c +++ b/src/ftgrid.c @@ -57,6 +57,13 @@ extern void af_glyph_hints_dump_segments( AF_GlyphHints hints ); extern void af_glyph_hints_dump_points( AF_GlyphHints hints ); extern void af_glyph_hints_dump_edges( AF_GlyphHints hints ); + extern FT_Error af_glyph_hints_get_num_segments( AF_GlyphHints hints, + int dimension, + FT_Int* num_segments ); + extern FT_Error af_glyph_hints_get_segment_offset( AF_GlyphHints hints, + int dimension, + FT_Int idx, + FT_Pos* offset ); #ifdef __cplusplus } #endif @@ -87,12 +94,14 @@ typedef struct status_ grColor on_color; grColor conic_color; grColor cubic_color; + grColor segment_color; int do_horz_hints; int do_vert_hints; int do_blue_hints; int do_outline; int do_dots; + int do_segment; double gamma; const char* header; @@ -116,6 +125,7 @@ grid_status_init( GridStatus st, st->on_color = grFindColor( display->bitmap, 64, 64, 255, 255 ); st->conic_color = grFindColor( display->bitmap, 0, 128, 0, 255 ); st->cubic_color = grFindColor( display->bitmap, 255, 64, 255, 255 ); + st->segment_color
Re: [ft-devel] [Patch] CJK autofit/autohint blue zones
Oops, a bug fixed. diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c index c15d343..2be157a 100644 --- a/src/autofit/afcjk.c +++ b/src/autofit/afcjk.c @@ -45,8 +45,456 @@ /*/ /*/ + /* Basically the Latin version with AF_CJKMetrics to replace AF_LatinMetrics */ + FT_LOCAL_DEF( void ) + af_cjk_metrics_init_widths( AF_CJKMetricsmetrics, + FT_Face face, + FT_ULong charcode ) + { +/* scan the array of segments in each direction */ +AF_GlyphHintsRec hints[1]; + + +af_glyph_hints_init( hints, face->memory ); + +metrics->axis[AF_DIMENSION_HORZ].width_count = 0; +metrics->axis[AF_DIMENSION_VERT].width_count = 0; + +{ + FT_Error error; + FT_UInt glyph_index; + int dim; + AF_CJKMetricsRec dummy[1]; + AF_Scalerscaler = &dummy->root.scaler; + + + glyph_index = FT_Get_Char_Index( face, charcode ); + if ( glyph_index == 0 ) +goto Exit; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || face->glyph->outline.n_points <= 0 ) +goto Exit; + + FT_ZERO( dummy ); + + dummy->units_per_em = metrics->units_per_em; + scaler->x_scale = scaler->y_scale = 0x1L; + scaler->x_delta = scaler->y_delta = 0; + scaler->face= face; + scaler->render_mode = FT_RENDER_MODE_NORMAL; + scaler->flags = 0; + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + + error = af_glyph_hints_reload( hints, &face->glyph->outline ); + if ( error ) +goto Exit; + + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { +AF_CJKAxisaxis= &metrics->axis[dim]; +AF_AxisHints axhints = &hints->axis[dim]; +AF_Segmentseg, limit, link; +FT_UInt num_widths = 0; + + +error = af_latin_hints_compute_segments( hints, + (AF_Dimension)dim ); +if ( error ) + goto Exit; + +af_latin_hints_link_segments( hints, + (AF_Dimension)dim ); + +seg = axhints->segments; +limit = seg + axhints->num_segments; + +for ( ; seg < limit; seg++ ) +{ + link = seg->link; + + /* we only consider stem segments there! */ + if ( link && link->link == seg && link > seg ) + { +FT_Pos dist; + + +dist = seg->pos - link->pos; +if ( dist < 0 ) + dist = -dist; + +if ( num_widths < AF_CJK_MAX_WIDTHS ) + axis->widths[ num_widths++ ].org = dist; + } +} + +af_sort_widths( num_widths, axis->widths ); +axis->width_count = num_widths; + } + + Exit: + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { +AF_CJKAxisaxis = &metrics->axis[dim]; +FT_Posstdw; + + +stdw = ( axis->width_count > 0 ) + ? axis->widths[0].org + : AF_LATIN_CONSTANT( metrics, 50 ); + +/* let's try 20% of the smallest width */ +axis->edge_distance_threshold = stdw / 5; +axis->standard_width = stdw; +axis->extra_light = 0; + } +} + +af_glyph_hints_done( hints ); + } + + + +#define AF_CJK_MAX_TEST_CHARACTERS 32 + + + /* Every blue zone has 2 types of fill and unfill, + * Which means fill the entire square or not. + * */ + enum + { +AF_CJK_BLUE_TYPE_FILL, +AF_CJK_BLUE_TYPE_UNFILL, +AF_CJK_BLUE_TYPE_MAX + }; + + /* Put some common and representative CJK characters here. */ + static const FT_ULong af_cjk_blue_chars[AF_CJK_BLUE_MAX] + [AF_CJK_BLUE_TYPE_MAX] + [AF_CJK_MAX_TEST_CHARACTERS] = + { +{ + { + 0X4ED6, 0X4EEC, 0X4F60, 0X4F86, 0X5011, 0X5230, 0X548C, 0X5730, + 0X5BF9, 0X5C0D, 0X5C31, 0X5E2D, 0X6211, 0X65F6, 0X6642, 0X6703, + 0X6765, 0X70BA, 0X80FD, 0X8230, 0X8AAA, 0X8BF4, 0X8FD9, 0X9019, + 0X9F4A /* top fill */ + }, + { + 0X519B, 0X540C, 0X5DF2, 0X613F, 0X65E2, 0X661F, 0X662F, 0X666F, + 0X6C11, 0X7167, 0X73B0, 0X73FE, 0X7406, 0X7528, 0X7F6E, 0X8981, + 0X8ECD, 0X90A3, 0X914D, 0X91CC, 0X958B, 0X96F7, 0X9732, 0X9762, + 0X987E /* top unfill */ + } +}, +{ + { + 0X4E2A, 0X4E3A, 0X4EBA, 0X4ED6, 0X4EE5, 0X4EEC, 0X4F60, 0X4F86, + 0X500B, 0X5011, 0X5230, 0X548C, 0X5927, 0X5BF9, 0X5C0D, 0X5C31, + 0X6211, 0X65F6, 0X6642, 0X6709, 0X6765, 0X70BA, 0X8981, 0X8AAA, + 0X8BF4 /* bottom fill */ + }, + { + 0X4E3B, 0X4E9B, 0X56E0, 0X5B83, 0X60F3, 0X610F, 0X7406, 0X751F, + 0X7576, 0X770B, 0X7740, 0X7F6E, 0X8005, 0X81EA, 0X8457,
Re: [ft-devel] [Patch] CJK autofit/autohint blue zones
On 04/21/2011 09:24 PM, Just Fill Bugs wrote: I meant some steps were missing in the code. The bluezone is not properly grid fit before the numbers being used to align segments. There are indeed some problems with the patch. They happened when the bluezones were scaled at af_cjk_metrics_scale_dim() 1. The shoot in cjk means undershoot, so the shoot should be the smaller one. 2. The fit can be set at 1/2 a pixel in the patch. Maybe that is useful for latin round edge. But for CJK, undershoot are straight edge too. So 1/2 pixel is meaningless except creating blur. 3. The undershoot is compared to the un-fitted reference when calculating a grid fit distance. But its fitted position was calculated from fitted reference + fitted distance. This could over-compensate the offset. I update the patch to the current git and address the problems. Please review the logic behind the idea. There could be other improvements when scaling the bluezone. Like under small size, round the bluezones to the ceiling unconditionally. That could make glyph bigger and clearer. But could make it 1 pixel extra bigger than the intended size. diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c index c15d343..f12d0dd 100644 --- a/src/autofit/afcjk.c +++ b/src/autofit/afcjk.c @@ -45,8 +45,456 @@ /*/ /*/ + /* Basically the Latin version with AF_CJKMetrics to replace AF_LatinMetrics */ + FT_LOCAL_DEF( void ) + af_cjk_metrics_init_widths( AF_CJKMetricsmetrics, + FT_Face face, + FT_ULong charcode ) + { +/* scan the array of segments in each direction */ +AF_GlyphHintsRec hints[1]; + + +af_glyph_hints_init( hints, face->memory ); + +metrics->axis[AF_DIMENSION_HORZ].width_count = 0; +metrics->axis[AF_DIMENSION_VERT].width_count = 0; + +{ + FT_Error error; + FT_UInt glyph_index; + int dim; + AF_CJKMetricsRec dummy[1]; + AF_Scalerscaler = &dummy->root.scaler; + + + glyph_index = FT_Get_Char_Index( face, charcode ); + if ( glyph_index == 0 ) +goto Exit; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || face->glyph->outline.n_points <= 0 ) +goto Exit; + + FT_ZERO( dummy ); + + dummy->units_per_em = metrics->units_per_em; + scaler->x_scale = scaler->y_scale = 0x1L; + scaler->x_delta = scaler->y_delta = 0; + scaler->face= face; + scaler->render_mode = FT_RENDER_MODE_NORMAL; + scaler->flags = 0; + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + + error = af_glyph_hints_reload( hints, &face->glyph->outline ); + if ( error ) +goto Exit; + + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { +AF_CJKAxisaxis= &metrics->axis[dim]; +AF_AxisHints axhints = &hints->axis[dim]; +AF_Segmentseg, limit, link; +FT_UInt num_widths = 0; + + +error = af_latin_hints_compute_segments( hints, + (AF_Dimension)dim ); +if ( error ) + goto Exit; + +af_latin_hints_link_segments( hints, + (AF_Dimension)dim ); + +seg = axhints->segments; +limit = seg + axhints->num_segments; + +for ( ; seg < limit; seg++ ) +{ + link = seg->link; + + /* we only consider stem segments there! */ + if ( link && link->link == seg && link > seg ) + { +FT_Pos dist; + + +dist = seg->pos - link->pos; +if ( dist < 0 ) + dist = -dist; + +if ( num_widths < AF_CJK_MAX_WIDTHS ) + axis->widths[ num_widths++ ].org = dist; + } +} + +af_sort_widths( num_widths, axis->widths ); +axis->width_count = num_widths; + } + + Exit: + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { +AF_CJKAxisaxis = &metrics->axis[dim]; +FT_Posstdw; + + +stdw = ( axis->width_count > 0 ) + ? axis->widths[0].org + : AF_LATIN_CONSTANT( metrics, 50 ); + +/* let's try 20% of the smallest width */ +axis->edge_distance_threshold = stdw / 5; +axis->standard_width = stdw; +axis->extra_light = 0; + } +} + +af_glyph_hints_done( hints ); + } + + + +#define AF_CJK_MAX_TEST_CHARACTERS 32 + + + /* Every blue zone has 2 types of fill and unfill, + *
Re: [ft-devel] Any tool that visually present segments of autofit module?
On 04/22/2011 09:06 PM, Just Fill Bugs wrote: Besides, the vertical segments are abnormal. There are some non-uniform drift from where it supposed to be. I don't know where the problem are. Apparently, handle->hinted = 0 will not completely disable hinting. 'V' and 'H' will turn off hinting more complete. ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] Any tool that visually present segments of autofit module?
On 04/20/2011 02:52 PM, Werner LEMBERG wrote: Are there any tool which visually present segments of autofit module? Something like stems shown in the glyph view of fontforge. No, but I'll probably add this to ftgrid since it would be helpful for my work on the ttfautohint stuff. But it isn't an urgent issue, and in case you have time to implement it I would be very grateful :-) OK, I made a simple patch to draw the segment data. I have to copy afhints.h and aftypes.h to the src/ directory because I really need some structs from autofit/. Besides, the vertical segments are abnormal. There are some non-uniform drift from where it supposed to be. I don't know where the problem are. Attach a image to show ftgrid with arphic uming font. You can use 'h' to toggle ignoring the hinting and 's' to toggle drawing stems. <>diff --git a/src/ftgrid.c b/src/ftgrid.c index 13858dd..f45133a 100644 --- a/src/ftgrid.c +++ b/src/ftgrid.c @@ -15,6 +15,7 @@ #include "ftcommon.h" #include "common.h" +#include "afhints.h" #include /* the following header shouldn't be used in normal programs */ @@ -39,17 +40,12 @@ #define snprintf _snprintf #endif - - /* these variables, structures and declarations are for */ - /* communication with the debugger in the autofit module; */ - /* normal programs don't need this*/ - struct AF_GlyphHintsRec_; - typedef struct AF_GlyphHintsRec_* AF_GlyphHints; - +/* these variables, structures and declarations are for */ +/* communication with the debugger in the autofit module; */ +/* normal programs don't need this*/ int_af_debug_disable_horz_hints; int_af_debug_disable_vert_hints; int_af_debug_disable_blue_hints; - AF_GlyphHints _af_debug_hints; #ifdef __cplusplus extern "C" { @@ -87,12 +83,14 @@ typedef struct status_ grColor on_color; grColor conic_color; grColor cubic_color; + grColor stem_color; int do_horz_hints; int do_vert_hints; int do_blue_hints; int do_outline; int do_dots; + int do_stem; double gamma; const char* header; @@ -116,6 +114,7 @@ grid_status_init( GridStatus st, st->on_color = grFindColor( display->bitmap, 64, 64, 255, 255 ); st->conic_color = grFindColor( display->bitmap, 0, 128, 0, 255 ); st->cubic_color = grFindColor( display->bitmap, 255, 64, 255, 255 ); + st->stem_color= grFindColor( display->bitmap, 64, 255, 128, 64 ); st->disp_width= display->bitmap->width; st->disp_height = display->bitmap->rows; st->disp_bitmap = display->bitmap; @@ -125,6 +124,7 @@ grid_status_init( GridStatus st, st->do_blue_hints = 1; st->do_dots = 1; st->do_outline= 1; + st->do_stem = 0; st->Num= 0; st->gamma = 1.0; @@ -218,6 +218,42 @@ grid_status_draw_grid( GridStatus st ) grFillHLine( st->disp_bitmap, 0, y_org, st->disp_width, st->axis_color ); } +static void +grid_hint_draw_stem( GridStatus st, + AF_GlyphHints hints ) +{ + FT_Int dimension; + int x_org = (int)st->x_origin; + int y_org = (int)st->y_origin; + + + for ( dimension = 1; dimension >= 0; dimension-- ) + { +AF_AxisHints axis = &hints->axis[dimension]; +AF_Segmentsegments = axis->segments; +AF_Segmentlimit= segments + axis->num_segments; +AF_Segmentseg; + + +for ( seg = segments; seg < limit; seg++ ) +{ + FT_Pos pos; + + if ( dimension == AF_DIMENSION_HORZ ) + { +pos = x_org + (int)seg->first->ox * st->scale; +grFillVLine( st->disp_bitmap, (int)pos, 0, +st->disp_height, st->stem_color ); + } + else + { +pos = y_org - (int)seg->first->oy * st->scale; +grFillHLine( st->disp_bitmap, 0, (int)pos, +st->disp_width, st->stem_color ); + } +} + } +} static void ft_bitmap_draw( FT_Bitmap* bitmap, @@ -403,6 +439,10 @@ grid_status_draw_outline( GridStatus st, handle->load_flags | FT_LOAD_NO_BITMAP ) ) return; + /* Draw stem before draw glyph. */ + if ( status.do_stem && handle->autohint ) +grid_hint_draw_stem ( &status, _af_debug_hints ); + slot = size->face->glyph; if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) { @@ -501,6 +541,7 @@ grid_status_draw_outline( GridStatus st, grLn(); grWriteln( " a : toggle anti-aliasing" ); grWriteln( " f : toggle forced autofit mode" ); +grWriteln( " h : toggle ignore hinting mode" ); grWriteln( " left/right : decrement/increment glyph index" ); grWriteln( " up/down: change character size" ); grLn(); @@ -522,6 +563,7 @@ grid_status_draw_outline( GridStatus st, grWriteln( " H : toggle horizontal hinting" );
Re: [ft-devel] [Patch] CJK autofit/autohint blue zones
On 04/20/2011 09:27 PM, mpsuz...@hiroshima-u.ac.jp wrote: > On Wed, 20 Apr 2011 14:53:08 +0200 (CEST) > Werner LEMBERG wrote: > >>> It's kinda weird because the bluezones should be grid fit before >>> being used to align stems. In the pictures, the top bluezone was >>> obviously not grid fit. Maybe a step was missed. >> >> Indeed, it looks odd. I was just going to write that I don't see a >> real improvement... Toshiya-san, may I ask you to give a detailed >> recipe how you've created those images? > > My pictures were taken as: > ... I meant some steps were missing in the code. The bluezone is not properly grid fit before the numbers being used to align segments. ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] [Patch] CJK autofit/autohint blue zones
On 04/20/2011 08:34 PM, Just Fill Bugs wrote: > On 04/20/2011 02:16 PM, mpsuz...@hiroshima-u.ac.jp wrote: >> Maybe my impression about vertical bluezone is based on the >> typography in Japanese market, so, I don't think this is >> generic. Please let me know if there is such requirement in >> Chinese or Korean typography. > > There is require to align side of glyph in vertical writing in Chinese. > I meant to write "There is NO require to align side of glyph in vertical writing Chinese." Sorry. ___ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] [PATCH] CJK Autohinter should not clump stems together when there are too many of them
On 04/20/2011 06:35 PM, Werner LEMBERG wrote: > > Thanks for reviewing. Do you have an idea how to increase the > legibility of the longest strokes? Contrary to the proposed patch I > think that this what you suggest is quite hard a job to achieve since > you not only have to do feature analysis, e.g., mark horizontal stems > which are surrounded by vertical stems like this > > |-| > > as `unimportant', but also distort the glyph accordingly so that > `important' stems are aligned to the grid... > There could be an extra step for grouping stems. Stems belong to the same contour or surrounded by a outer contour are grouped together. Counter hinting could be performed on intra and inter groups. ___ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] [Patch] CJK autofit/autohint blue zones
On 04/20/2011 07:31 PM, mpsuz...@hiroshima-u.ac.jp wrote: > > Here is the anti-aliasing comparison. The patch makes > the contrast of some top horizontal strokes (因, 置, > 里, 面) weak. > It's kinda weird because the bluezones should be grid fit before being used to align stems. In the pictures, the top bluezone was obviously not grid fit. Maybe a step was missed. ___ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] [Patch] CJK autofit/autohint blue zones
On 04/20/2011 02:16 PM, mpsuz...@hiroshima-u.ac.jp wrote: > Q1) The vertical bluezones are essential? > > In vertical CJK typography, there would be the requirement > to align long center stems (of the glyphs like "十", "土", > "王"), to pretend the centerlines of the glyphs are aligned. > However, I'm questionable if there is a requirement to align > non-center stems to be aligned. Maybe the alignment of the > vertical stems of the radical-"enclosure" glyphs (like "回", > "囚", "困") or radical-"gate" glyphs (like "門", "開", "閉" ) > may improve the quality. But I'm questionable if there is > the requirement to align the left vertical stems of radical > "mound" glyphs (like "阿", "防", "阻"), or radical "mouse" > glyphs (like "叫", "叩", "叱"). > > Maybe my impression about vertical bluezone is based on the > typography in Japanese market, so, I don't think this is > generic. Please let me know if there is such requirement in > Chinese or Korean typography. There is require to align side of glyph in vertical writing in Chinese. For the vertical blue zone. Partly because I kinda misunderstood the icfb tag describe by Adobe at http://partners.adobe.com/public/developer/opentype/index_tag4.html#ideoembox I guess it mostly talking about horizontal alignment using icfb, while I mistook it's also used for vertical layout. Another reason I consider to add vertical blue zone is that I don't know how vertical layout looks like at small size on screen. Without blue zone, the width of glyphs will vary quite frequently at small points. I don't know how our eyes tolerant to that. Just better safe than sorry. Of course it can always be removed now and add back by request. > > Q2) What kind of glyphs are good to calculate the fill bluezone? > > It seems that the characters to calculate the top-fill bluezone > is collected from the characters which have some peak/apex in > upper boundary but have no horizontal strokes. Is it possible to > reduce the testing characters by using the characters with the > the radicals with peak, like, "京" (radical lid), "令" (radical > man), "安" (radical roof), "床" (radical dotted-cliff), "草" > (radical grass)? > In my personal opinion, using "dot beyond horizontal stroke" is > good benchmark to reserve the room of the dot in low resolution. > Top fill really just verticle stems and dot like strokes which are more extruded than horizontal stems. I agree. For complex enough character, dot like strokes are more representative. > > However, some strokes have inconstant line width issues; > the top horizontal stroke of "面" is typical example. > "看" in IPA Gothic shows similar issue. Maybe this can be alleviated by take into account the accumulated small 'drift' of alignment of previous stems as aflatin2.c did. And turn on grey scale rendering should help too. > > I think your patch is very good but the list of testing > characters requires more discussion. So I will try to add > new API for the client to modify the list. > Thanks for your work! ___ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel