ttf2eot 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +4 -0
- data/ext/ttf2eot_ext/OpenTypeUtilities.cpp +334 -0
- data/ext/ttf2eot_ext/OpenTypeUtilities.h +36 -0
- data/ext/ttf2eot_ext/extconf.rb +3 -0
- data/ext/ttf2eot_ext/ttf2eot.cpp +54 -0
- data/lib/ttf2eot.rb +47 -0
- metadata +63 -0
data/Rakefile
ADDED
@@ -0,0 +1,334 @@
|
|
1
|
+
/* Modified for use with ttf2eot, originally from WebKit. */
|
2
|
+
|
3
|
+
/*
|
4
|
+
* Copyright (C) 2008 Apple Inc. All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions
|
8
|
+
* are met:
|
9
|
+
* 1. Redistributions of source code must retain the above copyright
|
10
|
+
* notice, this list of conditions and the following disclaimer.
|
11
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
12
|
+
* notice, this list of conditions and the following disclaimer in the
|
13
|
+
* documentation and/or other materials provided with the distribution.
|
14
|
+
*
|
15
|
+
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
|
16
|
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
18
|
+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
|
19
|
+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
20
|
+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
21
|
+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
22
|
+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
23
|
+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
24
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
25
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
26
|
+
*/
|
27
|
+
|
28
|
+
#include <string.h>
|
29
|
+
#include <vector>
|
30
|
+
|
31
|
+
#ifndef _MSC_VER
|
32
|
+
# include <stdint.h>
|
33
|
+
#else
|
34
|
+
typedef unsigned char uint8_t;
|
35
|
+
#endif
|
36
|
+
|
37
|
+
#include "OpenTypeUtilities.h"
|
38
|
+
|
39
|
+
|
40
|
+
using std::vector;
|
41
|
+
|
42
|
+
typedef unsigned Fixed;
|
43
|
+
|
44
|
+
#define DEFAULT_CHARSET 1
|
45
|
+
|
46
|
+
struct BigEndianUShort {
|
47
|
+
operator unsigned short() const { return (v & 0x00ff) << 8 | v >> 8; }
|
48
|
+
BigEndianUShort(unsigned short u) : v((u & 0x00ff) << 8 | u >> 8) { }
|
49
|
+
unsigned short v;
|
50
|
+
};
|
51
|
+
|
52
|
+
struct BigEndianULong {
|
53
|
+
operator unsigned() const { return (v & 0xff) << 24 | (v & 0xff00) << 8 | (v & 0xff0000) >> 8 | v >> 24; }
|
54
|
+
BigEndianULong(unsigned u) : v((u & 0xff) << 24 | (u & 0xff00) << 8 | (u & 0xff0000) >> 8 | u >> 24) { }
|
55
|
+
unsigned v;
|
56
|
+
};
|
57
|
+
|
58
|
+
#pragma pack(1)
|
59
|
+
|
60
|
+
struct EOTPrefix {
|
61
|
+
unsigned eotSize;
|
62
|
+
unsigned fontDataSize;
|
63
|
+
unsigned version;
|
64
|
+
unsigned flags;
|
65
|
+
uint8_t fontPANOSE[10];
|
66
|
+
uint8_t charset;
|
67
|
+
uint8_t italic;
|
68
|
+
unsigned weight;
|
69
|
+
unsigned short fsType;
|
70
|
+
unsigned short magicNumber;
|
71
|
+
unsigned unicodeRange[4];
|
72
|
+
unsigned codePageRange[2];
|
73
|
+
unsigned checkSumAdjustment;
|
74
|
+
unsigned reserved[4];
|
75
|
+
unsigned short padding1;
|
76
|
+
};
|
77
|
+
|
78
|
+
struct TableDirectoryEntry {
|
79
|
+
BigEndianULong tag;
|
80
|
+
BigEndianULong checkSum;
|
81
|
+
BigEndianULong offset;
|
82
|
+
BigEndianULong length;
|
83
|
+
};
|
84
|
+
|
85
|
+
struct sfntHeader {
|
86
|
+
Fixed version;
|
87
|
+
BigEndianUShort numTables;
|
88
|
+
BigEndianUShort searchRange;
|
89
|
+
BigEndianUShort entrySelector;
|
90
|
+
BigEndianUShort rangeShift;
|
91
|
+
TableDirectoryEntry tables[1];
|
92
|
+
};
|
93
|
+
|
94
|
+
struct OS2Table {
|
95
|
+
BigEndianUShort version;
|
96
|
+
BigEndianUShort avgCharWidth;
|
97
|
+
BigEndianUShort weightClass;
|
98
|
+
BigEndianUShort widthClass;
|
99
|
+
BigEndianUShort fsType;
|
100
|
+
BigEndianUShort subscriptXSize;
|
101
|
+
BigEndianUShort subscriptYSize;
|
102
|
+
BigEndianUShort subscriptXOffset;
|
103
|
+
BigEndianUShort subscriptYOffset;
|
104
|
+
BigEndianUShort superscriptXSize;
|
105
|
+
BigEndianUShort superscriptYSize;
|
106
|
+
BigEndianUShort superscriptXOffset;
|
107
|
+
BigEndianUShort superscriptYOffset;
|
108
|
+
BigEndianUShort strikeoutSize;
|
109
|
+
BigEndianUShort strikeoutPosition;
|
110
|
+
BigEndianUShort familyClass;
|
111
|
+
uint8_t panose[10];
|
112
|
+
BigEndianULong unicodeRange[4];
|
113
|
+
uint8_t vendID[4];
|
114
|
+
BigEndianUShort fsSelection;
|
115
|
+
BigEndianUShort firstCharIndex;
|
116
|
+
BigEndianUShort lastCharIndex;
|
117
|
+
BigEndianUShort typoAscender;
|
118
|
+
BigEndianUShort typoDescender;
|
119
|
+
BigEndianUShort typoLineGap;
|
120
|
+
BigEndianUShort winAscent;
|
121
|
+
BigEndianUShort winDescent;
|
122
|
+
BigEndianULong codePageRange[2];
|
123
|
+
BigEndianUShort xHeight;
|
124
|
+
BigEndianUShort capHeight;
|
125
|
+
BigEndianUShort defaultChar;
|
126
|
+
BigEndianUShort breakChar;
|
127
|
+
BigEndianUShort maxContext;
|
128
|
+
};
|
129
|
+
|
130
|
+
struct headTable {
|
131
|
+
Fixed version;
|
132
|
+
Fixed fontRevision;
|
133
|
+
BigEndianULong checkSumAdjustment;
|
134
|
+
BigEndianULong magicNumber;
|
135
|
+
BigEndianUShort flags;
|
136
|
+
BigEndianUShort unitsPerEm;
|
137
|
+
long long created;
|
138
|
+
long long modified;
|
139
|
+
BigEndianUShort xMin;
|
140
|
+
BigEndianUShort xMax;
|
141
|
+
BigEndianUShort yMin;
|
142
|
+
BigEndianUShort yMax;
|
143
|
+
BigEndianUShort macStyle;
|
144
|
+
BigEndianUShort lowestRectPPEM;
|
145
|
+
BigEndianUShort fontDirectionHint;
|
146
|
+
BigEndianUShort indexToLocFormat;
|
147
|
+
BigEndianUShort glyphDataFormat;
|
148
|
+
};
|
149
|
+
|
150
|
+
struct nameRecord {
|
151
|
+
BigEndianUShort platformID;
|
152
|
+
BigEndianUShort encodingID;
|
153
|
+
BigEndianUShort languageID;
|
154
|
+
BigEndianUShort nameID;
|
155
|
+
BigEndianUShort length;
|
156
|
+
BigEndianUShort offset;
|
157
|
+
};
|
158
|
+
|
159
|
+
struct nameTable {
|
160
|
+
BigEndianUShort format;
|
161
|
+
BigEndianUShort count;
|
162
|
+
BigEndianUShort stringOffset;
|
163
|
+
nameRecord nameRecords[1];
|
164
|
+
};
|
165
|
+
|
166
|
+
#pragma pack()
|
167
|
+
|
168
|
+
static void appendBigEndianStringToEOTHeader(vector<uint8_t>&eotHeader, const BigEndianUShort* string, unsigned short length)
|
169
|
+
{
|
170
|
+
size_t size = eotHeader.size();
|
171
|
+
eotHeader.resize(size + length + 2 * sizeof(unsigned short));
|
172
|
+
unsigned short* dst = reinterpret_cast<unsigned short*>(&eotHeader[0] + size);
|
173
|
+
unsigned i = 0;
|
174
|
+
dst[i++] = length;
|
175
|
+
unsigned numCharacters = length / 2;
|
176
|
+
for (unsigned j = 0; j < numCharacters; j++)
|
177
|
+
dst[i++] = string[j];
|
178
|
+
dst[i] = 0;
|
179
|
+
}
|
180
|
+
|
181
|
+
bool getEOTHeader(unsigned char* fontData, size_t fontSize, vector<uint8_t>& eotHeader, size_t& overlayDst, size_t& overlaySrc, size_t& overlayLength)
|
182
|
+
{
|
183
|
+
overlayDst = 0;
|
184
|
+
overlaySrc = 0;
|
185
|
+
overlayLength = 0;
|
186
|
+
|
187
|
+
size_t dataLength = fontSize;
|
188
|
+
const char* data = (const char *) fontData;
|
189
|
+
|
190
|
+
eotHeader.resize(sizeof(EOTPrefix));
|
191
|
+
EOTPrefix* prefix = reinterpret_cast<EOTPrefix*>(&eotHeader[0]);
|
192
|
+
|
193
|
+
prefix->fontDataSize = dataLength;
|
194
|
+
prefix->version = 0x00020001;
|
195
|
+
prefix->flags = 0;
|
196
|
+
|
197
|
+
if (dataLength < offsetof(sfntHeader, tables))
|
198
|
+
return false;
|
199
|
+
|
200
|
+
const sfntHeader* sfnt = reinterpret_cast<const sfntHeader*>(data);
|
201
|
+
|
202
|
+
if (dataLength < offsetof(sfntHeader, tables) + sfnt->numTables * sizeof(TableDirectoryEntry))
|
203
|
+
return false;
|
204
|
+
|
205
|
+
bool haveOS2 = false;
|
206
|
+
bool haveHead = false;
|
207
|
+
bool haveName = false;
|
208
|
+
|
209
|
+
const BigEndianUShort* familyName = 0;
|
210
|
+
unsigned short familyNameLength = 0;
|
211
|
+
const BigEndianUShort* subfamilyName = 0;
|
212
|
+
unsigned short subfamilyNameLength = 0;
|
213
|
+
const BigEndianUShort* fullName = 0;
|
214
|
+
unsigned short fullNameLength = 0;
|
215
|
+
const BigEndianUShort* versionString = 0;
|
216
|
+
unsigned short versionStringLength = 0;
|
217
|
+
|
218
|
+
for (unsigned i = 0; i < sfnt->numTables; i++) {
|
219
|
+
unsigned tableOffset = sfnt->tables[i].offset;
|
220
|
+
unsigned tableLength = sfnt->tables[i].length;
|
221
|
+
|
222
|
+
if (dataLength < tableOffset || dataLength < tableLength || dataLength < tableOffset + tableLength)
|
223
|
+
return false;
|
224
|
+
|
225
|
+
unsigned tableTag = sfnt->tables[i].tag;
|
226
|
+
switch (tableTag) {
|
227
|
+
case 'OS/2':
|
228
|
+
{
|
229
|
+
if (dataLength < tableOffset + sizeof(OS2Table))
|
230
|
+
return false;
|
231
|
+
|
232
|
+
haveOS2 = true;
|
233
|
+
const OS2Table* OS2 = reinterpret_cast<const OS2Table*>(data + tableOffset);
|
234
|
+
for (unsigned j = 0; j < 10; j++)
|
235
|
+
prefix->fontPANOSE[j] = OS2->panose[j];
|
236
|
+
prefix->italic = OS2->fsSelection & 0x01;
|
237
|
+
prefix->weight = OS2->weightClass;
|
238
|
+
// FIXME: Should use OS2->fsType, but some TrueType fonts set it to an over-restrictive value.
|
239
|
+
// Since ATS does not enforce this on Mac OS X, we do not enforce it either.
|
240
|
+
prefix->fsType = 0;
|
241
|
+
for (unsigned j = 0; j < 4; j++)
|
242
|
+
prefix->unicodeRange[j] = OS2->unicodeRange[j];
|
243
|
+
for (unsigned j = 0; j < 2; j++)
|
244
|
+
prefix->codePageRange[j] = OS2->codePageRange[j];
|
245
|
+
break;
|
246
|
+
}
|
247
|
+
case 'head':
|
248
|
+
{
|
249
|
+
if (dataLength < tableOffset + sizeof(headTable))
|
250
|
+
return false;
|
251
|
+
|
252
|
+
haveHead = true;
|
253
|
+
const headTable* head = reinterpret_cast<const headTable*>(data + tableOffset);
|
254
|
+
prefix->checkSumAdjustment = head->checkSumAdjustment;
|
255
|
+
break;
|
256
|
+
}
|
257
|
+
case 'name':
|
258
|
+
{
|
259
|
+
if (dataLength < tableOffset + offsetof(nameTable, nameRecords))
|
260
|
+
return false;
|
261
|
+
|
262
|
+
haveName = true;
|
263
|
+
const nameTable* name = reinterpret_cast<const nameTable*>(data + tableOffset);
|
264
|
+
for (int j = 0; j < name->count; j++) {
|
265
|
+
if (dataLength < tableOffset + offsetof(nameTable, nameRecords) + (j + 1) * sizeof(nameRecord))
|
266
|
+
return false;
|
267
|
+
if (name->nameRecords[j].platformID == 3 && name->nameRecords[j].encodingID == 1 && name->nameRecords[j].languageID == 0x0409) {
|
268
|
+
if (dataLength < tableOffset + name->stringOffset + name->nameRecords[j].offset + name->nameRecords[j].length)
|
269
|
+
return false;
|
270
|
+
|
271
|
+
unsigned short nameLength = name->nameRecords[j].length;
|
272
|
+
const BigEndianUShort* nameString = reinterpret_cast<const BigEndianUShort*>(data + tableOffset + name->stringOffset + name->nameRecords[j].offset);
|
273
|
+
|
274
|
+
switch (name->nameRecords[j].nameID) {
|
275
|
+
case 1:
|
276
|
+
familyNameLength = nameLength;
|
277
|
+
familyName = nameString;
|
278
|
+
break;
|
279
|
+
case 2:
|
280
|
+
subfamilyNameLength = nameLength;
|
281
|
+
subfamilyName = nameString;
|
282
|
+
break;
|
283
|
+
case 4:
|
284
|
+
fullNameLength = nameLength;
|
285
|
+
fullName = nameString;
|
286
|
+
break;
|
287
|
+
case 5:
|
288
|
+
versionStringLength = nameLength;
|
289
|
+
versionString = nameString;
|
290
|
+
break;
|
291
|
+
default:
|
292
|
+
break;
|
293
|
+
}
|
294
|
+
}
|
295
|
+
}
|
296
|
+
break;
|
297
|
+
}
|
298
|
+
default:
|
299
|
+
break;
|
300
|
+
}
|
301
|
+
if (haveOS2 && haveHead && haveName)
|
302
|
+
break;
|
303
|
+
}
|
304
|
+
|
305
|
+
prefix->charset = DEFAULT_CHARSET;
|
306
|
+
prefix->magicNumber = 0x504c;
|
307
|
+
prefix->reserved[0] = 0;
|
308
|
+
prefix->reserved[1] = 0;
|
309
|
+
prefix->reserved[2] = 0;
|
310
|
+
prefix->reserved[3] = 0;
|
311
|
+
prefix->padding1 = 0;
|
312
|
+
|
313
|
+
appendBigEndianStringToEOTHeader(eotHeader, familyName, familyNameLength);
|
314
|
+
appendBigEndianStringToEOTHeader(eotHeader, subfamilyName, subfamilyNameLength);
|
315
|
+
appendBigEndianStringToEOTHeader(eotHeader, versionString, versionStringLength);
|
316
|
+
|
317
|
+
// If possible, ensure that the family name is a prefix of the full name.
|
318
|
+
if (fullNameLength >= familyNameLength && memcmp(familyName, fullName, familyNameLength)) {
|
319
|
+
overlaySrc = reinterpret_cast<const char*>(fullName) - data;
|
320
|
+
overlayDst = reinterpret_cast<const char*>(familyName) - data;
|
321
|
+
overlayLength = familyNameLength;
|
322
|
+
}
|
323
|
+
|
324
|
+
appendBigEndianStringToEOTHeader(eotHeader, fullName, fullNameLength);
|
325
|
+
|
326
|
+
unsigned short padding = 0;
|
327
|
+
eotHeader.push_back(padding);
|
328
|
+
eotHeader.push_back(padding);
|
329
|
+
|
330
|
+
prefix = reinterpret_cast<EOTPrefix*>(&eotHeader[0]);
|
331
|
+
prefix->eotSize = eotHeader.size() + fontSize;
|
332
|
+
|
333
|
+
return true;
|
334
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
/* Modified for use with ttf2eot, originally from WebKit. */
|
2
|
+
|
3
|
+
/*
|
4
|
+
* Copyright (C) 2008 Apple Inc. All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions
|
8
|
+
* are met:
|
9
|
+
* 1. Redistributions of source code must retain the above copyright
|
10
|
+
* notice, this list of conditions and the following disclaimer.
|
11
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
12
|
+
* notice, this list of conditions and the following disclaimer in the
|
13
|
+
* documentation and/or other materials provided with the distribution.
|
14
|
+
*
|
15
|
+
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
|
16
|
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
18
|
+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
|
19
|
+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
20
|
+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
21
|
+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
22
|
+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
23
|
+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
24
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
25
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
26
|
+
*/
|
27
|
+
|
28
|
+
#ifndef OpenTypeUtilities_h
|
29
|
+
#define OpenTypeUtilities_h
|
30
|
+
|
31
|
+
using std::vector;
|
32
|
+
|
33
|
+
bool getEOTHeader(unsigned char * fontData, size_t fontSize, vector<uint8_t>& eotHeader, size_t& overlayDst, size_t& overlaySrc, size_t& overlayLength);
|
34
|
+
|
35
|
+
|
36
|
+
#endif // OpenTypeUtilities_h
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <stdio.h>
|
3
|
+
#include <assert.h>
|
4
|
+
#include <limits.h>
|
5
|
+
#include <string.h>
|
6
|
+
#include <ruby.h>
|
7
|
+
|
8
|
+
#include <vector>
|
9
|
+
|
10
|
+
#ifndef _MSC_VER
|
11
|
+
# include <stdint.h>
|
12
|
+
#else
|
13
|
+
typedef unsigned char uint8_t;
|
14
|
+
#endif
|
15
|
+
|
16
|
+
#include "OpenTypeUtilities.h"
|
17
|
+
|
18
|
+
VALUE eTTFConversionError;
|
19
|
+
|
20
|
+
static VALUE mTTF2EOT_eot_header(VALUE self, VALUE input) {
|
21
|
+
vector<uint8_t> eotHeader(512);
|
22
|
+
bool success;
|
23
|
+
size_t overlayDst = 0;
|
24
|
+
size_t overlaySrc = 0;
|
25
|
+
size_t overlayLength = 0;
|
26
|
+
|
27
|
+
if ( TYPE(input) != T_STRING )
|
28
|
+
rb_raise(rb_eTypeError, "TTF2EOT.eot_header expects a string as input");
|
29
|
+
|
30
|
+
success = getEOTHeader(
|
31
|
+
(unsigned char *) RSTRING_PTR(input),
|
32
|
+
RSTRING_LEN(input),
|
33
|
+
eotHeader,
|
34
|
+
overlayDst,
|
35
|
+
overlaySrc,
|
36
|
+
overlayLength
|
37
|
+
);
|
38
|
+
|
39
|
+
if ( success ) {
|
40
|
+
return rb_str_new((char *) &eotHeader[0], eotHeader.size());
|
41
|
+
} else {
|
42
|
+
rb_raise(
|
43
|
+
eTTFConversionError,
|
44
|
+
"could not get EOT header - ensure input contains valid TTF font data"
|
45
|
+
);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
extern "C" void Init_ttf2eot_ext() {
|
50
|
+
VALUE mTTF2EOT = rb_const_get(rb_cObject, rb_intern("TTF2EOT"));
|
51
|
+
eTTFConversionError = rb_define_class_under(mTTF2EOT, "ConversionError", rb_eStandardError);
|
52
|
+
|
53
|
+
rb_define_module_function(mTTF2EOT, "eot_header", (VALUE(*)(...))mTTF2EOT_eot_header, 1);
|
54
|
+
}
|
data/lib/ttf2eot.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
module TTF2EOT
|
2
|
+
# Public: Converts a TTF font file to an EOT font.
|
3
|
+
#
|
4
|
+
# input - the input TTF font as a String (representing a path) or IO object
|
5
|
+
# (responding to #read).
|
6
|
+
# output - the output destination as a String (representing a path) or IO
|
7
|
+
# object where the EOT font will be written.
|
8
|
+
#
|
9
|
+
# Examples:
|
10
|
+
#
|
11
|
+
# TTF2EOT.convert("input.ttf", "output.eot")
|
12
|
+
# # => #<File:output.eot>
|
13
|
+
#
|
14
|
+
# input = StringIO.new(File.read("input.ttf"))
|
15
|
+
# output = StringIO.new
|
16
|
+
# TTF2EOT.convert(input, output)
|
17
|
+
# # => #<StringIO:0x007f815a83a210>
|
18
|
+
#
|
19
|
+
# Returns the output IO object.
|
20
|
+
# Raises TTF2EOT::ConversionError if the input data is invalid.
|
21
|
+
def convert(input, output)
|
22
|
+
input = File.open(input, "rb") unless input.respond_to?(:read)
|
23
|
+
output = File.open(output, "wb") unless output.respond_to?(:write)
|
24
|
+
|
25
|
+
source = input.read
|
26
|
+
header = eot_header(source)
|
27
|
+
|
28
|
+
output.write header
|
29
|
+
output.write source
|
30
|
+
output.flush
|
31
|
+
|
32
|
+
output
|
33
|
+
end
|
34
|
+
module_function :convert
|
35
|
+
|
36
|
+
# Internal: Get an EOT header for a TTF font.
|
37
|
+
#
|
38
|
+
# font_data - a String containing valid TTF font data.
|
39
|
+
#
|
40
|
+
# Returns a String with the EOT header for the input data.
|
41
|
+
# Raises TTF2EOT::ConversionError if the input data is invalid.
|
42
|
+
def eot_header(font_data)
|
43
|
+
raise NotImlementedError, "this method is defined by the ttf2eot c extension"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
require "ttf2eot_ext"
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ttf2eot
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Bernerd Schaefer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake-compiler
|
16
|
+
requirement: &70362718527040 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70362718527040
|
25
|
+
description: Convert TTF fonts to EOT fonts
|
26
|
+
email: bj.schaefer@gmail.com
|
27
|
+
executables: []
|
28
|
+
extensions:
|
29
|
+
- ext/ttf2eot_ext/extconf.rb
|
30
|
+
extra_rdoc_files: []
|
31
|
+
files:
|
32
|
+
- Rakefile
|
33
|
+
- lib/ttf2eot.rb
|
34
|
+
- ext/ttf2eot_ext/OpenTypeUtilities.cpp
|
35
|
+
- ext/ttf2eot_ext/ttf2eot.cpp
|
36
|
+
- ext/ttf2eot_ext/OpenTypeUtilities.h
|
37
|
+
- ext/ttf2eot_ext/extconf.rb
|
38
|
+
homepage:
|
39
|
+
licenses: []
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options: []
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirements: []
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 1.8.11
|
59
|
+
signing_key:
|
60
|
+
specification_version: 3
|
61
|
+
summary: Convert TTF fonts to EOT fonts
|
62
|
+
test_files: []
|
63
|
+
has_rdoc:
|