我需要在内部网应用程序上使用一些谷歌字体。客户端可能有也可能没有互联网连接。阅读许可条款,这似乎是法律允许的。


当前回答

你可以从https://github.com/google/fonts下载原始字体

之后,使用字体游弋工具将您的大型Unicode字体分成多个子集(例如拉丁,西里尔)。您应该使用该工具执行以下操作:

为您支持的每种语言生成子集 使用unicode范围子集节省带宽 删除臃肿从你的字体和优化他们的网页 将字体转换为压缩的woff2格式 为旧浏览器提供.woff备份 自定义字体加载和渲染 使用@font-face规则生成CSS文件 自托管web字体或在本地使用它们


字体游侠:https://www.npmjs.com/package/font-ranger

附注:你也可以使用Node.js API自动化这个过程

其他回答

我有一个类似于@neverpanic的PHP脚本,自动从谷歌下载CSS和字体(暗示和未暗示)。然后,它根据用户代理从您自己的服务器提供正确的CSS和字体。它有自己的缓存,所以用户代理的字体和CSS只会被下载一次。

它还处于早期阶段,但可以在这里找到:DaAwesomeP / php-offline-fonts

我写了一个bash脚本,在谷歌的服务器上使用不同的用户代理获取CSS文件,将不同的字体格式下载到本地目录,并编写包含它们的CSS文件。注意,该脚本需要Bash版本4.x。

请参阅https://neverpanic.de/blog/2014/03/19/downloading-google-web-fonts-for-local-hosting/获取脚本(我在这里不复制它,所以我只需要在需要时在一个地方更新它)。

编辑:移动到https://github.com/neverpanic/google-font-download

最简单的方法-使用google-webfonts-helper

假设我们想要托管字体Red Rose:

Open google-webfonts-helper and filter for the required font on top left (type Red Rose and enter..) Choose from the charsets (default is latin; select others like latin-ext if you want extended support) Select the styles (deafult is regular) From the Copy CSS tab Select Modern Browser if you wish to support only modern browsers (woff2, woff) Select Best Support if you wish to support all browsers (I chose this - woff2, woff,ttf,svg,eot) In case your font files do not reside in ../fonts/ path, you can edit it to represent your actual path (for me it was ../assets/fonts/) Copy the CSS and keep for future use Download the zip file named red-rose-v1-latin-ext_latin; unzip it and place all fonts directly into your assets/fonts directory (based on what you gave earlier) In your stylesheet where you wish to embed, paste the copied CSS. It will look like the below if you chose these options

/* red-rose-regular - latin-ext_latin */
@font-face {
  font-family: 'Red Rose';
  font-style: normal;
  font-weight: 400;
  src: url('../assets/fonts/red-rose-v1-latin-ext_latin-regular.eot'); /* IE9 Compat Modes */
  src: local('Red Rose Regular'), local('RedRose-Regular'),
       url('../assets/fonts/red-rose-v1-latin-ext_latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
       url('../assets/fonts/red-rose-v1-latin-ext_latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
       url('../assets/fonts/red-rose-v1-latin-ext_latin-regular.woff') format('woff'), /* Modern Browsers */
       url('../assets/fonts/red-rose-v1-latin-ext_latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
       url('../assets/fonts/red-rose-v1-latin-ext_latin-regular.svg#RedRose') format('svg'); /* Legacy iOS */
}
/* Red Rose will now be available for use in your stylesheet, provide this font */

:root {
  font-family: 'Red Rose', cursive, sans-serif;
}

这一切!

您可以遵循使用PHP开发的脚本。 在那里你可以下载任何谷歌字体使用脚本。 它将下载字体,并创建一个CSS文件和存档压缩。 您可以从GitHub https://github.com/souravmsh/google-fonts-downloader下载源代码

$obj = new GoogleFontsDownloader;
        
if(isset($_GET['url']) && !empty($_GET['url']))
{
    $obj->generate($_GET['url']);
}

if(isset($_GET['download']) && !empty($_GET['download']) && $_GET['download']=='true')
{
    $obj->download();
}

/**
* GoogleFontsDownloader
* Easy way to download any google fonts.
* @author     Shohrab Hossain
* @version    1.0.0 
*/
class GoogleFontsDownloader
{
    private $url      = '';
    private $dir      = 'dist/';
    private $fontsDir = 'fonts/';
    private $cssDir   = 'css/';
    private $fileName = 'fonts.css';
    private $content  = '';
    private $errors   = '';
    private $success  = '';
    public  $is_downloadable  = false;

    public function __construct()
    {
        ini_set('allow_url_fopen', 'on');
        ini_set('allow_url_include', 'on');
    }
 
    public function generate($url = null)
    {
        if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) 
        {
            $this->errors .= "<li><strong>Invalid url!</strong> $url</li>";
        }
        else
        {
            $this->url = $url;
            // delete previous files
            $this->_destroy();
            // write font.css
            $this->_css();
            // write fonts
            $this->_fonts();
            // archive files
            $this->_archive();
        }  
        // show all messages
        $this->_message();
    }
 
    public function download()
    { 
        // Download the created zip file
        $zipFileName = trim($this->dir, '/').'.zip';
        if (file_exists($zipFileName))
        {
            header("Content-type: application/zip");
            header("Content-Disposition: attachment; filename = $zipFileName");
            header("Pragma: no-cache");
            header("Expires: 0");
            readfile("$zipFileName");
 
            // delete file 
            unlink($zipFileName);
            array_map('unlink', glob("$this->dir/*.*"));
            rmdir($this->dir);

        } 
    }   
 
    private function _archive()
    {
        if (is_dir($this->dir))
        {
            $zipFileName = trim($this->dir, '/').'.zip';
            $zip = new \ZipArchive(); 
            if ($zip->open($zipFileName, ZipArchive::CREATE) === TRUE) 
            {
                $zip->addGlob($this->dir. "*.*");
                $zip->addGlob($this->dir. "*/*.*");
                if ($zip->status == ZIPARCHIVE::ER_OK)
                {
                    $this->success .= '<li>Zip create successful!</li>';
                    $this->is_downloadable = true;
                }
                else 
                {
                    $this->errors .= '<li>Failed to create to zip</li>';
                } 
            } 
            else 
            {
                $this->errors .= '<li>ZipArchive not found!</li>';
            }  
            $zip->close(); 
        }
        else
        {
            $this->errors .= "<li><strong>File</strong> not exists!</li>";
        } 
    }   
  
    private function _css()
    {  
        $filePath = $this->dir.$this->cssDir.$this->fileName;
        $content  = $this->_request($this->url);
        if (!empty($content))
        {
            if (file_put_contents($filePath, $content))
            {
                $this->success .= "<li>$this->fileName generated successful!</li>";
                $this->content = $content; 
            }
            else
            {
                $this->errors .= '<li>Permission errro in $this->fileName! Unable to write $filePath.</li>';
            }
        }
        else
        {
            $this->errors .= '<li>Unable to create fonts.css file!</li>';
        }
    }

    private function _fonts()
    {
        if (!empty($this->content))
        {
            preg_match_all('#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#', $this->content, $match);
            $gFontPaths = $match[0];
            if (!empty($gFontPaths) && is_array($gFontPaths) && sizeof($gFontPaths)>0)
            {
                $count = 0;
                foreach ($gFontPaths as $url) 
                {
                    $name     = basename($url);
                    $filePath = $this->dir.$this->fontsDir.$name;
                    $this->content = str_replace($url, '../'.$this->fontsDir.$name, $this->content);

                    $fontContent  = $this->_request($url);
                    if (!empty($fontContent))
                    {
                        file_put_contents($filePath, $fontContent);
                        $count++;
                        $this->success .= "<li>The font $name downloaded!</li>";
                    }
                    else
                    {
                        $this->errors .= "<li>Unable to download the font $name!</li>";
                    } 
                }

                file_put_contents($this->dir.$this->cssDir.$this->fileName, $this->content);
                $this->success .= "<li>Total $count font(s) downloaded!</li>";
            }
        }
    }

    private function _request($url)
    {
        $ch = curl_init(); 
        curl_setopt_array($ch, array(
            CURLOPT_SSL_VERIFYPEER => FALSE,
            CURLOPT_HEADER         => FALSE,
            CURLOPT_FOLLOWLOCATION => TRUE,
            CURLOPT_URL            => $url,
            CURLOPT_REFERER        => $url,
            CURLOPT_RETURNTRANSFER => TRUE,
        ));
        $result = curl_exec($ch);
        curl_close($ch);

        if (!empty($result))
        {
            return $result;
        } 
        return false;
    }

    private function _destroy()
    {
        $cssPath = $this->dir.$this->cssDir.$this->fileName;
        if (file_exists($cssPath) && is_file($cssPath))
        {
            unlink($cssPath);
        } 
        else
        {
            mkdir($this->dir.$this->cssDir, 0777, true);
        }

        $fontsPath = $this->dir.$this->fontsDir;
        if (!is_dir($fontsPath))
        {
            mkdir($fontsPath, 0777, true);
        }
        else
        {
            array_map(function($font) use($fontsPath) {
                if (file_exists($fontsPath.$font) && is_file($fontsPath.$font))
                {
                    unlink($fontsPath.$font);
                }
            }, glob($fontsPath.'*.*')); 
        }
    }

    private function _message()
    {
        if (strlen($this->errors)>0)
        {
            echo "<div class='alert alert-danger'><ul>$this->errors</ul></div>";
        }  
        if (strlen($this->success)>0)
        {
            echo "<div class='alert alert-success'><ul>$this->success</ul></div>";
        } 
    } 
}

编辑:正如luckyrumo指出的那样,字体被放弃了,取而代之的是:https://github.com/fontsource/fontsource

如果您正在使用Webpack,您可能会对这个项目感兴趣:https://github.com/KyleAMathews/typefaces

例如,你想使用Roboto字体:

npm install typeface-roboto --save

然后把它导入你的应用的入口点(主js文件):

import 'typeface-roboto'