* [9fans] update to mkfont.b
@ 2003-08-13 15:10 chris
0 siblings, 0 replies; only message in thread
From: chris @ 2003-08-13 15:10 UTC (permalink / raw)
To: 9fans
[-- Attachment #1: Type: text/plain, Size: 291 bytes --]
Earlier version generated a lot of blank cell info.
This version trims each unicode block down to the range
of available glyphs.
e.g.
--rw-r--r-- M 9 chris chris 38803 Aug 13 14:16 comic.14.e000-f8ff
goes to
--rw-r--r-- M 9 chris chris 433 Aug 13 16:09 comic.14.f001-f005
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: 10236 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);
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;
# force glyph 0
if (start == 0)
first = 0;
last := 0;
for (c := first; c <= end; c++) {
if (c &&!face.haschar(c))
continue;
last = c;
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(first, last, glyphs[first-start:last-start+1], 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 15:10 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-13 15:10 [9fans] update to mkfont.b 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).