Mercurial > mplayer.hg
changeset 1505:842c29861e25
upgraded to 1.0b version by Artur Zaprzala <artur.zaprzala@talex.com.pl>
author | arpi |
---|---|
date | Mon, 13 Aug 2001 18:37:10 +0000 |
parents | f4f686aed404 |
children | 94d929f91b06 |
files | TOOLS/subfont-c/Makefile TOOLS/subfont-c/README TOOLS/subfont-c/encodings/charmap2enc TOOLS/subfont-c/encodings/osd-mplayer TOOLS/subfont-c/encodings/runme-kr TOOLS/subfont-c/osd/README TOOLS/subfont-c/osd/gen.py TOOLS/subfont-c/osd/osd.t1a TOOLS/subfont-c/osd/runme TOOLS/subfont-c/runme TOOLS/subfont-c/subfont.c |
diffstat | 11 files changed, 1591 insertions(+), 284 deletions(-) [+] |
line wrap: on
line diff
--- a/TOOLS/subfont-c/Makefile Mon Aug 13 13:12:49 2001 +0000 +++ b/TOOLS/subfont-c/Makefile Mon Aug 13 18:37:10 2001 +0000 @@ -1,24 +1,18 @@ -#font="/mnt/win/windows/fonts/arial.ttf" -#font="/mnt/win/windows/fonts/comic.ttf" -#font="/mnt/win/windows/fonts/verdanai.ttf" -font="/mnt/win/windows/fonts/verdana.ttf" - -#encoding=windows-1250 -encoding=iso-8859-2 - -fontsize=20 include ../../config.mak LDLIBS=-lm $(shell freetype-config --libs) CFLAGS=$(OPTFLAGS) $(shell freetype-config --cflags) +#CFLAGS+=-DOLD_FREETYPE2 +#CFLAGS+=-g +#CFLAGS+=-DDEBUG + + subfont: subfont.o -run: subfont - ./subfont $(encoding) $(fontsize) $(font) - cat font.desc.tail >> font.desc - cp font.desc *.raw ~/.mplayer/font/ +subfont.S: subfont.c + $(CC) $(CFLAGS) -S $^ -o $@ clean: - rm -f subfont subfont.o + rm -f subfont subfont.o core
--- a/TOOLS/subfont-c/README Mon Aug 13 13:12:49 2001 +0000 +++ b/TOOLS/subfont-c/README Mon Aug 13 18:37:10 2001 +0000 @@ -1,41 +1,62 @@ -About: -~~~~~~ -`subfont' program renders antialiased fonts for mplayer using freetype library. -Should work with TrueType, Type1 and any other font supported by libfreetype. - -Goals: - - internationalization: supports any 8 bit encoding (uses iconv). - - nice look: creates glyph `shadows' using algorithm derived from gaussian blur (slow!). - - -Note: -~~~~~ -Starting x position of each char and the bitmap width is aligned to multiple of 8 -(required for under-development MMX renderer). - - Usage: ~~~~~~ -Usage: subfont encoding ppem font [alphaFactor [minAlpha [radius]]] - Program creates 3 files: font.desc, <encoding>-a.raw, <encoding>-b.raw. - You should append font.desc.tail (desc for OSD characters by a'rpi & chass) to font.desc, - and copy font.desc and all *.raw files to ~/.mplayer/font/ directory. - - encoding must be 8 bit encoding, like iso-8859-2. - To list encodings available on your system use iconv -l. - ppem Font size in pixels (e.g. 24). - font Font file path. Any format supported by freetype library (*.ttf, *.pf?, *). - alphaFactor Alpha map scaling factor (default is 1.0), float. - minAlpha Alpha map minimum value (default is 1.0, max is 255), float. - radius Alpha map blur radius (default is 6 pixels), integer. +1. Make sure you have FreeType 2 installed. +2. Get a TrueType or Type 1 font. +3. Modify `runme' script for your encoding and font path. +4. Type: ./runme +5. Copy *.raw and font.desc files to ~/.mplayer/font/ +6. Run subfont alone to see more options. -Example: -~~~~~~~~ -make -./subfont iso-8859-2 20 verdana.ttf -cat font.desc.tail >> font.desc -cp font.desc *.raw ~/.mplayer/font/ +About: +~~~~~~ +`subfont' program renders antialiased OSD and subtitle fonts for mplayer. + +What you get are bitmap and alpha *.raw files and a font.desc. +What you need is TrueType, Type 1 or any other font supported by FreeType. + +Alpha channel is created using outline and Gaussian blur filters. + +ANY encoding is now supported! That is, all 8-bit encodings known by libc +and user-supplied encodings (also multibyte) through custom encoding files. + +I prepared also Type 1 font `osd.pfb' for OSD characters based on bitmaps +created by chass. + +Subfont was tested with Korean fonts from truetype-fonts-ko-2.0-1k.noarch.rpm +I found on http://rpmfind.net/ and euc-kr encoding. Custom encoding file +for euc-kr was generated from charmap I found in /usr/share/i18n/charmaps/EUC-KR.gz +(glibc package). This should work with -unicode switch for mplayer +(though it is not Unicode encoding). +It took about 14 seconds to render over 8000 characters on P3 @ 600MHz. + + +Custom encodings: +~~~~~~~~~~~~~~~~~ +For each character you want to render write the line consisting of: + hexadecimal Unicode character code, + followed by whitespace, + followed by hexadecimal number representing your encoding, + followed by new line character. + +Example: to render a single letter `aogonek' (Unicode 0x0105) and encode +it using iso-8859-2 encoding (0xB1), your custom encoding file will consist +of a sigle line: +0105 B1 + + +Notes: +~~~~~~ + + Starting x position of each character and the bitmap width is aligned +to multiple of 8 (required by mplayer). + + + Currently subfont won't work on big-endian systems. + + + My development platform is RedHat 7.1. FreeType versions tested are +2.0.1 through 2.0.4. + + + FreeType library has a bug that makes subfont display some warning message +about Unicode charmap for osd.pfb. Author:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TOOLS/subfont-c/encodings/charmap2enc Mon Aug 13 18:37:10 2001 +0000 @@ -0,0 +1,11 @@ +#!/usr/bin/awk -f +# only for mostly 2-byte encodings like euc-kr + +$2~"^/x..$" { + c = substr($2, 3, 2) + if (c<"80") + print substr($1, 3, 4) "\t" c +} +$2~"^/x../x..$" { + print substr($1, 3, 4) "\t" substr($2, 3, 2) substr($2, 7, 2) +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TOOLS/subfont-c/encodings/osd-mplayer Mon Aug 13 18:37:10 2001 +0000 @@ -0,0 +1,15 @@ +E001 01 +E002 02 +E003 03 +E004 04 +E005 05 +E006 06 +E007 07 +E008 08 +E009 09 +E00A 0A +E00B 0B +E010 10 +E011 11 +E012 12 +E013 13
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TOOLS/subfont-c/encodings/runme-kr Mon Aug 13 18:37:10 2001 +0000 @@ -0,0 +1,1 @@ +gunzip -c /usr/share/i18n/charmaps/EUC-KR.gz | ./charmap2enc > euc-kr
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TOOLS/subfont-c/osd/README Mon Aug 13 18:37:10 2001 +0000 @@ -0,0 +1,3 @@ +Requires t1utils and python. + +Based on font created by chass.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TOOLS/subfont-c/osd/gen.py Mon Aug 13 18:37:10 2001 +0000 @@ -0,0 +1,441 @@ +#!/usr/bin/python + +from math import * +import sys +import string + +k = (sqrt(2.)-1.)*4./3. + +chars = [] +encoding = [] +count = 1 +first = 1 + +def append(s): + chars.append(s) + +def rint(x): + return int(round(x)) +""" + if x>=0: + return int(x+0.5) + else: + return int(x-0.5) +""" + +class vec: + def __init__(self, x, y=0): + if type(x) is type(()): + self.x, self.y = x + else: + self.x = x + self.y = y + def set(self, x, y): + self.__init__(x, y) + def move(self, x, y): + self.x = self.x + x + self.y = self.y + y + def __add__(self, v): + return vec(self.x+v.x, self.y+v.y) + def __sub__(self, v): + return vec(self.x-v.x, self.y-v.y) + def int(self): + return vec(rint(self.x), rint(self.y)) + def t(self): + return (self.x, self.y) + +class pvec(vec): + def __init__(self, l, a): + self.x = l * cos(a) + self.y = l * sin(a) + + +pen = vec(0,0) + +def moveto(x, y=0): + global first + dx = rint(x-pen.x) + dy = rint(y-pen.y) + if dx!=0: + if dy!=0: + append("\t%i %i rmoveto" % (dx, dy)) + else: + append("\t%i hmoveto" % (dx)) + elif dy!=0: + append("\t%i vmoveto" % (dy)) + elif first: + append("\t0 hmoveto") + first = 0 + pen.x = pen.x+dx + pen.y = pen.y+dx + +def rlineto(v): + if v.x!=0: + if v.y!=0: + append("\t%i %i rlineto" % (v.x, v.y)) + else: + append("\t%i hlineto" % (v.x)) + elif v.y!=0: + append("\t%i vlineto" % (v.y)) + +def closepath(): + append("\tclosepath") + +history = [] +def movebase(x, y=0): + history.append((x,y)) + pen.move(-x, -y) + +def moveback(): + x, y = history.pop() + pen.move(x, y) + +def ellipse(rx, ry = None, half=0): + # rx>0 => counter-clockwise (filled) + # rx<0 => clockwise + + if ry==None: ry = abs(rx) + + dx1 = rint(k*rx) + dx2 = rx-dx1 + + dy1 = rint(k*ry) + dy2 = ry-dy1 + + rx = abs(rx) + moveto(0, -ry) + append("\t%i 0 %i %i 0 %i rrcurveto" % (+dx1, +dx2, +dy2, +dy1)) + append("\t0 %i %i %i %i 0 rrcurveto" % (+dy1, -dx2, +dy2, -dx1)) + if not half: + append("\t%i 0 %i %i 0 %i rrcurveto" % (-dx1, -dx2, -dy2, -dy1)) + append("\t0 %i %i %i %i 0 rrcurveto" % (-dy1, +dx2, -dy2, +dx1)) + closepath() + if half: + pen.set(0, ry) + else: + pen.set(0, -ry) + +circle = ellipse + +def rect(w, h): + moveto(0, 0) + if w>0: + append("\t%i hlineto" % (w)) + append("\t%i vlineto" % (h)) + append("\t%i hlineto" % (-w)) + pen.set(0, h) + else: + append("\t%i vlineto" % (h)) + append("\t%i hlineto" % (-w)) + append("\t%i vlineto" % (-h)) + pen.set(-w, 0) + closepath() + +def poly(p): + moveto(0, 0) + prev = vec(0, 0) + for q in p: + rlineto(vec(q)-prev) + prev = vec(q) + closepath() + pen.set(prev.x, prev.y) + +def line(w, l, a): + vw = pvec(w*.5, a-pi*.5) + vl = pvec(l, a) + p = vw + moveto(p.x, p.y) + p0 = p + #print '%%wla %i %i %.3f: %.3f %.3f' % (w, l, a, p0.x, p0.y) + p = p+vl + rlineto((p-p0).int()) + p0 = p + #print '%%wla %i %i %.3f: %.3f %.3f' % (w, l, a, p0.x, p0.y) + p = p-vw-vw + rlineto((p-p0).int()) + p0 = p + #print '%%wla %i %i %.3f: %.3f %.3f' % (w, l, a, p0.x, p0.y) + p = p-vl + #print '%%wla %i %i %.3f: %.3f %.3f' % (w, l, a, p.x, p.y) + rlineto((p-p0).int()) + closepath() + pen.set(p.x, p.y) + + +def begin(name, code, hsb, w): + global first, count, history + history = [] + pen.set(0, 0) + append("""\ +/uni%04X { %% %s + %i %i hsbw""" % (code+0xE000, name, hsb, w)) + i = len(encoding) + while i<code: + encoding.append('dup %i /.notdef put' % (i,)) + i = i+1 + encoding.append('dup %i /uni%04X put' % (code, code+0xE000)) + count = count + 1 + first = 1 + + +def end(): + append("""\ + endchar +} ND""") + + + +######################################## + +r = 400 +s = 375 +hsb = 200 # horizontal side bearing +hsb2 = 30 +over = 10 # overshoot +width = 2*r+2*over+2*hsb2 + +######################################## +begin('play', 0x01, hsb, width) +poly(( (s,r), + (0, 2*r),)) +end() + + +######################################## +w=150 +begin('pause', 0x02, hsb, width) +rect(w, 2*r) +movebase(2*w) +rect(w, 2*r) +end() + + +######################################## +begin('stop', 0x03, hsb, width) +rect(665, 720) +end() + + +######################################## +begin('rewind', 0x04, hsb/2, width) +movebase(2*s+15) +poly(( (0, 2*r), + (-s, r),)) +movebase(-s-15) +poly(( (0, 2*r), + (-s, r),)) +end() + + +######################################## +begin('fast forward', 0x05, hsb/2, width) +poly(( (s,r), + (0, 2*r),)) +movebase(s+15) +poly(( (s,r), + (0, 2*r),)) +end() + + +######################################## +begin('clock', 0x06, hsb2, width) +movebase(r, r) +circle(r+over) +wc = 65 +r0 = r-3*wc +n = 4 +movebase(-wc/2, -wc/2) +rect(-wc, wc) +moveback() +for i in range(n): + a = i*2*pi/n + v = pvec(r0, a) + movebase(v.x, v.y) + line(-wc, r-r0, a) + moveback() +hh = 11 +mm = 8 +line(-50, r*.5, pi/2-2*pi*(hh+mm/60.)/12) +line(-40, r*.9, pi/2-2*pi*mm/60.) +end() + + +######################################## +begin('contrast', 0x07, hsb2, width) +movebase(r, r) +circle(r+over) +circle(-(r+over-80), half=1) +end() + + +######################################## +begin('saturation', 0x08, hsb2, width) +movebase(r, r) +circle(r+over) +circle(-(r+over-80)) + +v = pvec(160, pi/2) +movebase(v.x, v.y) +circle(80) +moveback() + +v = pvec(160, pi/2+pi*2/3) +movebase(v.x, v.y) +circle(80) +moveback() + +v = pvec(160, pi/2-pi*2/3) +movebase(v.x, v.y) +circle(80) +end() + + +######################################## +begin('volume', 0x09, 0, 1000) +poly(( (1000, 0), + (0, 500),)) +end() + + +######################################## +begin('brightness', 0x0A, hsb2, width) +movebase(r, r) +circle(150) +circle(-100) + +rb = 375 +wb = 50 +l = 140 +n = 8 +for i in range(n): + a = i*2*pi/n + v = pvec(l, a) + movebase(v.x, v.y) + line(wb, rb-l, a) + moveback() +end() + + +######################################## +begin('hue', 0x0B, hsb2, width) +movebase(r, r) +circle(r+over) +ellipse(-(322), 166) +movebase(0, 280) +circle(-(60)) +end() + + +######################################## +begin('progress [', 0x10, (334-182)/2, 334) +poly(( (182, 0), + (182, 90), + (145, 90), + (145, 550), + (182, 550), + (182, 640), + (0, 640), +)) +end() + + +######################################## +begin('progress |', 0x11, (334-166)/2, 334) +rect(166, 640) +end() + + +######################################## +begin('progress ]', 0x12, (334-182)/2, 334) +poly(( (182, 0), + (182, 640), + (0, 640), + (0, 550), + (37, 550), + (37, 90), + (0, 90), +)) +end() + + +######################################## +begin('progress .', 0x13, (334-130)/2, 334) +movebase(0, (640-130)/2) +rect(130, 130) +end() + + + +######################################## +print """\ +%!PS-AdobeFont-1.0: OSD 1.00 +%%CreationDate: Sun Jul 22 12:38:28 2001 +% +%%EndComments +12 dict begin +/FontInfo 9 dict dup begin +/version (Version 1.00) readonly def +/Notice () readonly def +/FullName (OSD) readonly def +/FamilyName (OSD) readonly def +/Weight (Regular) readonly def +/ItalicAngle 0.000000 def +/isFixedPitch false def +/UnderlinePosition -133 def +/UnderlineThickness 49 def +end readonly def +/FontName /OSD def +/PaintType 0 def +/StrokeWidth 0 def +/FontMatrix [0.001 0 0 0.001 0 0] def +/FontBBox {0 -10 1000 800} readonly def +/Encoding 256 array""" + +print string.join(encoding, '\n') +i = len(encoding) +while i<256: + print 'dup %i /.notdef put' % i + i = i+1 + + +print """\ +readonly def +currentdict end +currentfile eexec +dup /Private 15 dict dup begin +/RD{string currentfile exch readstring pop}executeonly def +/ND{noaccess def}executeonly def +/NP{noaccess put}executeonly def +/ForceBold false def +/BlueValues [ -15 0 717 734 693 708 630 649 593 611 658 679 780 800 ] def +/OtherBlues [ -112 -93 -200 -178 -45 -26 -134 -116 -71 -51 ] def +/StdHW [ 7 ] def +/StdVW [ 8 ] def +/StemSnapH [ 4 7 10 13 18 22 27 30 33 38 61 65 ] def +/StemSnapV [ 5 8 11 15 18 21 25 30 33 36 52 64 ] def +/MinFeature {16 16} def +/password 5839 def +/Subrs 1 array +dup 0 { + return + } NP + ND +2 index +/CharStrings %i dict dup begin""" % count + +print """\ +/.notdef { + 0 400 hsbw + endchar +} ND""" + +print string.join(chars, '\n') + + +print """\ +end +end +readonly put +noaccess put +dup/FontName get exch definefont pop +mark currentfile closefile"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TOOLS/subfont-c/osd/osd.t1a Mon Aug 13 18:37:10 2001 +0000 @@ -0,0 +1,589 @@ +%!PS-AdobeFont-1.0: OSD 1.00 +%%CreationDate: Sun Jul 22 12:38:28 2001 +% +%%EndComments +12 dict begin +/FontInfo 9 dict dup begin +/version (Version 1.00) readonly def +/Notice () readonly def +/FullName (OSD) readonly def +/FamilyName (OSD) readonly def +/Weight (Regular) readonly def +/ItalicAngle 0.000000 def +/isFixedPitch false def +/UnderlinePosition -133 def +/UnderlineThickness 49 def +end readonly def +/FontName /OSD def +/PaintType 0 def +/StrokeWidth 0 def +/FontMatrix [0.001 0 0 0.001 0 0] def +/FontBBox {0 -10 1000 800} readonly def +/Encoding 256 array +dup 0 /.notdef put +dup 1 /uniE001 put +dup 2 /uniE002 put +dup 3 /uniE003 put +dup 4 /uniE004 put +dup 5 /uniE005 put +dup 6 /uniE006 put +dup 7 /uniE007 put +dup 8 /uniE008 put +dup 9 /uniE009 put +dup 10 /uniE00A put +dup 11 /uniE00B put +dup 12 /.notdef put +dup 13 /.notdef put +dup 14 /.notdef put +dup 15 /.notdef put +dup 16 /uniE010 put +dup 17 /uniE011 put +dup 18 /uniE012 put +dup 19 /uniE013 put +dup 20 /.notdef put +dup 21 /.notdef put +dup 22 /.notdef put +dup 23 /.notdef put +dup 24 /.notdef put +dup 25 /.notdef put +dup 26 /.notdef put +dup 27 /.notdef put +dup 28 /.notdef put +dup 29 /.notdef put +dup 30 /.notdef put +dup 31 /.notdef put +dup 32 /.notdef put +dup 33 /.notdef put +dup 34 /.notdef put +dup 35 /.notdef put +dup 36 /.notdef put +dup 37 /.notdef put +dup 38 /.notdef put +dup 39 /.notdef put +dup 40 /.notdef put +dup 41 /.notdef put +dup 42 /.notdef put +dup 43 /.notdef put +dup 44 /.notdef put +dup 45 /.notdef put +dup 46 /.notdef put +dup 47 /.notdef put +dup 48 /.notdef put +dup 49 /.notdef put +dup 50 /.notdef put +dup 51 /.notdef put +dup 52 /.notdef put +dup 53 /.notdef put +dup 54 /.notdef put +dup 55 /.notdef put +dup 56 /.notdef put +dup 57 /.notdef put +dup 58 /.notdef put +dup 59 /.notdef put +dup 60 /.notdef put +dup 61 /.notdef put +dup 62 /.notdef put +dup 63 /.notdef put +dup 64 /.notdef put +dup 65 /.notdef put +dup 66 /.notdef put +dup 67 /.notdef put +dup 68 /.notdef put +dup 69 /.notdef put +dup 70 /.notdef put +dup 71 /.notdef put +dup 72 /.notdef put +dup 73 /.notdef put +dup 74 /.notdef put +dup 75 /.notdef put +dup 76 /.notdef put +dup 77 /.notdef put +dup 78 /.notdef put +dup 79 /.notdef put +dup 80 /.notdef put +dup 81 /.notdef put +dup 82 /.notdef put +dup 83 /.notdef put +dup 84 /.notdef put +dup 85 /.notdef put +dup 86 /.notdef put +dup 87 /.notdef put +dup 88 /.notdef put +dup 89 /.notdef put +dup 90 /.notdef put +dup 91 /.notdef put +dup 92 /.notdef put +dup 93 /.notdef put +dup 94 /.notdef put +dup 95 /.notdef put +dup 96 /.notdef put +dup 97 /.notdef put +dup 98 /.notdef put +dup 99 /.notdef put +dup 100 /.notdef put +dup 101 /.notdef put +dup 102 /.notdef put +dup 103 /.notdef put +dup 104 /.notdef put +dup 105 /.notdef put +dup 106 /.notdef put +dup 107 /.notdef put +dup 108 /.notdef put +dup 109 /.notdef put +dup 110 /.notdef put +dup 111 /.notdef put +dup 112 /.notdef put +dup 113 /.notdef put +dup 114 /.notdef put +dup 115 /.notdef put +dup 116 /.notdef put +dup 117 /.notdef put +dup 118 /.notdef put +dup 119 /.notdef put +dup 120 /.notdef put +dup 121 /.notdef put +dup 122 /.notdef put +dup 123 /.notdef put +dup 124 /.notdef put +dup 125 /.notdef put +dup 126 /.notdef put +dup 127 /.notdef put +dup 128 /.notdef put +dup 129 /.notdef put +dup 130 /.notdef put +dup 131 /.notdef put +dup 132 /.notdef put +dup 133 /.notdef put +dup 134 /.notdef put +dup 135 /.notdef put +dup 136 /.notdef put +dup 137 /.notdef put +dup 138 /.notdef put +dup 139 /.notdef put +dup 140 /.notdef put +dup 141 /.notdef put +dup 142 /.notdef put +dup 143 /.notdef put +dup 144 /.notdef put +dup 145 /.notdef put +dup 146 /.notdef put +dup 147 /.notdef put +dup 148 /.notdef put +dup 149 /.notdef put +dup 150 /.notdef put +dup 151 /.notdef put +dup 152 /.notdef put +dup 153 /.notdef put +dup 154 /.notdef put +dup 155 /.notdef put +dup 156 /.notdef put +dup 157 /.notdef put +dup 158 /.notdef put +dup 159 /.notdef put +dup 160 /.notdef put +dup 161 /.notdef put +dup 162 /.notdef put +dup 163 /.notdef put +dup 164 /.notdef put +dup 165 /.notdef put +dup 166 /.notdef put +dup 167 /.notdef put +dup 168 /.notdef put +dup 169 /.notdef put +dup 170 /.notdef put +dup 171 /.notdef put +dup 172 /.notdef put +dup 173 /.notdef put +dup 174 /.notdef put +dup 175 /.notdef put +dup 176 /.notdef put +dup 177 /.notdef put +dup 178 /.notdef put +dup 179 /.notdef put +dup 180 /.notdef put +dup 181 /.notdef put +dup 182 /.notdef put +dup 183 /.notdef put +dup 184 /.notdef put +dup 185 /.notdef put +dup 186 /.notdef put +dup 187 /.notdef put +dup 188 /.notdef put +dup 189 /.notdef put +dup 190 /.notdef put +dup 191 /.notdef put +dup 192 /.notdef put +dup 193 /.notdef put +dup 194 /.notdef put +dup 195 /.notdef put +dup 196 /.notdef put +dup 197 /.notdef put +dup 198 /.notdef put +dup 199 /.notdef put +dup 200 /.notdef put +dup 201 /.notdef put +dup 202 /.notdef put +dup 203 /.notdef put +dup 204 /.notdef put +dup 205 /.notdef put +dup 206 /.notdef put +dup 207 /.notdef put +dup 208 /.notdef put +dup 209 /.notdef put +dup 210 /.notdef put +dup 211 /.notdef put +dup 212 /.notdef put +dup 213 /.notdef put +dup 214 /.notdef put +dup 215 /.notdef put +dup 216 /.notdef put +dup 217 /.notdef put +dup 218 /.notdef put +dup 219 /.notdef put +dup 220 /.notdef put +dup 221 /.notdef put +dup 222 /.notdef put +dup 223 /.notdef put +dup 224 /.notdef put +dup 225 /.notdef put +dup 226 /.notdef put +dup 227 /.notdef put +dup 228 /.notdef put +dup 229 /.notdef put +dup 230 /.notdef put +dup 231 /.notdef put +dup 232 /.notdef put +dup 233 /.notdef put +dup 234 /.notdef put +dup 235 /.notdef put +dup 236 /.notdef put +dup 237 /.notdef put +dup 238 /.notdef put +dup 239 /.notdef put +dup 240 /.notdef put +dup 241 /.notdef put +dup 242 /.notdef put +dup 243 /.notdef put +dup 244 /.notdef put +dup 245 /.notdef put +dup 246 /.notdef put +dup 247 /.notdef put +dup 248 /.notdef put +dup 249 /.notdef put +dup 250 /.notdef put +dup 251 /.notdef put +dup 252 /.notdef put +dup 253 /.notdef put +dup 254 /.notdef put +dup 255 /.notdef put +readonly def +currentdict end +currentfile eexec +dup /Private 15 dict dup begin +/RD{string currentfile exch readstring pop}executeonly def +/ND{noaccess def}executeonly def +/NP{noaccess put}executeonly def +/ForceBold false def +/BlueValues [ -15 0 717 734 693 708 630 649 593 611 658 679 780 800 ] def +/OtherBlues [ -112 -93 -200 -178 -45 -26 -134 -116 -71 -51 ] def +/StdHW [ 7 ] def +/StdVW [ 8 ] def +/StemSnapH [ 4 7 10 13 18 22 27 30 33 38 61 65 ] def +/StemSnapV [ 5 8 11 15 18 21 25 30 33 36 52 64 ] def +/MinFeature {16 16} def +/password 5839 def +/Subrs 1 array +dup 0 { + return + } NP + ND +2 index +/CharStrings 16 dict dup begin +/.notdef { + 0 400 hsbw + endchar +} ND +/uniE001 { % play + 200 880 hsbw + 0 hmoveto + 375 400 rlineto + -375 400 rlineto + closepath + endchar +} ND +/uniE002 { % pause + 200 880 hsbw + 0 hmoveto + 150 hlineto + 800 vlineto + -150 hlineto + closepath + 300 -800 rmoveto + 150 hlineto + 800 vlineto + -150 hlineto + closepath + endchar +} ND +/uniE003 { % stop + 200 880 hsbw + 0 hmoveto + 665 hlineto + 720 vlineto + -665 hlineto + closepath + endchar +} ND +/uniE004 { % rewind + 100 880 hsbw + 765 hmoveto + 800 vlineto + -375 -400 rlineto + closepath + -15 -400 rmoveto + 800 vlineto + -375 -400 rlineto + closepath + endchar +} ND +/uniE005 { % fast forward + 100 880 hsbw + 0 hmoveto + 375 400 rlineto + -375 400 rlineto + closepath + 390 -800 rmoveto + 375 400 rlineto + -375 400 rlineto + closepath + endchar +} ND +/uniE006 { % clock + 30 880 hsbw + 400 -10 rmoveto + 226 0 184 184 0 226 rrcurveto + 0 226 -184 184 -226 0 rrcurveto + -226 0 -184 -184 0 -226 rrcurveto + 0 -226 184 -184 226 0 rrcurveto + closepath + -33 377 rmoveto + 65 vlineto + 65 hlineto + -65 vlineto + closepath + 173 66 rmoveto + 195 hlineto + -65 vlineto + -195 hlineto + closepath + -238 238 rmoveto + 195 vlineto + 65 hlineto + -195 vlineto + closepath + -238 -237 rmoveto + -195 hlineto + 65 vlineto + 195 hlineto + closepath + 237 -238 rmoveto + -195 vlineto + -65 hlineto + 195 vlineto + closepath + 10 194 rmoveto + -88 180 rlineto + 45 22 rlineto + 88 -180 rlineto + closepath + -36 4 rmoveto + 268 241 rlineto + 27 -30 rlineto + -268 -241 rlineto + closepath + endchar +} ND +/uniE007 { % contrast + 30 880 hsbw + 400 -10 rmoveto + 226 0 184 184 0 226 rrcurveto + 0 226 -184 184 -226 0 rrcurveto + -226 0 -184 -184 0 -226 rrcurveto + 0 -226 184 -184 226 0 rrcurveto + closepath + 80 vmoveto + -182 0 -148 148 0 182 rrcurveto + 0 182 148 148 182 0 rrcurveto + closepath + endchar +} ND +/uniE008 { % saturation + 30 880 hsbw + 400 -10 rmoveto + 226 0 184 184 0 226 rrcurveto + 0 226 -184 184 -226 0 rrcurveto + -226 0 -184 -184 0 -226 rrcurveto + 0 -226 184 -184 226 0 rrcurveto + closepath + 80 vmoveto + -182 0 -148 148 0 182 rrcurveto + 0 182 148 148 182 0 rrcurveto + 182 0 148 -148 0 -182 rrcurveto + 0 -182 -148 -148 -182 0 rrcurveto + closepath + 410 vmoveto + 44 0 36 36 0 44 rrcurveto + 0 44 -36 36 -44 0 rrcurveto + -44 0 -36 -36 0 -44 rrcurveto + 0 -44 36 -36 44 0 rrcurveto + closepath + -139 -240 rmoveto + 44 0 36 36 0 44 rrcurveto + 0 44 -36 36 -44 0 rrcurveto + -44 0 -36 -36 0 -44 rrcurveto + 0 -44 36 -36 44 0 rrcurveto + closepath + 277 hmoveto + 44 0 36 36 0 44 rrcurveto + 0 44 -36 36 -44 0 rrcurveto + -44 0 -36 -36 0 -44 rrcurveto + 0 -44 36 -36 44 0 rrcurveto + closepath + endchar +} ND +/uniE009 { % volume + 0 1000 hsbw + 0 hmoveto + 1000 hlineto + -1000 500 rlineto + closepath + endchar +} ND +/uniE00A { % brightness + 30 880 hsbw + 400 250 rmoveto + 83 0 67 67 0 83 rrcurveto + 0 83 -67 67 -83 0 rrcurveto + -83 0 -67 -67 0 -83 rrcurveto + 0 -83 67 -67 83 0 rrcurveto + closepath + 50 vmoveto + -55 0 -45 45 0 55 rrcurveto + 0 55 45 45 55 0 rrcurveto + 55 0 45 -45 0 -55 rrcurveto + 0 -55 -45 -45 -55 0 rrcurveto + closepath + 140 75 rmoveto + 235 hlineto + 50 vlineto + -235 hlineto + closepath + -23 56 rmoveto + 166 166 rlineto + -35 35 rlineto + -166 -166 rlineto + closepath + -56 23 rmoveto + 235 vlineto + -50 hlineto + -235 vlineto + closepath + -56 -23 rmoveto + -166 166 rlineto + -35 -35 rlineto + 166 -166 rlineto + closepath + -23 -56 rmoveto + -235 hlineto + -50 vlineto + 235 hlineto + closepath + 23 -56 rmoveto + -166 -166 rlineto + 35 -35 rlineto + 166 166 rlineto + closepath + 56 -23 rmoveto + -235 vlineto + 50 hlineto + 235 vlineto + closepath + 56 23 rmoveto + 166 -166 rlineto + 35 35 rlineto + -166 166 rlineto + closepath + endchar +} ND +/uniE00B { % hue + 30 880 hsbw + 400 -10 rmoveto + 226 0 184 184 0 226 rrcurveto + 0 226 -184 184 -226 0 rrcurveto + -226 0 -184 -184 0 -226 rrcurveto + 0 -226 184 -184 226 0 rrcurveto + closepath + 244 vmoveto + -178 0 -144 74 0 92 rrcurveto + 0 92 144 74 178 0 rrcurveto + 178 0 144 -74 0 -92 rrcurveto + 0 -92 -144 -74 -178 0 rrcurveto + closepath + 386 vmoveto + -33 0 -27 27 0 33 rrcurveto + 0 33 27 27 33 0 rrcurveto + 33 0 27 -27 0 -33 rrcurveto + 0 -33 -27 -27 -33 0 rrcurveto + closepath + endchar +} ND +/uniE010 { % progress [ + 76 334 hsbw + 0 hmoveto + 182 hlineto + 90 vlineto + -37 hlineto + 460 vlineto + 37 hlineto + 90 vlineto + -182 hlineto + closepath + endchar +} ND +/uniE011 { % progress | + 84 334 hsbw + 0 hmoveto + 166 hlineto + 640 vlineto + -166 hlineto + closepath + endchar +} ND +/uniE012 { % progress ] + 76 334 hsbw + 0 hmoveto + 182 hlineto + 640 vlineto + -182 hlineto + -90 vlineto + 37 hlineto + -460 vlineto + -37 hlineto + closepath + endchar +} ND +/uniE013 { % progress . + 102 334 hsbw + 255 vmoveto + 130 hlineto + 130 vlineto + -130 hlineto + closepath + endchar +} ND +end +end +readonly put +noaccess put +dup/FontName get exch definefont pop +mark currentfile closefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TOOLS/subfont-c/osd/runme Mon Aug 13 18:37:10 2001 +0000 @@ -0,0 +1,5 @@ +# +./gen.py > osd.t1a && +t1asm --pfb osd.t1a osd.pfb && +ftview 80 osd.pfb &> /dev/null & +#../subfont iso-8859-2 25 osd.pfb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TOOLS/subfont-c/runme Mon Aug 13 18:37:10 2001 +0000 @@ -0,0 +1,24 @@ +#!/bin/bash + +font=arial.ttf +encoding=iso-8859-2 +fontsize=24 +symbolssize=35 +blur=2 +outline=1.5 + +make || exit + +./subfont --blur $blur --outline $outline "$encoding" $fontsize "$font" &>log || exit +cat log +./subfont --append --blur $blur --outline $outline encodings/osd-mplayer $symbolssize osd/osd.pfb + +#cp font.desc *.raw ~/.mplayer/font/ + +exit + +SIZE=`awk '/^bitmap size/ {print $NF}' log`+800 +display -size $SIZE gray:$encoding-a.raw & +display -size $SIZE gray:$encoding-b.raw & +#convert -size $SIZE gray:$encoding-a.raw $encoding-a.png +#convert -size $SIZE gray:$encoding-b.raw $encoding-b.png
--- a/TOOLS/subfont-c/subfont.c Mon Aug 13 13:12:49 2001 +0000 +++ b/TOOLS/subfont-c/subfont.c Mon Aug 13 18:37:10 2001 +0000 @@ -16,53 +16,72 @@ #include <iconv.h> #include <math.h> #include <string.h> +#include <libgen.h> -#if 0 /* freetype 2.0.1 */ -#include <freetype/freetype.h> -#else /* freetype 2.0.3 */ + +#ifndef OLD_FREETYPE2 + #include <ft2build.h> #include FT_FREETYPE_H +#include FT_GLYPH_H + +#else /* freetype 2.0.1 */ + +#include <freetype/freetype.h> +#include <freetype/ftglyph.h> + +#endif + +#ifndef DEBUG +#define DEBUG 0 #endif -#include FT_GLYPH_H + +//// default values +char *encoding = "iso-8859-1"; /* target encoding */ +char *charmap = "ucs-4"; /* font charmap encoding, I hope ucs-4 is always big endian */ + /* gcc 2.1.3 doesn't support ucs-4le, but supports ucs-4 (==ucs-4be) */ +int ppem = 22; /* font size in pixels */ + +double radius = 2; /* blur radius */ +double thickness = 1.5; /* outline thickness */ +int padding; + +char* font_desc = "font.desc"; +//char* font_desc = "/dev/stdout"; + +//// constants +int const colors = 256; +int const maxcolor = 255; +unsigned const base = 256; +unsigned const first_char = 33; +#define max_charset_size 60000 +//int const max_charset_size = 256; +unsigned charset_size = 0; + +//// +char *command; +char *font_path; +//char *font_metrics; +int append_mode = 0; + +unsigned char *buffer, *abuffer; +int width, height; +static FT_ULong charset[max_charset_size]; /* characters we want to render; Unicode */ +static FT_ULong charcodes[max_charset_size]; /* character codes in 'encoding' */ +iconv_t cd; // iconv conversion descriptor -#define f266toInt(x) (((x)+32)>>6) /* round fractional fixed point number to integer */ - /* coordinates are in 26.6 pixels (i.e. 1/64th of pixels) */ - - -int const test = 1; - -/* default values */ -char *encoding = "iso-8859-1"; /* target encoding */ -/* gcc 2.1.3 doesn't support ucs-4le, but supports ucs-4 (==ucs-4be) */ -char *charmap = "ucs-4"; /* ucs-4le font charmap encoding */ -int ppem = 20; /* font size in pixels */ - -int const colors = 256; -int const maxcolor = 255; -int radius = 2; /* blur radius */ -double minalpha = 1.0; /* good value for minalpha is 0.5 */ -double alpha_factor = 1.0; +#define eprintf(...) fprintf(stderr, __VA_ARGS__) +#define ERROR_(msg, ...) (eprintf("%s: error: " msg "\n", command, __VA_ARGS__), exit(1)) +#define WARNING_(msg, ...) eprintf("%s: warning: " msg "\n", command, __VA_ARGS__) +#define ERROR(...) ERROR_(__VA_ARGS__, NULL) +#define WARNING(...) WARNING_(__VA_ARGS__, NULL) -int const first_char = 33; -int const charset_size = 256; - -char *command; -char *font_path = NULL; -/*char *font_metrics = NULL;*/ - - -unsigned char *buffer; -unsigned char *ebuffer; // temporary buffer for alphamap creation (edges) -unsigned char *abuffer; -int width, height; -static FT_ULong ustring[256]; - -#define eprintf(...) fprintf(stderr, __VA_ARGS__) -#define ERROR(msg, ...) (eprintf("%s: error: " msg "\n", command, ##__VA_ARGS__), exit(1)) -#define WARNING(msg, ...) eprintf("%s: warning: " msg "\n", command, ##__VA_ARGS__) +#define f266toInt(x) (((x)+32)>>6) // round fractional fixed point number to integer + // coordinates are in 26.6 pixels (i.e. 1/64th of pixels) +#define ALIGN(x) (((x)+7)&~7) // 8 byte align @@ -80,6 +99,7 @@ buffer[drow+dp] = bitmap->buffer[srow+sp]; } + void write_header(FILE *f) { static unsigned char header[800] = "mhwanh"; int i; @@ -91,6 +111,7 @@ fwrite(header, 1, 800, f); } + void write_bitmap() { FILE *f; int const max_name = 128; @@ -98,38 +119,40 @@ snprintf(name, max_name, "%s-b.raw", encoding); f = fopen(name, "wb"); - if (f==NULL) ERROR("fopen failed.",NULL); + if (f==NULL) ERROR("fopen failed."); write_header(f); fwrite(buffer, 1, width*height, f); fclose(f); snprintf(name, max_name, "%s-a.raw", encoding); f = fopen(name, "wb"); - if (f==NULL) ERROR("fopen failed.",NULL); + if (f==NULL) ERROR("fopen failed."); write_header(f); fwrite(abuffer, 1, width*height, f); fclose(f); } + void render() { FT_Library library; FT_Face face; FT_Error error; FT_GlyphSlot slot; - FT_ULong glyph_index; - FT_Glyph glyphs[charset_size]; + FT_ULong glyph_index, character, code; + //FT_Glyph glyphs[max_charset_size]; + FT_Glyph glyph; FILE *f; int const load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; int pen_x, pen_xa, pen_y, ymin, ymax; - int i, c; + int i, uni_charmap = 1; int baseline, space_advance = 20; /* initialize freetype */ error = FT_Init_FreeType(&library); - if (error) ERROR("Init_FreeType failed.",NULL); + if (error) ERROR("Init_FreeType failed."); error = FT_New_Face(library, font_path, 0, &face); - if (error) ERROR("New_Face failed.",NULL); + if (error) ERROR("New_Face failed."); /* if (font_metrics) { @@ -139,8 +162,39 @@ */ - if (face->charmap->encoding!=ft_encoding_unicode) - WARNING("Selected font has no unicode charmap. Very bad!",NULL); +#if 0 + /************************************************************/ + eprintf("Font encodings:\n"); + for (i = 0; i<face->num_charmaps; ++i) + eprintf("'%.4s'\n", (char*)&face->charmaps[i]->encoding); + + //error = FT_Select_Charmap(face, ft_encoding_unicode); + //error = FT_Select_Charmap(face, ft_encoding_adobe_standard); + //error = FT_Select_Charmap(face, ft_encoding_adobe_custom); + //error = FT_Set_Charmap(face, face->charmaps[1]); + //if (error) WARNING("Select_Charmap failed."); +#endif +#if 0 + /************************************************************/ + if (FT_HAS_GLYPH_NAMES(face)) { + int const max_gname = 128; + char gname[max_gname]; + for (i = 0; i<face->num_glyphs; ++i) { + FT_Get_Glyph_Name(face, i, gname, max_gname); + eprintf("%02x `%s'\n", i, gname); + } + + } +#endif + + + if (face->charmap==NULL || face->charmap->encoding!=ft_encoding_unicode) { + WARNING("Unicode charmap not available for this font. Very bad!"); + uni_charmap = 0; + error = FT_Set_Charmap(face, face->charmaps[0]); + if (error) WARNING("No charmaps! Strange."); + } + /* set size */ @@ -156,38 +210,46 @@ jppem = face->available_sizes[i].height; } } - WARNING("Selected font is not scalable. Using ppem=%i", face->available_sizes[j].height); + WARNING("Selected font is not scalable. Using ppem=%i.", face->available_sizes[j].height); error = FT_Set_Pixel_Sizes(face, face->available_sizes[j].width, face->available_sizes[j].height); } - if (error) WARNING("Set_Pixel_Sizes failed.",NULL); + if (error) WARNING("Set_Pixel_Sizes failed."); if (FT_IS_FIXED_WIDTH(face)) - WARNING("Selected font is fixed-width.",NULL); + WARNING("Selected font is fixed-width."); /* compute space advance */ error = FT_Load_Char(face, ' ', load_flags); - if (error) WARNING("spacewidth set to default.",NULL); - else space_advance = f266toInt(face->glyph->advance.x); /* +32 is for rounding */ + if (error) WARNING("spacewidth set to default."); + else space_advance = f266toInt(face->glyph->advance.x); /* create font.desc */ - f = fopen("font.desc", "w"); - if (f==NULL) ERROR("fopen failed.",NULL); + f = fopen(font_desc, append_mode ? "a":"w"); + if (f==NULL) ERROR("fopen failed."); /* print font.desc header */ - fprintf(f, "[info]\n"); - fprintf(f, "name 'File generated for %s encoding using `%s%s%s' face (%s), ppem=%i'\n", - encoding, - face->family_name, - face->style_name ? " ":"", face->style_name ? face->style_name:"", - font_path, - ppem); - fprintf(f, "descversion 1\n"); - fprintf(f, "spacewidth %i\n", 2*radius + space_advance); - fprintf(f, "charspace %i\n", -2*radius); - fprintf(f, "height %i\n", f266toInt(face->size->metrics.height)); + if (append_mode) { + fprintf(f, "\n\n# Subtitle font for %s encoding, face \"%s%s%s\", ppem=%i\n", + encoding, + face->family_name, + face->style_name ? " ":"", face->style_name ? face->style_name:"", + ppem); + } else { + fprintf(f, "# This file was generated with subfont for Mplayer.\n# Subfont by Artur Zaprzala <zybi@fanthom.irc.pl>.\n\n"); + fprintf(f, "[info]\n"); + fprintf(f, "name 'Subtitle font for %s encoding, face \"%s%s%s\", ppem=%i'\n", + encoding, + face->family_name, + face->style_name ? " ":"", face->style_name ? face->style_name:"", + ppem); + fprintf(f, "descversion 1\n"); + fprintf(f, "spacewidth %i\n", 2*padding + space_advance); + fprintf(f, "charspace %i\n", -2*padding); + fprintf(f, "height %i\n", f266toInt(face->size->metrics.height)); + } fprintf(f, "\n[files]\n"); fprintf(f, "alpha %s-a.raw\n", encoding); fprintf(f, "bitmap %s-b.raw\n", encoding); @@ -199,288 +261,429 @@ pen_y = 0; ymin = INT_MAX; ymax = INT_MIN; - for (c= first_char, i= 0; c<charset_size; ++c, ++i) { + for (i= 0; i<charset_size; ++i) { FT_UInt glyph_index; FT_BBox bbox; + character = charset[i]; + code = charcodes[i]; - glyph_index = FT_Get_Char_Index(face, ustring[i]); - if (glyph_index<=0) { - WARNING("Glyph for char %3i|%2X|U%04X not found.", c, c, ustring[i]); - continue; + if (character==0) + glyph_index = 0; + else { + glyph_index = FT_Get_Char_Index(face, uni_charmap ? character:code); + if (glyph_index==0) { + WARNING("Glyph for char 0x%02x|U+%04X|%c not found.", code, character, + code<' '||code>255 ? '.':code); + continue; + } } error = FT_Load_Glyph(face, glyph_index, load_flags); if (error) { - WARNING("Load_Glyph %3u|%2X (char %3i|%2X|U%04X) failed.", glyph_index, glyph_index, c, c, ustring[i]); + WARNING("Load_Glyph 0x%02x (char 0x%02x|U+%04X) failed.", glyph_index, code, character); continue; } slot = face->glyph; - error = FT_Get_Glyph(slot, &glyphs[i]); + error = FT_Get_Glyph(slot, &glyph); - FT_Glyph_Get_CBox(glyphs[i], ft_glyph_bbox_pixels, &bbox); + FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_pixels, &bbox); if (pen_y+bbox.yMax>ymax) { ymax = pen_y+bbox.yMax; - /* eprintf("%3i: ymax %i (%c)\n", c, ymax, c); */ + // eprintf("%3i: ymax %i (%c)\n", code, ymax, code); } if (pen_y+bbox.yMin<ymin) { ymin = pen_y+bbox.yMin; - /* eprintf("%3i: ymin %i (%c)\n", c, ymin, c); */ + // eprintf("%3i: ymin %i (%c)\n", code, ymin, code); } /* advance pen */ - pen_xa = pen_x + f266toInt(slot->advance.x) + 2*radius; - /* pen_y += f266toInt(slot->advance.y); // for vertical layout */ + pen_xa = pen_x + f266toInt(slot->advance.x) + 2*padding; + // pen_y += f266toInt(slot->advance.y); // for vertical layout /* font.desc */ - if (c=='\'') - fprintf(f, "\"%c\" %i %i\n", c, pen_x, pen_xa-1); - else - fprintf(f, "'%c' %i %i\n", c, pen_x, pen_xa-1); - pen_x = (pen_xa+7)&~7; /* 8 byte align */ + fprintf(f, "0x%02x %i %i;\tU+%04X|%c\n", code, pen_x, pen_xa-1, character, code<' '||code>255 ? '.':code); + pen_x = ALIGN(pen_xa); } fclose(f); - if (ymax<=ymin) ERROR("Something went wrong.",NULL); + if (ymax<=ymin) ERROR("Something went wrong. Use the source!"); width = pen_x; - height = ymax - ymin + 2*radius; - baseline = ymax + radius; + height = ymax - ymin + 2*padding; + baseline = ymax + padding; eprintf("bitmap size: %ix%i\n", width, height); buffer = (unsigned char*)malloc(width*height); - ebuffer = (unsigned char*)malloc(width*height); abuffer = (unsigned char*)malloc(width*height); - if (buffer==NULL || abuffer==NULL) ERROR("malloc failed.",NULL); + if (buffer==NULL || abuffer==NULL) ERROR("malloc failed."); + + memset(buffer, 0, width*height); /* render glyphs */ pen_x = 0; pen_y = baseline; - for (c= first_char, i= 0; c<charset_size; ++c, ++i) { + for (i= 0; i<charset_size; ++i) { FT_UInt glyph_index; + character = charset[i]; + code = charcodes[i]; - glyph_index = FT_Get_Char_Index(face, ustring[i]); - if (glyph_index==0) continue; + if (character==0) + glyph_index = 0; + else { + glyph_index = FT_Get_Char_Index(face, uni_charmap ? character:code); + if (glyph_index==0) + continue; + } + error = FT_Load_Glyph(face, glyph_index, load_flags); if (error) { - /* WARNING("Load_Glyph failed"); */ + // WARNING("Load_Glyph failed."); continue; } error = FT_Render_Glyph(face->glyph, ft_render_mode_normal); - if (error) WARNING("Render_Glyph %3i|%2X (char %3i|%2X|U%04X) failed.", glyph_index, glyph_index, c, c, ustring[i]); + if (error) WARNING("Render_Glyph 0x%02x (char 0x%02x|U+%04X) failed.", glyph_index, code, character); slot = face->glyph; paste_bitmap(&slot->bitmap, - pen_x + radius + slot->bitmap_left, + pen_x + padding + slot->bitmap_left, pen_y - slot->bitmap_top ); /* advance pen */ - pen_x += f266toInt(slot->advance.x) + 2*radius; - /* pen_y += f266toInt(slot->advance.y); // for vertical layout */ - pen_x = (pen_x+7)&~7; /* 8 byte align */ + pen_x += f266toInt(slot->advance.x) + 2*padding; + // pen_y += f266toInt(slot->advance.y); // for vertical layout + pen_x = ALIGN(pen_x); } error = FT_Done_FreeType(library); - if (error) ERROR("Done_FreeType failed.",NULL); + if (error) ERROR("Done_FreeType failed."); } + +/* decode from 'encoding' to unicode */ +FT_ULong decode_char(char c) { + FT_ULong o; + char *inbuf = &c; + char *outbuf = (char*)&o; + int inbytesleft = 1; + int outbytesleft = sizeof(FT_ULong); + + size_t count = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + if (count==-1) o = 0; + + /* convert unicode BE -> LE */ + o = ((o>>24)&0xff) + | ((o>>8)&0xff00) + | ((o&0xff00)<<8) + | ((o&0xff)<<24); + + /* we don't want control characters */ + if (o>=0x7f && o<0xa0) o = 0; + return o; +} + + void prepare_charset() { - iconv_t cd; - unsigned char text[charset_size]; - char *inbuf = text; - char *outbuf = (char*) ustring; - int inbuf_left = charset_size; - int outbuf_left = 4*charset_size; - int i; - size_t count; + FILE *f; + FT_ULong i; + + f = fopen(encoding, "r"); // try to read custom encoding + if (f==NULL) { + int count = 0; + // check if ucs-4 is available + cd = iconv_open(charmap, charmap); + if (cd==(iconv_t)-1) ERROR("iconv doesn't know %s encoding. Use the source!", charmap); + iconv_close(cd); + + cd = iconv_open(charmap, encoding); + if (cd==(iconv_t)-1) ERROR("Unsupported encoding `%s', use iconv --list to list character sets known on your system.", encoding); - for (i = first_char; i<charset_size; ++i) text[i-first_char] = i; + charset_size = 256 - first_char; + for (i = 0; i<charset_size; ++i) { + charcodes[count] = i+first_char; + charset[count] = decode_char(i+first_char); + //eprintf("%04X U%04X\n", charcodes[count], charset[count]); + if (charset[count]!=0) ++count; + } + charcodes[count] = charset[count] = 0; ++count; + charset_size = count; - /* check if ucs-4le is available */ - cd = iconv_open(charmap, charmap); - if (cd==(iconv_t)-1) ERROR("iconv doesn't know %s encoding. Use the source!", charmap); - iconv_close(cd); + iconv_close(cd); + } else { + unsigned int character, code; + int count; + + eprintf("Reading custom encoding from file '%s'.\n", encoding); - cd = iconv_open(charmap, encoding); - if (cd==(iconv_t)-1) ERROR("Unsupported encoding, use iconv -l to list character sets known on your system.",NULL); - while (1) { - count = iconv(cd, &inbuf, &inbuf_left, &outbuf, &outbuf_left); - if (inbuf_left==0) break; - /* skip undefined characters */ - inbuf+= 1; - inbuf_left-= 1; - *(FT_ULong*)outbuf = 0; - outbuf+=sizeof(FT_ULong); + while ((count = fscanf(f, "%x%*[ \t]%x", &character, &code)) != EOF) { + if (charset_size==max_charset_size) { + WARNING("There is no place for more than %i characters. Use the source!", max_charset_size); + break; + } + if (count==0) ERROR("Unable to parse custom encoding file."); + if (character<32) continue; // skip control characters + charset[charset_size] = character; + charcodes[charset_size] = count==2 ? code : character; + ++charset_size; + } + fclose(f); + encoding = basename(encoding); } - iconv_close(cd); + if (charset_size==0) ERROR("No characters to render!"); +} + + +// general outline +void outline( + unsigned char *s, + unsigned char *t, + int width, + int height, + int *m, + int r, + int mwidth) { - /* converting unicodes BE -> LE */ - for (i = 0; i<256; ++i){ - FT_ULong x=ustring[i]; - x= ((x>>24)&255) - | (((x>>16)&255)<<8) - | (((x>> 8)&255)<<16) - | ((x&255)<<24); - ustring[i]=x; + int x, y, mx, my; + for (y = 0; y<height; ++y) { + for (x = 0; x<width; ++x, ++s, ++t) { + unsigned max = 0; + unsigned *mrow = m + r; + unsigned char *srow = s -r*width; + + for (my = -r; my<=r; ++my, srow+= width, mrow+= mwidth) { + if (y+my < 0) continue; + if (y+my >= height) break; + + for (mx = -r; mx<=r; ++mx) { + unsigned v; + if (x+mx < 0) continue; + if (x+mx >= width) break; + + v = srow[mx] * mrow[mx]; + if (v>max) max = v; + } + } + *t = (max + base/2) / base; + } } - } -void blur() { - int const r = radius; - int const w = 2*r+1; /* matrix size */ - double const A = log(1.0/maxcolor)/((r+1)*(r+1)); - double const B = maxcolor; - int sum=0; + +// 1 pixel outline +void outline1( + unsigned char *s, + unsigned char *t, + int width, + int height) { + + int x, y, mx, my; + + for (x = 0; x<width; ++x, ++s, ++t) *t = *s; + for (y = 1; y<height-1; ++y) { + *t++ = *s++; + for (x = 1; x<width-1; ++x, ++s, ++t) { + unsigned v = ( + s[-1-width]+ + s[-1+width]+ + s[+1-width]+ + s[+1+width] + )/2 + ( + s[-1]+ + s[+1]+ + s[-width]+ + s[+width]+ + s[0] + ); + *t = v>maxcolor ? maxcolor : v; + } + *t++ = *s++; + } + for (x = 0; x<width; ++x, ++s, ++t) *t = *s; +} + - int i, x, y, mx, my; - unsigned char *m = (unsigned char*)malloc(w*w); +// brute-force gaussian blur +void blur( + unsigned char *s, + unsigned char *t, + int width, + int height, + int *m, + int r, + int mwidth, + unsigned volume) { + + int x, y, mx, my; + + for (y = 0; y<height; ++y) { + for (x = 0; x<width; ++x, ++s, ++t) { + unsigned sum = 0; + unsigned *mrow = m + r; + unsigned char *srow = s -r*width; + + for (my = -r; my<=r; ++my, srow+= width, mrow+= mwidth) { + if (y+my < 0) continue; + if (y+my >= height) break; - if (m==NULL) ERROR("malloc failed",NULL); + for (mx = -r; mx<=r; ++mx) { + if (x+mx < 0) continue; + if (x+mx >= width) break; + + sum+= srow[mx] * mrow[mx]; + } + } + *t = (sum + volume/2) / volume; + } + } +} + + +void alpha() { + int const g_r = ceil(radius); + int const o_r = ceil(thickness); + int const g_w = 2*g_r+1; // matrix size + int const o_w = 2*o_r+1; // matrix size + double const A = log(1.0/base)/(radius*radius*2); + + int mx, my; + unsigned volume = 0; // volume under Gaussian area is exactly -pi*base/A + + unsigned *gm = (unsigned*)malloc(g_w*g_w * sizeof(unsigned)); + unsigned *om = (unsigned*)malloc(o_w*o_w * sizeof(unsigned)); + unsigned char *tbuffer = (unsigned char*)malloc(width*height); + if (gm==NULL || om==NULL || tbuffer==NULL) ERROR("malloc failed."); /* Gaussian matrix */ - for (my = 0; my<w; ++my) { - for (mx = 0; mx<w; ++mx) { - m[mx+my*w] = (int)(exp(A * ((mx-r)*(mx-r)+(my-r)*(my-r))) * B + .5); - sum+=m[mx+my*w]; - if (test) eprintf("%3i ", m[mx+my*w]); + for (my = 0; my<g_w; ++my) { + for (mx = 0; mx<g_w; ++mx) { + gm[mx+my*g_w] = (unsigned)(exp(A * ((mx-g_r)*(mx-g_r)+(my-g_r)*(my-g_r))) * base + .5); + volume+= gm[mx+my*g_w]; + if (DEBUG) eprintf("%3i ", gm[mx+my*g_w]); } - if (test) eprintf("\n"); + if (DEBUG) eprintf("\n"); } - printf("gauss sum = %d\n",sum); - - /* This is not a gaussian blur! */ - /* And is very slow */ - - // PASS-1 : build edge mask: - memset(ebuffer,0,width*height); // clear - for (y = 1; y<height-1; ++y){ - int ay=y*width; - int ax; - for (ax = 1; ax<width-1; ++ax) { - int p = - - ( (buffer[ax-1+ay-width]) + - (buffer[ax-1+ay+width]) + - (buffer[ax+1+ay-width]) + - (buffer[ax+1+ay+width]) )/2 + - - ( (buffer[ax-1+ay]) + - (buffer[ax+1+ay]) + - (buffer[ax+ay-width]) + - (buffer[ax+ay+width]) + - - (buffer[ax+ay]) ) ; - - ebuffer[ax+ay]=(p>255)?255:p; - } -// printf("\n"); + if (DEBUG) { + eprintf("A= %f\n", A); + eprintf("volume: %i; exact: %.0f; volume/exact: %.6f\n\n", volume, -M_PI*base/A, volume/(-M_PI*base/A)); } - // PASS-2 : blur - for (y = 0; y<height; ++y){ - for (x = 0; x<width; ++x) { - float max = 0; - for (my = -r; my<=r; ++my){ - int ay=y+my; - if(ay>0 && ay<height){ - int by=r+(my+r)*w; - ay*=width; - for (mx = -r; mx<=r; ++mx) - if(x+mx>0 && x+mx<width) - max+=ebuffer[x+mx+ay]*m[mx+by]; - } - } - max*=alpha_factor/(float)sum; -// printf("%5.3f ",max); - if(max>255) max=255; - abuffer[x+y*width] = max; + + /* outline matrix */ + for (my = 0; my<o_w; ++my) { + for (mx = 0; mx<o_w; ++mx) { + // antialiased circle would be perfect here, but this one is good enough + double d = thickness + 1 - sqrt((mx-o_r)*(mx-o_r)+(my-o_r)*(my-o_r)); + om[mx+my*o_w] = d>=1 ? base : d<=0 ? 0 : (d*base + .5); + if (DEBUG) eprintf("%3i ", om[mx+my*o_w]); } -// printf("\n"); + if (DEBUG) eprintf("\n"); } + if (DEBUG) eprintf("\n"); - free(m); + + outline(buffer, tbuffer, width, height, om, o_r, o_w); // solid outline + //outline(buffer, tbuffer, width, height, gm, g_r, g_w); // Gaussian outline + //outline1(buffer, tbuffer, width, height); // solid 1 pixel outline + + blur(tbuffer, abuffer, width, height, gm, g_r, g_w, volume); + + free(gm); + free(om); + free(tbuffer); } + void usage() { - printf("Usage: %s encoding ppem font [alphaFactor [minAlpha [radius]]]\n", command); - printf( + printf("Usage: %s [--append] [--blur b] [--outline o] encoding ppem font\n", command); + printf("\n" " Program creates 3 files: font.desc, <encoding>-a.raw, <encoding>-b.raw.\n" - " You should append font.desc.tail (desc for OSD characters by a'rpi & chass) to font.desc,\n" - " and copy font.desc and all *.raw files to ~/.mplayer/font/ directory.\n" "\n" - " encoding must be 8 bit encoding, like iso-8859-2.\n" - " To list encodings available on your system use iconv -l.\n" - " ppem Font size in pixels (e.g. 24).\n" - " font Font file path. Any format supported by freetype library (*.ttf, *.pf?, *).\n" - " alphaFactor Alpha map scaling factor (default is 1.0), float.\n" - " minAlpha Alpha map minimum value (default is 1.0, max is 255), float.\n" - " radius Alpha map blur radius (default is 6 pixels), integer.\n" + " --append append results to existing font.desc.\n" + " --blur b specify blur radius, float.\n" + " --outline o specify outline thickness, float.\n" + " encoding must be an 8 bit encoding, like iso-8859-2, or path to custom encoding file (see README).\n" + " To list encodings available on your system use iconv --list.\n" + " ppem Font size in pixels (e.g. 24).\n" + " font Font file path. Any format supported by the freetype library (*.ttf, *.pfb, ...).\n" ); exit(1); } + void parse_args(int argc, char **argv) { - int i; + int i, a = 0; double d; - command = strrchr(argv[0], '/'); - if (command==NULL) command = argv[0]; + command = strrchr(argv[a], '/'); + if (command==NULL) command = argv[a]; else ++command; + ++a; --argc; - if (argc<4) usage(); + if (argc==0) usage(); + if (strcmp(argv[a], "--append")==0) { + append_mode = 1; + ++a; --argc; + } - encoding = argv[1]; + + if (argc==0) usage(); + if (strcmp(argv[a], "--blur")==0) { + ++a; --argc; + if (argc==0) usage(); - i = atoi(argv[2]); - if (i>1) ppem = i; - - font_path = argv[3]; + d = atof(argv[a]); + if (d>=0 && d<20) radius = d; + else WARNING("using default blur radius."); + ++a; --argc; + } - if (argc>4) { - d = atof(argv[4]); - if (d>0.001 && d<1000.) alpha_factor = d; - else WARNING("alphaFactor set to default.",NULL); + if (argc==0) usage(); + if (strcmp(argv[a], "--outline")==0) { + ++a; --argc; + if (argc==0) usage(); + + d = atof(argv[a]); + if (d>=0 && d<20) thickness = d; + else WARNING("using default outline thickness."); + ++a; --argc; } - if (argc>5) { - d = atof(argv[5]); - if (d>0.1 && d<=maxcolor) minalpha = d; - else WARNING("minAlpha set to default.",NULL); - } - if (argc>6) { - i = atoi(argv[6]); - if (i>=0 && i<20) radius = i; - else WARNING("radius set to default.",NULL); - } + + if (argc<3) usage(); + + if (argv[a][0]!=0) + encoding = argv[a]; + ++a; --argc; + + i = atoi(argv[a]); + if (i>1) ppem = i; + ++a; --argc; + + font_path = argv[a]; + ++a; --argc; } + int main(int argc, char **argv) { parse_args(argc, argv); + padding = ceil(radius) + ceil(thickness); prepare_charset(); render(); - blur(); + alpha(); write_bitmap(); free(buffer); free(abuffer); - puts( - "\n" - "*****************************************\n" - "* Remember to run: *\n" - "* cat font.desc.tail >> font.desc *\n" - "*****************************************" - ); - +// fflush(stderr); return 0; }