|
From: | Jeff Finger |
Subject: | [ft] Adding Outline Information |
Date: | Tue, 8 Jan 2008 17:57:43 +0200 |
Is there any way that my driver can add information (64 bytes) to
an FT_Outline without breaking things? Since FT_Outline is part of the public
interface of FreeType, I suspect there is no good way. My problem is that my renderer requires that some additional
information exist at scan-conversion time. This information is created during
FT_Load_Glyph and needs to be available during rendering, that is,
surviving any caching of outlines. Any ideas would be greatly appreciated. I had hoped to avoid creating
some new outline type besides FT_GLYPH_FORMAT_OUTLINE, but there may be no
other way. Am I missing something obvious or something big in the FreeType
architecture? I hope so. In more detail.... I have been given a task has some difficult constraints, and I am
trying to find a safe way to accomplish the task. Constraints: 1. Replace FreeType's native reading, adjusting, and scan
conversion of some format F for some subset of fonts in format F, perhaps all
of them. 2. Not change FreeType's rendering of fonts in other formats. 3. Continue to use FT_GLYPH_FORMAT_OUTLINE so as to not break
existing clients of FreeType, such as existing outline caches, that handle type
F. A Partial Solution: 1. Have my driver read and adjust the desired set of fonts: Unregister the FreeType
native FT_Driver_Class for format F and register my own driver class FC. FC
either calls methods from the FreeType native FT_Driver_Class or calls its own
methods depending on whether it wants to deal with the font. (I am skipping
over various initialization and finalization considerations, which are easy
enough to solve.) The goal here is to keep the native class from potentially
grabbing the font before I have a chance to decide what to do. Perhaps a better
solution is to modify both drivers’ face_init methods so that it does not
matter which is called first. This allows reading and
adjusting of outlines, that is, proceeding through FT_Load_Glyph without
rendering the glyph. We then want to use our own
renderer for outlines we created. 2. Distinguish our outlines from the native driver’s outlines: Use unused
outline->flags bit: This is a hack, I realize. By
design, an FT_Outline is an FT_Outline, and it has lost all traces of how it
got to be that way. On the other hand, the 'flags' field of the outline only
uses a few bits, so there are bits I can set to say that this is one of my
FT_Outlines. While that is not perhaps technically safe to do, it is hard to
imagine that a client would copy only the bits that are defined in the FreeType
interface. One could imagine problems in flags comparisons in unlikely
scenarios. By using a bit in outline->flags, we can identify which
FT_Outlines we created. 3. Have our renderer render outlines created by our driver: Unregister the native
renderers and register our own for rendering FT_GLYPH_FORMAT_OUTLINE. We then
choose whose methods to call for a given FT_Outline depending on the whether it
is ours or native. (Again, I am skipping over various initialization and
finalization considerations, which are easy enough to solve.) And again,
perhaps using FT_Err_Cannot_Render_Glyph and changing the existing renderers’
render function to cooperate with my renderer might be considered cleaner in
terms of deciding who renders a given glyph. The Problem: In addition to the outline, my renderer needs some additional
information, 64 bytes worth, that is created at FT_Load_Glyph time. Since the
outline might live in someone's cache between its creation and its rendering as
a bitmap, this additional information probably needs to be with the outline in
the cache. How to I pass it along?? I’d like to just put it in the
FT_Outline somehow…. Various Bad Solutions and non-Solutions: 1. I could easily add information to my driver's GlyphSlot, for
example, but the GlyphSlot might get reused between the time the outline is
cached and the time that the outline is scan converted. 2. I could create outlines with additional information at the end of
the FT_Outline and some 0xDEADBEEF identifier to say whether the data made it
back in to the renderer. This might be safe in and of itself, (though the
0xDEADBEEF identifier is not 100% guaranteed to mean that the information is
really present), but it would not help if important clients like outline caches
throw away this extra information. Fixing the FreeType FTC_* cache to preserve
this information is doable, but other clients would not necessarily preserve
the information. 3. I could change the definition of FT_Outline and recompile FreeType
to contain additional information, but this could break clients that are not
compiled with the new definition, even if I put the new definition at the end
of the struct. FT_Outline is a public part of the interface. There is no
guarantee that clients would handle the bigger structure properly. There could
be crashes, unexpected results, or just about any other problem. 4. Stick my information onto the end of one of the arrays in
FT_Outline. This would (probably) leave the FT_Outline legal, but it would not
survive any copying of the outline. 5. Try to build a separate cache for the additional information. But
that won’t work, because that should be done by the client, not by
FreeType. Any help would be wonderful. Thank you, Jeff Finger Checked by AVG Free Edition. |
[Prev in Thread] | Current Thread | [Next in Thread] |