javascript
  • css
  • 2013-01-23 101 views 11 likes 
    11

    某些字体不支持CSS斜体或粗体(例如,Zapfino不支持斜体,因为它已经非常符合脚本)。我想检测何时不支持字体样式,因此我可以在编辑器中禁用样式按钮。检测粗体和斜体支持

    我试过的东西like this

    that.checkFontData = function(fontList) 
    { var test = $("<span style='font-size:24px;absolute;visibility:hidden;height:auto;width:auto;white-space:nowrap;'>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678910</span>"); 
        $('body').append(test); 
        for (var i= 0, iMax = fontList.length; i < iMax; ++i) 
        { test.css('fontFamily', fontList[i]); 
         var normalWidth = test.outerWidth(true); 
         var normalHeight = test.outerHeight(true); 
         test.css('fontStyle', 'italic'); 
         var italicWidth = test.outerWidth(true); 
         var italicHeight = test.outerHeight(true); 
         test.css('fontStyle', 'normal'); 
         test.css('fontWeight', 'bold'); 
         var boldWidth = test.outerWidth(true); 
         var boldHeight = test.outerHeight(true); 
         console.log(fontList[i] + ", normal: " + normalWidth + ", bold: " + boldWidth + ", italic: " + italicWidth ); 
        } 
        test.remove(); 
    }; 
    

    ,但它不工作...许多字体的斜体提供或加粗的报告相同的宽度。

    接下来,我想用canvas元素来检测这个,但是,唉,firefox甚至不会在画布中呈现斜体文本,所以那个想法就不明显了。

    你会建议什么?

    +1

    OCR,如果真的很重要。不能拿出更好的东西 – user1721135

    +1

    手动检查它,并硬编码结果 – P1nGu1n

    +2

    像P1nGu1n这样的硬编码结果将是我脑海中最好的最合理的解决方案。大概你控制自己的字体 - 这应该很容易。 – rlemon

    回答

    0

    使用Font.js,您可能对字体指标有更可靠的访问权限进行计算。 http://pomax.nihongoresources.com/pages/Font.js

    1

    我测试过的的jsfiddle你的代码,它确实给不同尺寸的天然网络字体像GeorgiaArial,而不是像Snowburst One(Googlefont)外部加载字体。

    JS fiddle of your script

    经过一番研究,我发现,为@font-face加载字体没有CSS字体转换应用。人们加载@font-face变化和应用它们,像这样:

    body { font-family:"DroidSerifRegular", Georgia, serif; } 
    h1 { 
        font-family:"DroidSerifBold", Georgia, serif; 
        font-weight:normal; 
    } 
    em { 
        font-family:"DroidSerifItalic", Georgia, serif; 
        font-weight:normal; 
        font-style:normal; 
    } 
    strong em { 
        font-family:"DroidSerifBoldItalic", Georgia, serif; 
        font-weight:normal; 
        font-style:normal; 
    } 
    

    如果您正在使用@font-face字体有像上面的例子变化,你也许可以想出某种命名约定。然后,您可以通过检查宽度与备用字体的比较来检查这些字体是否存在。

    test.css('fontFamily', 'sans-serif'); 
    var defaultWidth = test.outerWidth(true); 
    
    for (var i= 0, iMax = fontList.length; i < iMax; ++i) 
    { test.css('fontFamily', fontList[i] + ', sans-serif'); 
    
        var normalWidth = test.outerWidth(true); 
        var normalHeight = test.outerHeight(true); 
        test.css('fontFamily', fontList[i] + 'Italic, sans-serif'); 
        var italicWidth = test.outerWidth(true); 
        var italicHeight = test.outerHeight(true); 
        test.css('fontFamily', fontList[i] + 'Bold, sans-serif'); 
        var boldWidth = test.outerWidth(true); 
        var boldHeight = test.outerHeight(true); 
        console.log("default: "+ defaultWidth + ", " fontList[i] + ", normal: " + normalWidth + ", bold: " + boldWidth + ", italic: " + italicWidth ); 
    } 
    

    如果样式版本的宽度与默认宽度相比,则它是“宾果”!

    注意:这对于等宽字体无效,因为所有字符的宽度始终相同。

    +0

    在你的jsfiddle,你只测试格鲁吉亚,从来没有Arial。尝试用'var fontlist = [“Georgia”,“Arial”]替换第一行;'你会看到Arial在正常和斜体中获得相同的尺寸。 – pieroxy

    +0

    我解决了数组的问题。导致相同的尺寸,因为当装入新的数组项时,样式不会被清除。我已更新我的示例来解决此问题。 –

    +0

    啊,我看到我困惑的地方。您的Arial方法根据不同的浏览器/操作系统组合给出不同的大小。 Windows Firefox和Chrome为Arial Italic报告不同的维度,但IE和Linux上的所有浏览器都为Arial Italic和Arial返回相同的维度。所以,这是一个打击和小姐... – pieroxy

    4

    要检测加粗斜体支持,您可以将文本转换为图像并进行比较。

    做到这一点的方法是:

    1. 创建canvas见下面(不需要将它添加到DOM)在canvas
    2. 画文本画布转换成图片(这里我用png
    3. 比较图片的base64字符串

    关于canvas

    接下来,我想用帆布元素检测出来,但是,唉,火狐甚至不呈现在画布斜体文字,这样搞砸这一想法。

    由于本地斜体字体不存在,因此某些字体在Firefox的画布中不是斜体。其他浏览器会尝试伪造(倾斜)字体。

    View on jsFiddle(这个演示也测试了谷歌的字体Snowburst One

    function detectBoldItalic(fonts) { 
        // Create canvas 
        var canvas = document.createElement('canvas'); 
        canvas.width = 1000; 
        canvas.height = 30; 
        var context = canvas.getContext("2d"); 
        var test = {}, results = {}; 
        // Default 
        context.font = "normal 16px a base case font"; 
        context.fillText("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678910", 10, 20); 
        var standard = canvas.toDataURL("image/png"); 
        context.setTransform(1, 0, 0, 1, 0, 0); 
        context.clearRect(0, 0, canvas.width, canvas.height); 
        // Start test 
        for (var i = 0; i < fonts.length; i++) { 
         var styles = ["normal", "bold", "italic"]; 
         test[fonts[i]] = {}; 
         results[fonts[i]] = {}; 
         for (var j = 0; j < styles.length; j++) { 
          // Draw text in canvas 
          context.font = styles[j] + " 16px " + fonts[i]; 
          context.fillText("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678910", 10, 20); 
          // Convert canvas to png 
          test[fonts[i]][styles[j]] = canvas.toDataURL("image/png"); 
          // Clear canvas 
          context.setTransform(1, 0, 0, 1, 0, 0); 
          context.clearRect(0, 0, canvas.width, canvas.height); 
         } 
         if (test[fonts[i]]["normal"] !== standard) { 
          results[fonts[i]]["bold"] = test[fonts[i]]["normal"] !== test[fonts[i]]["bold"] ? true:false; // Support bold 
          results[fonts[i]]["italic"] = test[fonts[i]]["normal"] !== test[fonts[i]]["italic"] ? true:false; // Support italic 
         } else { 
          results[fonts[i]] = false; // Font does not exist 
         } 
        } 
        return results; 
    } 
    console.log(detectBoldItalic(["Arial","Zapfino"])); 
    
    +0

    我相信没有办法指定'font-stretch:condensed'在画布元素上。所以我相信没有办法使用你的方法来检测对斜体/粗体'Arial Narrow'字体的支持。您的答案仍然是最好的,但具有其他优点 - 特别是因为它能够区分更精确的不同字体样式。 – pieroxy

    相关问题