|
From: | Graham Asher |
Subject: | RE: [ft-devel] limiting the heap memory used by a TrueType font |
Date: | Fri, 14 Dec 2007 14:46:38 -0000 |
David, I realise that in the
case of memory-mapped data this is not needed (you speak to one who has been
single-stepping through the code, and modifying it). I should have clarified my
first message by explaining that I am working with a platform where the data is
stored in segmented form in Flash memory that is subject to relocation, and
thus, although the stream interface works very fast, because it has access to
the pointers to the data segments, it cannot be dispensed with. I expect that
this is a common situation. However, what I have
done is essential for the platform I am working on, and may well be essential
for other low-RAM devices. In my current work we can use large TrueType fonts
(~2BM Japanese fonts, for example) successfully with my changes; we cannot use
them without my changes. Also, my CMAP code is entirely non-invasive; it doesn’t
change the FreeType code or API at all but is an optional add-on. (You call a
function that gets the memory offset of the charmap, stores it, then unloads
the CMAP table; then you use a replacement function instead of
FT_Get_Char_Index.) Note also that what I
propose is optional; and can be tuned to affect CMAP, LOCA, etc., tables above
a certain size only; and if made a run-time option rather than a compile-time
option (I mentioned this in my first message), can be made to work only for
non-memory-mapped files. I don’t think making
FT_Get_Char_Index use a stream interface would cripple text layout performance.
I have no benchmarking to back that assertion up yet, I admit, but my
experience when profiling is that TrueType rendering is dominated by
rasterization. The stream interface will often (as is the case with my current
work) have access to the data in the form of a series of discontinuous memory
blocks; that is, the file is memory-mapped but segmented and thus requires a
stream interface, but the overhead is relatively low because the data is
actually in memory. Further, getting a
glyph location from the LOCA table requires a only one seek and two reads;
there is no very good reason for copying the LOCA table into RAM. Here is a working and
tested alternative version of tt_face_get_location; in this code, the pointer
face->glyph_locations has been replaced by an offset
face->glyph_locations_offset. FT_LOCAL_DEF(
FT_ULong )
tt_face_get_location( TT_Face face,
FT_UInt gindex,
FT_UInt *asize ) { FT_ULong pos1,
pos2; FT_ULong p; FT_ULong
p_limit; FT_Stream stream
= face->root.stream; FT_Error error =
0; pos1 = pos2 = 0; if ( gindex <
face->num_locations ) { if (
face->header.Index_To_Loc_Format != 0 ) { p =
face->glyph_locations_offset + gindex * 4; p_limit =
face->glyph_locations_offset + face->num_locations * 4; error
= FT_Stream_Seek(stream,p); pos1
= FT_Stream_ReadLong(stream,&error); pos2 = pos1; if ( p + 4
<= p_limit ) pos2 =
FT_Stream_ReadLong(stream,&error); } else { p =
face->glyph_locations_offset + gindex * 2; p_limit =
face->glyph_locations_offset + face->num_locations * 2; error
= FT_Stream_Seek(stream,p); pos1
= FT_Stream_ReadShort(stream,&error) & 0xFFFF; pos2 = pos1; if ( p + 2
<= p_limit ) pos2 =
FT_Stream_ReadShort(stream,&error) & 0xFFFF; pos1
<<= 1; pos2
<<= 1; } } /* It isn't
mentioned explicitly that the `loca' table must be */ /* ordered, but
implicitly it refers to the length of an entry */ /* as the
difference between the current and the next position. */ /* Anyway, there
do exist (malformed) fonts which don't obey */ /* this rule, so
we are only able to provide an upper bound for */ /* the
size. */ if ( pos2 >=
pos1 ) *asize =
(FT_UInt)( pos2 - pos1 ); else *asize =
(FT_UInt)( face->glyf_len - pos1 ); return pos1; } In conclusion I
believe that what I have done is not only useful – in fact, essential –
to my current project but of potential use to FreeType users on other devices
with limited heap memory. Best regards, Graham From:
address@hidden [mailto:address@hidden On Behalf Of David Turner Hi Graham, 2007/12/11, Graham
Asher <address@hidden>: TrueType fonts contain
several tables that vary in a linear way with the |
[Prev in Thread] | Current Thread | [Next in Thread] |