Show More
Commit Description:
force log out when password change
Commit Description:
force log out when password change
References:
File last commit:
Show/Diff file:
Action:
node_modules/fontkit/src/glyph/Glyph.js
| 212 lines
| 5.3 KiB
| application/javascript
| JavascriptLexer
|
r789 | import { cache } from '../decorators'; | |||
import Path from './Path'; | ||||
import unicode from 'unicode-properties'; | ||||
import StandardNames from './StandardNames'; | ||||
/** | ||||
* Glyph objects represent a glyph in the font. They have various properties for accessing metrics and | ||||
* the actual vector path the glyph represents, and methods for rendering the glyph to a graphics context. | ||||
* | ||||
* You do not create glyph objects directly. They are created by various methods on the font object. | ||||
* There are several subclasses of the base Glyph class internally that may be returned depending | ||||
* on the font format, but they all inherit from this class. | ||||
*/ | ||||
export default class Glyph { | ||||
constructor(id, codePoints, font) { | ||||
/** | ||||
* The glyph id in the font | ||||
* @type {number} | ||||
*/ | ||||
this.id = id; | ||||
/** | ||||
* An array of unicode code points that are represented by this glyph. | ||||
* There can be multiple code points in the case of ligatures and other glyphs | ||||
* that represent multiple visual characters. | ||||
* @type {number[]} | ||||
*/ | ||||
this.codePoints = codePoints; | ||||
this._font = font; | ||||
// TODO: get this info from GDEF if available | ||||
this.isMark = this.codePoints.length > 0 && this.codePoints.every(unicode.isMark); | ||||
this.isLigature = this.codePoints.length > 1; | ||||
} | ||||
_getPath() { | ||||
return new Path(); | ||||
} | ||||
_getCBox() { | ||||
return this.path.cbox; | ||||
} | ||||
_getBBox() { | ||||
return this.path.bbox; | ||||
} | ||||
_getTableMetrics(table) { | ||||
if (this.id < table.metrics.length) { | ||||
return table.metrics.get(this.id); | ||||
} | ||||
let metric = table.metrics.get(table.metrics.length - 1); | ||||
let res = { | ||||
advance: metric ? metric.advance : 0, | ||||
bearing: table.bearings.get(this.id - table.metrics.length) || 0 | ||||
}; | ||||
return res; | ||||
} | ||||
_getMetrics(cbox) { | ||||
if (this._metrics) { return this._metrics; } | ||||
let {advance:advanceWidth, bearing:leftBearing} = this._getTableMetrics(this._font.hmtx); | ||||
// For vertical metrics, use vmtx if available, or fall back to global data from OS/2 or hhea | ||||
if (this._font.vmtx) { | ||||
var {advance:advanceHeight, bearing:topBearing} = this._getTableMetrics(this._font.vmtx); | ||||
} else { | ||||
let os2; | ||||
if (typeof cbox === 'undefined' || cbox === null) { ({ cbox } = this); } | ||||
if ((os2 = this._font['OS/2']) && os2.version > 0) { | ||||
var advanceHeight = Math.abs(os2.typoAscender - os2.typoDescender); | ||||
var topBearing = os2.typoAscender - cbox.maxY; | ||||
} else { | ||||
let { hhea } = this._font; | ||||
var advanceHeight = Math.abs(hhea.ascent - hhea.descent); | ||||
var topBearing = hhea.ascent - cbox.maxY; | ||||
} | ||||
} | ||||
if (this._font._variationProcessor && this._font.HVAR) { | ||||
advanceWidth += this._font._variationProcessor.getAdvanceAdjustment(this.id, this._font.HVAR); | ||||
} | ||||
return this._metrics = { advanceWidth, advanceHeight, leftBearing, topBearing }; | ||||
} | ||||
/** | ||||
* The glyph’s control box. | ||||
* This is often the same as the bounding box, but is faster to compute. | ||||
* Because of the way bezier curves are defined, some of the control points | ||||
* can be outside of the bounding box. Where `bbox` takes this into account, | ||||
* `cbox` does not. Thus, cbox is less accurate, but faster to compute. | ||||
* See [here](http://www.freetype.org/freetype2/docs/glyphs/glyphs-6.html#section-2) | ||||
* for a more detailed description. | ||||
* | ||||
* @type {BBox} | ||||
*/ | ||||
@cache | ||||
get cbox() { | ||||
return this._getCBox(); | ||||
} | ||||
/** | ||||
* The glyph’s bounding box, i.e. the rectangle that encloses the | ||||
* glyph outline as tightly as possible. | ||||
* @type {BBox} | ||||
*/ | ||||
@cache | ||||
get bbox() { | ||||
return this._getBBox(); | ||||
} | ||||
/** | ||||
* A vector Path object representing the glyph outline. | ||||
* @type {Path} | ||||
*/ | ||||
@cache | ||||
get path() { | ||||
// Cache the path so we only decode it once | ||||
// Decoding is actually performed by subclasses | ||||
return this._getPath(); | ||||
} | ||||
/** | ||||
* Returns a path scaled to the given font size. | ||||
* @param {number} size | ||||
* @return {Path} | ||||
*/ | ||||
getScaledPath(size) { | ||||
let scale = 1 / this._font.unitsPerEm * size; | ||||
return this.path.scale(scale); | ||||
} | ||||
/** | ||||
* The glyph's advance width. | ||||
* @type {number} | ||||
*/ | ||||
@cache | ||||
get advanceWidth() { | ||||
return this._getMetrics().advanceWidth; | ||||
} | ||||
/** | ||||
* The glyph's advance height. | ||||
* @type {number} | ||||
*/ | ||||
@cache | ||||
get advanceHeight() { | ||||
return this._getMetrics().advanceHeight; | ||||
} | ||||
get ligatureCaretPositions() {} | ||||
_getName() { | ||||
let { post } = this._font; | ||||
if (!post) { | ||||
return null; | ||||
} | ||||
switch (post.version) { | ||||
case 1: | ||||
return StandardNames[this.id]; | ||||
case 2: | ||||
let id = post.glyphNameIndex[this.id]; | ||||
if (id < StandardNames.length) { | ||||
return StandardNames[id]; | ||||
} | ||||
return post.names[id - StandardNames.length]; | ||||
case 2.5: | ||||
return StandardNames[this.id + post.offsets[this.id]]; | ||||
case 4: | ||||
return String.fromCharCode(post.map[this.id]); | ||||
} | ||||
} | ||||
/** | ||||
* The glyph's name | ||||
* @type {string} | ||||
*/ | ||||
@cache | ||||
get name() { | ||||
return this._getName(); | ||||
} | ||||
/** | ||||
* Renders the glyph to the given graphics context, at the specified font size. | ||||
* @param {CanvasRenderingContext2d} ctx | ||||
* @param {number} size | ||||
*/ | ||||
render(ctx, size) { | ||||
ctx.save(); | ||||
let scale = 1 / this._font.head.unitsPerEm * size; | ||||
ctx.scale(scale, scale); | ||||
let fn = this.path.toFunction(); | ||||
fn(ctx); | ||||
ctx.fill(); | ||||
ctx.restore(); | ||||
} | ||||
} | ||||