Opentype smcp and valt feature

Tosche's picture

Hi, everyone.

Right now I'm writing Opentype programs, and there are two things I don't get it.

The font has small cap characters and Th ligature. Th is controlled by 'liga' feature (sub T h by TH;), but when the smcp feature is turned on, Th doesn't separate into T(cap) and h(smallcap) and remains still. How can I avoid this?

I'd like to use 'valt' feature, which is used for vertical setting. It's supposed to controll vertical bearings(like moving g up or l down), but I have no idea how to write the code. It's very strange thing for Japanese people to ask about this, but I know almost nothing about Opentype things. If you know anything about this or any good books to learn these, please tell me.

k.l.'s picture

ad 1: 'smcp' should precede 'liga'. So if 'smcp' has done its job and replaced h by smallcap H, there is no T h left for 'liga' to replace by T_h.

Tosche's picture

Thank you very much for the information...but it actually happens.

John Hudson's picture

You need to manually order your lookups so that the smcp lookup precedes the liga lookup. These kinds of features are applied simultaneously by the layout engine based upon the order of lookups in the font, not on a specified order of features hardcoded in the layout engine (as happens for some other kinds of features).

If you are making your font in FontLab, you have to order the lookups by ordering the features to which that are associated. You do this in the OpenType panel by clicking on and dragging feature tags up and down in the feature list.

[In Microsoft's VOLT tool, you can control the order of the lookups independently of the features with which they are associated, which is sometimes useful.]

k.l.'s picture

Could you post your actual liga/smcp code, in the order in which it appears in the OT Panel? And, of which application are you speaking? Do you test in FLS, or InDesign, or Illustrator, ...?

Tosche's picture

I dragged smcp feature above liga tag, then everything went well. Thanks! I don't know how to use lookup, but anyway I don't need to use it this time.

I use FontLab5 on Mac and test the behavior on Illustrator and InDesign, but it's okay since the solution is found. Thank you very much.

But I still don't know about valt feature...
If anyone knows about this, please help me.

k.l.'s picture

When I wrote in my first post that "'smcp' should precede 'liga'" this meant that you need do reorder features as John described ...  :)

(Haven't seen John posts when posting my last one.)

Kunihiko_Okano's picture

I've heard that most of applications don't support 'valt' feature.
So all Japanese fonts control the positioning of full-width 'g' and 'y' for vertical setting with 'vmtx' table.

I've tried to compile valt feature in FLS like this,

feature valt {
pos A <0 -1000 0 0>;
} valt;

and then, FLS showed it correctly in Preview palet, but it didn't work with Illustrator CS3.
valt feature might be for full-width Latin characters in CJKV font.

Do you want to set your font vertically with Japanese fonts?

Tosche's picture

Oh, sorry. I didn't understand what you meant. I didn't think that 'smcp' feature visually needed to be placed avobe the 'liga' feature until I really did that.

>Okano San
>>Do you want to set your font vertically with Japanese fonts?
Yes, I do. Maybe I'll ask you personally.
By the way, I wanted to make a contact with you some time.
I didn't imagine that I would see you in such occasion :)

lunde's picture

I should first state that the 'valt' GPOS feature is effectively deprecated, because there is a better way to achieve the functionality. Given that the context in which its functionality is expected to be used is vertical writing, and that it is also expected to be default behavior, we discovered that we could effect this through 'vmtx' table overrides.

I developed a Perl script, several years ago, that takes two files as input. One is a coverage table, specifically a list of CIDs and CID ranges that are candidates for this treatment. This means anything that is classified as full-width Latin, full-width Greek, or full-width Cyrillic, including full-width symbols. The other is the AFM file for the font, which has the glyph-level BBox information. (The AFDKO tool called "tx" has a mighty convenient "-afm" option for generating AFM files from a font.)

Consider the full-width Latin glyphs for a, b, and p. In Adobe-Japan1-6, the CIDs are 816, 817, and 831, respectively. For Kozuka Mincho Pr6N Regular, the AFM records for these glyphs are as follows:

C -1 ; W0X 1000 ; N 816 ; B 276 -12 754 514 ;
C -1 ; W0X 1000 ; N 817 ; B 240 -12 762 772 ;
C -1 ; W0X 1000 ; N 831 ; B 248 -257 775 514 ;

Given that the top and bottom of the design space is at 880 and -120, what we effectively want to do is to center the glyphs within that 1000-unit space. When I run my script, which I named, the following is the output for these three glyphs:

table vmtx {
    VertOriginY \816 751;
    VertOriginY \831 628;
} vmtx;

What happened to the entry for CID+817? Look at its Y-axis values, specifically -12 and 772. There is exactly 108 units between the edges and the edges of the design space, so the glyph is alrady centered, and no adjustment is necessary. The default value is 880, and thus is not necessary.

The workhorse portion of my script, which iterates through AFM records, ignoring those not in the coverage table (%cidrange), is below:

$ybottomlimit = -120;
$ytoplimit = 880;
$ycenter = ($ybottomlimit + $ytoplimit) / 2;

while ($line = <STDIN>) {
    if ($line =~ /^C.*/) {
        chomp $line;
        ($cid,$ymin,$ymax) = (split(/ /,$line))[7,11,13];
        if (exists $cidrange{$cid}) {
            $halfy = ($ymax - $ymin) / 2;
            $yminnew = $ycenter - $halfy;
            $pushy = round($yminnew - $ymin);
            $pushy =~ s/^\+(\d+)/$1/;
            printf STDOUT " VertOriginY \\$cid %s;\n",$ytoplimit - $pushy if $pushy !~ /^-?[0-4]$/;

sub round {
    my ($arg) = @_;
    if ($arg =~ /\.[0-4]\d*/) {
        $arg =~ s/\.[0-4]\d*$//;
    } elsif ($arg =~ /\.[5-9]\d*/) {
        $arg =~ s/(\d+)\.[5-9]\d*$/$1 + 1/e;
    } return $arg;

If anyone would like the complete Perl script or the coverage tables for our CID character collections, or both, please feel free to drop me an email.

Dr. Ken Lunde
Senior Computer Scientist, CJKV Type Development
Adobe Systems Incorporated

Kunihiko_Okano's picture

Thanks Dr.Lunde!
I'm very curious about your script and like to use it.
I'll get in touch with you after a while.


Syndicate content Syndicate content