Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Got rid of all trailing spaces. From now on no trailing spaces will b…

…e allowed in any patch.
  • Loading branch information...
commit 5c3ea394bf41a4bf27a4a379151570db1a4617d8 1 parent 2bd440d
Simo Kinnunen authored
Showing with 1,135 additions and 1,135 deletions.
  1. +33 −33 doc/optimal-scaling.html
  2. +5 −5 examples/gradient.html
  3. +21 −21 examples/text-shadow.html
  4. +49 −49 generate/convert.php
  5. +1 −1  generate/css/style.css
  6. +61 −61 generate/index.html
  7. +5 −5 generate/js/ui.js
  8. +1 −1  generate/lib/ConversionException.php
  9. +30 −30 generate/lib/Cufon.php
  10. +63 −63 generate/lib/FontForgeScript.php
  11. +29 −29 generate/lib/JSEncoder.php
  12. +8 −8 generate/lib/JSEncoderKey.php
  13. +75 −75 generate/lib/SVGFont.php
  14. +13 −13 generate/lib/SVGFontContainer.php
  15. +29 −29 generate/lib/UnicodeRange.php
  16. +55 −55 generate/lib/VMLPath.php
  17. +35 −35 generate/view/conversion-error.php
  18. +32 −32 generate/view/input-error.php
  19. +32 −32 generate/view/upload-empty-error.php
  20. +32 −32 generate/view/upload-size-error.php
  21. +214 −214 js/cufon.js
  22. +1 −1  tests/cssready/delayed-css.php
  23. +30 −30 tests/cssready/index.html
  24. +7 −7 tests/cssready/link-altstylesheet-simple-fake/index.html
  25. +7 −7 tests/cssready/link-altstylesheet-simple-print/index.html
  26. +9 −9 tests/cssready/link-altstylesheet-simple/index.html
  27. +7 −7 tests/cssready/link-next/index.html
  28. +4 −4 tests/cssready/link-next/next.html
  29. +7 −7 tests/cssready/link-stylesheet-404-print/index.html
  30. +7 −7 tests/cssready/link-stylesheet-404/index.html
  31. +7 −7 tests/cssready/link-stylesheet-charsetempty-print/index.html
  32. +7 −7 tests/cssready/link-stylesheet-charsetempty/index.html
  33. +7 −7 tests/cssready/link-stylesheet-commentempty-print/index.html
  34. +7 −7 tests/cssready/link-stylesheet-commentempty/index.html
  35. +9 −9 tests/cssready/link-stylesheet-disabled/index.html
  36. +7 −7 tests/cssready/link-stylesheet-empty-print/index.html
  37. +7 −7 tests/cssready/link-stylesheet-empty/index.html
  38. +7 −7 tests/cssready/link-stylesheet-import-print/index.html
  39. +7 −7 tests/cssready/link-stylesheet-import/index.html
  40. +7 −7 tests/cssready/link-stylesheet-printimport/index.html
  41. +7 −7 tests/cssready/link-stylesheet-simple-fake/index.html
  42. +7 −7 tests/cssready/link-stylesheet-simple-print/index.html
  43. +7 −7 tests/cssready/link-stylesheet-simple/index.html
  44. +7 −7 tests/cssready/link-stylesheet-slow-print/index.html
  45. +7 −7 tests/cssready/link-stylesheet-slow/index.html
  46. +7 −7 tests/cssready/link-stylesheet-slowdisabled/index.html
  47. +6 −6 tests/cssready/no-stylesheets/index.html
  48. +9 −9 tests/cssready/style-404import-print/index.html
  49. +9 −9 tests/cssready/style-404import/index.html
  50. +7 −7 tests/cssready/style-empty-print/index.html
  51. +7 −7 tests/cssready/style-empty/index.html
  52. +9 −9 tests/cssready/style-emptyimport-print/index.html
  53. +9 −9 tests/cssready/style-emptyimport/index.html
  54. +9 −9 tests/cssready/style-import-fake/index.html
  55. +9 −9 tests/cssready/style-import-print/index.html
  56. +9 −9 tests/cssready/style-import/index.html
  57. +9 −9 tests/cssready/style-printimport/index.html
  58. +8 −8 tests/cssready/style-simple-fake/index.html
  59. +8 −8 tests/cssready/style-simple-print/index.html
  60. +8 −8 tests/cssready/style-simple/index.html
  61. +1 −1  tests/line-height/index.html
  62. +1 −1  tests/line-height/quirks.html
  63. +1 −1  tests/line-height/transitional.html
66 doc/optimal-scaling.html
View
@@ -3,76 +3,76 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
-
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-
+
<title>Chart of optimal scaling values</title>
-
+
<style type="text/css">
-
+
body {
font: 9pt Arial, Verdana, Helvetica, sans-serif;
}
-
+
#scale-value-chart {
border-collapse: collapse;
border-spacing: 0;
}
-
+
#scale-value-chart caption {
font-size: 200%;
font-weight: bold;
padding: 0.5em;
}
-
+
#scale-value-chart th {
background: #eee;
vertical-align: bottom;
width: 1em;
}
-
+
#scale-value-chart th.col-text {
padding-left: 2em;
padding-right: 2em;
width: auto;
}
-
+
#scale-value-chart td {
border: 2px solid #fff;
padding: 1px 2px;
text-align: center;
}
-
+
#scale-value-chart .pos {
background: #00ff00;
color: #fff;
}
-
+
#scale-value-chart .neg {
background: #ffdddd;
}
-
+
</style>
-
+
</head>
-
+
<body>
-
+
<noscript>
-
+
<h1>Chart of optimal scaling values</h1>
-
+
<p>You need JavaScript to view this chart.</p>
-
+
</noscript>
-
+
<script type="text/javascript">
-
+
var sizes = {};
var map = [];
var best = [];
var length = 0;
-
+
for (var i = 8; i <= 48; i += 1, ++length) {
sizes[i] = [];
for (var j = 1; j < 100; ++j) {
@@ -83,9 +83,9 @@
map[size][i] = true;
}
}
-
+
var table = document.createElement('table');
-
+
table.id = 'scale-value-chart';
var caption = document.createElement('caption');
@@ -95,10 +95,10 @@
table.appendChild(caption);
var thead = table.createTHead();
-
+
var header1 = thead.insertRow(-1);
var header2 = thead.insertRow(-1);
-
+
var scaleHeading = document.createElement('th');
scaleHeading.className = 'col-text';
scaleHeading.rowSpan = 2;
@@ -110,7 +110,7 @@
header1.appendChild(pxHeading);
var count = 0;
-
+
for (var size in sizes) {
var th = document.createElement('th');
th.appendChild(document.createTextNode(size));
@@ -125,9 +125,9 @@
matchHeading.rowSpan = 2;
matchHeading.innerHTML = 'Font sizes<br />matched in total';
header1.appendChild(matchHeading);
-
+
var tbody = document.createElement('tbody');
-
+
table.appendChild(tbody);
for (var i = 0, l = map.length; i < l; ++i) {
@@ -147,11 +147,11 @@
var matchCell = row.insertCell(-1);
matchCell.innerHTML = matches;
}
-
+
document.body.appendChild(table);
-
+
</script>
-
+
</body>
-
-</html>
+
+</html>
10 examples/gradient.html
View
@@ -7,20 +7,20 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>cufón / examples / gradient</title>
-
+
<style type="text/css">
-
+
body {
background: #fff;
color: #555;
}
-
+
h1 {
font: normal 200px Arial, Verdana, Helvetica, sans-serif;
margin: 0.8em 0 0 0;
text-align: center;
}
-
+
</style>
<script src="../js/cufon.js" type="text/javascript"></script>
@@ -42,4 +42,4 @@
</body>
-</html>
+</html>
42 examples/text-shadow.html
View
@@ -3,20 +3,20 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
-
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-
+
<title>cufón / examples / text-shadow</title>
<script src="../js/cufon.js" type="text/javascript"></script>
<script src="../fonts/Vegur.font.js" type="text/javascript"></script>
-
+
<style type="text/css">
-
+
body {
background: #fff;
color: #000;
}
-
+
h1, h2, h3, h4, h5, h6 {
background: #CCCCCC;
color: #D1D1D1;
@@ -25,25 +25,25 @@
margin: 1em 0;
padding: 20px;
}
-
+
h3 {
background: #CCCCFF;
color: #fff;
}
-
+
h4 {
background: #CCCCFF;
color: #ffa800;
}
-
+
</style>
-
+
<script type="text/javascript">
Cufon.replace('h1', {
textShadow: '#fff -1px -1px, #333 1px 1px'
});
-
+
Cufon.replace('h2', {
textShadow: '#fff 1px 1px, #333 -1px -1px'
});
@@ -55,25 +55,25 @@
Cufon.replace('h4', {
textShadow: '-1px -1px rgba(51, 51, 51, 0.6)'
});
-
+
</script>
-
+
</head>
-
+
<body>
-
+
<p>These examples are based on <a href="http://www.w3.org/Style/Examples/007/text-shadow">CSS: text shadows</a> by Bert Bos. See the <a href="http://www.w3.org/TR/CSS2/text.html#text-shadow-props">CSS2 text-shadow specification</a> for syntax. Please note that offsets can only be defined in pixels and that blur is not supported at all.</p>
-
+
<p>Additional limitations since the release of Internet Explorer 8: One element may only have two shadows, and they may not have varying levels of opacity.</p>
-
+
<h1>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</h1>
-
+
<h2>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</h2>
-
+
<h3>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</h3>
-
+
<h4>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</h4>
-
+
</body>
-
+
</html>
98 generate/convert.php
View
@@ -9,49 +9,49 @@ function usage()
-b --callback The JavaScript function that handles the font.
Defaults to Cufon.registerFont.
-
+
Example: -b myRegisterFont
-
+
-c --characters All of these characters are included in the
resulting font file.
-
+
Example: -c "abc123"
-
+
-d --domain Restricts the font file to one or more domain
names.
-
+
Example: -d example.org -d example.com
-
+
-f --fontforge Path to the FontForge binary.
-
+
-h --help Displays this message.
-
+
-n --family-name The font-family of the font. By default the
real name of the font is used, but it may not
always be what you need.
-
+
Example: -n "Nifty Font"
-
+
-u --unicode-range See http://www.w3.org/TR/css3-webfonts/#dataqual
-
+
Example: -u "U+00??,U+20A7"
-
+
-s --scale Scales the font's em-size to this value. Defaults
to 360.
-
+
Example: --scale 720
-
+
-k --no-kerning Disables kerning.
-
+
-l --no-scaling No scaling, use the native value instead.
-
+
-m --no-simplify Keep the paths as they are, do not attempt to
simplify them.
-
+
-e --simplify-delta Simplified paths may differ from the original
by this many units (relative to scaling value).
Defaults to 2.
-
+
Example: -e 1
Sample usage:
@@ -146,9 +146,9 @@ function usage()
switch (PHP_SAPI)
{
case 'cli':
-
+
$fontforge = trim(`which fontforge`);
-
+
$options = array(
'family' => '',
'terms' => 'yes',
@@ -164,11 +164,11 @@ function usage()
'simplifyDelta' => 2,
'kerning' => 'yes'
);
-
+
$domains = array();
-
+
$args = $_SERVER['argv'];
-
+
for (next($args); ($arg = current($args)) !== false; next($args))
{
switch ($arg)
@@ -231,33 +231,33 @@ function usage()
$files[] = $arg;
}
}
-
+
if (!is_executable($fontforge))
{
echo "Could not find FontForge binary\n";
exit(4);
}
-
+
define('CUFON_FONTFORGE', $fontforge);
-
+
if (empty($files))
{
echo 'Nothing to convert.';
exit(0);
}
-
+
$options['domains'] = implode(', ', $domains);
-
+
$options = filter_var_array($options, $filters);
-
+
$errors = array_diff_key(array_filter($options, 'is_null'), $optional);
-
+
if (!empty($errors))
{
usage();
exit(1);
}
-
+
foreach ($files as $file)
{
try
@@ -265,9 +265,9 @@ function usage()
foreach (Cufon::generate($file, $options) as $id => $json)
{
echo $json;
-
+
$fonts[] = $id;
- }
+ }
}
catch (ConversionException $e)
{
@@ -275,22 +275,22 @@ function usage()
exit(2);
}
}
-
+
break;
default:
-
+
if (!is_readable('settings.ini'))
{
echo 'settings.ini is missing';
exit(1);
}
-
+
$config = parse_ini_file('settings.ini', false);
-
+
define('CUFON_VALID', true);
define('CUFON_FONTFORGE', $config['fontforge']);
-
+
switch ($_SERVER['REQUEST_METHOD'])
{
case 'POST':
@@ -300,9 +300,9 @@ function usage()
header('Location: ./');
exit(0);
}
-
+
$options = filter_input_array(INPUT_POST, $filters);
-
+
if (isset($_FILES['font']))
{
foreach ($_FILES['font']['error'] as $key => $error)
@@ -328,7 +328,7 @@ function usage()
}
}
}
-
+
if (empty($files))
{
require 'view/upload-empty-error.php';
@@ -336,17 +336,17 @@ function usage()
}
$errors = array_diff_key(array_filter($options, 'is_null'), $optional);
-
+
if (!empty($errors))
{
require 'view/input-error.php';
exit(0);
}
-
+
ob_start();
-
+
$fonts = array();
-
+
foreach ($files as $file)
{
try
@@ -354,9 +354,9 @@ function usage()
foreach (Cufon::generate($file, $options) as $id => $json)
{
echo $json;
-
+
$fonts[] = $id;
- }
+ }
}
catch (ConversionException $e)
{
@@ -365,7 +365,7 @@ function usage()
exit(0);
}
}
-
+
$filename = preg_replace(
array(
'/\s+/',
@@ -376,7 +376,7 @@ function usage()
''
),
empty($fonts) ? 'Cufon Font' : implode('-', $fonts)) . '.font.js';
-
+
header(sprintf('Content-Disposition: attachment; filename=%s', $filename));
header('Content-Type: text/javascript');
}
2  generate/css/style.css
View
@@ -164,4 +164,4 @@ button:hover, #nav a:hover, #nav a:active, .actions a:hover, .actions a:active {
#lfont_3 {
font-style: italic;
font-weight: bold;
-}
+}
122 generate/index.html
View
@@ -3,39 +3,39 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
-
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="imagetoolbar" content="no" />
-
+
<title>cufón - fonts for the people</title>
-
+
<meta name="description" content="Fast text replacement with canvas and VML - no Flash or images required." />
-
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
-
+
<script src="js/ui.js" type="text/javascript"></script>
-
+
<script src="../js/cufon.js" type="text/javascript"></script>
<script src="../fonts/Vegur.font.js" type="text/javascript"></script>
-
+
<script type="text/javascript"> Cufon.replace([ 'h1', 'h3' ]); </script>
-
+
</head>
-
+
<body>
-
+
<div id="doc">
<div id="page">
-
+
<div id="head">
-
+
<h1><a href="/">cufón - fonts for the people</a></h1>
-
+
</div>
-
+
<div id="nav">
-
+
<ul class="nav">
<li><a href="http://cufon.shoqolate.com/js/cufon-yui.js">Download</a></li>
<li class="current"><a href=".">Generator</a></li>
@@ -43,17 +43,17 @@
<li><a href="http://groups.google.com/group/cufon" class="external">Community</a></li>
<li><a href="http://github.com/sorccu/cufon/tree/master">Source</a></li>
</ul>
-
+
</div>
-
+
<div id="content">
-
+
<form action="convert.php" method="post" enctype="multipart/form-data">
-
+
<div class="section">
-
+
<h3>Select the font you'd like to use</h3>
-
+
<dl>
<dt><label for="ifont_0" id="lfont_0">Regular typeface</label></dt>
<dd><input type="file" name="font[]" id="ifont_0" size="70" /></dd>
@@ -64,18 +64,18 @@
<dt><label for="ifont_3" id="lfont_3">Bold Italic typeface (optional)</label></dt>
<dd><input type="file" name="font[]" id="ifont_3" size="70" /></dd>
</dl>
-
+
<p class="info">On Windows, <em>you may first have to copy the font file out of the Fonts folder and paste it elsewhere</em> in order to be able to select it.</p>
-
+
<p class="info">Currently only TrueType (TTF), OpenType (OTF), Printer Font Binary (PFB) and PostScript fonts are supported. Files are disposed of immediately after conversion.</p>
-
+
<dl>
<dt><label for="ifamily">Use the following value as the <code>font-family</code> of the generated font (optional)</label></dt>
<dd><input type="text" name="family" id="ifamily" size="70" maxlength="150" />
<p class="info">Useful if you're using multiple variants of the same font (bold, italic etc). Sometimes they may have slightly different family names, which may lead to unexpected behavior.</p>
</dd>
</dl>
-
+
<dl>
<dt><label for="ipermission" class="important"><input type="checkbox" name="permission" id="ipermission" value="yes" /> The EULAs of these fonts allow Web Embedding (without <a href="http://www.adobe.com/products/flashplayer/" class="external">Adobe Flash</a>)</label></dt>
<dd>
@@ -89,13 +89,13 @@
<a href="http://www.linotype.com/2061-28225/licenseagreementforfontsoftware.html" class="external">Linotype</a> (extended).</p>
</dd>
</dl>
-
+
</div>
-
+
<div class="section">
-
+
<h3>Include the following glyphs (if available)</h3>
-
+
<dl>
<dt><label for="iglyphs_all"><input type="checkbox" name="glyphs[]" id="iglyphs_all" value="0x0-0xFFFF" /> All</label></dt>
<dd>Includes all available glyphs. Highly unrecommended.</dd>
@@ -126,13 +126,13 @@
<dt><label for="icustomGlyphs"> .. and also these single characters</label></dt>
<dd><input type="text" name="customGlyphs" id="icustomGlyphs" size="70" maxlength="250" /></dd>
</dl>
-
+
</div>
-
+
<div class="section">
-
+
<h3>Security</h3>
-
+
<dl>
<dt><label for="idomains">Limit usage to the following domain(s)</label></dt>
<dd>
@@ -141,13 +141,13 @@
<p class="info">Separate multiple domains by either commas or spaces. You can also use wildcards (e.g. *.example.org to cover all subdomains of example.org). Using a font that doesn't match any of the allowed domains results in no text showing up.</p>
</dd>
</dl>
-
+
</div>
-
+
<div class="section">
-
+
<h3>Performance &amp; file size</h3>
-
+
<dl>
<dt><label for="iemSize">Scale the font to the following size</label></dt>
<dd>
@@ -164,15 +164,15 @@
</dd>
<dt><label for="ikerning"><input type="checkbox" name="kerning" id="ikerning" value="yes" checked="checked" /> Include kerning tables (improves readability but slightly increases file size)</label></dt>
</dl>
-
+
<p>Also, try to make sure your server serves gzipped JavaScript. 70-80% drops in file size are not unheard of.</p>
-
+
</div>
-
+
<div id="customization" class="section">
-
+
<h3>Customization (for 3rd-party scripts only)</h3>
-
+
<dl>
<dt><label for="icallback">The following JavaScript function will receive the font data</label></dt>
<dd><input type="text" name="callback" id="icallback" value="Cufon.registerFont" size="70" maxlength="250" />
@@ -180,44 +180,44 @@
<a href="#set-callback" class="callback" title="Raphael.registerFont"><img src="img/raphael16.png" alt="Raphaël" title="Raphaël" width="16" height="16" /></a>
</dd>
</dl>
-
+
</div>
-
+
<div class="section">
-
+
<h3>Terms</h3>
-
+
<p>Cufón is distributed under the <a href="http://en.wikipedia.org/wiki/MIT_License" class="external">MIT license</a>. By using this tool you agree to its terms.</p>
-
+
<p>Should you require help you may ask for it at <a href="http://groups.google.com/group/cufon" class="external">our Google Group</a>, but keep
in mind that you are in no way entitled to support, which means that even if you do not
get a satisfactory answer you may not complain about it. Nice people are more likely to
get helpful answers.</p>
-
+
<p><label for="iterms" class="important"><input type="checkbox" name="terms" id="iterms" value="yes" /> I acknowledge and accept these terms</label></p>
-
+
</div>
-
+
<div class="actions">
-
+
<button type="submit">Let's do this!</button>
-
+
</div>
-
+
</form>
-
+
</div>
-
+
<div id="foot">
-
+
<p>Idea and implementation by Simo Kinnunen, 2008-. Bugs by nature.</p>
-
+
</div>
-
+
</div>
-
+
</div>
-
+
</body>
-
+
</html>
10 generate/js/ui.js
View
@@ -1,5 +1,5 @@
(function() {
-
+
function addEvent(el, type, listener) {
if (el.addEventListener) {
el.addEventListener(type, listener, false);
@@ -10,7 +10,7 @@
});
}
}
-
+
function handle(el) {
switch (el.nodeName.toLowerCase()) {
case '#text':
@@ -30,7 +30,7 @@
}
return false;
}
-
+
addEvent(document, 'click', function(e) {
if (!handle(e.target || e.srcElement)) return;
if (e.preventDefault) e.preventDefault();
@@ -38,5 +38,5 @@
if (e.stopPropagation) e.stopPropagation();
else e.returnValue = false;
});
-
-})();
+
+})();
2  generate/lib/ConversionException.php
View
@@ -1,4 +1,4 @@
<?php
class ConversionException extends RuntimeException {
-}
+}
60 generate/lib/Cufon.php
View
@@ -5,29 +5,29 @@
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'UnicodeRange.php';
class Cufon {
-
+
public static function getUnusedFilename($suffix)
{
$filename = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'cufon_';
-
+
do
{
$wanted = $filename . uniqid(mt_rand(), true) . $suffix;
}
while (file_exists($wanted));
-
+
return $wanted;
}
-
+
public static function log($message)
{
$args = func_get_args();
-
+
array_shift($args);
-
+
error_log(sprintf("[cufon]: %s", vsprintf($message, $args)), 0);
}
-
+
/**
* @param string $file
* @param array $options
@@ -36,29 +36,29 @@ public static function log($message)
public static function generate($file, array $options)
{
Cufon::log('Processing %s', $file);
-
+
$script = new FontForgeScript();
-
+
$script->open($file);
$script->flattenCID();
$script->reEncode('unicode');
$script->selectNone();
-
+
if (!empty($options['glyphs']))
{
foreach ($options['glyphs'] as $glyph)
{
$ranges = explode(',', $glyph);
-
+
foreach ($ranges as $range)
{
if (strpos($range, '-')) // can't be 0 anyway
{
// the range regex allows for things like 0xff-0xff-0xff, so we'll
// just ignore everything between the first and last one.
-
+
$points = explode('-', $range);
-
+
$script->selectUnicodeRange(intval(reset($points), 16), intval(end($points), 16));
}
else
@@ -68,54 +68,54 @@ public static function generate($file, array $options)
}
}
}
-
+
if (!empty($options['customGlyphs']))
- {
+ {
$glyphs = preg_split('//u', $options['customGlyphs'], -1, PREG_SPLIT_NO_EMPTY);
-
+
foreach ($glyphs as $glyph)
{
$script->selectUnicode(UnicodeRange::getCodePoint($glyph));
}
}
-
+
$script->selectInvert();
$script->detachAndRemoveGlyphs();
-
+
$script->setFontOrder(FontForgeScript::ORDER_CUBIC);
-
+
if (!$options['disableScaling'])
{
$script->scaleToEm($options['emSize']);
}
-
+
$script->selectAll();
$script->verticalFlip(0);
-
+
if ($options['simplify'])
{
$script->simplify($options['simplifyDelta']);
}
-
+
$script->roundToInt(1);
-
+
$svgFile = Cufon::getUnusedFilename('.svg');
-
+
Cufon::log('Converting to SVG with filename %s', $svgFile);
-
+
$script->generate($svgFile);
$script->execute();
-
+
$fonts = array();
-
+
foreach (SVGFontContainer::fromFile($svgFile, $options) as $font)
{
$fonts[$font->getId()] = $options['callback'] . '(' . $font->toJavaScript() . ');';
}
-
+
unlink($svgFile);
-
+
return $fonts;
}
-
+
}
126 generate/lib/FontForgeScript.php
View
@@ -3,27 +3,27 @@
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ConversionException.php';
class FontForgeScript {
-
+
const ORDER_QUADRATIC = 2;
const ORDER_CUBIC = 3;
-
+
/**
* @var array
*/
private $commands = array();
-
+
/**
* @var array
*/
private $files = array();
-
+
/**
* @return void
*/
public function __construct()
{
}
-
+
/**
* @return string
*/
@@ -31,7 +31,7 @@ public function __toString()
{
return implode("\n", $this->commands);
}
-
+
/**
* @return void
*/
@@ -45,17 +45,17 @@ public function __destruct()
}
}
}
-
+
/**
* @return FontForgeScript
*/
public function close()
{
$this->commands[] = 'Close()';
-
+
return $this;
}
-
+
/**
* @fixme Sometimes removes glyphs it shouldn't.
* @return FontForgeScript
@@ -63,63 +63,63 @@ public function close()
public function clear()
{
$this->commands[] = 'Clear()';
-
+
return $this;
}
-
+
/**
* @return FontForgeScript
*/
public function detachAndRemoveGlyphs()
{
$this->commands[] = 'DetachAndRemoveGlyphs()';
-
+
return $this;
}
-
+
/**
* @return void
*/
public function execute()
{
$filename = Cufon::getUnusedFilename('.pe');
-
+
file_put_contents($filename, $this->__toString());
-
+
$this->files[] = $filename;
-
+
chmod($filename, 0777);
-
+
$command = sprintf('env %s -script %s 2>&1', CUFON_FONTFORGE, escapeshellarg($filename));
-
+
Cufon::log('Executing command: %s', $command);
-
+
$status = 0;
-
+
$output = array();
-
+
exec($command, $output, $status);
-
+
Cufon::log('Exited with status %d, output: %s', $status, implode(' / ', $output));
-
+
if ($status > 0)
{
throw new ConversionException('Conversion failed');
}
-
+
return $output;
}
-
+
/**
* @return FontForgeScript
*/
public function flattenCID()
{
$this->commands[] = 'if ($iscid); CIDFlatten(); endif;';
-
+
return $this;
}
-
+
/**
* @param string $filename
* @return FontForgeScript
@@ -127,10 +127,10 @@ public function flattenCID()
public function generate($filename)
{
$this->commands[] = sprintf('Generate("%s")', addslashes($filename));
-
+
return $this;
}
-
+
/**
* @param int $at
* @return FontForgeScript
@@ -138,10 +138,10 @@ public function generate($filename)
public function horizontalFlip($at = null)
{
$this->commands[] = sprintf('HFlip(%s)', is_int($at) ? $at : '');
-
+
return $this;
}
-
+
/**
* @param string $filename
* @return FontForgeScript
@@ -149,12 +149,12 @@ public function horizontalFlip($at = null)
public function open($filename)
{
$this->commands[] = sprintf('Open("%s")', addslashes($filename));
-
+
chmod($filename, 0777);
-
+
return $this;
}
-
+
/**
* @param int $point
* @return FontForgeScript
@@ -162,10 +162,10 @@ public function open($filename)
public function reduceUnicode($point)
{
$this->commands[] = sprintf('SelectFewerSingletons(0u%X)', $point);
-
+
return $this;
}
-
+
/**
* @param int $from
* @param int $to
@@ -174,10 +174,10 @@ public function reduceUnicode($point)
public function reduceUnicodeRange($from, $to)
{
$this->commands[] = sprintf('SelectFewer(0u%X, 0u%X)', $from, $to);
-
+
return $this;
}
-
+
/**
* @param string $encoding
* @return FontForgeScript
@@ -185,20 +185,20 @@ public function reduceUnicodeRange($from, $to)
public function reEncode($encoding)
{
$this->commands[] = sprintf('Reencode("%s")', $encoding);
-
+
return $this;
}
-
+
/**
* @return FontForgeScript
*/
public function removeAllKerns()
{
$this->commands[] = 'RemoveAllKerns()';
-
+
return $this;
}
-
+
/**
* http://fontforge.sourceforge.net/scripting-alpha.html#RoundToInt
*
@@ -208,10 +208,10 @@ public function removeAllKerns()
public function roundToInt($factor = 1)
{
$this->commands[] = sprintf('RoundToInt(%d)', $factor);
-
+
return $this;
}
-
+
/**
* @param int $emSize
* @return FontForgeScript
@@ -220,37 +220,37 @@ public function scaleToEm($emSize)
{
$this->commands[] = sprintf('ScaleToEm(%d)', $emSize);
}
-
+
/**
* @return FontForgeScript
*/
public function selectAll()
{
$this->commands[] = 'SelectAll()';
-
+
return $this;
}
-
+
/**
* @return FontForgeScript
*/
public function selectInvert()
{
$this->commands[] = 'SelectInvert()';
-
+
return $this;
}
-
+
/**
* @return FontForgeScript
*/
public function selectNone()
{
$this->commands[] = 'SelectNone()';
-
+
return $this;
}
-
+
/**
* @param int $point
* @return FontForgeScript
@@ -258,10 +258,10 @@ public function selectNone()
public function selectUnicode($point)
{
$this->commands[] = sprintf('SelectMoreSingletons(0u%X)', $point);
-
+
return $this;
}
-
+
/**
* @param int $from
* @param int $to
@@ -270,10 +270,10 @@ public function selectUnicode($point)
public function selectUnicodeRange($from, $to)
{
$this->commands[] = sprintf('SelectMore(0u%X, 0u%X)', $from, $to);
-
+
return $this;
}
-
+
/**
* @param int $order
* @return FontForgeScript
@@ -281,22 +281,22 @@ public function selectUnicodeRange($from, $to)
public function setFontOrder($order)
{
$this->commands[] = sprintf('SetFontOrder(%d)', $order);
-
+
return $this;
}
-
+
/**
* http://fontforge.sourceforge.net/scripting-alpha.html#Simplify
- *
+ *
* @return FontForgeScript
*/
public function simplify($error = 3)
{
$this->commands[] = sprintf('Simplify(1 | 2 | 4 | 8 | 32 | 64, %d)', $error);
-
+
return $this;
}
-
+
/**
* @param int $at
* @return FontForgeScript
@@ -304,8 +304,8 @@ public function simplify($error = 3)
public function verticalFlip($at = null)
{
$this->commands[] = sprintf('VFlip(%s)', is_int($at) ? $at : '');
-
+
return $this;
}
-
-}
+
+}
58 generate/lib/JSEncoder.php
View
@@ -3,17 +3,17 @@
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'JSEncoderKey.php';
class JSEncoder {
-
+
/**
* @var JSEncoderKey
*/
private $key;
-
+
/**
* @var string
*/
private $encoded = '';
-
+
/**
* @param string $str
* @return void
@@ -21,57 +21,57 @@ class JSEncoder {
public function __construct($str)
{
$this->key = new JSEncoderKey();
-
+
$this->encoded = $this->encode($str);
}
-
+
/**
* Based on Base64. Idea stolen from an old trojan, author unknown.
- *
+ *
* @param string $str
* @return string
*/
private function encode($str)
{
$length = strlen($str);
-
+
$pad = $length % 3;
-
+
if ($pad)
{
$length += 3 - $pad;
}
-
+
$str = str_pad($str, $length, ' ');
-
+
$value = '';
-
+
for ($i = 0; $i < $length - 2; $i += 3)
{
$mask = (ord($str{$i}) << 16 & 0xff0000) + (ord($str{$i + 1}) << 8 & 0xff00) + (ord($str{$i + 2}) & 0xff);
-
+
$bits = array(
($mask & 0xfc0000) >> 18,
($mask & 0x3f000) >> 12,
($mask & 0xfc0) >> 6,
($mask & 0x3f)
);
-
+
$value .= $this->key[$bits[0]] . $this->key[$bits[1]] . $this->key[$bits[2]] . $this->key[$bits[3]];
}
-
+
return $value;
}
-
+
/**
* @return string
*/
public function getDecoder()
{
$keyOffset = mt_rand(0, strlen($this->encoded));
-
+
$data = substr($this->encoded, 0, $keyOffset) . $this->key . substr($this->encoded, $keyOffset);
-
+
$decoder =
'function(s){var c="charAt",i="indexOf",a=String(arguments.cal' .
'lee).replace(/\s+/g,""),z=s.length+%d-a.length+(a.charCodeAt(' .
@@ -82,28 +82,28 @@ public function getDecoder()
'x))&255)<<6|k[i](v[c](++x))&255;t+=String.fromCharCode((m&167' .
'11680)>>16,(m&65280)>>8,m&255);}e.text=t;h.insertBefore(e,h.f' .
'irstChild);h.removeChild(e);}';
-
+
$predictedSize = self::getInjectedSize(strlen($decoder) - 3);
-
+
$blocker = $keyOffset - strlen($data) + $predictedSize;
-
+
$lengthBeforeAdjustment = strlen($blocker);
-
+
$blocker += $lengthBeforeAdjustment - strlen($predictedSize);
-
+
do
{
$blocker -= $lengthBeforeAdjustment - strlen($blocker);
-
+
$sizeChanged = strlen($blocker) !== $lengthBeforeAdjustment;
$lengthBeforeAdjustment = strlen($blocker);
}
while ($sizeChanged);
-
+
return sprintf('(%s)(%s)', sprintf($decoder, $blocker), json_encode($data));
}
-
+
/**
* @param string $str
* @return int
@@ -111,10 +111,10 @@ public function getDecoder()
private static function getInjectedSize($size)
{
$length = $size + strlen($size);
-
+
$length += strlen($length) - strlen($size);
-
+
return $length;
}
-
-}
+
+}
16 generate/lib/JSEncoderKey.php
View
@@ -1,10 +1,10 @@
<?php
class JSEncoderKey implements ArrayAccess, Countable {
-
+
/**
* Only 0x3f + 1 (64) values are needed.
- *
+ *
* @var array
*/
private $salt = array();
@@ -15,12 +15,12 @@ class JSEncoderKey implements ArrayAccess, Countable {
public function __construct()
{
$this->salt = str_split('!#$%&()*+,-.0123456789:;=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~', 1);
-
+
shuffle($this->salt);
-
+
array_splice($this->salt, 64);
}
-
+
/**
* @return string
*/
@@ -28,7 +28,7 @@ public function __toString()
{
return implode('', $this->salt);
}
-
+
/**
* @see Countable::count()
*
@@ -83,5 +83,5 @@ public function offsetUnset($offset)
{
throw new RuntimeException('JSEncoderKey is immutable');
}
-
-}
+
+}
150 generate/lib/SVGFont.php
View
@@ -6,7 +6,7 @@
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'VMLPath.php';
class SVGFont {
-
+
/**
* @var SimpleXMLElement
*/
@@ -16,35 +16,35 @@ class SVGFont {
* @var SVGFontContainer
*/
private $container;
-
+
/**
* @param string $file
*/
public function __construct(SimpleXMLElement $document, SVGFontContainer $container)
- {
+ {
$this->document = $document;
-
+
$this->container = $container;
}
-
+
public function __toString()
{
return $this->document->asXML();
}
-
+
/**
* @return string
*/
public function getId()
{
$faces = $this->document->xpath('//font-face');
-
+
if (!empty($faces))
{
$face = $faces[0];
-
+
$parts = array();
-
+
foreach (array('font-family', 'font-style', 'font-weight') as $attribute)
{
if (isset($face[$attribute]))
@@ -52,13 +52,13 @@ public function getId()
$parts[] = $this->getSanitizedFaceValue($attribute, (string) $face[$attribute]);
}
}
-
+
return implode('_', $parts);
}
-
+
return null;
}
-
+
/**
* @param string $key
* @param string $value
@@ -68,40 +68,40 @@ private function getSanitizedFaceValue($key, $value)
switch ($key)
{
case 'font-family':
-
+
$options = $this->container->getOptions();
-
+
$family = $options['family'];
-
+
if (!is_null($family) && $family !== '')
{
return $family;
}
-
+
break;
-
+
case 'font-weight':
-
+
$weight = intval($value);
-
+
if ($weight < 100)
{
$weight *= 100;
}
-
+
return max(100, min($weight, 900));
}
-
+
return $value;
}
-
+
/**
* @return string
*/
public function toJavaScript()
{
$font = $this->document;
-
+
$fontJSON = array(
'w' => (int) $font['horiz-adv-x'],
'face' => array(),
@@ -109,50 +109,50 @@ public function toJavaScript()
' ' => new stdClass() // some fonts do not contain a glyph for space
)
);
-
+
$face = $font->xpath('font-face');
-
+
if (empty($face))
{
return null;
}
-
+
foreach ($face[0]->attributes() as $key => $val)
{
$fontJSON['face'][$key] = $this->getSanitizedFaceValue($key, (string) $val);
}
-
+
$nameIndex = array();
$charIndex = array();
-
+
foreach ($font->xpath('glyph') as $glyph)
{
if (!isset($glyph['unicode']))
{
continue;
}
-
+
if (mb_strlen($glyph['unicode'], 'utf-8') > 1)
{
// it's a ligature, for now we'll just ignore it
-
+
continue;
}
-
+
$data = new stdClass();
-
+
if (isset($glyph['d']))
{
$data->d = substr(VMLPath::fromSVG((string) $glyph['d']), 1, -2); // skip m and xe
}
-
+
if (isset($glyph['horiz-adv-x']))
{
$data->w = (int) $glyph['horiz-adv-x'];
}
-
+
$char = (string) $glyph['unicode'];
-
+
if (isset($glyph['glyph-name']))
{
foreach (explode(',', (string) $glyph['glyph-name']) as $glyphName)
@@ -161,53 +161,53 @@ public function toJavaScript()
$charIndex[$char] = $data;
}
}
-
+
$fontJSON['glyphs'][$char] = $data;
}
-
+
$options = $this->container->getOptions();
-
+
$emSize = (int) $fontJSON['face']['units-per-em'];
-
+
// for some extremely weird reason FontForge sometimes pumps out
// astronomical kerning values.
// @todo figure out what's really wrong
$kerningLimit = $emSize * 2;
-
+
if ($options['kerning'])
{
foreach ($font->xpath('hkern') as $hkern)
{
$k = (int) $hkern['k'];
-
+
if (abs($k) > $kerningLimit)
{
continue;
}
-
+
$firstSet = array();
$secondSet = array();
-
+
if (isset($hkern['u1']))
{
$firstSet = self::getMatchingCharsFromUnicodeRange((string) $hkern['u1'], $charIndex);
}
-
+
if (isset($hkern['g1']))
{
$firstSet = array_merge($firstSet, self::getMatchingCharsFromGlyphNames((string) $hkern['g1'], $nameIndex));
}
-
+
if (isset($hkern['u2']))
{
$secondSet = self::getMatchingCharsFromUnicodeRange((string) $hkern['u2'], $charIndex);
}
-
+
if (isset($hkern['g2']))
{
$secondSet = array_merge($secondSet, self::getMatchingCharsFromGlyphNames((string) $hkern['g2'], $nameIndex));
}
-
+
if (!empty($secondSet))
{
foreach ($firstSet as $firstGlyph)
@@ -215,29 +215,29 @@ public function toJavaScript()
foreach ($secondSet as $secondGlyph)
{
$glyph = $fontJSON['glyphs'][$firstGlyph];
-
+
if (!isset($glyph->k))
{
$glyph->k = array();
}
-
+
$glyph->k[$secondGlyph] = $k;
}
}
}
}
}
-
+
$nbsp = utf8_encode(chr(0xa0));
-
+
if (!isset($fontJSON['glyphs'][$nbsp]) && isset($fontJSON['glyphs'][' ']))
{
$fontJSON['glyphs'][$nbsp] = $fontJSON['glyphs'][' '];
}
-
+
return self::processFont($fontJSON, $options);
}
-
+
/**
* @param array $data
* @param array $options
@@ -246,22 +246,22 @@ public function toJavaScript()
private static function processFont($data, $options)
{
$domains = preg_split('/\s*[, ]\s*/', trim($options['domains']), -1, PREG_SPLIT_NO_EMPTY);
-
+
if (empty($domains))
{
return json_encode($data);
}
-
+
$domainMap = array();
-
+
foreach ($domains as $domain)
{
$domain = preg_quote(preg_replace('@^\w+://@', '', mb_strtolower($domain, 'utf-8')), '/');
-
+
// this is kind of ugly, but we have to make sure that JSEncoder
// only gets ASCII characters
$domain = str_replace('\\\\', '\\', substr(json_encode($domain), 1, -1));
-
+
if (substr($domain, 0, 2) === '\\.')
{
$domain = ".+{$domain}";
@@ -270,27 +270,27 @@ private static function processFont($data, $options)
{
$domain = '.+' . substr($domain, 2);
}
-
+
$domainMap[$domain] = 1;
}
-
+
$glyphs = $data['glyphs'];
-
+
unset($data['glyphs']);
-
+
uasort($glyphs, array(__CLASS__, 'sortRandom'));
-
+
$encoder = new JSEncoder(
sprintf('(function(){var b=_cufon_bridge_,c=%s.split(""),i=0,p=b.p,l=p.length,g=b.f.glyphs={};if(/^(?:www\\.)?(?:%s)$/.test(location.hostname))for(;i<l;++i)g[c[i]]=p[i]})()',
json_encode(implode('', array_keys($glyphs))),
implode('|', array_keys($domainMap))));
-
+
return sprintf('(function(f){_cufon_bridge_={p:%s,f:f};try{%s}catch(e){}delete _cufon_bridge_;return f})(%s)',
json_encode(array_values($glyphs)),
$encoder->getDecoder(),
json_encode($data));
}
-
+
/**
* @param string $group
* @param array $nameIndex
@@ -299,7 +299,7 @@ private static function processFont($data, $options)
private static function getMatchingCharsFromGlyphNames($group, $nameIndex)
{
$matches = array();
-
+
foreach (explode(',', $group) as $g)
{
if (isset($nameIndex[$g]))
@@ -307,10 +307,10 @@ private static function getMatchingCharsFromGlyphNames($group, $nameIndex)
$matches[] = $nameIndex[$g];
}
}
-
+
return $matches;
}
-
+
/**
* @param string $unicodeRange
* @param array $charIndex
@@ -319,9 +319,9 @@ private static function getMatchingCharsFromGlyphNames($group, $nameIndex)
private static function getMatchingCharsFromUnicodeRange($unicodeRange, $charIndex)
{
$matches = array();
-
+
$range = new UnicodeRange($unicodeRange);
-
+
if ($range->isSimple())
{
if ($charIndex[$unicodeRange])
@@ -332,7 +332,7 @@ private static function getMatchingCharsFromUnicodeRange($unicodeRange, $charInd
else
{
reset($charIndex);
-
+
while (list($char) = each($charIndex))
{
if ($range->contains($char))
@@ -341,10 +341,10 @@ private static function getMatchingCharsFromUnicodeRange($unicodeRange, $charInd
}
}
}
-
+
return $matches;
}
-
+
/**
* @param mixed $a
* @param mixed $b
@@ -354,5 +354,5 @@ private static function sortRandom($a, $b)
{
return mt_rand(-1, 1);
}
-
-}
+
+}
26 generate/lib/SVGFontContainer.php
View
@@ -3,7 +3,7 @@
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'SVGFont.php';
class SVGFontContainer implements IteratorAggregate {
-
+
/**
* @param string $file
* @return SVGFont
@@ -11,13 +11,13 @@ class SVGFontContainer implements IteratorAggregate {
public static function fromFile($file, array $options)
{
$xml = file_get_contents($file);
-
+
// Get rid of unwanted control characters
// (only allow Tab, LF and CR)
$xml = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $xml);
-
+
$params = defined('LIBXML_COMPACT') ? constant('LIBXML_COMPACT') : 0;
-
+
return new SVGFontContainer(simplexml_load_string($xml, 'SimpleXMLElement', $params), $options);
}
@@ -25,12 +25,12 @@ public static function fromFile($file, array $options)
* @var SimpleXMLElement
*/
private $document;
-
+
/**
* @var array
*/
private $options;
-
+
/**
* @param SimpleXMLElement $document
* @return void
@@ -38,22 +38,22 @@ public static function fromFile($file, array $options)
public function __construct(SimpleXMLElement $document, array $options)
{
$this->document = $document;
-
+
$this->options = $options;
}
-
+
/**
* @return array of SVGFont
*/
public function getFonts()
{
$fonts = array();
-
+
foreach ($this->document->xpath('//font') as $font)
{
$fonts[] = new SVGFont($font, $this);
}
-
+
return $fonts;
}
@@ -65,7 +65,7 @@ public function getIterator()
{
return new ArrayIterator($this->getFonts());
}
-
+
/**
* @return array
*/
@@ -73,5 +73,5 @@ public function getOptions()
{
return $this->options;
}
-
-}
+
+}
58 generate/lib/UnicodeRange.php
View
@@ -1,10 +1,10 @@
<?php
class UnicodeRange {
-
+
/**
* @see http://www.w3.org/TR/css3-webfonts/#dataqual
- *
+ *
* @param string $range
* @return UnicodeRange
*/
@@ -12,25 +12,25 @@ public static function fromCSSValue($range)
{
return new UnicodeRange($range);
}
-
+
/**
* @see http://www.php.net/manual/en/function.ord.php#68914
- *
+ *
* @param string $char
* @return int
*/
public static function getCodePoint($char)
{
$cp = unpack('N', mb_convert_encoding($char, 'UCS-4BE', 'UTF-8'));
-
+
return $cp[1];
}
-
+
/**
* @var array
*/
private $ranges = array();
-
+
/**
* @param string $range