From a84fa13189caa866c6fee5263409bebb391cb77b Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Mon, 9 Jan 2012 19:36:24 -0600 Subject: [PATCH 1/4] using font flags to recognize the symbol and serif fonts; using the encoding instead of predefined MacRoman in TrueType fonts --- src/canvas.js | 2 +- src/fonts.js | 58 ++++++--------------------------------------------- 2 files changed, 7 insertions(+), 53 deletions(-) diff --git a/src/canvas.js b/src/canvas.js index 3fd55b45d..0ad02dc24 100644 --- a/src/canvas.js +++ b/src/canvas.js @@ -557,7 +557,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { (fontObj.bold ? 'bold' : 'normal'); var italic = fontObj.italic ? 'italic' : 'normal'; - var serif = fontObj.serif ? 'serif' : 'sans-serif'; + var serif = fontObj.isSerifFont ? 'serif' : 'sans-serif'; var typeface = '"' + name + '", ' + serif; var rule = italic + ' ' + bold + ' ' + size + 'px ' + typeface; this.ctx.font = rule; diff --git a/src/fonts.js b/src/fonts.js index 1b959d6c2..389f0810d 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -339,53 +339,6 @@ var stdFontMap = { 'TimesNewRomanPSMT-Italic': 'Times-Italic' }; -var serifFonts = { - 'Adobe Jenson': true, 'Adobe Text': true, 'Albertus': true, - 'Aldus': true, 'Alexandria': true, 'Algerian': true, - 'American Typewriter': true, 'Antiqua': true, 'Apex': true, - 'Arno': true, 'Aster': true, 'Aurora': true, - 'Baskerville': true, 'Bell': true, 'Bembo': true, - 'Bembo Schoolbook': true, 'Benguiat': true, 'Berkeley Old Style': true, - 'Bernhard Modern': true, 'Berthold City': true, 'Bodoni': true, - 'Bauer Bodoni': true, 'Book Antiqua': true, 'Bookman': true, - 'Bordeaux Roman': true, 'Californian FB': true, 'Calisto': true, - 'Calvert': true, 'Capitals': true, 'Cambria': true, - 'Cartier': true, 'Caslon': true, 'Catull': true, - 'Centaur': true, 'Century Old Style': true, 'Century Schoolbook': true, - 'Chaparral': true, 'Charis SIL': true, 'Cheltenham': true, - 'Cholla Slab': true, 'Clarendon': true, 'Clearface': true, - 'Cochin': true, 'Colonna': true, 'Computer Modern': true, - 'Concrete Roman': true, 'Constantia': true, 'Cooper Black': true, - 'Corona': true, 'Ecotype': true, 'Egyptienne': true, - 'Elephant': true, 'Excelsior': true, 'Fairfield': true, - 'FF Scala': true, 'Folkard': true, 'Footlight': true, - 'FreeSerif': true, 'Friz Quadrata': true, 'Garamond': true, - 'Gentium': true, 'Georgia': true, 'Gloucester': true, - 'Goudy Old Style': true, 'Goudy Schoolbook': true, 'Goudy Pro Font': true, - 'Granjon': true, 'Guardian Egyptian': true, 'Heather': true, - 'Hercules': true, 'High Tower Text': true, 'Hiroshige': true, - 'Hoefler Text': true, 'Humana Serif': true, 'Imprint': true, - 'Ionic No. 5': true, 'Janson': true, 'Joanna': true, - 'Korinna': true, 'Lexicon': true, 'Liberation Serif': true, - 'Linux Libertine': true, 'Literaturnaya': true, 'Lucida': true, - 'Lucida Bright': true, 'Melior': true, 'Memphis': true, - 'Miller': true, 'Minion': true, 'Modern': true, - 'Mona Lisa': true, 'Mrs Eaves': true, 'MS Serif': true, - 'Museo Slab': true, 'New York': true, 'Nimbus Roman': true, - 'NPS Rawlinson Roadway': true, 'Palatino': true, 'Perpetua': true, - 'Plantin': true, 'Plantin Schoolbook': true, 'Playbill': true, - 'Poor Richard': true, 'Rawlinson Roadway': true, 'Renault': true, - 'Requiem': true, 'Rockwell': true, 'Roman': true, - 'Rotis Serif': true, 'Sabon': true, 'Scala': true, - 'Seagull': true, 'Sistina': true, 'Souvenir': true, - 'STIX': true, 'Stone Informal': true, 'Stone Serif': true, - 'Sylfaen': true, 'Times': true, 'Trajan': true, - 'Trinité': true, 'Trump Mediaeval': true, 'Utopia': true, - 'Vale Type': true, 'Bitstream Vera': true, 'Vera Serif': true, - 'Versailles': true, 'Wanted': true, 'Weiss': true, - 'Wide Latin': true, 'Windsor': true, 'XITS': true -}; - var FontLoader = { listeningForFontLoad: false, @@ -742,7 +695,8 @@ var Font = (function FontClosure() { var names = name.split('+'); names = names.length > 1 ? names[1] : names[0]; names = names.split(/[-,_]/g)[0]; - this.serif = serifFonts[names] || (name.search(/serif/gi) != -1); + this.isSerifFont = !!(properties.flags & 2); + this.isSymbolicFont = !!(properties.flags & 4); var type = properties.type; this.type = type; @@ -750,7 +704,7 @@ var Font = (function FontClosure() { // If the font is to be ignored, register it like an already loaded font // to avoid the cost of waiting for it be be loaded by the platform. if (properties.ignore) { - this.loadedName = this.serif ? 'serif' : 'sans-serif'; + this.loadedName = this.isSerifFont ? 'serif' : 'sans-serif'; this.loading = false; return; } @@ -2184,12 +2138,12 @@ var Font = (function FontClosure() { unicode = GlyphsUnicode[glyphName] || charcode; break; } - if (!this.hasEncoding) { + if (!this.hasEncoding || this.isSymbolicFont) { unicode = this.useToUnicode ? this.toUnicode[charcode] : charcode; break; } - if (this.hasShortCmap && false) { - var j = Encodings.MacRomanEncoding.indexOf(glyphName); + if (this.hasShortCmap) { + var j = this.encoding.indexOf(glyphName); unicode = j >= 0 ? j : this.glyphNameMap[glyphName]; } else { From 550819b8298ab48df53e2c571f73ec4870f1c95e Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Mon, 9 Jan 2012 21:15:18 -0600 Subject: [PATCH 2/4] fix serif and symbol attribute detection for standard fonts --- src/evaluator.js | 7 +++++++ src/fonts.js | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/evaluator.js b/src/evaluator.js index 198659201..60ab66560 100644 --- a/src/evaluator.js +++ b/src/evaluator.js @@ -758,10 +758,17 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { baseFontName = baseFontName.name.replace(/[,_]/g, '-'); var metrics = this.getBaseFontMetrics(baseFontName); + // Simulating descriptor flags attribute + var fontNameWoStyle = baseFontName.split('-')[0]; + var flags = (serifFonts[fontNameWoStyle] || + (fontNameWoStyle.search(/serif/gi) != -1) ? 2 : 0) | + (symbolsFonts[fontNameWoStyle] ? 4 : 32); + var properties = { type: type.name, widths: metrics.widths, defaultWidth: metrics.defaultWidth, + flags: flags, firstChar: 0, lastChar: maxCharIndex }; diff --git a/src/fonts.js b/src/fonts.js index 389f0810d..4950a844a 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -339,6 +339,57 @@ var stdFontMap = { 'TimesNewRomanPSMT-Italic': 'Times-Italic' }; +var serifFonts = { + 'Adobe Jenson': true, 'Adobe Text': true, 'Albertus': true, + 'Aldus': true, 'Alexandria': true, 'Algerian': true, + 'American Typewriter': true, 'Antiqua': true, 'Apex': true, + 'Arno': true, 'Aster': true, 'Aurora': true, + 'Baskerville': true, 'Bell': true, 'Bembo': true, + 'Bembo Schoolbook': true, 'Benguiat': true, 'Berkeley Old Style': true, + 'Bernhard Modern': true, 'Berthold City': true, 'Bodoni': true, + 'Bauer Bodoni': true, 'Book Antiqua': true, 'Bookman': true, + 'Bordeaux Roman': true, 'Californian FB': true, 'Calisto': true, + 'Calvert': true, 'Capitals': true, 'Cambria': true, + 'Cartier': true, 'Caslon': true, 'Catull': true, + 'Centaur': true, 'Century Old Style': true, 'Century Schoolbook': true, + 'Chaparral': true, 'Charis SIL': true, 'Cheltenham': true, + 'Cholla Slab': true, 'Clarendon': true, 'Clearface': true, + 'Cochin': true, 'Colonna': true, 'Computer Modern': true, + 'Concrete Roman': true, 'Constantia': true, 'Cooper Black': true, + 'Corona': true, 'Ecotype': true, 'Egyptienne': true, + 'Elephant': true, 'Excelsior': true, 'Fairfield': true, + 'FF Scala': true, 'Folkard': true, 'Footlight': true, + 'FreeSerif': true, 'Friz Quadrata': true, 'Garamond': true, + 'Gentium': true, 'Georgia': true, 'Gloucester': true, + 'Goudy Old Style': true, 'Goudy Schoolbook': true, 'Goudy Pro Font': true, + 'Granjon': true, 'Guardian Egyptian': true, 'Heather': true, + 'Hercules': true, 'High Tower Text': true, 'Hiroshige': true, + 'Hoefler Text': true, 'Humana Serif': true, 'Imprint': true, + 'Ionic No. 5': true, 'Janson': true, 'Joanna': true, + 'Korinna': true, 'Lexicon': true, 'Liberation Serif': true, + 'Linux Libertine': true, 'Literaturnaya': true, 'Lucida': true, + 'Lucida Bright': true, 'Melior': true, 'Memphis': true, + 'Miller': true, 'Minion': true, 'Modern': true, + 'Mona Lisa': true, 'Mrs Eaves': true, 'MS Serif': true, + 'Museo Slab': true, 'New York': true, 'Nimbus Roman': true, + 'NPS Rawlinson Roadway': true, 'Palatino': true, 'Perpetua': true, + 'Plantin': true, 'Plantin Schoolbook': true, 'Playbill': true, + 'Poor Richard': true, 'Rawlinson Roadway': true, 'Renault': true, + 'Requiem': true, 'Rockwell': true, 'Roman': true, + 'Rotis Serif': true, 'Sabon': true, 'Scala': true, + 'Seagull': true, 'Sistina': true, 'Souvenir': true, + 'STIX': true, 'Stone Informal': true, 'Stone Serif': true, + 'Sylfaen': true, 'Times': true, 'Trajan': true, + 'Trinité': true, 'Trump Mediaeval': true, 'Utopia': true, + 'Vale Type': true, 'Bitstream Vera': true, 'Vera Serif': true, + 'Versailles': true, 'Wanted': true, 'Weiss': true, + 'Wide Latin': true, 'Windsor': true, 'XITS': true +}; + +var symbolsFonts = { + 'Dingbats': true, 'Symbol': true, 'ZapfDingbats': true +}; + var FontLoader = { listeningForFontLoad: false, From 933be30c3a867ae3afca6fb1b03c741788f5a7d4 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Tue, 10 Jan 2012 19:41:45 -0600 Subject: [PATCH 3/4] Converting MacRoman symbols to Unicodes --- src/fonts.js | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/fonts.js b/src/fonts.js index 4950a844a..8f20deff9 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -835,7 +835,6 @@ var Font = (function FontClosure() { this.widthMultiplier = !properties.fontMatrix ? 1.0 : 1.0 / properties.fontMatrix[0]; this.encoding = properties.baseEncoding; - this.hasShortCmap = properties.hasShortCmap; this.loadedName = getUniqueName(); this.loading = true; }; @@ -1805,7 +1804,20 @@ var Font = (function FontClosure() { this.useToUnicode = true; } } - properties.hasShortCmap = hasShortCmap; + + if (hasShortCmap && this.hasEncoding && !this.isSymbolicFont) { + // Re-encode short map encoding to unicode -- that simplifies the + // resolution of MacRoman encoded glyphs logic for TrueType fonts. + for (var i = 0, ii = glyphs.length; i < ii; i++) { + var code = glyphs[i].unicode; + var glyphName = properties.baseEncoding[code]; + if (!glyphName) + continue; + if (!(glyphName in GlyphsUnicode)) + continue; + glyphs[i].unicode = GlyphsUnicode[glyphName]; + } + } // remove glyph references outside range of avaialable glyphs for (var i = 0, ii = ids.length; i < ii; i++) { @@ -2193,15 +2205,11 @@ var Font = (function FontClosure() { unicode = this.useToUnicode ? this.toUnicode[charcode] : charcode; break; } - if (this.hasShortCmap) { - var j = this.encoding.indexOf(glyphName); - unicode = j >= 0 ? j : - this.glyphNameMap[glyphName]; - } else { - unicode = glyphName in GlyphsUnicode ? - GlyphsUnicode[glyphName] : - this.glyphNameMap[glyphName]; - } + + // MacRoman encoding address by re-encoding the cmap table + unicode = glyphName in GlyphsUnicode ? + GlyphsUnicode[glyphName] : + this.glyphNameMap[glyphName]; break; default: warn('Unsupported font type: ' + this.type); From 09dfde69a285b547886c12539420673357726cb6 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Tue, 10 Jan 2012 22:01:24 -0600 Subject: [PATCH 4/4] Duplicate short map into private use area --- src/fonts.js | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/fonts.js b/src/fonts.js index 8f20deff9..329d7ad77 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -1807,15 +1807,27 @@ var Font = (function FontClosure() { if (hasShortCmap && this.hasEncoding && !this.isSymbolicFont) { // Re-encode short map encoding to unicode -- that simplifies the - // resolution of MacRoman encoded glyphs logic for TrueType fonts. + // resolution of MacRoman encoded glyphs logic for TrueType fonts: + // copying all characters to private use area, all mapping all known + // glyphs to the unicodes. The glyphs and ids arrays will grow. + var usedUnicodes = []; for (var i = 0, ii = glyphs.length; i < ii; i++) { var code = glyphs[i].unicode; + glyphs[i].unicode += kCmapGlyphOffset; + var glyphName = properties.baseEncoding[code]; - if (!glyphName) - continue; - if (!(glyphName in GlyphsUnicode)) - continue; - glyphs[i].unicode = GlyphsUnicode[glyphName]; + if (glyphName in GlyphsUnicode) { + var unicode = GlyphsUnicode[glyphName]; + if (unicode in usedUnicodes) + continue; + + usedUnicodes[unicode] = true; + glyphs.push({ + unicode: unicode, + code: glyphs[i].code + }); + ids.push(ids[i]); + } } }