New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

canvas-text-opentypejs-shim

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

canvas-text-opentypejs-shim - npm Package Compare versions

Comparing version 0.1.1 to 0.1.2

79

canvas-text-opentypejs-shim.js

@@ -8,13 +8,2 @@ (function (root, factory) {

}(this, function () {
// adopted from https://github.com/kangax/fabric.js/blob/v1.6.6/src/parser.js#L703
var num = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)'
var fontCSS = new RegExp(
'(normal|italic|oblique)?\\s*' +
'(normal|small-caps)?\\s*' +
'(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*' +
'(normal|ultra-condensed|extra-condensed|condensed|semi-condensed|' +
'semi-expanded|expanded|extra-expanded|ultra-expanded)?\\s*' +
'(' + num + '(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|' + num + '))?\\s+' +
'(.*)')
/**

@@ -39,12 +28,62 @@ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/font

function parseCSSFont (font) {
var m = font.match(fontCSS)
return {
fontStyle: m[1] || 'normal',
fontVariant: m[2] || 'normal',
fontWeight: m[3] || 'normal',
fontStretch: m[4] || 'normal',
fontSize: m[5],
lineHeight: m[6] || 'normal',
fontFamily: m[7]
var fontFamilyIndex = [
font.lastIndexOf(' ', font.indexOf(',')) + 1 || -1,
font.indexOf('"'),
font.indexOf('\'')
].reduce(
function (r, v) { return ~v && v < r ? v : r },
font.lastIndexOf(' ')
)
var split = font.slice(0, fontFamilyIndex).trim().split(/\s+/)
var fontSize = split[split.length - 1]
var lineHeightIndex = fontSize.indexOf('/')
var o = {
fontStyle: 'normal',
fontVariant: 'normal',
fontWeight: 'normal',
fontStretch: 'normal',
fontSize: ~lineHeightIndex
? fontSize.slice(0, lineHeightIndex) : fontSize,
lineHeight: ~lineHeightIndex
? fontSize.slice(lineHeightIndex + 1) : 'normal',
fontFamily: font.slice(fontFamilyIndex)
}
split.slice(0, -1).forEach(function (v) {
switch (v) {
case 'normal':
break
case 'italic':
case 'oblique':
o.fontStyle = v
break
case 'small-caps':
o.fontVariant = v
break
case 'bold':
case 'bolder':
case 'lighter':
case '100':
case '200':
case '300':
case '400':
case '500':
case '600':
case '700':
case '800':
case '900':
o.fontWeight = v
break
case 'ultra-condensed':
case 'extra-condensed':
case 'condensed':
case 'semi-condensed':
case 'semi-expanded':
case 'expanded':
case 'extra-expanded':
case 'ultra-expanded':
o.fontStretch = v
break
}
})
return o
}

@@ -51,0 +90,0 @@

@@ -1,1 +0,1 @@

!function(t,n){"object"==typeof module&&module.exports?module.exports=n():t["canvas-text-opentypejs-shim"]=n()}(this,function(){function t(t){var n=t.match(o);return{fontStyle:n[1]||"normal",fontVariant:n[2]||"normal",fontWeight:n[3]||"normal",fontStretch:n[4]||"normal",fontSize:n[5],lineHeight:n[6]||"normal",fontFamily:n[7]}}function n(t,n,e){for(var o=0,a=0,i=0,r=n.stringToGlyphs(t),l=0;l<r.length;l++){var s=r[l];s.advanceWidth&&(i+=s.advanceWidth),l<r.length-1&&(i+=n.getKerningValue(s,r[l+1])),s.yMax&&(o=Math.max(o,s.yMax)),s.yMin&&(a=Math.min(a,s.yMin))}var d=1/n.unitsPerEm*e;return{width:i*d,actualBoundingBoxAscent:o*d,actualBoundingBoxDescent:a*d,fontBoundingBoxAscent:n.ascender*d,fontBoundingBoxDescent:n.descender*d}}var e="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",o=new RegExp("(normal|italic|oblique)?\\s*(normal|small-caps)?\\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded)?\\s*("+e+"(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|"+e+"))?\\s+(.*)");return function(e,o){function a(t,o,a,i,r){var d=a,c=o;if("alphabetic"!==e.textBaseline||"start"!==e.textAlign&&"left"!==e.textAlign){var u=n(t,s,l);"top"===e.textBaseline?d+=u.actualBoundingBoxAscent-u.fontBoundingBoxDescent:"hanging"===e.textBaseline?d+=u.actualBoundingBoxAscent:"middle"===e.textBaseline?d+=u.actualBoundingBoxAscent/2:"ideographic"!==e.textBaseline&&"bottom"!==e.textBaseline||(d+=u.fontBoundingBoxDescent),"right"===e.textAlign||"end"===e.textAlign?c-=u.width:"center"===e.textAlign&&(c-=u.width/2)}var f=s.getPath(t,c,d,l);r?(f.fill=null,f.stroke=e.strokeStyle):f.fill=e.fillStyle,f.draw(e)}function i(n){if(r!==n){var e=t(n);if(!/\d+px/.test(e.fontSize))throw new Error('font-size must be in "px"');if(s=o.resolveFont(e),!s&&d)throw new Error("Font instance wasn't found (\""+e.fontFamily+'")');l=parseInt(e.fontSize,10)}r=n}var r,l,s,d="boolean"!=typeof o.strict||o.strict,c=!0,u=e.measureText;e.measureText=function(t){return c&&(i(e.font),s)?n(t,s,l):u.apply(this,arguments)};var f=e.fillText;e.fillText=function(t,n,o,r){return c&&(i(e.font),s)?a(t,n,o,r,!1):f.apply(this,arguments)};var x=e.strokeText;return e.strokeText=function(t,n,o,r){return c&&(i(e.font),s&&a(t,n,o,r,!0)),x.apply(this,arguments)},{enable:function(t){c=!!t}}}});
!function(e,t){"object"==typeof module&&module.exports?module.exports=t():e["canvas-text-opentypejs-shim"]=t()}(this,function(){function e(e){var t=[e.lastIndexOf(" ",e.indexOf(","))+1||-1,e.indexOf('"'),e.indexOf("'")].reduce(function(e,t){return~t&&t<e?t:e},e.lastIndexOf(" ")),n=e.slice(0,t).trim().split(/\s+/),a=n[n.length-1],i=a.indexOf("/"),o={fontStyle:"normal",fontVariant:"normal",fontWeight:"normal",fontStretch:"normal",fontSize:~i?a.slice(0,i):a,lineHeight:~i?a.slice(i+1):"normal",fontFamily:e.slice(t)};return n.slice(0,-1).forEach(function(e){switch(e){case"normal":break;case"italic":case"oblique":o.fontStyle=e;break;case"small-caps":o.fontVariant=e;break;case"bold":case"bolder":case"lighter":case"100":case"200":case"300":case"400":case"500":case"600":case"700":case"800":case"900":o.fontWeight=e;break;case"ultra-condensed":case"extra-condensed":case"condensed":case"semi-condensed":case"semi-expanded":case"expanded":case"extra-expanded":case"ultra-expanded":o.fontStretch=e}}),o}function t(e,t,n){for(var a=0,i=0,o=0,s=t.stringToGlyphs(e),r=0;r<s.length;r++){var c=s[r];c.advanceWidth&&(o+=c.advanceWidth),r<s.length-1&&(o+=t.getKerningValue(c,s[r+1])),c.yMax&&(a=Math.max(a,c.yMax)),c.yMin&&(i=Math.min(i,c.yMin))}var l=1/t.unitsPerEm*n;return{width:o*l,actualBoundingBoxAscent:a*l,actualBoundingBoxDescent:i*l,fontBoundingBoxAscent:t.ascender*l,fontBoundingBoxDescent:t.descender*l}}return function(n,a){function i(e,a,i,o,s){var l=i,f=a;if("alphabetic"!==n.textBaseline||"start"!==n.textAlign&&"left"!==n.textAlign){var d=t(e,c,r);"top"===n.textBaseline?l+=d.actualBoundingBoxAscent-d.fontBoundingBoxDescent:"hanging"===n.textBaseline?l+=d.actualBoundingBoxAscent:"middle"===n.textBaseline?l+=d.actualBoundingBoxAscent/2:"ideographic"!==n.textBaseline&&"bottom"!==n.textBaseline||(l+=d.fontBoundingBoxDescent),"right"===n.textAlign||"end"===n.textAlign?f-=d.width:"center"===n.textAlign&&(f-=d.width/2)}var u=c.getPath(e,f,l,r);s?(u.fill=null,u.stroke=n.strokeStyle):u.fill=n.fillStyle,u.draw(n)}function o(t){if(s!==t){var n=e(t);if(!/\d+px/.test(n.fontSize))throw new Error('font-size must be in "px"');if(c=a.resolveFont(n),!c&&l)throw new Error("Font instance wasn't found (\""+n.fontFamily+'")');r=parseInt(n.fontSize,10)}s=t}var s,r,c,l="boolean"!=typeof a.strict||a.strict,f=!0,d=n.measureText;n.measureText=function(e){return f&&(o(n.font),c)?t(e,c,r):d.apply(this,arguments)};var u=n.fillText;n.fillText=function(e,t,a,s){return f&&(o(n.font),c)?i(e,t,a,s,!1):u.apply(this,arguments)};var x=n.strokeText;return n.strokeText=function(e,t,a,s){return f&&(o(n.font),c&&i(e,t,a,s,!0)),x.apply(this,arguments)},{enable:function(e){f=!!e}}}});

@@ -11,12 +11,39 @@ // https://github.com/shyiko/canvas-text-opentypejs-shim

const fs = require('fs')
const applyCanvasTextOpenTypeJsShim =
const useOpenTypeJsForText =
(() => { try { return require('../canvas-text-opentypejs-shim') } catch (e) {} })() ||
require('canvas-text-opentypejs-shim')
fetch('https://fonts.gstatic.com/s/roboto' +
'/v15/QHD8zigcbDB8aPfIoaupKOvvDin1pK8aKteLpeZ5c0A.ttf')
// this way fabric tends to yield more consistent results when compared to
// CanvasRenderingContext2D.drawText
fabric.Text.prototype._fontSizeMult = 1.25
/**
* @param fontFamily e.g. "'Open Sans', sans-serif"
* @return e.g. ["Open Sans", "sans-serif"]
*/
function splitFontFamily (fontFamily) {
return fontFamily.split(',')
.map((f) => f.trim().replace(/^['"]/, '').replace(/['"]$/, ''))
.filter(Boolean)
}
// making sure whatever context is used to measure/draw text it has shim active
// (given openTypeJsShimConfig was provided)
fabric.Text.prototype._setTextStyles = (function (original) {
return function (ctx) {
var cfg = this.openTypeJsShimConfig
if (cfg && !ctx.measureText.__openTypeJsShimConfig) {
useOpenTypeJsForText(ctx, cfg)
ctx.measureText.__openTypeJsShimConfig = cfg
}
return original.call(this, ctx)
}
})(fabric.Text.prototype._setTextStyles)
fetch('https://rawgit.com/google/fonts/master/apache/' +
'opensans/OpenSans-Regular.ttf')
.then((res) => new Promise((resolve, reject) => {
res.body
.on('error', reject)
.pipe(fs.createWriteStream('Roboto.ttf'))
.pipe(fs.createWriteStream('OpenSans-Regular.ttf'))
.on('error', reject)

@@ -26,18 +53,19 @@ .on('finish', resolve)

.then(() => {
const font = opentype.loadSync('Roboto.ttf')
const font = opentype.loadSync('OpenSans-Regular.ttf')
const canvas = fabric.createCanvasForNode(this.width, this.height)
applyCanvasTextOpenTypeJsShim(canvas.contextContainer, {
const ctx = fabric.createCanvasForNode(200, 200)
const shimConfig = {
resolveFont: function (o) {
if (o.fontFamily.trim().replace(/^['"]/, '').replace(/['"]$/, '') === 'Roboto') {
if (splitFontFamily(o.fontFamily)[0] === 'Open Sans') {
return font
}
}
})
}
canvas.add(new fabric.Text('Hello World', {
left: 0, top: 0, fontFamily: 'Roboto', fontSize: 26
ctx.add(new fabric.Text('Hello World', {
left: -0.5, top: -0.5, fontFamily: 'Open Sans', fontSize: 26,
openTypeJsShimConfig: shimConfig
}))
console.log(`<img src="${canvas.toDataURL()}">`)
console.log(`<img src="${ctx.toDataURL()}">`)
})

@@ -11,12 +11,22 @@ // https://github.com/shyiko/canvas-text-opentypejs-shim

const fs = require('fs')
const applyCanvasTextOpenTypeJsShim =
const useOpenTypeJsForText =
(() => { try { return require('../canvas-text-opentypejs-shim') } catch (e) {} })() ||
require('canvas-text-opentypejs-shim')
fetch('https://fonts.gstatic.com/s/roboto' +
'/v15/QHD8zigcbDB8aPfIoaupKOvvDin1pK8aKteLpeZ5c0A.ttf')
/**
* @param fontFamily e.g. "'Open Sans', sans-serif"
* @return e.g. ["Open Sans", "sans-serif"]
*/
function splitFontFamily (fontFamily) {
return fontFamily.split(',')
.map((f) => f.trim().replace(/^['"]/, '').replace(/['"]$/, ''))
.filter(Boolean)
}
fetch('https://rawgit.com/google/fonts/master/apache/' +
'opensans/OpenSans-Regular.ttf')
.then((res) => new Promise((resolve, reject) => {
res.body
.on('error', reject)
.pipe(fs.createWriteStream('Roboto.ttf'))
.pipe(fs.createWriteStream('OpenSans-Regular.ttf'))
.on('error', reject)

@@ -26,9 +36,9 @@ .on('finish', resolve)

.then(() => {
const font = opentype.loadSync('Roboto.ttf')
const font = opentype.loadSync('OpenSans-Regular.ttf')
const canvas = new NodeCanvas(200, 200)
const ctx = canvas.getContext('2d')
applyCanvasTextOpenTypeJsShim(ctx, {
useOpenTypeJsForText(ctx, {
resolveFont: function (o) {
if (o.fontFamily === 'Roboto') {
if (splitFontFamily(o.fontFamily)[0] === 'Open Sans') {
return font

@@ -39,7 +49,7 @@ }

ctx.font = '26px Roboto'
ctx.font = '26px "Open Sans"'
ctx.fillText('Hello World', 0, 26)
console.log(canvas.toBuffer())
console.log(`<img src="data:image/png;base64,${canvas.toBuffer().toString('base64')}">`)
})
{
"name": "canvas-text-opentypejs-shim",
"version": "0.1.1",
"version": "0.1.2",
"description": "Consistent text rendering for <canvas>",

@@ -5,0 +5,0 @@ "author": "Stanley Shyiko <stanley.shyiko@gmail.com>",

@@ -22,3 +22,3 @@ # canvas-text-opentypejs-shim

```javascript
const applyCanvasTextOpenTypeJsShim = require('canvas-text-opentypejs-shim')
const useOpenTypeJsForText = require('canvas-text-opentypejs-shim')

@@ -28,3 +28,3 @@ const canvas ...

applyCanvasTextOpenTypeJsShim(ctx, {resolveFont: (o) => opentypeFontInstance})
useOpenTypeJsForText(ctx, {resolveFont: (o) => opentypeFontInstance})

@@ -31,0 +31,0 @@ ctx.font = '26px Roboto'

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc