缩放到EM框

@param {Array} glyfList glyf列表
@param {number} ascent 上升
@param {number} descent 下降
@param {number} ajdustToEmPadding  顶部和底部留白
@return {Array} glyfList
969502
function adjustToEmBox(glyfList, ascent, descent, ajdustToEmPadding) {

            glyfList.forEach(function (g) {

                if (g.contours && g.contours.length) {
                    var rightSideBearing = g.advanceWidth - g.xMax;
                    var bound = computeBoundingBox.computePath.apply(null, g.contours);
                    var scale = (ascent - descent - ajdustToEmPadding) / bound.height;
                    var center = (ascent + descent) / 2;
                    var yOffset = center - (bound.y + bound.height / 2) * scale;

                    g.contours.forEach(function (contour) {
                        if (scale !== 1) {
                            pathAdjust(contour, scale, scale);
                        }

                        pathAdjust(contour, 1, 1, 0, yOffset);
                        pathCeil(contour);
                    });

                    var box = computeBoundingBox.computePathBox.apply(null, g.contours);

                    g.xMin = box.x;
                    g.xMax = box.x + box.width;
                    g.yMin = box.y;
                    g.yMax = box.y + box.height;

                    g.leftSideBearing = g.xMin;
                    g.advanceWidth = g.xMax + rightSideBearing;

                }

            });

            return glyfList;
        }
726828
def get_text_width_height_descent(self, s, prop, ismath):
        
        #return 1, 1
        if ismath: s = self.strip_math(s)

        if self.gc is None:
            gc = self.new_gc()
        else:
            gc = self.gc
        gfx_ctx = gc.gfx_ctx
        font = self.get_wx_font(s, prop)
        gfx_ctx.SetFont(font, wx.BLACK)
        w, h, descent, leading = gfx_ctx.GetFullTextExtent(s)

        return w, h, descent
1282668
private JNoteElementAbstract getHighestNoteGlyphBetween(NoteAbstract start, NoteAbstract end, boolean excludeStartAndEnd) {
		Collection jnotes = getNoteGlyphesBetween(start, end);
		JNoteElementAbstract ret = null;
		boolean first = true;
		for (Iterator it = jnotes.iterator(); it.hasNext();) {
			JNoteElementAbstract n = (JNoteElementAbstract) it.next();
			if (first && excludeStartAndEnd) {
				//ignore start ?
				first = false;
				continue;
			}
			if (!it.hasNext() && excludeStartAndEnd) {
				//ignore end ?
				break;
			}
			if (ret == null)
				ret = n;
			else {
				if (n.getBoundingBox().getMinY()
					< ret.getBoundingBox().getMinY())
					ret = n;
			}
		}
		return ret;
	}
219774
function traverseEnterLeave(from, to, fn, argFrom, argTo) {
  var common = from && to ? getLowestCommonAncestor(from, to) : null;
  var pathFrom = [];
  while (from && from !== common) {
    pathFrom.push(from);
    from = getParent(from);
  }
  var pathTo = [];
  while (to && to !== common) {
    pathTo.push(to);
    to = getParent(to);
  }
  var i;
  for (i = 0; i < pathFrom.length; i++) {
    fn(pathFrom[i], 'bubbled', argFrom);
  }
  for (i = pathTo.length; i-- > 0;) {
    fn(pathTo[i], 'captured', argTo);
  }
}
284767
function glyf2svg(glyf, ttf) {

    if (!glyf) {
        return '';
    }

    var pathArray = [];

    if (!glyf.compound) {
        if (glyf.contours && glyf.contours.length) {
            pathArray.push(contours2svg(glyf.contours));
        }

    }
    else {
        var glyfs = glyf.glyfs;
        glyfs.forEach(function (g) {
            var glyph = ttf.glyf[g.glyphIndex];

            if (!glyph || !glyph.contours || !glyph.contours.length) {
                return;
            }

            var contours = lang.clone(glyph.contours); // 这里需要进行matrix变换，需要复制一份
            var transform = g.transform;
            for (var i = 0, l = contours.length; i < l; i++) {
                pathTransform(
                    contours[i],
                    transform.a,
                    transform.b,
                    transform.c,
                    transform.d,
                    transform.e,
                    transform.f
                );
                pathArray.push(contour2svg(contours[i]));
            }
        });
    }

    return pathArray.join(' ');
}
1085894
function flattenSlotSegLevels(levels) {
	var segs = [];
	var i, level;
	var j;

	for (i=0; i<levels.length; i++) {
		level = levels[i];

		for (j=0; j<level.length; j++) {
			segs.push(level[j]);
		}
	}

	return segs;
}
12518
def vertical_gradient(self, x0, y0, x1, y1, start, end):
        """"""
        x0, y0, x1, y1 = self.rect_helper(x0, y0, x1, y1)
        grad = gradient_list(start, end, y1 - y0)
        for x in range(x0, x1 + 1):
            for y in range(y0, y1 + 1):
                self.point(x, y, grad[y - y0])
12372
function(g,g2,x1,y1,x2,y2){
		// source側はtaranslateのぶん足されていないので、加算しておきます
		var sx1 = this.x0+x1*this.bw-1, sy1 = this.y0+y1*this.bh-1,
			sx2 = this.x0+x2*this.bw+2, sy2 = this.y0+y2*this.bh+2;
		if(sx1<0){ sx1=0;} if(sx2>g2.child.width) { sx2=g2.child.width;}
		if(sy1<0){ sy1=0;} if(sy2>g2.child.height){ sy2=g2.child.height;}
		g.drawImage(g2.child, sx1, sy1, (sx2-sx1), (sy2-sy1), sx1-this.x0, sy1-this.y0, (sx2-sx1), (sy2-sy1));
	}
774881
function buildGradient() {
            if (!chartGradientEl) {
                chartGradientEl = svg.select('.metadata-group')
                  .append('linearGradient')
                    .attr('id', gradientId)
                    .attr('gradientUnits', 'userSpaceOnUse')
                    .attr('x1', 0)
                    .attr('x2', xScale(data[data.length - 1].date))
                    .attr('y1', 0)
                    .attr('y2', 0)
                  .selectAll('stop')
                    .data([
                        {offset: '0%', color: gradient[0]},
                        {offset: '100%', color: gradient[1]}
                    ])
                  .enter().append('stop')
                    .attr('offset', ({offset}) => offset)
                    .attr('stop-color', ({color}) => color);
            }
        }
967510
def to_glyphs_glyph_anchors(self, ufo_glyph, layer):
    """"""
    for ufo_anchor in ufo_glyph.anchors:
        anchor = self.glyphs_module.GSAnchor()
        anchor.name = ufo_anchor.name
        anchor.position = Point(ufo_anchor.x, ufo_anchor.y)
        layer.anchors.append(anchor)
1100936
public static Vector3d getTranslScrewComponent(Matrix4d m) {

		int foldType = SpaceGroup.getRotAxisType(m);
		// For reference see:
		// http://www.crystallography.fr/mathcryst/pdf/Gargnano/Aroyo_Gargnano_1.pdf

		Vector3d transl = null;

		Matrix3d W =
				new Matrix3d(m.m00,m.m01,m.m02,
						m.m10,m.m11,m.m12,
						m.m20,m.m21,m.m22);

		if (foldType>=0) {

			// the Y matrix: Y = W^k-1 + W^k-2 ... + W + I  ; with k the fold type
			Matrix3d Y = new Matrix3d(1,0,0, 0,1,0, 0,0,1);
			Matrix3d Wk = new Matrix3d(1,0,0, 0,1,0, 0,0,1);

			for (int k=0;k<foldType;k++) {
				Wk.mul(W); // k=0 Wk=W, k=1 Wk=W^2, k=2 Wk=W^3, ... k=foldType-1, Wk=W^foldType
				if (k!=foldType-1) Y.add(Wk);
			}

			transl = new Vector3d(m.m03, m.m13, m.m23);
			Y.transform(transl);

			transl.scale(1.0/foldType);

		} else {

			if (foldType==-2) { // there are glide planes only in -2
				Matrix3d Y = new Matrix3d(1,0,0, 0,1,0, 0,0,1);
				Y.add(W);

				transl = new Vector3d(m.m03, m.m13, m.m23);
				Y.transform(transl);

				transl.scale(1.0/2.0);
			} else { // for -1, -3, -4 and -6 there's nothing to do: fill with 0s
				transl = new Vector3d(0,0,0);
			}
		}

		return transl;
	}
611338
private Collection getNoteGlyphesBetween(NoteAbstract start, NoteAbstract end) {
		Collection jnotes = new Vector();
		try {
			Collection notes = m_music.getVoice(start.getReference().getVoice()).getNotesBetween(start, end);
            for (Object note : notes) {
                NoteAbstract n = (NoteAbstract) note;
                jnotes.add(getRenditionObjectFor(n));
            }
		} catch (Exception e) {
			// TODO: handle exception, shouldn't happen
		}
		return jnotes;
	}
630287
def makeMissingRequiredGlyphs(font, glyphSet):
        
        if ".notdef" in glyphSet:
            return

        unitsPerEm = otRound(getAttrWithFallback(font.info, "unitsPerEm"))
        ascender = otRound(getAttrWithFallback(font.info, "ascender"))
        descender = otRound(getAttrWithFallback(font.info, "descender"))
        defaultWidth = otRound(unitsPerEm * 0.5)
        glyphSet[".notdef"] = StubGlyph(name=".notdef",
                                        width=defaultWidth,
                                        unitsPerEm=unitsPerEm,
                                        ascender=ascender,
                                        descender=descender)
1305800
function getSegments(font, bound) {
  var prevGlyph = null;
  var result = [];
  var segment = {};

  var delta;
  var prevEndCode = 0;
  var prevDelta = -1;

  _.forEach(font._glyphs, function (glyph) {
    if (glyph.unicode === undefined) { // ignore glyphs with missed unicode
      return;
    }
    if (bound === undefined || glyph.unicode <= bound) {
      // Initialize first segment or add new segment if code "hole" is found
      if (prevGlyph === null || glyph.unicode !== prevGlyph.unicode + 1) {
        if (prevGlyph !== null) {
          segment.end = prevGlyph;
          delta = prevEndCode - segment.start.unicode + prevDelta + 1;
          segment.delta = encodeDelta(delta);
          prevEndCode = segment.end.unicode;
          prevDelta = delta;
          result.push(segment);
          segment = {};
        }
        segment.start = glyph;
      }
      prevGlyph = glyph;
    }
  });

  // Need to finish the last segment
  if (prevGlyph !== null) {
    segment.end = prevGlyph;
    delta = prevEndCode - segment.start.unicode + prevDelta + 1;
    segment.delta = delta > 0x7FFF ? delta - 0x10000 : (delta < -0x7FFF ? delta + 0x10000 : delta);
    result.push(segment);
  }
  return result;
}
1344343
function parseGlyph(data, index, start) {
    var p, glyph, flag, i, j, flags,
        endPointIndices, numberOfCoordinates, repeatCount, points, point, px, py,
        component, moreComponents;
    p = new parse.Parser(data, start);
    glyph = new Glyph(index, start);

    glyph.numberOfContours = p.parseShort();
    glyph.xMin = p.parseShort();
    glyph.yMin = p.parseShort();
    glyph.xMax = p.parseShort();
    glyph.yMax = p.parseShort();
    glyph.parsed = true;

    if (glyph.numberOfContours > 0) {
        // This glyph is not a composite.
        endPointIndices = glyph.endPointIndices = [];
        for (i = 0; i < glyph.numberOfContours; i += 1) {
            endPointIndices.push(p.parseUShort());
        }

        glyph.instructionLength = p.parseUShort();
        glyph.instructions = [];
        for (i = 0; i < glyph.instructionLength; i += 1) {
            glyph.instructions.push(p.parseByte());
        }

        numberOfCoordinates = endPointIndices[endPointIndices.length - 1] + 1;
        flags = [];
        for (i = 0; i < numberOfCoordinates; i += 1) {
            flag = p.parseByte();
            flags.push(flag);
            // If bit 3 is set, we repeat this flag n times, where n is the next byte.
            if ((flag & 8) > 0) {
                repeatCount = p.parseByte();
                for (j = 0; j < repeatCount; j += 1) {
                    flags.push(flag);
                    i += 1;
                }
            }
        }
//        check.argument(flags.length === numberOfCoordinates, 'Bad flags.');

        if (endPointIndices.length > 0) {
            points = [];
            // X/Y coordinates are relative to the previous point, except for the first point which is relative to 0,0.
            if (numberOfCoordinates > 0) {
                for (i = 0; i < numberOfCoordinates; i += 1) {
                    flag = flags[i];
                    point = {};
                    point.onCurve = !!(flag & 1);
                    point.lastPointOfContour = endPointIndices.indexOf(i) >= 0;
                    points.push(point);
                }
                px = 0;
                for (i = 0; i < numberOfCoordinates; i += 1) {
                    flag = flags[i];
                    point = points[i];
                    point.x = parseGlyphCoordinate(p, flag, px, 2, 16);
                    px = point.x;
                }

                py = 0;
                for (i = 0; i < numberOfCoordinates; i += 1) {
                    flag = flags[i];
                    point = points[i];
                    point.y = parseGlyphCoordinate(p, flag, py, 4, 32);
                    py = point.y;
                }
            }
            glyph.points = points;
        } else {
            glyph.points = [];
        }
    } else if (glyph.numberOfContours === 0) {
        glyph.points = [];
    } else {
        glyph.isComposite = true;
        glyph.points = [];
        glyph.components = [];
        moreComponents = true;
        while (moreComponents) {
            flags = p.parseUShort();
            component = {
                glyphIndex: p.parseUShort(),
                 xScale: 1,
                 scale01: 0,
                 scale10: 0,
                 yScale: 1,
                 dx: 0,
                 dy: 0
             };
            if ((flags & 1) > 0) {
                // The arguments are words
                component.dx = p.parseShort();
                component.dy = p.parseShort();
            } else {
                // The arguments are bytes
                component.dx = p.parseChar();
                component.dy = p.parseChar();
            }
            if ((flags & 8) > 0) {
                // We have a scale
                component.xScale = component.yScale = p.parseF2Dot14();
            } else if ((flags & 64) > 0) {
                // We have an X / Y scale
                component.xScale = p.parseF2Dot14();
                component.yScale = p.parseF2Dot14();
            } else if ((flags & 128) > 0) {
                // We have a 2x2 transformation
                component.xScale = p.parseF2Dot14();
                component.scale01 = p.parseF2Dot14();
                component.scale10 = p.parseF2Dot14();
                component.yScale = p.parseF2Dot14();
            }

            glyph.components.push(component);
            moreComponents = !!(flags & 32);
        }
    }

    glyph.size = p.relativeOffset;
    return glyph;
}
289096
function skip1(previousExpr) {
   
   
      if( previousExpr == always ) {
         /* If there is no previous expression this consume command 
            is at the start of the jsonPath.
            Since JSONPath specifies what we'd like to find but not 
            necessarily everything leading down to it, when running
            out of JSONPath to check against we default to true */
         return always;
      }

      /** return true if the ascent we have contains only the JSON root,
       *  false otherwise
       */
      function notAtRoot(ascent){
         return headKey(ascent) != ROOT_PATH;
      }
      
      return lazyIntersection(
               /* If we're already at the root but there are more 
                  expressions to satisfy, can't consume any more. No match.

                  This check is why none of the other exprs have to be able 
                  to handle empty lists; skip1 is the only evaluator that 
                  moves onto the next token and it refuses to do so once it 
                  reaches the last item in the list. */
               notAtRoot,
               
               /* We are not at the root of the ascent yet.
                  Move to the next level of the ascent by handing only 
                  the tail to the previous expression */ 
               compose2(previousExpr, tail) 
      );
                                                                                                               
   }
336087
function _getFirstGlyph() {
         var keys = Object.keys(this.glyphs);

         for (var i = 0; i < keys.length; i++) {
           if (keys[i] > 32) {
             return this.glyphs[keys[i]];
           }
         }

         return null;
       }