关联glyf相关的信息
@param {Object} font font对象
542934
function resolveGlyf(font) {

            var codes = font.cmap;
            var glyf = font.CFF.glyf;
            var subsetMap = font.readOptions.subset ? font.subsetMap : null; // 当前ttf的子集列表
            // unicode
            Object.keys(codes).forEach(function (c) {
                var i = codes[c];
                if (subsetMap && !subsetMap[i]) {
                    return;
                }
                if (!glyf[i].unicode) {
                    glyf[i].unicode = [];
                }
                glyf[i].unicode.push(+c);
            });

            // leftSideBearing
            font.hmtx.forEach(function (item, i) {
                if (subsetMap && !subsetMap[i]) {
                    return;
                }
                glyf[i].advanceWidth = glyf[i].advanceWidth || item.advanceWidth || 0;
                glyf[i].leftSideBearing = item.leftSideBearing;
            });

            // 设置了subsetMap之后需要选取subset中的字形
            if (subsetMap) {
                var subGlyf = [];
                Object.keys(subsetMap).forEach(function (i) {
                    subGlyf.push(glyf[+i]);
                });
                glyf = subGlyf;
            }

            font.glyf = glyf;
        }
1159719
function fontValueParse(input) {

    var states = {
        VARIATION: 1,
        LINE_HEIGHT: 2,
        FONT_FAMILY: 3
    };

    var state = states.VARIATION;
    var buffer = '';
    var result = {
        'font-family': []
    };


    for (var c, i = 0; c = input.charAt(i); i += 1) {
        if (state === states.FONT_FAMILY && (c === '"' || c === '\'')) {
            var index = i + 1;

            // consume the entire string
            do {
                index = input.indexOf(c, index) + 1;
                if (!index) {
                    // If a string is not closed by a ' or " return null.
                    // TODO: Check to see if this is correct.
                    return null;
                }
            } while (input.charAt(index - 2) === '\\');

            result['font-family']
            .push(input.slice(i + 1, index - 1)
            .replace(/\\('|")/g, '$1'));

            i = index - 1;
            buffer = '';
        } else if (state === states.FONT_FAMILY && c === ',') {
            if (!/^\s*$/.test(buffer)) {
                result['font-family'].push(buffer.replace(/^\s+|\s+$/, '').replace(/\s+/g, ' '));
                buffer = '';
            }
        } else if (state === states.VARIATION && (c === ' ' || c === '/')) {
            if (/^((xx|x)-large|(xx|s)-small|small|large|medium)$/.test(buffer) ||
                /^(larg|small)er$/.test(buffer) ||
                /^(\+|-)?([0-9]*\.)?[0-9]+(em|ex|ch|rem|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc|%)$/.test(buffer)) {
                state = c === '/' ? states.LINE_HEIGHT : states.FONT_FAMILY;
                result['font-size'] = buffer;
            } else if (/^(italic|oblique)$/.test(buffer)) {
                result['font-style'] = buffer;
            } else if (/^small-caps$/.test(buffer)) {
                result['font-variant'] = buffer;
            } else if (/^(bold(er)?|lighter|[1-9]00)$/.test(buffer)) {
                result['font-weight'] = buffer;
            } else if (/^((ultra|extra|semi)-)?(condensed|expanded)$/.test(buffer)) {
                result['font-stretch'] = buffer;
            }
            buffer = '';
        } else if (state === states.LINE_HEIGHT && c === ' ') {
            if (/^(\+|-)?([0-9]*\.)?[0-9]+(em|ex|ch|rem|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc|%)?$/.test(buffer)) {
                result['line-height'] = buffer;
            }
            state = states.FONT_FAMILY;
            buffer = '';
        } else {
            buffer += c;
        }
    }

    if (state === states.FONT_FAMILY && !/^\s*$/.test(buffer)) {
        result['font-family'].push(buffer.replace(/^\s+|\s+$/, '').replace(/\s+/g, ' '));
    }

    if (result['font-size'] && result['font-family'].length) {
        return result;
    } else {
        return null;
    }
}
494143
def com_google_fonts_check_whitespace_widths(ttFont):
  """"""
  from fontbakery.utils import get_glyph_name

  space_name = get_glyph_name(ttFont, 0x0020)
  nbsp_name = get_glyph_name(ttFont, 0x00A0)

  space_width = ttFont['hmtx'][space_name][0]
  nbsp_width = ttFont['hmtx'][nbsp_name][0]

  if space_width > 0 and space_width == nbsp_width:
    yield PASS, "Whitespace and non-breaking space have the same width."
  else:
    yield FAIL, ("Whitespace and non-breaking space have differing width:"
                 " Whitespace ({}) is {} font units wide, non-breaking space"
                 " ({}) is {} font units wide. Both should be positive and the"
                 " same.").format(space_name, space_width, nbsp_name,
                                  nbsp_width)
909748
function calculateTextStyle(helper, item)
{
    if (item instanceof TextStyle)
    {
        const font = item.toFontString();

        TextMetrics.measureFont(font);

        return true;
    }

    return false;
}
766168
function parse_fonts(t, styles, themes, opts) {
	styles.Fonts = [];
	var font = {};
	var pass = false;
	t[0].match(tagregex).forEach(function(x) {
		var y = parsexmltag(x);
		switch(strip_ns(y[0])) {
			case '<fonts': case '<fonts>': case '</fonts>': break;

			/* 18.8.22 font CT_Font */
			case '<font': case '<font>': break;
			case '</font>': case '<font/>':
				styles.Fonts.push(font);
				font = {};
				break;

			/* 18.8.29 name CT_FontName */
			case '<name': if(y.val) font.name = y.val; break;
			case '<name/>': case '</name>': break;

			/* 18.8.2  b CT_BooleanProperty */
			case '<b': font.bold = y.val ? parsexmlbool(y.val) : 1; break;
			case '<b/>': font.bold = 1; break;

			/* 18.8.26 i CT_BooleanProperty */
			case '<i': font.italic = y.val ? parsexmlbool(y.val) : 1; break;
			case '<i/>': font.italic = 1; break;

			/* 18.4.13 u CT_UnderlineProperty */
			case '<u':
				switch(y.val) {
					case "none": font.underline = 0x00; break;
					case "single": font.underline = 0x01; break;
					case "double": font.underline = 0x02; break;
					case "singleAccounting": font.underline = 0x21; break;
					case "doubleAccounting": font.underline = 0x22; break;
				} break;
			case '<u/>': font.underline = 1; break;

			/* 18.4.10 strike CT_BooleanProperty */
			case '<strike': font.strike = y.val ? parsexmlbool(y.val) : 1; break;
			case '<strike/>': font.strike = 1; break;

			/* 18.4.2  outline CT_BooleanProperty */
			case '<outline': font.outline = y.val ? parsexmlbool(y.val) : 1; break;
			case '<outline/>': font.outline = 1; break;

			/* 18.8.36 shadow CT_BooleanProperty */
			case '<shadow': font.shadow = y.val ? parsexmlbool(y.val) : 1; break;
			case '<shadow/>': font.shadow = 1; break;

			/* 18.8.12 condense CT_BooleanProperty */
			case '<condense': font.condense = y.val ? parsexmlbool(y.val) : 1; break;
			case '<condense/>': font.condense = 1; break;

			/* 18.8.17 extend CT_BooleanProperty */
			case '<extend': font.extend = y.val ? parsexmlbool(y.val) : 1; break;
			case '<extend/>': font.extend = 1; break;

			/* 18.4.11 sz CT_FontSize */
			case '<sz': if(y.val) font.sz = +y.val; break;
			case '<sz/>': case '</sz>': break;

			/* 18.4.14 vertAlign CT_VerticalAlignFontProperty */
			case '<vertAlign': if(y.val) font.vertAlign = y.val; break;
			case '<vertAlign/>': case '</vertAlign>': break;

			/* 18.8.18 family CT_FontFamily */
			case '<family': if(y.val) font.family = parseInt(y.val,10); break;
			case '<family/>': case '</family>': break;

			/* 18.8.35 scheme CT_FontScheme */
			case '<scheme': if(y.val) font.scheme = y.val; break;
			case '<scheme/>': case '</scheme>': break;

			/* 18.4.1 charset CT_IntProperty */
			case '<charset':
				if(y.val == '1') break;
				y.codepage = CS2CP[parseInt(y.val, 10)];
				break;

			/* 18.?.? color CT_Color */
			case '<color':
				if(!font.color) font.color = {};
				if(y.auto) font.color.auto = parsexmlbool(y.auto);

				if(y.rgb) font.color.rgb = y.rgb.slice(-6);
				else if(y.indexed) {
					font.color.index = parseInt(y.indexed, 10);
					var icv = XLSIcv[font.color.index];
					if(font.color.index == 81) icv = XLSIcv[1];
					if(!icv) throw new Error(x);
					font.color.rgb = icv[0].toString(16) + icv[1].toString(16) + icv[2].toString(16);
				} else if(y.theme) {
					font.color.theme = parseInt(y.theme, 10);
					if(y.tint) font.color.tint = parseFloat(y.tint);
					if(y.theme && themes.themeElements && themes.themeElements.clrScheme) {
						font.color.rgb = rgb_tint(themes.themeElements.clrScheme[font.color.theme].rgb, font.color.tint || 0);
					}
				}

				break;
			case '<color/>': case '</color>': break;

			/* 18.2.10 extLst CT_ExtensionList ? */
			case '<extLst': case '<extLst>': case '</extLst>': break;
			case '<ext': pass = true; break;
			case '</ext>': pass = false; break;
			default: if(opts && opts.WTF) {
				if(!pass) throw new Error('unrecognized ' + y[0] + ' in fonts');
			}
		}
	});
}
201422
function fallback( fonts ) {
    return new Promise(function (resolve, reject) {
        var divs = [];
        var body = document.body;
        fonts.forEach(function (font) {
            var div = document.createElement( 'div' );
            div.className = 'tfw-font-loader';
            div.style.fontFamily = font;
            body.appendChild( div );
        });
        // Ugly trick: juste wait 1.5 second.
        window.setTimeout(function () {
            divs.forEach(function (d) {
                body.removeChild( d );
            });
            resolve( fonts );
        }, 1500);
    });
}
468948
function FontpathRenderer(options) {
    if (!(this instanceof FontpathRenderer))
        return new FontpathRenderer(options)
    Base.call(this, options)

    this.data = {
        glyphs: [],
        underlines: []
    }
}
540167
function(font){
        var me = this;
        if(me.font !== font){
            me.font = font;
            me._fontHeight = Text.measureFontHeight(font);
        }

        return me;
    }
104456
def com_google_fonts_check_points_out_of_bounds(ttFont):
  """"""
  failed = False
  out_of_bounds = []
  for glyphName in ttFont['glyf'].keys():
    glyph = ttFont['glyf'][glyphName]
    coords = glyph.getCoordinates(ttFont['glyf'])[0]
    for x, y in coords:
      if x < glyph.xMin or x > glyph.xMax or \
         y < glyph.yMin or y > glyph.yMax or \
         abs(x) > 32766 or abs(y) > 32766:
        failed = True
        out_of_bounds.append((glyphName, x, y))

  if failed:
    yield WARN, ("The following glyphs have coordinates which are"
                 " out of bounds:\n{}\nThis happens a lot when points"
                 " are not extremes, which is usually bad. However,"
                 " fixing this alert by adding points on extremes may"
                 " do more harm than good, especially with italics,"
                 " calligraphic-script, handwriting, rounded and"
                 " other fonts. So it is common to"
                 " ignore this message".format(out_of_bounds))
  else:
    yield PASS, "All glyph paths have coordinates within bounds!"
348824
function measureTextWidth(font, text) {
       var characters = text.split("");
       var width = 0;
       var lastGlyph = null;

       for (var i = 0; i < characters.length; i++) {
         var ch = characters[i].charCodeAt(0);
         var glyph = font.fontData.glyphs[ch];
         var kerning = lastGlyph && lastGlyph.kerning ? lastGlyph.getKerning(ch) : 0;
         width += (glyph.xadvance + kerning) * font.fontScale.x;
         lastGlyph = glyph;
       }

       return width;
     }
272432
function groupTextsByFontFamilyProps(
  textByPropsArray,
  availableFontFaceDeclarations
) {
  const snappedTexts = _.flatMapDeep(textByPropsArray, textAndProps => {
    const family = textAndProps.props['font-family'];
    if (family === undefined) {
      return [];
    }

    // Find all the families in the traced font-family that we have @font-face declarations for:
    const families = fontFamily
      .parse(family)
      .filter(family =>
        availableFontFaceDeclarations.some(
          fontFace =>
            fontFace['font-family'].toLowerCase() === family.toLowerCase()
        )
      );

    return families.map(family => {
      const activeFontFaceDeclaration = fontSnapper(
        availableFontFaceDeclarations,
        {
          ...textAndProps.props,
          'font-family': fontFamily.stringify([family])
        }
      );

      if (!activeFontFaceDeclaration) {
        return [];
      }

      const { relations, ...props } = activeFontFaceDeclaration;
      const fontUrl = getPreferredFontUrl(relations);

      return {
        text: textAndProps.text,
        props,
        fontRelations: relations,
        fontUrl
      };
    });
  }).filter(textByProps => textByProps && textByProps.fontUrl);

  const textsByFontUrl = _.groupBy(snappedTexts, 'fontUrl');

  return _.map(textsByFontUrl, (textsPropsArray, fontUrl) => {
    const texts = textsPropsArray.map(obj => obj.text);
    const fontFamilies = new Set(
      textsPropsArray.map(obj => obj.props['font-family'])
    );
    const pageText = _.uniq(texts.join(''))
      .sort()
      .join('');

    let smallestOriginalSize;
    let smallestOriginalFormat;
    for (const relation of textsPropsArray[0].fontRelations) {
      if (relation.to.isLoaded) {
        const size = relation.to.rawSrc.length;
        if (smallestOriginalSize === undefined || size < smallestOriginalSize) {
          smallestOriginalSize = size;
          smallestOriginalFormat = relation.to.type.toLowerCase();
        }
      }
    }

    return {
      smallestOriginalSize,
      smallestOriginalFormat,
      texts,
      pageText,
      text: pageText,
      props: { ...textsPropsArray[0].props },
      fontUrl,
      fontFamilies
    };
  });
}
243328
public void setFont(Font font) {
		if (days != null) {
			for (int i = 0; i < 49; i++) {
				days[i].setFont(font);
			}
		}
		if (weeks != null) {
			for (int i = 0; i < 7; i++) {
				weeks[i].setFont(font);
			}
		}
	}
508074
def install_special_glyphs():
    '''
    
    '''
    from_dir = '~/repos/powerline/font'

    run('mkdir -p ~/.local/share/fonts')
    run(flo('cp {from_dir}/PowerlineSymbols.otf  ~/.local/share/fonts'))

    to_dir = '~/.config/fontconfig/conf.d/'
    run(flo('mkdir -p {to_dir}'))
    run(flo('cp {from_dir}/10-powerline-symbols.conf  {to_dir}'))
521782
function loadFont (fontFace, callback) {
  var defaultNode;
  var testNode;
  var checkFont;

  // See if we've previously loaded it.
  if (_loadedFonts[fontFace.id]) {
    return callback(null);
  }

  // See if we've previously failed to load it.
  if (_failedFonts[fontFace.id]) {
    return callback(_failedFonts[fontFace.id]);
  }

  // System font: assume already loaded.
  if (!fontFace.url) {
    return callback(null);
  }

  // Font load is already in progress:
  if (_pendingFonts[fontFace.id]) {
    _pendingFonts[fontFace.id].callbacks.push(callback);
    return;
  }

  // Create the test <span>'s for measuring.
  defaultNode = createTestNode('Helvetica', fontFace.attributes);
  testNode = createTestNode(fontFace.family, fontFace.attributes);
  document.body.appendChild(testNode);
  document.body.appendChild(defaultNode);

  _pendingFonts[fontFace.id] = {
    startTime: Date.now(),
    defaultNode: defaultNode,
    testNode: testNode,
    callbacks: [callback]
  };

  // Font watcher
  checkFont = function () {
    var currWidth = testNode.getBoundingClientRect().width;
    var defaultWidth = defaultNode.getBoundingClientRect().width;
    var loaded = currWidth !== defaultWidth;

    if (loaded) {
      handleFontLoad(fontFace, null);
    } else {
      // Timeout?
      if (Date.now() - _pendingFonts[fontFace.id].startTime >= kFontLoadTimeout) {
        handleFontLoad(fontFace, true);
      } else {
        requestAnimationFrame(checkFont);
      }
    }
  };

  // Start watching
  checkFont();
}
10497
function cleanTables(font) {
            delete font.readOptions;
            delete font.tables;
            delete font.hmtx;
            delete font.post.glyphNameIndex;
            delete font.post.names;
            delete font.subsetMap;

            // 删除无用的表
            var cff = font.CFF;
            delete cff.glyf;
            delete cff.charset;
            delete cff.encoding;
            delete cff.gsubrs;
            delete cff.gsubrsBias;
            delete cff.subrs;
            delete cff.subrsBias;
        }
1218997
function Font(buffer, options) {
        options = options || {
            type: 'ttf'
        };

        // 字形对象
        if (typeof buffer === 'object' && buffer.glyf) {
            this.set(buffer);
        }
        // buffer
        else if (buffer) {
            this.read(buffer, options);
        }
        // 空
        else {
            this.readEmpty();
        }
    }
1310311
def com_google_fonts_check_ligature_carets(ttFont, ligature_glyphs):
  """"""
  if ligature_glyphs == -1:
    yield FAIL, Message("malformed", "Failed to lookup ligatures."
                        " This font file seems to be malformed."
                        " For more info, read:"
                        " https://github.com"
                        "/googlefonts/fontbakery/issues/1596")
  elif "GDEF" not in ttFont:
    yield WARN, Message("GDEF-missing",
                        ("GDEF table is missing, but it is mandatory"
                         " to declare it on fonts that provide ligature"
                         " glyphs because the caret (text cursor)"
                         " positioning for each ligature must be"
                         " provided in this table."))
  else:
    lig_caret_list = ttFont["GDEF"].table.LigCaretList
    if lig_caret_list is None:
      missing = set(ligature_glyphs)
    else:
      missing = set(ligature_glyphs) - set(lig_caret_list.Coverage.glyphs)

    if lig_caret_list is None or lig_caret_list.LigGlyphCount == 0:
      yield WARN, Message("lacks-caret-pos",
                          ("This font lacks caret position values for"
                           " ligature glyphs on its GDEF table."))
    elif missing:
      missing = "\n\t- ".join(missing)
      yield WARN, Message("incomplete-caret-pos-data",
                          ("This font lacks caret positioning"
                           " values for these ligature glyphs:"
                           f"\n\t- {missing}\n\n  "))
    else:
      yield PASS, "Looks good!"