* [9fans] Re: diacritics
@ 2003-08-13 13:40 chris
0 siblings, 0 replies; only message in thread
From: chris @ 2003-08-13 13:40 UTC (permalink / raw)
To: 9fans
[-- Attachment #1: Type: text/plain, Size: 497 bytes --]
Ok, as promised and for what it's worth, here is a copy of my
limbo mkfont.b
usage: mkfont -biw fontpath pts
-b does fake embolden (by double-strike)
-i does fake italic (by shear)
-w does a bad job of enforcing fixed width for those fonts with poor metrics
It tends to create fonts that look to have too much leading.
This is because some subfonts have quite a lot of height - due to
diacritics etc.
Perhaps some options for constraining the unicode range might help.
Chris.
[-- Attachment #2.1: Type: text/plain, Size: 308 bytes --]
The following attachment had content that we can't
prove to be harmless. To avoid possible automatic
execution, we changed the content headers.
The original header was:
Content-Disposition: attachment; filename=mkfont.b
Content-Type: text/plain; charset="US-ASCII"
Content-Transfer-Encoding: 7bit
[-- Attachment #2.2: mkfont.b.suspect --]
[-- Type: application/octet-stream, Size: 10224 bytes --]
implement Mkfont;
include "sys.m";
include "draw.m";
include "arg.m";
include "freetype.m";
Mkfont: module {
init: fn(ctxt: ref Draw->Context, args: list of string);
};
sys: Sys;
draw: Draw;
Point, Rect, Image, Display: import draw;
ft: Freetype;
Face, Glyph: import ft;
fixadv := 0;
dobold := 0;
dosheer := 0;
disp: ref Display;
Subfont: adt {
start: int;
end: int;
glyphs: array of ref Freetype->Glyph;
mintop: int;
maxh: int;
maxadv: int;
};
init(nil: ref Draw->Context, argv: list of string)
{
sys = load Sys Sys->PATH;
draw = checkload(load Draw Draw->PATH, Draw->PATH);
arg := checkload(load Arg Arg->PATH, Arg->PATH);
ft = checkload(load Freetype Freetype->PATH, Freetype->PATH);
arg->init(argv);
arg->setusage("mkfont [-biw] fontpath pts");
while((opt := arg->opt()) != 0) {
case opt{
'b' =>
dobold = 1;
'i' =>
dosheer = 1;
'w' =>
fixadv = 1;
}
}
path := arg->earg();
pts := int arg->earg();
arg = nil;
ftbase := sys->sprint("%s.%d", basename(path), pts);
disp = Display.allocate(nil);
face := ft->newface(path, 0);
if (face == nil)
error(sys->sprint("loading font %s: %r", path));
if (dosheer) {
m := ref Freetype->Matrix(1<<16, 1<<14, 0, 1<<16);
face.settransform(m, nil);
}
err := face.setcharsize(pts<<6, 72, 72);
if (err != nil)
error(sys->sprint("cannot set point size: %s", err));
mintop := 100000;
maxh := 0;
maxadv := 0;
subfonts: list of ref Subfont;
for (ix := 0; ix < len uniblk; ix += 2) {
start := uniblk[ix];
end := uniblk[ix+1];
for (i := start; i <= end; i++) {
if (face.haschar(i)) {
sf := loadsubf(face, start, end, i);
if (sf.mintop < mintop)
mintop = sf.mintop;
if (sf.maxh > maxh)
maxh = sf.maxh;
if (sf.maxadv > maxadv)
maxadv = sf.maxadv;
subfonts = sf :: subfonts;
break;
}
}
}
subfonts = rev(subfonts);
# ensure glyph 0 exists
if (subfonts == nil || (hd subfonts).start != 0)
subfonts = loadsubf(face, 0, 0, 0) :: subfonts;
if (mintop < 0)
mintop = 0;
ascent := face.ascent - mintop;
height := maxh-mintop;
ftpath := ftbase+".font";
ftfd := sys->create(ftpath, Sys->OWRITE, 8r666);
if (ftfd == nil)
error(sys->sprint("failed to create %s: %r", ftpath));
sys->fprint(ftfd, "%d %d\n", height, ascent);
for (; subfonts != nil; subfonts = tl subfonts) {
sf := hd subfonts;
sfpath := sys->sprint("%s.%.4x-%.4x", ftbase, sf.start, sf.end);
sffd := sys->create(sfpath, Sys->OWRITE, 8r666);
if (sffd == nil) {
sys->fprint(stderr(), "cannot create %s: %r\n", sfpath);
continue;
}
glyphs := sf.glyphs;
h := sf.maxh-sf.mintop;
w := 0;
for (ix = 0; ix < len glyphs; ix++) {
g := glyphs[ix];
if (g != nil) {
w += g.width;
if (sf.mintop > 0)
g.top -= sf.mintop;
if (fixadv)
g.advance.x = maxadv;
if (dobold) {
g.advance.x += 1<<6; # glyph advance is 26.6 fixed point
w++;
}
}
}
if (writesubf(sffd, glyphs, ascent, w, h))
sys->fprint(ftfd, "0x%.4x\t0x%.4x\t%s\n", sf.start, sf.end, sfpath);
}
}
loadsubf(face: ref Freetype->Face, start: int, end: int, first: int): ref Subfont
{
mintop := 100000;
maxh := 0;
maxadv := 0;
glyphs := array [end-start+1] of ref Freetype->Glyph;
# ensure that glyph 0 exists
if (start == 0)
first = 0;
for (c := first; c <= end; c++) {
if (c &&!face.haschar(c))
continue;
g := face.loadglyph(c);
if (g == nil)
continue;
glyphs[c-start] = g;
g.top = face.ascent - g.top;
if (g.top < mintop)
mintop = g.top;
h := g.top + g.height;
if (h > maxh)
maxh = h;
if (g.advance.x > maxadv);
maxadv = g.advance.x;
}
return ref Subfont(start, end, glyphs, mintop, maxh, maxadv);
}
writesubf(fd: ref Sys->FD, glyphs: array of ref Glyph, ascent, width, height: int): int
{
ir := Rect((0, 0), (width, height));
img := disp.newimage(ir, Draw->GREY8, 0, Draw->Black);
if (img == nil) {
sys->fprint(stderr(), "cannot create subfont image: %r\n");
return 0;
}
nextx := 0;
for (c := 0; c < len glyphs; c++) {
g := glyphs[c];
if (g == nil)
continue;
dstr := Rect((nextx, g.top), (nextx+g.width, g.top+g.height));
img.writepixels(dstr, g.bitmap);
nextx += g.width;
if (dobold)
nextx++;
}
if (dobold)
img.drawop(Rect((1,0), (ir.max.x, ir.max.y)), disp.white, img, Point(0,0), Draw->SoverD);
disp.writeimage(fd, img);
writeglyphinfo(fd, glyphs, height, ascent);
return 1;
}
writeglyphinfo(fd: ref Sys->FD, glyphs: array of ref Glyph, height, ascent: int)
{
sys->fprint(fd, "%11d %11d %11d ", len glyphs, height, ascent);
empty := ref Freetype->Glyph (0, 0, 0, 0, (0, 0), nil);
nextx := 0;
for (ix := 0; ix < len glyphs; ix++) {
g := glyphs[ix];
if (g == nil)
g = empty;
writeglyph(fd, g, nextx);
nextx += g.width;
if (g != empty && dobold)
nextx++;
}
writeglyph(fd, empty, nextx);
}
writeglyph(fd: ref Sys->FD, g: ref Freetype->Glyph, x: int)
{
b := array [6] of byte;
ix := 0;
b[ix++] = byte (x & 16rff); # x low order
b[ix++] = byte ((x>>8) & 16rff); # x high order
b[ix++] = byte (g.top & 16rff); # top
b[ix++] = byte ((g.top + g.height) & 16rff); # bottom
b[ix++] = byte (g.left & 16rff); # left
b[ix++] = byte ((g.advance.x >> 6)& 16rff);
sys->write(fd, b, ix);
}
checkload[T](x: T, p: string): T
{
if(x == nil)
error(sys->sprint("cannot load %s: %r\n", p));
return x;
}
rev[T](l: list of T): list of T
{
n: list of T;
for (; l != nil; l = tl l)
n = hd l :: n;
return n;
}
stderr(): ref Sys->FD
{
return sys->fildes(2);
}
error(e: string)
{
sys->fprint(stderr(), "remotelogon: %s\n", e);
raise "fail:error";
}
basename(s: string): string
{
for ((nil, ls) := sys->tokenize(s, "/"); ls != nil; ls = tl ls)
s = hd ls;
for (i := len s - 1; i >= 0; i--) {
if (s[i] == '.')
break;
}
if (i < 0)
return s;
return s[:i];
}
uniblk := array [] of {
16r0000, 16r007F, # Basic Latin
16r0080, 16r00FF, # Latin-1 Supplement
16r0100, 16r017F, # Latin Extended-A
16r0180, 16r024F, # Latin Extended-B
16r0250, 16r02AF, # IPA Extensions
16r02B0, 16r02FF, # Spacing Modifier Letters
16r0300, 16r036F, # Combining Diacritical Marks
16r0370, 16r03FF, # Greek and Coptic
16r0400, 16r04FF, # Cyrillic
16r0500, 16r052F, # Cyrillic Supplementary
16r0530, 16r058F, # Armenian
16r0590, 16r05FF, # Hebrew
16r0600, 16r06FF, # Arabic
16r0700, 16r074F, # Syriac
16r0780, 16r07BF, # Thaana
16r0900, 16r097F, # Devanagari
16r0980, 16r09FF, # Bengali
16r0A00, 16r0A7F, # Gurmukhi
16r0A80, 16r0AFF, # Gujarati
16r0B00, 16r0B7F, # Oriya
16r0B80, 16r0BFF, # Tamil
16r0C00, 16r0C7F, # Telugu
16r0C80, 16r0CFF, # Kannada
16r0D00, 16r0D7F, # Malayalam
16r0D80, 16r0DFF, # Sinhala
16r0E00, 16r0E7F, # Thai
16r0E80, 16r0EFF, # Lao
16r0F00, 16r0FFF, # Tibetan
16r1000, 16r109F, # Myanmar
16r10A0, 16r10FF, # Georgian
16r1100, 16r11FF, # Hangul Jamo
16r1200, 16r137F, # Ethiopic
16r13A0, 16r13FF, # Cherokee
16r1400, 16r167F, # Unified Canadian Aboriginal Syllabics
16r1680, 16r169F, # Ogham
16r16A0, 16r16FF, # Runic
16r1700, 16r171F, # Tagalog
16r1720, 16r173F, # Hanunoo
16r1740, 16r175F, # Buhid
16r1760, 16r177F, # Tagbanwa
16r1780, 16r17FF, # Khmer
16r1800, 16r18AF, # Mongolian
16r1900, 16r194F, # Limbu
16r1950, 16r197F, # Tai Le
16r19E0, 16r19FF, # Khmer Symbols
16r1D00, 16r1D7F, # Phonetic Extensions
16r1E00, 16r1EFF, # Latin Extended Additional
16r1F00, 16r1FFF, # Greek Extended
16r2000, 16r206F, # General Punctuation
16r2070, 16r209F, # Superscripts and Subscripts
16r20A0, 16r20CF, # Currency Symbols
16r20D0, 16r20FF, # Combining Diacritical Marks for Symbols
16r2100, 16r214F, # Letterlike Symbols
16r2150, 16r218F, # Number Forms
16r2190, 16r21FF, # Arrows
16r2200, 16r22FF, # Mathematical Operators
16r2300, 16r23FF, # Miscellaneous Technical
16r2400, 16r243F, # Control Pictures
16r2440, 16r245F, # Optical Character Recognition
16r2460, 16r24FF, # Enclosed Alphanumerics
16r2500, 16r257F, # Box Drawing
16r2580, 16r259F, # Block Elements
16r25A0, 16r25FF, # Geometric Shapes
16r2600, 16r26FF, # Miscellaneous Symbols
16r2700, 16r27BF, # Dingbats
16r27C0, 16r27EF, # Miscellaneous Mathematical Symbols-A
16r27F0, 16r27FF, # Supplemental Arrows-A
16r2800, 16r28FF, # Braille Patterns
16r2900, 16r297F, # Supplemental Arrows-B
16r2980, 16r29FF, # Miscellaneous Mathematical Symbols-B
16r2A00, 16r2AFF, # Supplemental Mathematical Operators
16r2B00, 16r2BFF, # Miscellaneous Symbols and Arrows
16r2E80, 16r2EFF, # CJK Radicals Supplement
16r2F00, 16r2FDF, # Kangxi Radicals
16r2FF0, 16r2FFF, # Ideographic Description Characters
16r3000, 16r303F, # CJK Symbols and Punctuation
16r3040, 16r309F, # Hiragana
16r30A0, 16r30FF, # Katakana
16r3100, 16r312F, # Bopomofo
16r3130, 16r318F, # Hangul Compatibility Jamo
16r3190, 16r319F, # Kanbun
16r31A0, 16r31BF, # Bopomofo Extended
16r31F0, 16r31FF, # Katakana Phonetic Extensions
16r3200, 16r32FF, # Enclosed CJK Letters and Months
16r3300, 16r33FF, # CJK Compatibility
16r3400, 16r4DBF, # CJK Unified Ideographs Extension A
16r4DC0, 16r4DFF, # Yijing Hexagram Symbols
16r4E00, 16r9FFF, # CJK Unified Ideographs
16rA000, 16rA48F, # Yi Syllables
16rA490, 16rA4CF, # Yi Radicals
16rAC00, 16rD7AF, # Hangul Syllables
16rD800, 16rDB7F, # High Surrogates
16rDB80, 16rDBFF, # High Private Use Surrogates
16rDC00, 16rDFFF, # Low Surrogates
16rE000, 16rF8FF, # Private Use Area
16rF900, 16rFAFF, # CJK Compatibility Ideographs
16rFB00, 16rFB4F, # Alphabetic Presentation Forms
16rFB50, 16rFDFF, # Arabic Presentation Forms-A
16rFE00, 16rFE0F, # Variation Selectors
16rFE20, 16rFE2F, # Combining Half Marks
16rFE30, 16rFE4F, # CJK Compatibility Forms
16rFE50, 16rFE6F, # Small Form Variants
16rFE70, 16rFEFF, # Arabic Presentation Forms-B
16rFF00, 16rFFEF, # Halfwidth and Fullwidth Forms
16rFFF0, 16rFFFF, # Specials
};
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2003-08-13 13:40 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-13 13:40 [9fans] Re: diacritics chris
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).