Hi Alexander,

Alexander Kiel wrote:
> Hi Vincent,
> 
>>> I had a look at SeekableStream and I can imagine how the needs resulted
>>> in the ImageInputStream interface. I haven't decided yet if I should use
>>> ImageInputStream directly. Maybe someone else can throw it's two cents
>>> in here.
>> Here are my two cents: if you make use of classes in javax.imagio at
>> only one place in your font library, then there’s no need to worry about
>> creating a more neutral layer. If OTOH you need to use those classes
>> everywhere, then it makes sense to use a simplified abstraction layer.
>> That abstraction layer could be shipped as a separate module and evolve
>> separately. An implementation could be based on imageIO, Apache Commons
>> IO (?), your own implementation based on byte arrays for testing
>> purpose, etc.
> 
> Thanks for that. I think, I will write a OpenTypeDataInputStream which
> is not a FilterInputStream, but takes a ImageInputStream as constructor
> argument like a FilterInputStream would take a InputStream. This
> OpenTypeDataInputStream will be the API for all the Streams on top of
> it. So I would have only one point which depends on ImageInputStream.

You may want to use a factory a la SAXParserFactory. Although that may
go a bit far.


>> - is memory consumption that much of a problem anyway? I mean, fonts 
>> are
>>   intrinsically big, complex objects and there’s not much we can do
>>   about that. Many scripts in the world can’t do without advanced
>>   features. Making the parsing of some tables optional doesn’t look to
>>   me like the right way to optimise things. That would unnecessarily
>>   complicate the code.
> 
> If you only need the metrics, parsing the glyf or CFF table would be
> really unnecessary. So maybe a TableFilter interface would be useful.
> Like this:
> 
> public class OpenTypeFileInputStream {
> 
>     private TableFilter tableFilter = TableFilter.NO_FILTERING;
> 
>     public OpenTypeFileInputStream(OpenTypeDataInputStream in) {}
> 
>     public void setTableFilter(TableFilter tableFilter) {}
> }
> 
> public interface TableFilter {
> 
>     public static final TableFilter NO_FILTERING = new TableFilter() {
>         public doReadTable(Tag tableTag) { return true; }
>     }
> 
>     boolean doReadTable(Tag tableTag);
> }
> 
> A client which isn't aware of TableFilter would not notice any burden
> using the API. And the implementation in OpenTypeFileInputStream isn't
> so difficult.

This is an interesting idea. But how would you combine filters?
I’d suggest to keep it aside for the moment, and implement it if we are
actually running into performance issues. After all, if some caching is
done, the font should be parsed only once.


>> - instead of seekable streams, what about a filter that would re-order
>>   the font stream, caching whatever is necessary before re-sending it to
>>   the consumer object?
> 
> I don't want to do this. In the OpenType GPOS and GSUB tables you have
> maybe 5 levels of nested structures with headers and offsets. It gets
> really complex there.

I see... All right then.


>> - what about giving the font library a “playground” directory by
>>   inversion of control, that it can use to cache things? And if no
>>   directory is given it would use the memory. Maybe a common interface
>>   could be used for that, targeting either the hard drive or the memory.
> 
> Sure. By the way - is there any IoC container used in FOP? I did not see
> one so far. How is the bootstrapping done? This could be important for a
> central FontSource or such thing.

There’s no such thing as IoC container in FOP. I’m not sure how easy it
would be to introduce one. Although that would probably be A Good Thing.
So do design your font library with IoC in mind.


>> - does the use of serializable objects make sense? What would be more
>>   efficient: re-parsing font data all the time or re-loading
>>   serializable object representation of them?
> 
> You mean the font metrics XML files? I've alwas asking me for what
> propose they are there. No, I don't think, we need this. I really don't
> want to serialize the Advanced OpenType Features! It took me already a
> good amount of code to parse just a bit of it.

What I meant was to use the java.io.Serializable interface. I don’t
indeed think XML representations are any useful, apart maybe for
debugging purpose or to have a more human-readable version of the font
file.
IIC there would be next to nothing to do to cache Serializable objects
on the hard drive and retrieve them?


>> - what about looking at how fontconfig [1] (a font configuration library
>>   for Linux systems) does things? I know it makes use of a cache to
>>   speed up things. Maybe there are good ideas to borrow from there.
>>
>> [1] http://www.fontconfig.org/wiki/
> 
> I don't see speed a a problem as long as we parse every font only once.
> Parsing the OpenType font "Old Standard Regular" and converting it into
> a CustomFont is currently about 100 ms. 
> 
> 
> Best Regards
> Alex

HTH,
Vincent

Reply via email to