Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add table overrides, add ASCII aliases, fix typos, fix character orientation to match paper tape specification, and add tape edge lines. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
f19c56a4b901b417f861d1733cd85080 |
User & Date: | Ross 2016-03-15 00:02:49 |
Context
2016-03-19
| ||
02:35 | Add support for additional raw XML tables provided by a dotfont file. This is experimental and will change. It is demonstrated in sevensegmentextended.dotfont as a way to provide teh kerning table. check-in: e68ddc1529 user: Ross tags: trunk | |
2016-03-15
| ||
00:02 | Add table overrides, add ASCII aliases, fix typos, fix character orientation to match paper tape specification, and add tape edge lines. check-in: f19c56a4b9 user: Ross tags: trunk | |
2016-03-10
| ||
21:22 | Pick up circle definition as improved for the punched paper tape font. Adjust Makefile to have sensible targets, and to build TTF files for each demo font by default. check-in: 5322fb3e47 user: Ross tags: trunk | |
Changes
Changes to src/dotfonter.lua.
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 78 | if glyph.mac then ttfont.MapGlyph("mac", glyph.mac, glyph.name) end ttfont.MapGlyph("win", glyph.win, glyph.name) n = n + 1 end V('placed: 4 system glyphs and ', n, ' defined glyphs, total ', n+4, '.') --[[ Set the strings. Note that ffam, fsub, ufid, name, vers, and PSnm are required by Windows. Of those, fsub defaults to 'Regular' and name gets a sensible defaults based on ffam and fsub. | > > > > > > > > > | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | if glyph.mac then ttfont.MapGlyph("mac", glyph.mac, glyph.name) end ttfont.MapGlyph("win", glyph.win, glyph.name) n = n + 1 end V('placed: 4 system glyphs and ', n, ' defined glyphs, total ', n+4, '.') if dotfont.ASCIIAliasBase then ttfont.MapASCIIAliases("unicode", dotfont.ASCIIAliasBase) ttfont.MapASCIIAliases("mac", dotfont.ASCIIAliasBase) ttfont.MapASCIIAliases("win", dotfont.ASCIIAliasBase) V('aliased ASCII printable characters.') end --[[ Set the strings. Note that ffam, fsub, ufid, name, vers, and PSnm are required by Windows. Of those, fsub defaults to 'Regular' and name gets a sensible defaults based on ffam and fsub. |
︙ | ︙ | |||
86 87 88 89 90 91 92 | V(("%0.f: %q"):format(i, names[i])) end end end -- get the finished font and write it as TTX | | | 95 96 97 98 99 100 101 102 103 104 105 | V(("%0.f: %q"):format(i, names[i])) end end end -- get the finished font and write it as TTX local font = ttfont.GetFont(dotfont.Overrides) --print(font) font:save(args.basename .. ".ttx") V('wrote: ', args.basename, '.ttx') |
Changes to src/papertape.dotfont.
︙ | ︙ | |||
60 61 62 63 64 65 66 | local holes = { data = circle(37,51,51), timing = circle(23,51,51) } local function hole(n,h) local t={} | | | | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | local holes = { data = circle(37,51,51), timing = circle(23,51,51) } local function hole(n,h) local t={} local no = math.floor(n*102.4+51.2+0.5) for i=1,#h do t[i] = { h[i][1], h[i][2]+no, h[i][3] } end return t end -- Normalize a a glyph. -- Create an array of countours from its pat entry and provide defaults -- for metrics, name, and character codes. local function Glyph(t) assert(type(t)=='table') local pat = assert(t.pat) -- default metrics |
︙ | ︙ | |||
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | t[#t+1] = hole(3, holes.timing) for bit=0,7 do if n%2 == 1 then t[#t+1] = hole(bit > 2 and bit+1 or bit, holes.data) end n = math.floor(n / 2) end if t.unicode == 0xEE00 then t.lsb = 28 end return t end --[[ ##Punched Paper Tape Glyphs are layed out so that the least bit is at the top, or the tape is read from left to right. --]] | > > > > > > > > < < < < < < < < < < < < < | | | | > | | > > > > > > > > > > > > > > > | > | > > > > > > > > > > > > > > > > > > | > > > | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | t[#t+1] = hole(3, holes.timing) for bit=0,7 do if n%2 == 1 then t[#t+1] = hole(bit > 2 and bit+1 or bit, holes.data) end n = math.floor(n / 2) end -- correct LSB on code 0 if t.unicode == 0xEE00 then t.lsb = 28 end -- add tape edges with LSB to match t[#t+1] = {{-2,0},{-2,8},{105,8},{105,0}} t[#t+1] = {{-2,1016},{-2,1024},{105,1024},{105,1016}} t.lsb = -2 return t end --[[ ##Punched Paper Tape Glyphs are layed out so that the least bit is at the top, or the tape is read from left to right. --]] local Glyphs = {} for i=0,255,1 do local c = Glyph{unicode=0xee00+i, name=("uniEE%02X"):format(i), pat=i} Glyphs[#Glyphs+1] = c end return { Glyphs = Glyphs, ASCIIAliasBase = 0xee00, --[[ Set the strings. Note that ffam, fsub, ufid, name, vers, and PSnm are required by Windows. Of those, fsub defaults to 'Regular' and name gets a sensible defaults based on ffam and fsub. --]] Names = { copy='Copyright Ross Berteig 2016.', ffam='Punched Paper Tape LtR', PSnm='PunchedPaperTapeLtR-Regular', ufid='Punched Paper Tape LtR '.. os.date"%Y-%m-%d" , vers='Version 001.005', desc=[[ Each code point in range U+EE00 to U+EEFF (in the Unicode Private Use Area) maps to a glyph showing a single row of punched paper tape with that byte punched. The rows are layed out with the reference tape edge at the bottom, and if presented bytes in the order they are to be read from tape, the image will be of the reference face of a tape fed from left to right. ]], lice=[[ This font is licensed under the Creative Commons Attribution 4.0 International License. (CC-BY) ]], URLl='https://creativecommons.org/licenses/by/4.0/', URLv='http://curioser.cheshireeng.com/', URLd='http://curioser.cheshireeng.com/category/projects/dotfonter/', desi='Ross Berteig', --demo='', }, Overrides = { OS_2 = { xAvgCharWidth = "103", ulUnicodeRange1 = "00000000 00000000 00000000 00000001", ulUnicodeRange2 = "00010000 00000000 00000000 00000000", -- Private use area ulCodePageRange1 = "00000000 00000000 00000000 00000001", }, head = { xMax = "103" }, hhea = { descent = -1 }, hmtx = { [1] = { width = 103 }, -- override width of .notdef [3] = { width = 103 }, -- override width of nonmarkingreturn [4] = { width = 103 }, -- override width of space }, } } |
Changes to src/ttfhead.lua.
︙ | ︙ | |||
43 44 45 46 47 48 49 | M.lowestRecPPEM = 8 M.fontDirectionHint = 2 M.indexToLocFormat = 0 M.glyphDataFormat = 0 M.created = "Sun Feb 27 14:41:58 2011" M.modified = M.created | | > > > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | M.lowestRecPPEM = 8 M.fontDirectionHint = 2 M.indexToLocFormat = 0 M.glyphDataFormat = 0 M.created = "Sun Feb 27 14:41:58 2011" M.modified = M.created function M.SetRevisions(version) local v = version:match"%d+.%d+" if v then M.fontRevision = v end M.modified = os.date"!%a %b %d %H:%M:%S %Y" end function M.GetTable() return ttx.buildTable("head",{ 'tableVersion','fontRevision','checkSumAdjustment','magicNumber', 'flags','unitsPerEm','created','modified','xMin','yMin','xMax','yMax','macStyle', 'lowestRecPPEM','fontDirectionHint','indexToLocFormat','glyphDataFormat'}, M) |
︙ | ︙ |
Changes to src/ttfname.lua.
1 2 3 4 5 6 7 8 9 10 11 12 | --[[ #TTF name table This is where all the text metadata about the font lives, and often in multiple copies for each string. Also possibly in multiple languages, but this code isn't explicitly supporting that. The strings are identified by an unsigned short value that the TTF spec calls an "index". But it is normal for some indeces to be missing. I haven't found a clear statement of which strings are mandatory, and that might be platform and consuming application dependent. | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | --[[ #TTF name table This is where all the text metadata about the font lives, and often in multiple copies for each string. Also possibly in multiple languages, but this code isn't explicitly supporting that. The strings are identified by an unsigned short value that the TTF spec calls an "index". But it is normal for some indeces to be missing. I haven't found a clear statement of which strings are mandatory, and that might be platform and consuming application dependent. Indices 1, 2, 3, 4, 6, 16, 17, 18 and 20 are all clearly intended to be seen or used by end users to choose this font by name. Index 19 ought to be used by anything that presents font specimins, but testing shows that Windows ignores it. According to [this answer at Stack Overflow](http://stackoverflow.com/a/21815641/68204) strings 3 and 6 are mandatory for a font to be installed (or even Previewed) in Windows, which was not clear from any text in any of the TTF or OTF documentation. |
︙ | ︙ |
Changes to src/ttfont.lua.
︙ | ︙ | |||
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | local ttfpost = require 'ttfpost' local ttfos_2 = require 'ttfos_2' M.maxX, M.minX, M.maxY, M.minY = 0,0,0,0 M.perEm = 1024 M.head = ttfhead M.hhea = ttfhhea local tables = {} -- Rember the order glyphs get created so that the TTF file -- will define them in the same order. This works by using the -- table GlyphOrder defined by TTX for the purpose tables.GlyphOrder = X"GlyphOrder" tables.nextid = 0 -- Horizontal metrics for each glyph. tables.hmtx = X"hmtx" -- Glyph outlines for each glyph, along with an empty -- index table that will be entirely filled by the -- TTX to TTF compiler tables.loca = X"loca" tables.glyf = X"glyf" | > > > > > > > > > | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | local ttfpost = require 'ttfpost' local ttfos_2 = require 'ttfos_2' M.maxX, M.minX, M.maxY, M.minY = 0,0,0,0 M.perEm = 1024 M.head = ttfhead M.hhea = ttfhhea local tables = {} -- Rember the order glyphs get created so that the TTF file -- will define them in the same order. This works by using the -- table GlyphOrder defined by TTX for the purpose tables.GlyphOrder = X"GlyphOrder" tables.nextid = 0 -- Horizontal metrics for each glyph. tables.hmtx = X"hmtx" -- Tables that can have entries overridden local overridable = { head = ttfhead, hhea = ttfhhea, OS_2 = ttfos_2, hmtx = tables.hmtx, } -- Glyph outlines for each glyph, along with an empty -- index table that will be entirely filled by the -- TTX to TTF compiler tables.loca = X"loca" tables.glyf = X"glyf" |
︙ | ︙ | |||
138 139 140 141 142 143 144 | {896, 0}, }, contour{ {192, 64}, {832, 64}, {832, 704}, {192, 704}, | | | | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | {896, 0}, }, contour{ {192, 64}, {832, 64}, {832, 704}, {192, 704}, }, --[[ contour{ {128, 45}, {851, 768}, {896, 723}, {183, 0}, }, contour{ {128, 723}, {183, 768}, {896, 45}, {851, 0}, }, --]] xml.new{[0]='instructions',xml.new'assembly'}, } -- an empty glyph. local nullglyph = xml.new{[0]="TTGlyph", name=".null" } local crglyph = xml.new{[0]="TTGlyph", name="nonmarkingreturn" } local spaceglyph = xml.new{[0]="TTGlyph", name="space" } |
︙ | ︙ | |||
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | map = maps[map] or tonumber(map) if not map then error"map not valid" end if map >= 2 and map <= 4 then setname(map, code, name) end end tables.name = ttfname.BuildNameTable{ copy='Copyright Lloyd Fingal 2015.', ufid='xyzzy', ffam='Sample Silly Script', PSnm='SampleSillyScript-Regular', --[=[ [1024]=[[ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. ]] --]=] } | > > > > > > > > > > > > < | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | map = maps[map] or tonumber(map) if not map then error"map not valid" end if map >= 2 and map <= 4 then setname(map, code, name) end end function M.MapASCIIAliases(map, base) local maps = {unicode=2, mac=3, win=4} map = maps[map] or tonumber(map) if not map then error"map not valid" end for ascii=0x21,0x7e do local name = ("uni%04X"):format(base+ascii) if map >= 2 and map <= 4 then setname(map, ascii, name) end end end tables.name = ttfname.BuildNameTable{ copy='Copyright Lloyd Fingal 2015.', ufid='xyzzy', ffam='Sample Silly Script', PSnm='SampleSillyScript-Regular', --[=[ [1024]=[[ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. ]] --]=] } local names function M.SetNames(t) tables.name, names = ttfname.BuildNameTable(t) return names end function M.GetFont(overrides) ttfhead.xMin = M.minX ttfhead.yMin = M.minY ttfhead.xMax = M.maxX ttfhead.yMax = M.maxY ttfhhea.ascent = M.maxY ttfos_2.sTypoAscender = M.maxY ttfos_2.usWinAscent = M.maxY ttfhhea.descent = M.minY ttfos_2.sTypoDescender = M.minY ttfos_2.usWinDescent = math.abs(M.minY) ttfhhea.xMaxExtent = M.maxX ttfhhea.lineGap = 128 ttfos_2.sTypoLineGap = 128 ttfhead.SetRevisions(names[5]) if overrides then for k,v in pairs(overrides) do local t = overridable[k] if t then for k,v in pairs(v) do local node = t[k] if node then if type(node)=='string' then t[k] = tostring(v) elseif type(node)=='number' then t[k] = tonumber(v) elseif type(v)=='table' and type(node)=='table' then for k,v in pairs(v) do node[k] = v end else --can't override if V then V("Can't override ", type(node), " with ", type(v), "\n") end end end end end end end tables.head = ttfhead.GetTable() tables.hhea = ttfhhea.GetTable() tables.maxp = ttfmaxp.GetTable() tables.post = ttfpost.GetTable() tables.OS_2 = ttfos_2.GetTable() if not tables.loca then tables.loca = xml.new"loca" end --[[ if not tables.gasp then tables.gasp = xml.new"gasp" end tables.gasp:append(xml.new{[0]="gaspRange", rangeMaxPPEM=65535, rangeGaspBehavior=2}) --]] local font = xml.new{[0]="ttFont", sfntVersion="\\x00\\x01\\x00\\x00", ttLibVersion="3.0"} for _,tn in ipairs{'GlyphOrder','head','hhea','maxp', 'OS_2','hmtx','cmap','loca','glyf','name','post', 'gasp'} do if tables[tn] then font:append(tables[tn]) end end return font end return M |