freetype
[Top][All Lists]
Advanced

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

Re: [ft] Faster computation of text width?


From: John Found
Subject: Re: [ft] Faster computation of text width?
Date: Fri, 13 Mar 2015 12:37:38 +0200

On Fri, 13 Mar 2015 09:45:57 +0100 (CET)
Werner LEMBERG <address@hidden> wrote:

> 
> > According to the FreeType documentation, the fastest way to compute
> > the width of some text string is to use FT_Get_Advance function that
> > returns the advance values without loading and rendering the glyphs.
> 
> See documentation of FT_ADVANCE_FLAG_FAST_ONLY for reasons why this
> can take a long time.

Indeed, working more on this issue I realized, that using 
FT_ADVANCE_FLAG_FAST_ONLY
together with FT_LOAD_TARGET_LCD causes FT_Get_Advance to fail always. 
Removing FT_ADVANCE_FLAG_FAST_ONLY, makes it work but very slow.

On the other hand, using FT_LOAD_NO_HINTING makes it to work really fast, 
but the computed width is not the same as the width of the rendered string
with hinting enabled.

Which makes this function almost useless in the real world... :(


> 
> Hmm.  Please provide a small snippet that demonstrates the problem.
> 

Well I tested it with the following code (I simplified it in order to be more 
clear).
The benchmark is to call the code 1000 times for a string 85 characters long. 
All text in the string is in English.

1. Using FT_Get_Advance: 

.char_loop:
        stdcall DecodeUtf8, [esi]
        jc      .finish                 ; invalid UTF-8

        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax
        mov     ebx, eax        ; glyph index

        lea     eax, [.advance]
        cinvoke FT_Get_Advance, [.face], ebx, 0 and FT_ADVANCE_FLAG_FAST_ONLY 
or FT_LOAD_NO_HINTING, eax

        test    eax, eax
        jnz     .char_loop

        mov     eax, [.advance]
        sar     eax, 10         ; make it 26.6
        add     [.x], eax
        jmp     .char_loop

Benchmark approximately: 
  60ms   with FT_ADVANCE_FLAG_FAST_ONLY + FT_LOAD_NO_HINTING; Wrong width 
computed (3px wider)
  1600ms with FT_LOAD_TARGET_LCD only; Exact width computed.


2. Using the cache sub-system:

.char_loop:
        stdcall DecodeUtf8, [esi]
        jc      .finish

        cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax
        mov     ebx, eax

        lea     ecx, [.type]
        lea     edx, [.glyph]
        cinvoke FTC_ImageCache_Lookup, [FTCImageCache], ecx, ebx, edx, 0

        test    eax, eax
        jnz     .char_loop

        mov     ebx, [.glyph]

        mov     eax, [ebx+FT_GlyphRec.advance.x]
        sar     eax, 10        ; format 16.16 fixed decimal point.
        add     [.x], eax
        jmp     .char_loop


Benchmark approximately:

  65ms with the same flags used for rendering (FT_LOAD_TARGET_LCD + 
FT_LOAD_RENDER); Exact width computed.


-- 
http://fresh.flatassembler.net
http://asm32.info
John Found <address@hidden>



reply via email to

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