diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/mathml/tools/utils | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/mathml/tools/utils')
3 files changed, 251 insertions, 0 deletions
diff --git a/testing/web-platform/tests/mathml/tools/utils/__init__.py b/testing/web-platform/tests/mathml/tools/utils/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/utils/__init__.py diff --git a/testing/web-platform/tests/mathml/tools/utils/mathfont.py b/testing/web-platform/tests/mathml/tools/utils/mathfont.py new file mode 100644 index 0000000000..d030c9f2ce --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/utils/mathfont.py @@ -0,0 +1,218 @@ +import fontforge + +PUA_startCodePoint = 0xE000 +em = 1000 + +def create(aName, aCopyRight): + print("Generating %s.woff..." % aName, end="") + mathFont = fontforge.font() + mathFont.fontname = aName + mathFont.familyname = aName + mathFont.fullname = aName + mathFont.copyright = aCopyRight + mathFont.encoding = "UnicodeFull" + + # Create a space character. Also force the creation of some MATH subtables + # so that OTS will not reject the MATH table. + g = mathFont.createChar(ord(" "), "space") + g.width = em + g.italicCorrection = 0 + g.topaccent = 0 + g.mathKern.bottomLeft = tuple([(0,0)]) + g.mathKern.bottomRight = tuple([(0,0)]) + g.mathKern.topLeft = tuple([(0,0)]) + g.mathKern.topRight = tuple([(0,0)]) + mathFont[ord(" ")].horizontalVariants = "space" + mathFont[ord(" ")].verticalVariants = "space" + return mathFont + +def drawRectangleGlyph(glyph, width, ascent, descent = 0, padding_left = 0): + p = glyph.glyphPen() + p.moveTo(padding_left, -descent) + p.lineTo(padding_left, ascent) + p.lineTo(padding_left + width, ascent) + p.lineTo(padding_left + width, -descent) + p.closePath(); + glyph.width = padding_left + width + +def createSquareGlyph(aFont, aCodePoint): + g = aFont.createChar(aCodePoint) + drawRectangleGlyph(g, em, em, 0) + +def drawHexaDigit(aGlyph, aX, aValue): + t = em / 10 + p = aGlyph.glyphPen(replace = False) + if aValue == 0: + p.moveTo(aX + t, t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.closePath() + elif aValue == 1: + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + elif aValue == 2: + p.moveTo(aX + t, em - t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, em / 2) + p.lineTo(aX + t, em / 2) + p.lineTo(aX + t, t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + elif aValue == 3: + p.moveTo(aX + t, em - t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.lineTo(aX + t, t) + p.endPath() + p.moveTo(aX + t, em / 2) + p.lineTo(aX + em / 2 - 2.5 * t, em / 2) + p.endPath() + elif aValue == 4: + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + p.moveTo(aX + t, em - t) + p.lineTo(aX + t, em / 2) + p.lineTo(aX + em / 2 - 2.5 * t, em / 2) + p.endPath() + elif aValue == 5: + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + t, em / 2) + p.lineTo(aX + em / 2 - t, em / 2) + p.lineTo(aX + em / 2 - t, t) + p.lineTo(aX + t, t) + p.endPath() + elif aValue == 6: + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + t, t) + p.lineTo(aX + em / 2 - t, t) + p.lineTo(aX + em / 2 - t, em / 2) + p.lineTo(aX + 2.5 * t, em / 2) + p.endPath() + elif aValue == 7: + p.moveTo(aX + t, em - t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + elif aValue == 8: + p.moveTo(aX + t, t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.closePath() + p.moveTo(aX + 2.5 * t, em / 2) + p.lineTo(aX + em / 2 - 2.5 * t, em / 2) + p.endPath() + elif aValue == 9: + p.moveTo(aX + t, t) + p.lineTo(aX + em / 2 - t, t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + t, em / 2) + p.lineTo(aX + em / 2 - 2.5 * t, em / 2) + p.endPath() + elif aValue == 10: # A + p.moveTo(aX + t, t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + p.moveTo(aX + 2.5 * t, em / 2) + p.lineTo(aX + em / 2 - 2.5 * t, em / 2) + p.endPath() + elif aValue == 11: # b + p.moveTo(aX + t, em - t) + p.lineTo(aX + t, t) + p.lineTo(aX + em / 2 - t, t) + p.lineTo(aX + em / 2 - t, em / 2) + p.lineTo(aX + 2.5 * t, em / 2) + p.endPath() + elif aValue == 12: # C + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + t, t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + elif aValue == 13: # d + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.lineTo(aX + t, t) + p.lineTo(aX + t, em / 2) + p.lineTo(aX + em / 2 - 2.5 * t, em / 2) + p.endPath() + elif aValue == 14: # E + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + t, t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + p.moveTo(aX + em / 2 - t, em / 2) + p.lineTo(aX + 2.5 * t, em / 2) + p.endPath() + elif aValue == 15: # F + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + t, t) + p.endPath() + p.moveTo(aX + em / 2 - t, em / 2) + p.lineTo(aX + 2.5 * t, em / 2) + p.endPath() + +def createGlyphFromValue(aFont, aCodePoint): + g = aFont.createChar(aCodePoint) + value = aCodePoint + for i in range(0, 5): + drawHexaDigit(g, (5 - (i + 1)) * em / 2, value % 16) + value /= 16 + g.width = 5 * em / 2 + g.stroke("circular", em / 10, "square", "miter", "cleanup") + +def createSizeVariants(aFont, aUsePUA = False): + if aUsePUA: + codePoint = PUA_startCodePoint + else: + codePoint = -1 + for size in (0, 1, 2, 3): + g = aFont.createChar(codePoint, "v%d" % size) + drawRectangleGlyph(g, em, (size + 1) * em, 0) + if aUsePUA: + codePoint += 1 + g = aFont.createChar(codePoint, "h%d" % size) + drawRectangleGlyph(g, (size + 1) * em, em, 0) + if aUsePUA: + codePoint += 1 + +def createStretchy(aFont, codePoint, isHorizontal): + if isHorizontal: + aFont[codePoint].horizontalVariants = "h0 h1 h2 h3" + # Part: (glyphName, isExtender, startConnector, endConnector, fullAdvance) + aFont[codePoint].horizontalComponents = \ + (("h2", False, 0, em, 3 * em), \ + ("h1", True, em, em, 2 * em)) + else: + aFont[codePoint].verticalVariants = "v0 v1 v2 v3" + # Part: (glyphName, isExtender, startConnector, endConnector, fullAdvance) + aFont[codePoint].verticalComponents = \ + (("v2", False, 0, em, 3 * em), \ + ("v1", True, em, em, 2 * em)) + +def save(aFont): + aFont.em = em + aFont.ascent = aFont.hhea_ascent = aFont.os2_typoascent = em + aFont.descent = aFont.hhea_descent = aFont.os2_typodescent = 0 + # aFont.os2_winascent, aFont.os2_windescent should be the maximum of + # ascent/descent for all glyphs. Does fontforge compute them automatically? + aFont.hhea_ascent_add = aFont.hhea_descent_add = 0 + aFont.os2_typoascent_add = aFont.os2_typodescent_add = 0 + aFont.os2_winascent_add = aFont.os2_windescent_add = 0 + aFont.os2_use_typo_metrics = True + aFont.generate("../../fonts/math/%s.woff" % aFont.fontname) + if aFont.validate() == 0: + print(" done.") + else: + print(" validation error!") + exit(1) diff --git a/testing/web-platform/tests/mathml/tools/utils/misc.py b/testing/web-platform/tests/mathml/tools/utils/misc.py new file mode 100644 index 0000000000..89ec1bdf80 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/utils/misc.py @@ -0,0 +1,33 @@ +import os +import progressbar +from urllib.request import urlopen + +UnicodeXMLURL = "https://raw.githubusercontent.com/w3c/xml-entities/gh-pages/unicode.xml" +InlineAxisOperatorsURL = "https://w3c.github.io/mathml-core/tables/inline-axis-operators.txt" + +def downloadWithProgressBar(url, outputDirectory="./", forceDownload=False): + + baseName = os.path.basename(url) + fileName = os.path.join(outputDirectory, baseName) + + if not forceDownload and os.path.exists(fileName): + return fileName + + request = urlopen(url) + totalSize = int(request.info().get('Content-Length').strip()) + bar = progressbar.ProgressBar(maxval=totalSize).start() + + chunkSize = 16 * 1024 + downloaded = 0 + print("Downloading %s" % url) + os.umask(0o002) + with open(fileName, 'wb') as fp: + while True: + chunk = request.read(chunkSize) + downloaded += len(chunk) + bar.update(downloaded) + if not chunk: break + fp.write(chunk) + bar.finish() + + return fileName |