mirror of https://github.com/mpv-player/mpv
upgraded to 1.0b version by Artur Zaprzala <artur.zaprzala@talex.com.pl>
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@1506 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
8632ea0526
commit
1aef871541
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
gunzip -c /usr/share/i18n/charmaps/EUC-KR.gz | ./charmap2enc > euc-kr
|
|
@ -0,0 +1,3 @@
|
|||
Requires t1utils and python.
|
||||
|
||||
Based on font created by chass.
|
|
@ -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"""
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -16,53 +16,72 @@
|
|||
#include <iconv.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
|
||||
|
||||
#ifndef OLD_FREETYPE2
|
||||
|
||||
#if 0 /* freetype 2.0.1 */
|
||||
#include <freetype/freetype.h>
|
||||
#else /* freetype 2.0.3 */
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#endif
|
||||
|
||||
#include FT_GLYPH_H
|
||||
|
||||
#else /* freetype 2.0.1 */
|
||||
|
||||
#include <freetype/freetype.h>
|
||||
#include <freetype/ftglyph.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
|
||||
#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 */
|
||||
//// 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 */
|
||||
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;
|
||||
int radius = 2; /* blur radius */
|
||||
double minalpha = 1.0; /* good value for minalpha is 0.5 */
|
||||
double alpha_factor = 1.0;
|
||||
|
||||
int const first_char = 33;
|
||||
int const charset_size = 256;
|
||||
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 = NULL;
|
||||
/*char *font_metrics = NULL;*/
|
||||
char *font_path;
|
||||
//char *font_metrics;
|
||||
int append_mode = 0;
|
||||
|
||||
|
||||
unsigned char *buffer;
|
||||
unsigned char *ebuffer; // temporary buffer for alphamap creation (edges)
|
||||
unsigned char *abuffer;
|
||||
unsigned char *buffer, *abuffer;
|
||||
int width, height;
|
||||
static FT_ULong ustring[256];
|
||||
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 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_(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)
|
||||
|
||||
#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 @@ void paste_bitmap(FT_Bitmap *bitmap, int x, int y) {
|
|||
buffer[drow+dp] = bitmap->buffer[srow+sp];
|
||||
}
|
||||
|
||||
|
||||
void write_header(FILE *f) {
|
||||
static unsigned char header[800] = "mhwanh";
|
||||
int i;
|
||||
|
@ -91,6 +111,7 @@ void write_header(FILE *f) {
|
|||
fwrite(header, 1, 800, f);
|
||||
}
|
||||
|
||||
|
||||
void write_bitmap() {
|
||||
FILE *f;
|
||||
int const max_name = 128;
|
||||
|
@ -98,38 +119,40 @@ void write_bitmap() {
|
|||
|
||||
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 @@ void render() {
|
|||
*/
|
||||
|
||||
|
||||
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 @@ void render() {
|
|||
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 @@ void render() {
|
|||
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];
|
||||
|
||||
if (character==0)
|
||||
glyph_index = 0;
|
||||
else {
|
||||
glyph_index = FT_Get_Char_Index(face, uni_charmap ? character:code);
|
||||
if (glyph_index==0)
|
||||
continue;
|
||||
}
|
||||
|
||||
glyph_index = FT_Get_Char_Index(face, ustring[i]);
|
||||
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;
|
||||
|
||||
for (i = first_char; i<charset_size; ++i) text[i-first_char] = 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);
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
|
||||
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);
|
||||
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;
|
||||
|
||||
iconv_close(cd);
|
||||
} else {
|
||||
unsigned int character, code;
|
||||
int count;
|
||||
|
||||
eprintf("Reading custom encoding from file '%s'.\n", encoding);
|
||||
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (charset_size==0) ERROR("No characters to render!");
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
int i, x, y, mx, my;
|
||||
unsigned char *m = (unsigned char*)malloc(w*w);
|
||||
// general outline
|
||||
void outline(
|
||||
unsigned char *s,
|
||||
unsigned char *t,
|
||||
int width,
|
||||
int height,
|
||||
int *m,
|
||||
int r,
|
||||
int mwidth) {
|
||||
|
||||
if (m==NULL) ERROR("malloc failed",NULL);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
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;
|
||||
}
|
||||
// printf("\n");
|
||||
}
|
||||
|
||||
free(m);
|
||||
/* 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]);
|
||||
}
|
||||
if (DEBUG) eprintf("\n");
|
||||
}
|
||||
if (DEBUG) eprintf("\n");
|
||||
|
||||
|
||||
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];
|
||||
|
||||
i = atoi(argv[2]);
|
||||
if (argc==0) usage();
|
||||
if (strcmp(argv[a], "--blur")==0) {
|
||||
++a; --argc;
|
||||
if (argc==0) usage();
|
||||
|
||||
d = atof(argv[a]);
|
||||
if (d>=0 && d<20) radius = d;
|
||||
else WARNING("using default blur radius.");
|
||||
++a; --argc;
|
||||
}
|
||||
|
||||
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<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[3];
|
||||
|
||||
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>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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue