1 --- texk/xdvik/ft2vert.c.orig	2015-07-19 18:49:42 UTC
2 +++ texk/xdvik/ft2vert.c
3 @@ -0,0 +1,399 @@
4 +/*
5 + * "ft2vert.c"
6 + *
7 + * Converter to vertical glyph ID by handling GSUB vrt2/vert feature
8 + * requires FreeType-2.1.10 or latter
9 + *
10 + * (C) 2005 Nobuyuki TSUCHIMURA
11 + *
12 + * This file is free
13 + * software; you can redistribute it and/or modify it under the terms of
14 + * the GNU Library General Public License as published by the Free
15 + * Software Foundation; either version 2 of the License, or (at your
16 + * option) any later version.  This library is distributed in the hope
17 + * that it will be useful, but WITHOUT ANY WARRANTY; without even the
18 + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 + * PURPOSE.  See the GNU Library General Public License for more details.
20 + * You should have received a copy of the GNU Library General Public
21 + * License along with this library; if not, write to the Free Software
22 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 + *
24 + * using such Lookup
25 + *   ScriptTag == 'kana'
26 + *   DefaultLangSys or LangSysTag == 'JAN '
27 + *   FeatureTag == 'vrt2' or 'vert'
28 + *
29 + * [reference]
30 + * http://partners.adobe.com/public/developer/opentype/index_table_formats1.html
31 + * http://partners.adobe.com/public/developer/opentype/index_table_formats.html
32 + * http://partners.adobe.com/public/developer/opentype/index_tag9.html#vrt2
33 + */
34 +
35 +#include "xdvi-config.h"
36 +#include "xdvi.h"
37 +#ifdef	PTEX
38 +
39 +#include <ft2build.h>
40 +#include FT_FREETYPE_H
41 +#include FT_OPENTYPE_VALIDATE_H
42 +
43 +#include <stdio.h>
44 +#include <stdlib.h>
45 +#include "ft2vert.h"
46 +
47 +#define TAG_KANA FT_MAKE_TAG('k', 'a', 'n', 'a')
48 +#define TAG_JAN  FT_MAKE_TAG('J', 'A', 'N', ' ')
49 +#define TAG_VERT FT_MAKE_TAG('v', 'e', 'r', 't')
50 +#define TAG_VRT2 FT_MAKE_TAG('v', 'r', 't', '2')
51 +
52 +#define MALLOC(ptr, size) ptr = xmalloc(sizeof((ptr)[0]) * (size))
53 +#define BYTE2(p) ((p) += 2, (int)(p)[-2] << 8  | (p)[-1])
54 +#define BYTE4(p) ((p) += 4, (int)(p)[-4] << 24 | (int)(p)[-3] << 16 | \
55 +		  (int)(p)[-2] << 8 | (p)[-1])
56 +
57 +struct ft2vert_st {
58 +    int SubTableCount;
59 +    struct SubTable_st {
60 +	struct SingleSubst_st {
61 +	    FT_UInt SubstFormat;
62 +	    FT_UInt DeltaGlyphID; /* SubstFormat == 1 */
63 +	    int     GlyphCount;   /* SubstFormat == 2 */
64 +	    FT_UInt *Substitute;  /* SubstFormat == 2 */
65 +	} SingleSubst;
66 +	struct Coverage_st {
67 +	    FT_UInt CoverageFormat;
68 +	    int     GlyphCount;   /* CoverageFormat == 1 */
69 +	    FT_UInt *GlyphArray;  /* CoverageFormat == 1 */
70 +	    int     RangeCount;   /* CoverageFormat == 2 */
71 +	    struct  RangeRecord_st
72 +		   *RangeRecord;  /* CoverageFormat == 2 */
73 +	} Coverage;
74 +    } *SubTable;
75 +    FT_Bytes kanaFeature;
76 +    FT_Bytes vertLookup;
77 +    FT_Bytes vrt2Lookup;
78 +};
79 +
80 +struct RangeRecord_st {
81 +    FT_UInt Start;
82 +    FT_UInt End;
83 +};
84 +
85 +
86 +int isInIndex(FT_Bytes s, int index) {
87 +    int i, count;
88 +
89 +    if (s == NULL) return FALSE;
90 +    count = BYTE2(s);
91 +    for (i=0; i<count; i++) {
92 +	if (index == BYTE2(s)) return TRUE;
93 +    }
94 +    return FALSE;
95 +}
96 +
97 +
98 +/**********  Debug ***************/
99 +
100 +#ifdef DEBUG
101 +static FT_Bytes gsub_top;
102 +
103 +void print_offset(char *message, const FT_Bytes ptr) {
104 +    printf("%s offset = %x\n", message, ptr - gsub_top);
105 +}
106 +
107 +char *tag_to_string(FT_Tag tag) {
108 +    static char str[5];
109 +    str[0] = tag >> 24;
110 +    str[1] = tag >> 16;
111 +    str[2] = tag >> 8;
112 +    str[3] = tag;
113 +    return str;
114 +}
115 +
116 +void hex_dump(const FT_Bytes top) {
117 +    int i, j;
118 +    FT_Bytes s = top;
119 +
120 +    for (j=0; j<100; j++) {
121 +	printf("%04x : ", j*8);
122 +	for (i=0; i<8; i++) {
123 +	    printf("%02x ", s[i+j*8]);
124 +	}
125 +	printf("\n");
126 +    }
127 +}
128 +#endif /* DEBUG */
129 +
130 +/**********  Lookup part ***************/
131 +
132 +void scan_Coverage(struct ft2vert_st *ret, const FT_Bytes top) {
133 +    int i;
134 +    FT_Bytes s = top;
135 +    struct Coverage_st *t;
136 +
137 +    t = &ret->SubTable[ret->SubTableCount].Coverage;
138 +    t->CoverageFormat = BYTE2(s);
139 +    switch (t->CoverageFormat) {
140 +    case 1:
141 +	t->GlyphCount = BYTE2(s);
142 +	MALLOC(t->GlyphArray, t->GlyphCount);
143 +	for (i=0; i<t->GlyphCount; i++) {
144 +	    t->GlyphArray[i] = BYTE2(s);
145 +	}
146 +	break;
147 +    case 2:
148 +	t->RangeCount = BYTE2(s);
149 +	MALLOC(t->RangeRecord, t->RangeCount);
150 +	for (i=0; i<t->RangeCount; i++) {
151 +	    t->RangeRecord[i].Start = BYTE2(s);
152 +	    t->RangeRecord[i].End   = BYTE2(s);
153 +	    s += 2; /* drop StartCoverageIndex */
154 +	}
155 +	break;
156 +    default:
157 +	fprintf(stderr, "scan_Coverage: unknown CoverageFormat (%d).",
158 +		t->CoverageFormat);
159 +	exit(1);
160 +    }
161 +    ret->SubTableCount++;
162 +}
163 +
164 +void scan_SubTable(struct ft2vert_st *ret, const FT_Bytes top) {
165 +    int i;
166 +    FT_Bytes s = top;
167 +    FT_Offset Coverage;
168 +    struct SingleSubst_st *t;
169 +
170 +    t = &ret->SubTable[ret->SubTableCount].SingleSubst;
171 +    t->SubstFormat = BYTE2(s);
172 +    Coverage       = BYTE2(s);
173 +    scan_Coverage(ret, top + Coverage);
174 +    switch (t->SubstFormat) {
175 +    case 1: /* SingleSubstFormat1 */
176 +	t->DeltaGlyphID = BYTE2(s);
177 +	break;
178 +    case 2: /* SingleSubstFormat2 */
179 +	t->GlyphCount   = BYTE2(s);
180 +	MALLOC(t->Substitute, t->GlyphCount);
181 +	for (i=0; i<t->GlyphCount; i++) {
182 +	    t->Substitute[i] = BYTE2(s);
183 +	}
184 +	break;
185 +    default:
186 +	fprintf(stderr, "scan_SubTable: unknown SubstFormat (%d).",
187 +		t->SubstFormat);
188 +	exit(1);
189 +    }
190 +}
191 +
192 +void scan_Lookup(struct ft2vert_st *ret, const FT_Bytes top) {
193 +    int i;
194 +    FT_Bytes s = top;
195 +    FT_UShort LookupType;
196 +    FT_UShort LookupFlag;
197 +    FT_UShort SubTableCount;
198 +    FT_UShort SubTable;
199 +
200 +    LookupType    = BYTE2(s);
201 +    LookupFlag    = BYTE2(s);
202 +    SubTableCount = BYTE2(s);
203 +    SubTable      = BYTE2(s);
204 +
205 +    MALLOC(ret->SubTable, SubTableCount);
206 +    for (i=0; i<SubTableCount; i++) {
207 +	scan_SubTable(ret, top + SubTable);
208 +    }
209 +    if (ret->SubTableCount != SubTableCount) {
210 +	fprintf(stderr, "warning (scan_Lookup): "
211 +		"SubTableCount (=%d) is not expected (=%d).\n",
212 +		ret->SubTableCount, SubTableCount);
213 +    }
214 +}
215 +
216 +
217 +void scan_LookupList(struct ft2vert_st *ret, const FT_Bytes top) {
218 +    int i;
219 +    FT_Bytes s = top;
220 +    int LookupCount;
221 +
222 +    LookupCount = BYTE2(s);
223 +
224 +    for (i=0; i<LookupCount; i++) {
225 +	FT_Bytes t = top + BYTE2(s);
226 +	if (isInIndex(ret->vertLookup, i)) {
227 +	    scan_Lookup(ret, t);
228 +	}
229 +    }
230 +}
231 +
232 +/********** Feature part ****************/
233 +
234 +void scan_FeatureList(struct ft2vert_st *ret, const FT_Bytes top) {
235 +    int i;
236 +    FT_Bytes s = top;
237 +    int FeatureCount;
238 +
239 +    FeatureCount = BYTE2(s);
240 +
241 +    for (i=0; i<FeatureCount; i++) {
242 +	FT_Tag FeatureTag = BYTE4(s);
243 +	FT_Offset Feature = BYTE2(s);
244 +	if (!isInIndex(ret->kanaFeature, i)) continue;
245 +	if (FeatureTag == TAG_VERT) {
246 +	    ret->vertLookup = top + Feature + 2;
247 +	} else if (FeatureTag == TAG_VRT2) {
248 +	    ret->vrt2Lookup = top + Feature + 2;
249 +	}
250 +    }
251 +}
252 +
253 +/********** Script part ****************/
254 +
255 +void scan_LangSys(struct ft2vert_st *ret, const FT_Bytes top) {
256 +    if (ret->kanaFeature == NULL) ret->kanaFeature = top + 4;
257 +}
258 +
259 +void scan_Script(struct ft2vert_st *ret, const FT_Bytes top) {
260 +    int i;
261 +    FT_Bytes s = top;
262 +    FT_Offset DefaultLangSys;
263 +    int LangSysCount;
264 +
265 +    DefaultLangSys = BYTE2(s);
266 +    if (DefaultLangSys != 0) {
267 +	scan_LangSys(ret, top + DefaultLangSys);
268 +    }
269 +    LangSysCount = BYTE2(s);
270 +
271 +    for (i=0; i<LangSysCount; i++) {
272 +	FT_Tag LangSysTag = BYTE4(s);
273 +	FT_Bytes t = top + BYTE2(s);
274 +	if (LangSysTag == TAG_JAN) {
275 +	    scan_LangSys(ret, t);
276 +	}
277 +    }
278 +}
279 +
280 +void scan_ScriptList(struct ft2vert_st *ret, const FT_Bytes top) {
281 +    int i;
282 +    FT_Bytes s = top;
283 +    int ScriptCount;
284 +
285 +    ScriptCount = BYTE2(s);
286 +
287 +    for (i=0; i<ScriptCount; i++) {
288 +	FT_Tag ScriptTag = BYTE4(s);
289 +	FT_Bytes t = top + BYTE2(s);
290 +	if (ScriptTag == TAG_KANA) {
291 +	    scan_Script(ret, t);
292 +	}
293 +    }
294 +}
295 +
296 +/********** header part *****************/
297 +
298 +void scan_GSUB_Header(struct ft2vert_st *ret, const FT_Bytes top) {
299 +    FT_Bytes s = top;
300 +    FT_Fixed  Version;
301 +    FT_Offset ScriptList;
302 +    FT_Offset FeatureList;
303 +    FT_Offset LookupList;
304 +
305 +#ifdef DEBUG
306 +    gsub_top    = top;
307 +#endif /* DEBUG */
308 +    Version     = BYTE4(s);
309 +    ScriptList  = BYTE2(s);
310 +    FeatureList = BYTE2(s);
311 +    LookupList  = BYTE2(s);
312 +
313 +    if (Version != 0x00010000) {
314 +	fprintf(stderr, "warning: GSUB Version (=%.1f) is not 1.0\n",
315 +		(double)Version / 0x10000);
316 +    }
317 +
318 +    scan_ScriptList (ret, top + ScriptList);
319 +    scan_FeatureList(ret, top + FeatureList);
320 +    /* vrt2 has higher priority over vert */
321 +    if (ret->vrt2Lookup != NULL) ret->vertLookup = ret->vrt2Lookup;
322 +    scan_LookupList (ret, top + LookupList);
323 +}
324 +
325 +struct ft2vert_st *ft2vert_init(FT_Face face) {
326 +    struct ft2vert_st *ret;
327 +    int ft_error;
328 +    FT_Bytes dummy, GSUB_table;
329 +
330 +    MALLOC(ret, 1);
331 +    ret->SubTableCount = 0;
332 +    ret->vertLookup  = NULL;
333 +    ret->vrt2Lookup  = NULL;
334 +    ret->kanaFeature = NULL;
335 +    ft_error =
336 +	FT_OpenType_Validate( face, FT_VALIDATE_GSUB,
337 +			      &dummy, &dummy, &dummy, &GSUB_table, &dummy);
338 +    if (ft_error == FT_Err_Unimplemented_Feature) {
339 +        fprintf(stderr, "warning: FT_OpenType_Validate is disabled. "
340 +                "Replace FreeType2 with otvalid-enabled version.\n");
341 +        return ret;
342 +    } else if (ft_error != 0 || GSUB_table == 0) {
343 +	fprintf(stderr, "warning: %s has no GSUB table.\n",
344 +		face->family_name);
345 +	return ret;
346 +    }
347 +    scan_GSUB_Header(ret, GSUB_table);
348 +    if (ret->SubTableCount == 0) {
349 +	fprintf(stderr, "warning: %s has no vrt2/vert feature.\n",
350 +		face->family_name);
351 +    }
352 +    free((void*)GSUB_table);
353 +    return ret;
354 +}
355 +
356 +/********** converting part *****************/
357 +
358 +static FT_UInt get_vert_nth_gid(struct SubTable_st *t, FT_UInt gid, int n) {
359 +    switch (t->SingleSubst.SubstFormat) {
360 +    case 1:
361 +	return gid + t->SingleSubst.DeltaGlyphID;
362 +    case 2:
363 +	return t->SingleSubst.Substitute[n];
364 +    }
365 +    fprintf(stderr, "get_vert_nth_gid: internal error");
366 +    exit(1);
367 +    return 0;
368 +}
369 +
370 +
371 +FT_UInt ft2vert_get_gid(struct ft2vert_st *ft2vert, FT_UInt gid) {
372 +    int i, k;
373 +    int j = 0; /* StartCoverageIndex */
374 +
375 +    for (k=0; k<ft2vert->SubTableCount; k++) {
376 +	struct SubTable_st *t = &ft2vert->SubTable[k];
377 +	switch (t->Coverage.CoverageFormat) {
378 +	case 1:
379 +	    for (i=0; i<t->Coverage.GlyphCount; i++) {
380 +		if (t->Coverage.GlyphArray[i] == gid) {
381 +		    return get_vert_nth_gid(t, gid, i);
382 +		}
383 +	    }
384 +	    break;
385 +	case 2:
386 +	    for (i=0; i<t->Coverage.RangeCount; i++) {
387 +		struct RangeRecord_st *r = &t->Coverage.RangeRecord[i];
388 +		if (r->Start <= gid && gid <= r->End) {
389 +		    return get_vert_nth_gid(t, gid, gid - r->Start + j);
390 +		}
391 +		j += r->End - r->Start + 1;
392 +	    }
393 +	    break;
394 +	default:
395 +	    fprintf(stderr, "ft2vert_get_gid: internal error");
396 +	    exit(1);
397 +	}
398 +    }
399 +    return gid;
400 +}
401 +
402 +#endif	/* PTEX */
403