当前位置:   article > 正文

在C#中将Base64编码的WOFF字符串转OTF字体并动态加载_31:/##x7qvzcx9ialhxnu##2:/$dtwpg5n$

31:/##x7qvzcx9ialhxnu##2:/$dtwpg5n$

项目需求

在某项目中有这样后个需求:有些字体使用了内嵌的Base64格式表示,如下所示:
(注,由于比较长,所以显示时有可能会自动隐藏)

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
  • 1

现在需要将这些代码转换为字体文件,并加载显示。

第1步 Base64 转 二进制字节

C#内置了Base64的处理代码,内容如下:

string base64string = "d09GRgABAAAA...(省略中间内容)...bTMgAAAA==";
byte[] bytes = Convert.FromBase64String(base64string);
  • 1
  • 2

第2步:WOFF 格式转 OTF

由于在C#中没有提供对WOFF格式的直接支持,所以这里引用了一个GitHub上别人写好的代码,用于将WOFF格式转为OTF格式,地址为 https://github.com/hanikesn,内容如下:

#!/usr/bin/env python3
#
# Copyright 2012, Steffen Hanikel (https://github.com/hanikesn)
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
# A tool to convert a WOFF back to a TTF/OTF font file, in pure Python

import struct
import sys
import zlib


def convert_streams(infile, outfile):
    WOFFHeader = {'signature': struct.unpack(">I", infile.read(4))[0],
                  'flavor': struct.unpack(">I", infile.read(4))[0],
                  'length': struct.unpack(">I", infile.read(4))[0],
                  'numTables': struct.unpack(">H", infile.read(2))[0],
                  'reserved': struct.unpack(">H", infile.read(2))[0],
                  'totalSfntSize': struct.unpack(">I", infile.read(4))[0],
                  'majorVersion': struct.unpack(">H", infile.read(2))[0],
                  'minorVersion': struct.unpack(">H", infile.read(2))[0],
                  'metaOffset': struct.unpack(">I", infile.read(4))[0],
                  'metaLength': struct.unpack(">I", infile.read(4))[0],
                  'metaOrigLength': struct.unpack(">I", infile.read(4))[0],
                  'privOffset': struct.unpack(">I", infile.read(4))[0],
                  'privLength': struct.unpack(">I", infile.read(4))[0]}

    outfile.write(struct.pack(">I", WOFFHeader['flavor']));
    outfile.write(struct.pack(">H", WOFFHeader['numTables']));
    maximum = list(filter(lambda x: x[1] <= WOFFHeader['numTables'], [(n, 2**n) for n in range(64)]))[-1]; 
    searchRange = maximum[1] * 16
    outfile.write(struct.pack(">H", searchRange));
    entrySelector = maximum[0]
    outfile.write(struct.pack(">H", entrySelector));
    rangeShift = WOFFHeader['numTables'] * 16 -  searchRange;
    outfile.write(struct.pack(">H", rangeShift));

    offset = outfile.tell()

    TableDirectoryEntries = []
    for i in range(0, WOFFHeader['numTables']):
        TableDirectoryEntries.append({'tag': struct.unpack(">I", infile.read(4))[0],
                               'offset': struct.unpack(">I", infile.read(4))[0],
                               'compLength': struct.unpack(">I", infile.read(4))[0],
                               'origLength': struct.unpack(">I", infile.read(4))[0],
                               'origChecksum': struct.unpack(">I", infile.read(4))[0]})
        offset += 4*4
        
    for TableDirectoryEntry in TableDirectoryEntries:   
        outfile.write(struct.pack(">I", TableDirectoryEntry['tag']))
        outfile.write(struct.pack(">I", TableDirectoryEntry['origChecksum']))
        outfile.write(struct.pack(">I", offset))
        outfile.write(struct.pack(">I", TableDirectoryEntry['origLength']))
        TableDirectoryEntry['outOffset'] = offset
        offset += TableDirectoryEntry['origLength']
        if (offset % 4) != 0:
            offset += 4 - (offset % 4)
            
    for TableDirectoryEntry in TableDirectoryEntries:
        infile.seek(TableDirectoryEntry['offset'])
        compressedData = infile.read(TableDirectoryEntry['compLength'])
        if TableDirectoryEntry['compLength'] != TableDirectoryEntry['origLength']:
            uncompressedData = zlib.decompress(compressedData)
        else:
            uncompressedData = compressedData
        outfile.seek(TableDirectoryEntry['outOffset'])
        outfile.write(uncompressedData)
        offset = TableDirectoryEntry['outOffset'] + TableDirectoryEntry['origLength'];
        padding = 0
        if (offset % 4) != 0:
            padding = 4 - (offset % 4)
        outfile.write(bytearray(padding));


def convert(infilename, outfilename):
    with open(infilename , mode='rb') as infile:
        with open(outfilename, mode='wb') as outfile:
            convert_streams(infile, outfile)


def main(argv):
    if len(argv) == 1 or len(argv) > 3:
        print('I convert *.woff files to *.otf files. (one at a time :)\n'
              'Usage: woff2otf.py web_font.woff [converted_filename.otf]\n'
              'If the target file name is omitted, it will be guessed. Have fun!\n')
        return

    source_file_name  = argv[1]
    if len(argv) == 3:
        target_file_name = argv[2]
    else:
        target_file_name = source_file_name.rsplit('.', 1)[0] + '.otf'

    convert(source_file_name, target_file_name)
    return 0


if __name__ == '__main__':
    sys.exit(main(sys.argv))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110

运行代码

./woff2otf.py font.woff font.otf
  • 1

第3步:动态加载字体

fontPath = @"C:\Windows\Fonts\somefont.otf";
System.Drawing.Text.PrivateFontCollection privateFonts = new System.Drawing.Text.PrivateFontCollection();
privateFonts.AddFontFile(fontPath);
someControl.Font = font = new Font(privateFonts.Families[0], 16);
  • 1
  • 2
  • 3
  • 4

小结

本文介绍了Base64的WOFF的字符串转换成二进制的WOFF字体文件、再转换为OTF格式,最后动态加载的整个过程。需要注意的是,第2步转换需要使用命令行进行调用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/250173
推荐阅读
相关标签
  

闽ICP备14008679号