跳转到内容

User:What7what8/NoMoreMissingGlyphs.js

维基百科,自由的百科全书
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
const { ceil, floor, max, min } = Math;
function getCssValue(element, property) {
  return window.getComputedStyle(element, null).getPropertyValue(property)
}

function getCssValues(element, properties) {
  const styles = window.getComputedStyle(element, null)

  return properties.map(p => styles.getPropertyValue(p))
}
const fontStretches = {
  "50%": "ultra-condensed",
  "62.5%": "extra-condensed",
  "75%": "condensed",
  "87.5%": "semi-condensed",
  "100%": "normal",
  "112.5%": "semi-expanded",
  "125%": "expanded",
  "150%": "extra-expanded",
  "200%": "ultra-expanded"
}

function getFont(element) {
  const style = window.getComputedStyle(element, null)
  let font = style.getPropertyValue("font")

  if (!font) {
    const fontStyle = style.getPropertyValue("font-style")
    const fontVariant = style.getPropertyValue("font-variant")
    const fontWeight = style.getPropertyValue("font-weight")
    const fontStretch =
      fontStretches[style.getPropertyValue("font-stretch")] || ""
    const fontSize = style.getPropertyValue("font-size")
    const lineHeight = style.getPropertyValue("line-height")
    const fontFamily = style.getPropertyValue("font-family")

    font = (
      fontStyle +
      " " +
      fontVariant +
      " " +
      fontWeight +
      " " +
      fontStretch +
      " " +
      fontSize +
      (lineHeight ? " / " + lineHeight : "") +
      " " +
      fontFamily
    )
      .replace(/ +/g, " ")
      .trim()
  }

  return font
}
const cachedMetrics = {}
function getFontMetrics(elementOrFont, specificChar) {
  let font

  if (typeof elementOrFont === "string") font = elementOrFont
  else font = getFont(elementOrFont)

  let metrics = !specificChar && cachedMetrics[font]

  if (metrics) return metrics

  let testFont = font
  let fontSize = 12
  let testFontSize = 12
  const fontParts = /(.?\b)((?:\d|\.)+)(px\b.)/.exec(font)

  // Double the font size so there's more pixel detail to scan, then scale down the result afterward.
  if (fontParts) {
    fontSize = parseFloat(fontParts[2])
    testFontSize = fontSize * 2
    testFont = fontParts[1] + testFontSize + fontParts[3]
  }

  const sampleText1 = "Eg"
  const sampleText2 = "ÅÊ"

  let lineHeight = fontSize * 1.2
  const padding = min(50, lineHeight * 1.5)
  const heightDiv = document.createElement("div")

  heightDiv.style.position = "absolute"
  heightDiv.style.opacity = "0"
  heightDiv.style.font = font
  heightDiv.innerHTML = sampleText1 + "<br>" + sampleText1
  document.body.appendChild(heightDiv)

  const heightDivHeight = parseFloat(
    getCssValue(heightDiv, "height").replace("px", "")
  )

  if (heightDivHeight >= fontSize * 2) lineHeight = heightDivHeight / 2

  document.body.removeChild(heightDiv)

  const canvas =
    getFontMetrics.canvas ||
    (getFontMetrics.canvas = document.createElement("canvas"))

  canvas.width = testFontSize * 2 + padding
  canvas.height = testFontSize * 3
  canvas.style.opacity = "1"

  const context = canvas.getContext("2d",{ willReadFrequently: true })
  const w = canvas.width,
    w4 = w * 4,
    h = canvas.height,
    baseline = h / 2

  context.fillStyle = "white"
  context.fillRect(-1, -1, w + 2, h + 2)
  context.fillStyle = "black"
  context.font = testFont
  context.fillText(sampleText1, padding / 2, baseline)

  let pixels = context.getImageData(0, 0, w, h).data
  let i = 0
  const len = pixels.length

  // Finding the ascent uses a normal, forward scanline
  while (++i < len && pixels[i] > 192) {}
  let ascent = baseline - floor(i / w4)

  // Finding the descent uses a reverse scanline
  i = len - 1
  while (--i > 0 && pixels[i] > 192) {}
  let descent = floor(i / w4) - baseline

  context.fillStyle = "white"
  context.fillRect(-1, -1, w + 2, h + 2)
  context.fillStyle = "black"
  context.fillText(sampleText2, padding / 2, baseline)
  pixels = context.getImageData(0, 0, w, h).data

  // Find full ascent, including diacriticals.
  i = 0
  while (++i < len && pixels[i] > 192) {}
  let fullAscent = baseline - floor(i / w4)

  let extraAscent = fullAscent
  let extraDescent = descent

  if (specificChar) {
    context.fillStyle = "white"
    context.fillRect(-1, -1, w + 2, h + 2)
    context.fillStyle = "black"
    context.fillText(specificChar, padding / 2, baseline)
    pixels = context.getImageData(0, 0, w, h).data

    // Find ascent of specificChar.
    i = 0
    while (++i < len && pixels[i] > 192) {}
    extraAscent = max(floor(i / w4) - baseline, fullAscent)

    // Find descent of specificChar.
    i = len - 1
    while (--i > 0 && pixels[i] > 192) {}
    extraDescent = max(floor(i / w4) - baseline, descent)
  }

  if (testFontSize > fontSize) {
    ascent = ceil(ascent / 2)
    fullAscent = ceil(fullAscent / 2)
    descent = ceil(descent / 2)
    extraAscent = ceil(extraAscent / 2)
    extraDescent = ceil(extraDescent / 2)
  }

  const leading = lineHeight - fullAscent - descent

  metrics = { font, lineHeight, ascent, fullAscent, descent, leading }

  if (!specificChar) cachedMetrics[font] = metrics
  else {
    metrics.extraAscent = extraAscent
    metrics.extraDescent = extraDescent
    metrics.extraLineHeight = max(extraAscent + extraDescent, lineHeight)
  }

  return metrics
}

function doesCharacterGlyphExist(elementOrFont, charOrCodePoint) {
  if (typeof charOrCodePoint === "number")
    charOrCodePoint = String.fromCodePoint(charOrCodePoint)

  const metrics = getFontMetrics(elementOrFont)
  const PADDING = 8
  const size = metrics.lineHeight + PADDING

  const canvas0 =
    doesCharacterGlyphExist.canvas0 ||
    (doesCharacterGlyphExist.canvas0 = document.createElement("canvas"))
  const canvas1 =
    doesCharacterGlyphExist.canvas1 ||
    (doesCharacterGlyphExist.canvas1 = document.createElement("canvas"))
  const canvases = [canvas0, canvas1]
  const pixmaps = []

  for (let i = 0; i < 2; ++i) {
    const canvas = canvases[i]

    canvas.width = size
    canvas.height = size
    canvas.style.opacity = "1"

    const context = canvas.getContext("2d",{ willReadFrequently: true })

    context.fillStyle = "white"
    context.fillRect(-1, -1, size + 2, size + 2)
    context.fillStyle = "black"
    context.font = metrics.font
    // Compare pixels for test character to pixels for known character without a glyph
    context.fillText(i === 0 ? charOrCodePoint : "\uFFFE", 0, metrics.ascent)

    pixmaps[i] = context.getImageData(0, 0, size, size).data
  }

  for (let i = 0; i < pixmaps[0].length; ++i) {
    if (pixmaps[0][i] !== pixmaps[1][i]) return true
  }

  return false
}

//----------------------------A simple line----------------------------

function unique(str) {
  return String.prototype.concat.call(...new Set(str));
}

function string2unicode(str){
  var ret ="";
  for(var i=0; i<str.length; i++){
       ret += "\\u" + str.charCodeAt(i).toString(16);
    }
    return ret;
}
//mw.loader.load("https://github.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic-Project/raw/main/PlangothicP2-Regular.ttf")
//mw.loader.load("https://github.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic-Project/raw/main/PlangothicP1-Regular%20(allideo).ttf")
$(function() {
	$('head').append(
		`<style>
		@font-face {
			font-family: P1;
			src: url("//github.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic-Project/raw/main/PlangothicP1-Regular%20(allideo).ttf") format("truetype");
		}
		@font-face {
			font-family: P2;
			src: url("//github.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic-Project/raw/main/PlangothicP2-Regular.ttf") format("truetype");
		}
		</style>`
		)
	$('head').append(`<span id="P1test" style="font-family=P1"></span><span id="P2test" style="font-family=P2"></span>`)
	$('#content').each(function(i,obj) {
		if (obj.innerText != null && obj.innerText !== ''){
			let needcheck = unique(obj.innerText)
			for (let checkchar of needcheck) {
				if(!doesCharacterGlyphExist(obj,checkchar)){
					console.log(checkchar+" Uni:"+string2unicode(checkchar))
				}
			}
		}
		/*
		for (var key in obj.innerText) {
			| trash code
			v
			console.log(obj.innerText[key]+":"+doesCharacterGlyphExist(obj,obj.innerText[key]))
		}
		*/
		
	});
})