From 9fc357b8a1cd0abd559848313db51c076c1ff849 Mon Sep 17 00:00:00 2001 From: Emily Eisenberg Date: Wed, 14 Aug 2013 10:51:09 -0700 Subject: [PATCH] Add italic correction Summary: Add margin to the right of characters that have italic correction. Test Plan: Look at `f'` and `C'` before and after. Note that they both now look good at small font sizes (like 17pt). Reviewers: alpert Reviewed By: alpert Differential Revision: http://phabricator.khanacademy.org/D3534 --- buildTree.js | 12 ++- fontMetrics.js | 197 +++++++++++++++++++++++++++++++++++++++- metrics/metric_parse.py | 14 ++- 3 files changed, 218 insertions(+), 5 deletions(-) diff --git a/buildTree.js b/buildTree.js index 40ec08a..583cce3 100644 --- a/buildTree.js +++ b/buildTree.js @@ -442,7 +442,17 @@ var makeText = function(value, style) { var metrics = fontMetrics.getCharacterMetrics(value, style); if (metrics) { - return new domTree.textNode(value, metrics.height, metrics.depth); + var textNode = new domTree.textNode(value, metrics.height, + metrics.depth); + if (metrics.italicCorrection > 0) { + var span = makeSpan([], [textNode]); + + span.style["margin-right"] = metrics.italicCorrection + "em"; + + return span; + } else { + return textNode; + } } else { console && console.warn("No character metrics for '" + value + "' in style '" + style + "'"); diff --git a/fontMetrics.js b/fontMetrics.js index c9143fc..9cecb43 100644 --- a/fontMetrics.js +++ b/fontMetrics.js @@ -66,6 +66,115 @@ var metrics = { // This map is generated by metrics/metric_parse.py var metricMap = { "roman": { + "italicCorrection": { + "\u2218": 0.0, + "\u03a5": 0.0, + "$": 0.0, + "\u03a9": 0.0, + "(": 0.0, + ",": 0.0, + "0": 0.0, + "4": 0.0, + "8": 0.0, + "<": 0.0, + "@": 0.0, + "D": 0.0, + "H": 0.0, + "L": 0.0, + "P": 0.0, + "T": 0.0, + "\u00d7": 0.0, + "X": 0.0, + "\u2264": 0.0, + "`": 0.0, + "d": 0.0, + "h": 0.0, + "l": 0.0, + "p": 0.0, + "t": 0.0, + "\u00f7": 0.0, + "x": 0.0, + "|": 0.0, + "\u2192": 0.0, + "\u2217": 0.0, + "\u039e": 0.0, + "\u00a0": 0.0, + "\u03a6": 0.0, + "+": 0.0, + "/": 0.0, + "3": 0.0, + "7": 0.0, + ";": 0.0, + "?": 0.0, + "C": 0.0, + "G": 0.0, + "K": 0.0, + "O": 0.0, + "S": 0.0, + "W": 0.0, + "[": 0.0, + "c": 0.0, + "g": 0.0, + "\u2032": 0.0, + "k": 0.0, + "o": 0.0, + "s": 0.0, + "w": 0.0, + "\u0393": 0.0, + "\u2212": 0.0, + "\u039b": 0.0, + "\u221e": 0.0, + "\u03a3": 0.0, + "\"": 0.0, + ".": 0.0, + "\u00b1": 0.0, + "2": 0.0, + "6": 0.0, + ":": 0.0, + ">": 0.0, + "B": 0.0, + "\u22c5": 0.0, + "F": 0.0, + "J": 0.0, + "N": 0.0, + "R": 0.0, + "V": 0.0, + "\u2265": 0.0, + "Z": 0.0, + "b": 0.0, + "f": 0.052, + "j": 0.0, + "n": 0.0, + "r": 0.0, + "v": 0.0, + "z": 0.0, + "\u2190": 0.0, + "\u0394": 0.0, + "\u0398": 0.0, + "!": 0.0, + "\u03a0": 0.0, + ")": 0.0, + "\u03a8": 0.0, + "1": 0.0, + "5": 0.0, + "9": 0.0, + "=": 0.0, + "A": 0.0, + "E": 0.0, + "I": 0.0, + "M": 0.0, + "Q": 0.0, + "U": 0.0, + "Y": 0.0, + "]": 0.0, + "a": 0.0, + "e": 0.0, + "i": 0.0, + "m": 0.0, + "q": 0.0, + "u": 0.0, + "y": 0.0 + }, "depth": { "\u2218": 0.0, "\u03a5": 0.0, @@ -286,14 +395,98 @@ var metricMap = { } }, "slanted": { + "italicCorrection": {}, "depth": {}, "height": {} }, "bold": { + "italicCorrection": {}, "depth": {}, "height": {} }, "italic": { + "italicCorrection": { + "A": 0.0, + "V": 0.186, + "C": 0.046, + "B": 0.0, + "x": 0.0, + "E": 0.026, + "D": 0.0, + "q": 0.006, + "G": 0.0, + "F": 0.106, + "\u03b1": 0.0, + "I": 0.058, + "\u03b3": 0.026, + "\u03b2": 0.01, + "\u03b5": 0.0, + "\u03b4": 0.008, + "\u03b7": 0.0, + "\u03b6": 0.037, + "\u03b9": 0.0, + "\u03b8": 0.0, + "\u03bb": 0.0, + "\u03ba": 0.0, + "\u03bd": 0.031, + "\u03bc": 0.0, + "\u03be": 0.009, + "\u03c1": 0.0, + "\u03c0": 0.0, + "\u03c3": 0.0, + "\u03c2": 0.047, + "\u03c5": 0.0, + "\u03c4": 0.074, + "\u03c7": 0.0, + "\u03c6": 0.0, + "\u03c9": 0.0, + "\u03c8": 0.0, + "K": 0.04, + "J": 0.079, + "M": 0.074, + "L": 0.0, + "O": 0.0, + "N": 0.078, + "\u03d1": 0.0, + "P": 0.112, + "S": 0.032, + "R": 0.0, + "\u03d5": 0.0, + "T": 0.12, + "W": 0.104, + "\u03d6": 0.0, + "Y": 0.182, + "X": 0.023, + "w": 0.0, + "Z": 0.041, + "a": 0.0, + "Q": 0.0, + "c": 0.0, + "b": 0.0, + "e": 0.0, + "d": 0.0, + "g": 0.0, + "f": 0.063, + "i": 0.0, + "h": 0.0, + "k": 0.0, + "j": 0.0, + "m": 0.0, + "l": 0.0, + "o": 0.0, + "n": 0.0, + "\u03f1": 0.0, + "p": 0.0, + "s": 0.0, + "r": 0.0, + "u": 0.0, + "t": 0.0, + "H": 0.05, + "v": 0.0, + "y": 0.0, + "U": 0.078, + "z": 0.002 + }, "depth": { "A": 0.0, "V": 0.022, @@ -460,6 +653,7 @@ var metricMap = { } }, "typewriter": { + "italicCorrection": {}, "depth": {}, "height": {} } @@ -469,7 +663,8 @@ var getCharacterMetrics = function(character, style) { if (character in metricMap[style].height) { return { height: metricMap[style].height[character], - depth: metricMap[style].depth[character] + depth: metricMap[style].depth[character], + italicCorrection: metricMap[style].italicCorrection[character] }; } else { return null; diff --git a/metrics/metric_parse.py b/metrics/metric_parse.py index 14e43b8..41d8ce4 100755 --- a/metrics/metric_parse.py +++ b/metrics/metric_parse.py @@ -43,10 +43,11 @@ def read_pl(pl_file): class Metric: - def __init__(self, char, height, depth): + def __init__(self, char, height, depth, italic_correction): self.char = char self.height = float(height) / 1000 self.depth = float(depth) / 1000 + self.italic_correction = float(italic_correction) / 1000 def __repr__(self): return "Char {0} ({1:.3f}+{2:.3f})".format( @@ -281,6 +282,7 @@ def read_metrics(pl_file, metrics): char_height = 0 char_depth = 0 + italic_correction = 0 for metric in elem[3:]: if metric[0] == "comment": @@ -289,9 +291,12 @@ def read_metrics(pl_file, metrics): char_height = int(metric[2]) elif metric[0] == "CHARDP": char_depth = int(metric[2]) + elif metric[0] == "CHARIC": + italic_correction = int(metric[2]) metrics[map_style].append( - Metric(map_char, char_height, char_depth)) + Metric(map_char, char_height, char_depth, + italic_correction)) def print_metrics(metrics): @@ -303,6 +308,9 @@ def print_metrics(metrics): "depth": { metric.char: metric.depth for metric in metric_list }, + "italicCorrection": { + metric.char: metric.italic_correction for metric in metric_list + }, } for style, metric_list in metrics.iteritems() } @@ -323,6 +331,6 @@ if __name__ == "__main__": for metric_file in file_map: read_metrics(metric_file, metrics) - metrics["roman"].append(Metric(u'\u00a0', 0, 0)) + metrics["roman"].append(Metric(u'\u00a0', 0, 0, 0)) print_metrics(metrics)