Precompute text width using a lookup table (#2311)

This simplifies and further optimizes text-width computation by computing the entire width table in advance, and serializing it in the style of QuickTextMeasurer (#1390). This entirely removes the need for PDFKit at runtime. This has the advantage of fixing #1305 – more generally: producing the same result everywhere – without having to deploy a copy of Verdana.

The lifting is delegated to these three libraries, which are housed in a monorepo: https://github.com/metabolize/anafanafo

I'd be happy to move it into the badges org if folks want to collaborate on maintaining them.

QuickTextMeasurer took kerning pairs into account, whereas this implementation does not. I was thinking kerning would be a necessary refinement, though this seems to work well enough.

I dropped in a binary-search package to traverse the data structure, in part to conserve space. This causes a moderate performance regression, though there is ample room for improving on that: https://github.com/badges/shields/pull/2311#issuecomment-439182704
This commit is contained in:
Paul Melnikow
2018-11-15 17:27:21 -05:00
committed by GitHub
parent fe05d00747
commit 51897b3c7e
21 changed files with 116 additions and 496 deletions

View File

@@ -6,6 +6,7 @@ const request = require('request')
const { makeBadgeData: getBadgeData } = require('./badge-data')
const log = require('./log')
const LruCache = require('../gh-badges/lib/lru-cache')
const makeBadge = require('../gh-badges/lib/make-badge')
const analytics = require('./analytics')
const { makeSend } = require('./result-sender')
const queryString = require('query-string')
@@ -88,9 +89,7 @@ function getBadgeMaxAge(handlerOptions, queryParams) {
// (undesirable and hard to debug).
//
// Pass just the handler function as shorthand.
//
// Inject `makeBadge` as a dependency.
function handleRequest(makeBadge, handlerOptions) {
function handleRequest(handlerOptions) {
if (typeof handlerOptions === 'function') {
handlerOptions = { handler: handlerOptions }
}
@@ -276,8 +275,6 @@ function isInt(number) {
module.exports = {
handleRequest,
makeHandleRequestFn: makeBadge => handlerOptions =>
handleRequest(makeBadge, handlerOptions),
clearRequestCache,
// Expose for testing.
_requestCache: requestCache,

View File

@@ -8,14 +8,11 @@ const Camp = require('camp')
const analytics = require('./analytics')
const { makeBadgeData: getBadgeData } = require('./badge-data')
const {
makeHandleRequestFn,
handleRequest,
clearRequestCache,
_requestCache,
getBadgeMaxAge,
} = require('./request-handler')
const testHelpers = require('../gh-badges/lib/make-badge-test-helpers')
const handleRequest = makeHandleRequestFn(testHelpers.makeBadge())
const baseUri = `http://127.0.0.1:${config.port}`

View File

@@ -5,7 +5,6 @@
const url = require('url')
const envFlag = require('node-env-flag')
const defaults = require('../gh-badges/lib/defaults')
function envArray(envVar, defaultValue, delimiter) {
delimiter = delimiter || ','
@@ -69,10 +68,6 @@ const config = {
},
trace: envFlag(process.env.TRACE_SERVICES),
},
font: {
path: process.env.FONT_PATH || defaults.font.path,
fallbackPath: process.env.FALLBACK_FONT_PATH,
},
profiling: {
makeBadge: envFlag(process.env.PROFILE_MAKE_BADGE),
},
@@ -80,8 +75,4 @@ const config = {
handleInternalErrors: envFlag(process.env.HANDLE_INTERNAL_ERRORS, true),
}
if (config.font.fallbackPath) {
console.log('FALLBACK_FONT_PATH is deprecated. Please use FONT_PATH.')
}
module.exports = config