Testing mftrace

I am not entirely sure how fair of a comparison I am making, but I am open to suggestions on how to better compare the hypothetical output of a font designed using METATYPE1, where a Type 1 font would be directly generated, versus a font designed using METAFONT, where a Type 1 font is generated using mftrace.

For my experiment, I chose to compare glyphs from the Type 1 version of Computer Modern maintained by the American Mathematical Society, which was presumable crafted by manually tracing the bitmap version and optimizing various aspects by hand, with glyphs generated by mftrace on 3000DPI bitmaps generated from the METAFONT source. I could imagine that it might be fairer to compare the result of using nearly identical METATYPE1 and METAFONT source to generate the Type 1 glyphs, but then I would be biasing the design process towards the limitations of METATYPE1. I had considered using the METAFONT source for AMS Euler, because the source is simply the outline and would be easy to convert to METATYPE1.

I also decided to use glyphs with plenty of curves for the test, as I figure that tracing software can probably do a pretty good job with straight lines.

In any event, I will leave it to you to decide whether you can distinguish which is version is which below.  The order in which the two versions appear differs for each of the three examples below.

qaqb

sasb

ampaampb

As you might have guessed, my opinion is that results are so nearly indistinguishable, that given the design limitations of METATYPE1,  it would make much more sense to work with METAFONT and mftrace, and use FontForge or a similar tool to add hinting as a postprocessing step.

Comments

The Controversial Comic Sans

I figured I would pass along Emily Steel's Wall Street Journal article: Typeface Inspired by Comic Books Has Become a Font of Ill Will.

Comments (2)

METATYPE1 and meta-fonts

I've been spending time lately learning more about working with METATYPE1, mostly for my own projects, but with the eventual hope of writing some tutorials.  While working on one of my running examples, I was encountering some difficulty expressing what I wanted in a reasonably declarative fashion. So I decided to see how it was done in Latin Modern.

I was dismayed to learn that Latin Modern is not a meta-font like Computer Modern. Instead the Type 1 versions of Computer Modern (which was developed by either Bluesky or Y&Y) were decompiled into MetaPost code as raw path outlines. So at that point all of the useful abstractions in Knuth's original code and specifications have been lost.

The only other major typeface developed in METATYPE1 that I know about, Antykwa Toruńska, has no source available and from the description I highly suspect that it was developed by creating raw paths that matched the scanned specimens. This got me thinking about whether there are any meta-fonts that have been developed in METATYPE1, or even whether Computer Modern might be the only full meta-font family in existence. I just skimmed through the METAFONT sources that are included in TeXLive, but didn't see anything particularly promising yet.

In any event, going back to the original issue, I have been starting to think that maybe the limitations of METATYPE1 are perhaps not worth being able to directly generate Type 1 fonts. It could be entirely possible that working in METAFONT and using something like mftrace to generate outline fonts from high-resolution bitmaps will produce results of sufficient quality. I'm hoping to do some tests to compare the two approaches this weekend.

(It is worth noting, that the comment about METATYPE1 on the mftrace page is slightly incorrect or out of date.  METATYPE1 can handle overlaps, there are just complicated restrictions on how overlapping may occur.  Finding clean approaches to avoid these restrictions was why I became interested in looking at the Latin Modern code to begin with.)

Comments (2)

Quality fonts

The other day on Digg I saw a link for 30 high-quality free fonts for professional designs. Many of the samples seem decent, but I guess it sparked the question in my mind of just what constitutes a "high-quality font".

I suppose when I think of a a quality font, I tend to expect a consistent design along with some of the following:

  • composing characters or glyphs for most diacritical marks, ideally Greek and Cyrillic glyphs as well
  • proper kerning
  • appropriate ligatures
  • old-style numbers
  • optical sizes

Given these criterion, offhand I have to say that perhaps the best high-quality free fonts that I can think of off the top of my head are probably the TeX Gyre fonts and the Latin Modern family.  I would be curious to hear about other recommendations.

Comments (2)

The Fifth Element

The other day, a colleague of mine pointed out to me that Aarhus University recently rolled out a new, somewhat controversial,  visual identity that includes a novel geometric alphabet that they call its "fifth element".

Comments

Fonts in LaTeX, Errata

About seven months ago, Vasile Gaburici alerted me to the fact that otftotfm has had experimental support for OpenType fonts TrueType outlines for quite some time. Furthermore, it will use kerning tables that ttf2tfm will ignore.  I am now finally getting around to writing a post to highlight this fact.

It seems likely that otftotfm may also work on pre-OpenType TrueType fonts because the OpenType font format is essentially the same as the TrueType format with potentially additional tables. At least, when I did cursory search on my computer I could not find any TrueType fonts that proved to be incompatible with otftotfm.

Therefore, if you want to use a TrueType font with pdfLaTeX you should ignore the instructions I give in ∃xistential Type Fonts in LaTeX, Part Three: pdfTeX and TrueType and use the same instructions as I gave for OpenType fonts in Fonts in LaTeX, Part Two: pdfTeX and OpenType. For your convenience, I have also created an updated the zip file for the example that uses otftotfm instead of ttf2tfm.

Comments

Resumption

That was a longer hiatus than I had intended. Partly because not everything went according to plan.

My original plan was that, upon returning from my vacation, I would spend my remaining time at EPFL writing a technical report explaining everything I knew about the problems with Scala Classic. Instead, on my first day back in the office, Martin came by with a draft of a new formal system, DOT (for Dependent Object Types), that he came up with while he was on vacation. After about four weeks I managed to root out pretty much all of the obvious problems with DOT, but another four weeks was not enough to get the proofs and the metatheory into a state that we were happy with. I am not really sure what will happen with DOT in the long term.

There are a few clever things about DOT that avoid some of the problems I encountered with Scala Classic. For example, Scala Classic only had intersection types while DOT has both intersection and union types, which solves some problems with computing the members of types.  However, with Scala Classic I was trying to model a minimal subset Scala language as it exists, without adding any new features that many never be supported by the full language. I have no idea if we will see union types in the actual Scala implementation anytime soon.

The other thing DOT does is give up the goal of trying to be a minimal subset of Scala and throws out quite a few important things from a user perspective. For example, there are no methods (only λ-abstractions), no existentials, no built-in inheritance or mix-in composition (though you can encode it by hand), and object fields must be syntactically values.

This last restriction is particularly important because it solves by fiat the problems that arose in Scala Classic from using paths that have an empty type in dependent type projections. However, it also means that you may not be able to directly encode some Scala programs into DOT without an effect or termination analysis. Therefore, while DOT has the potential to be a useful intermediary step, there will still be more work to be done to provide a semantics for a more realistic subset of the Scala language.

I have been in Copenhagen for a little over a month now, but I am not really ready to comment on the research I have been doing here yet.  So in the meantime I'll probably focus more on fonts and typography.

Comments (1)

Out with the cheese, in with the pastry

I have unfortunately been quite busy the past several months, and have not had as much time to write about what I have been doing as I would have liked.  For the most part, I have been splitting my time between teaching and research.  I will hopefully go into more detail about the latter in the near future.

However, I figured I should take some time now, before I leave for my first proper vacation in a year, to announce that I have accepted a postdoc position at ITU in Copenhagen with Carsten Schürmann.  This has been in the works for a while now, but this week I finally was able to make it official.  My plan is to start at ITU at the beginning of March, where I will be working on things relating to the LF family of logical frameworks, Twelf, and Delphin.

There are probably a vanishingly small number of you that care about what this means for Scala Classic, but I hope to write something much more detailed about it when I get back from my vacation.  I'll leave you in suspense with the short answer: despite all my efforts, it simply is not possible to prove it sound without making it a very different language.  Which is rather unfortunate.

Comments (4)

Algorithmic puzzle

I was assigned the task of fixing a bug in the Scala standard library involving the indexOf, which given a receiver object that is a sequence and another sequence of the correct type, checks whether the latter is contained within the latter and returns the index. The current version does not correctly handle the case when a suffix of the receiver object matches a strict prefix of the argument (for example, List(1,2,3).indexOf(List(3,4)) will report a match at the index of 2). This should be fixed for the upcoming 2.7.2-RC2 release.

As soon as I started rewriting the code, I wondered why the original author hadn't just used an off the shelf searching algorithm. However, a quick search reminded me why: algorithms like Knuth-Morris-Pratt and Boyer-Moor construct a table based upon the sequence to search for. However, Scala sequences may be infinite so it is not possible to blindly go ahead and attempt to construct a table, because doing so may diverge.

Furthermore, there is no way to test whether a sequence is finite without potentially diverging. So it is not possible to first test whether the argument is finite, because if the receiver object is finite then indexOf should return that there is no match. Alternately, testing whether the receiver object is finite would be incorrect because it is possible the argument is finite an could potentially match.

However, it seems like it should still be possible to do better than O(nm), where n is the length of the receiver and m the length of the argument. For example if you start out with the sequence 1, 2, 3, 1 ... and the pattern 1, 3, 4 ... it seems like it should be possible to exploit the fact that you've looked ahead and know that there is no point and comparing 2 with 1. Alternately it seems like it might be possible to lazily build a table from the argument, but I would need to think longer to see whether it is always possible, in Knuth-Morris-Pratt for example, to fill in a complete prefix of the table without having processed the entire pattern.

In any event, searching with combinations of keywords like "string", "searching", "lazy", "infinite", etc. did not really turn anything up. One possible direction might be to look at "incremental" search algorithms like those used in text editors, etc. However, I expect that because they are geared to interactive use that the pattern will usually be quite small and therefore much thought has not been put into optimizing them.

Comments (6)

Literally dependent types

Given that the formalization of Scala Classic has ground to a halt, for reasons I may go into later, I spent part of today hacking on the Scala compiler itself to add support for singleton literals. Currently, Scala allows singleton types for stable identifiers. My modification allows literals to be used in singleton types. I can't promise that it will be in the forthcoming Scala 2.7.2 release, but I would like it to be.

Overall it was far less work than I was expecting.  Scala already internally supports what it calls "constant types", there is just no way to write them in Scala source code presently.  Consequently, most of the effort was in extending the parser.

Given my modifications, it is now possible to write code like the following:

 
scala> val x : "foo".type = "foo"
x: "foo".type = foo
 

What I was not expecting was that out-of-the-box things like the following would work:

 
scala> val x : "foobar".type = "foo" + "bar"
x: "foobar".type = foobar
scala> val y : 10.type = 2 * 5
y: 10.type = 10
scala> def frob(arg : 10.type) : 6.type = arg - 4
frob: (10.type)6.type
 

Unfortunately the excitement soon passes when you realize all the things you can't do with singleton literals (yet). Even if we turn on the experimental dependent method support, you can't write things like

 
def add(arg : Int) : (arg + 5).type = arg + 5
 

because these are exactly what they are called, singleton literals, not full-blown dependent types.

One cute example, based on a use suggested by Sean McDirmid, would be that some people might do something like the following with implicits:

 
implicit stringToColor(arg : String) : java.awt.Color = java.awt.Color.getColor(arg)
 

However, with singleton literals you can tighten it up by ensuring that for some strings it will never fail:

 
implicit redToColor(arg : "red".type) : java.awt.Color = java.awt.Color.RED
implicit blueToColor(arg : "blue".type) : java.awt.Color = java.awt.Color.BLUE
 

Happily, the type inferencer already chooses the most specific implicit conversions.

In any event, they will hopefully become more useful as the type system continues to grow. I am also sure someone will probably come up with a clever use for them that hasn't occurred to me yet. If so, let me know.

Comments (3)

« Previous entries Next Page » Next Page »