我需要在内部网应用程序上使用一些谷歌字体。客户端可能有也可能没有互联网连接。阅读许可条款,这似乎是法律允许的。
当前回答
您可以遵循使用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>";
}
}
}
其他回答
实际上,您可以直接从谷歌下载所有字体格式变体,并将它们包含在您的css中,以从您的服务器提供服务。这样你就不必担心谷歌跟踪你网站的用户。然而,缺点可能会减慢你自己的发球速度。字体对资源的要求很高。我还没有在这个问题上做任何测试,不知道是否有人有类似的想法。
这在法律上是允许的,只要你遵守字体许可的条款——通常是OFL。
你需要一套网页字体格式,而font Squirrel Webfont Generator可以生成这些格式。
但是OFL要求在修改字体时重命名它们,使用生成器意味着修改它们。
您可以遵循使用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>";
}
}
}
你可以从https://github.com/google/fonts下载原始字体
之后,使用字体游弋工具将您的大型Unicode字体分成多个子集(例如拉丁,西里尔)。您应该使用该工具执行以下操作:
为您支持的每种语言生成子集 使用unicode范围子集节省带宽 删除臃肿从你的字体和优化他们的网页 将字体转换为压缩的woff2格式 为旧浏览器提供.woff备份 自定义字体加载和渲染 使用@font-face规则生成CSS文件 自托管web字体或在本地使用它们
字体游侠:https://www.npmjs.com/package/font-ranger
附注:你也可以使用Node.js API自动化这个过程
请记住,我的回答已经过时了很多。
下面还有一些技术上更复杂的答案,例如:
Neverpanic/google-font-download google-webfont-helper 本地字体
所以,不要因为这是目前公认的答案,就以为这是最好的答案。
你现在也可以下载谷歌的整个字体集通过github在他们的谷歌/字体资源库。它们还提供字体的约420MB压缩快照。
You first download your font selection as a zipped package, providing you with a bunch of true type fonts. Copy them somewhere public, somewhere you can link to from your css.
On the google webfont download page, you'll find a include link like so:
http://fonts.googleapis.com/css?family=Cantarell:400,700,400italic,700italic|Candal
It links to a CSS defining the fonts via a bunch of @font-face
defintions.
Open it in a browser to copy and paste them into your own CSS and modify the urls to include the right font file and format types.
So this:
@font-face {
font-family: 'Cantarell';
font-style: normal;
font-weight: 700;
src: local('Cantarell Bold'), local('Cantarell-Bold'), url(http://themes.googleusercontent.com/static/fonts/cantarell/v3/Yir4ZDsCn4g1kWopdg-ehHhCUOGz7vYGh680lGh-uXM.woff) format('woff');
}
becomes this:
/* Your local CSS File */
@font-face {
font-family: 'Cantarell';
font-style: normal;
font-weight: 700;
src: local('Cantarell Bold'), local('Cantarell-Bold'), url(../font/Cantarell-Bold.ttf) format('truetype');
}
As you can see, a downside of hosting the fonts on your own system this way is, that you restrict yourself to the true type format, whilst the google webfont service determines by the accessing device which formats will be transmitted.
Furthermore, I had to add a .htaccess
file to my the directory holding the fonts containing mime types to avoid errors from popping up in Chrome Dev Tools.
For this solution, only true type is needed, but defining more does not hurt when you want to include different fonts as well, like font-awesome
.
#.htaccess
AddType application/vnd.ms-fontobject .eot
AddType font/ttf .ttf
AddType font/otf .otf
AddType application/x-font-woff .woff