diff options
Diffstat (limited to 'Build/source/texk/ttf2pk2/ttfaux.c')
-rw-r--r-- | Build/source/texk/ttf2pk2/ttfaux.c | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/Build/source/texk/ttf2pk2/ttfaux.c b/Build/source/texk/ttf2pk2/ttfaux.c new file mode 100644 index 00000000000..b249f243daa --- /dev/null +++ b/Build/source/texk/ttf2pk2/ttfaux.c @@ -0,0 +1,391 @@ +/* + * ttfaux.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999, 2000, 2002, 2003 by + * Frederic Loyer <loyer@ensta.fr> + * Werner Lemberg <wl@gnu.org> + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> +#include <stdlib.h> + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_OUTLINE_H +#include FT_BBOX_H + +#include "ttf2tfm.h" +#include "newobj.h" +#include "ligkern.h" +#include "ttfenc.h" +#include "tfmaux.h" +#include "errormsg.h" +#include "ttfaux.h" +#include "filesrch.h" +#include "ftlib.h" + + +char *real_ttfname; + +int flags = FT_LOAD_DEFAULT|FT_LOAD_NO_SCALE; + +FT_BBox bbox; + + +static void +readttf_kern(Font *fnt) +{ + kern *nk; + ttfinfo *ti, *tj; + FT_Error error; + FT_Vector akerning; + + for (ti = fnt->charlist; ti; ti = ti->next) + { + kern head; + kern *tail = &head; + head.next = NULL; + for (tj = fnt->charlist; tj; tj = tj->next) + { + if ((error = FT_Get_Kerning(face, ti->glyphindex, tj->glyphindex, + FT_KERNING_UNSCALED, &akerning))) + oops("Cannot get kerning vector (error code = 0x%x).", error); + + if (akerning.x) + { + nk = newkern(); + nk->succ = tj->adobename; + nk->delta = transform(akerning.x * 1000 / fnt->units_per_em, 0, + fnt->efactor, fnt->slant); +#if 0 + nk->next = ti->kerns; + ti->kerns = nk; +#else + /* We append the new kern to reproduce the old .vpl file */ + tail->next = nk; + tail = nk; +#endif + } + } + ti->kerns = head.next; + } +} + + +void +readttf(Font *fnt, Boolean quiet, Boolean only_range) +{ + FT_Error error; + ttfinfo *ti, *Ti; + long Num, index; + unsigned int i, j; + long k, max_k; + int index_array[257]; + + static Boolean initialized = False; + + + /* + * We allocate a placeholder boundary and the `.notdef' character. + */ + + if (!only_range) + { + ti = newchar(fnt); + ti->charcode = -1; + ti->adobename = ".notdef"; + + ti = newchar(fnt); + ti->charcode = -1; + ti->adobename = "||"; /* boundary character name */ + } + + /* + * Initialize FreeType engine. + */ + + if (!initialized) + { + /* + * We use a dummy glyph size of 10pt. + */ + dpi = 92; + ptsize = 10 * 64; + + real_ttfname = TeX_search_ttf_file(&(fnt->ttfname)); + if (!real_ttfname) + oops("Cannot find `%s'.", fnt->ttfname); + + FTopen(real_ttfname, fnt, True, True); + + initialized = True; + } + + if (!quiet) + { + if (only_range) + printf("\n\n%s:\n", fnt->fullname); + printf("\n"); + printf("Glyph Code Glyph Name "); + printf("Width llx lly urx ury\n"); + printf("----------------------------------------"); + printf("---------------------------------\n"); + } + + /* + * We load only glyphs with a valid cmap entry. Nevertheless, for + * the default mapping, we use the first 256 glyphs addressed by + * ascending code points, followed by glyphs not in the cmap. + * + * If we compute a range, we take the character codes given in + * the fnt->sf_code array. + * + * If the -N flag is set, no cmap is used at all. Instead, the + * first 256 glyphs (with a valid PS name) are used for the default + * mapping. + */ + + if (!only_range) + for (i = 0; i < 257; i++) + index_array[i] = 0; + else + for (i = 0; i < 256; i++) + fnt->inencptrs[i] = 0; + + j = 0; + if (fnt->PSnames == Only) + max_k = face->num_glyphs - 1; + else + max_k = only_range ? 0xFF : 0x16FFFF; + + for (k = 0; k <= max_k; k++) + { + char buff[128]; + const char *an; + + + if (fnt->PSnames != Only) + { + if (only_range) + { + index = fnt->sf_code[k]; + if (index < 0) + continue; + j = k; + } + else + index = k; + + Num = FT_Get_Char_Index(face, index); + + /* now we try to get a vertical glyph form */ + if (has_gsub) + Num = Get_Vert(Num); + + if (Num < 0) + oops("Failure on cmap mapping from %s.", fnt->ttfname); + if (Num == 0) + continue; + if (!only_range) + if (Num <= 256) + index_array[Num] = 1; + } + else + { + Num = k; + index = 0; + } + + error = FT_Load_Glyph(face, Num, flags); + if (!error) + { + if (fnt->efactor != 1.0 || fnt->slant != 0.0 ) + FT_Outline_Transform(&face->glyph->outline, &matrix1); + if (fnt->rotate) + FT_Outline_Transform(&face->glyph->outline, &matrix2); + error = FT_Outline_Get_BBox(&face->glyph->outline, &bbox); /* we need the non- + grid-fitted bbox */ + } + if (!error) + { + if (fnt->PSnames) + { + (void)FT_Get_Glyph_Name(face, Num, buff, 128); + an = newstring(buff); + } + else + an = code_to_adobename(index); + + /* ignore characters not usable for typesetting with TeX */ + + if (strcmp(an, ".notdef") == 0) + continue; + if (strcmp(an, ".null") == 0) + continue; + if (strcmp(an, "nonmarkingreturn") == 0) + continue; + + ti = newchar(fnt); + ti->charcode = index; + ti->glyphindex = Num; + ti->adobename = an; + ti->llx = bbox.xMin * 1000 / fnt->units_per_em; + ti->lly = bbox.yMin * 1000 / fnt->units_per_em; + ti->urx = bbox.xMax * 1000 / fnt->units_per_em; + ti->ury = bbox.yMax * 1000 / fnt->units_per_em; + + ti->fntnum = fnt->subfont_num; + + /* + * We must now shift the rotated character both horizontally + * and vertically. The vertical amount is 25% by default. + */ + + if (fnt->rotate) + { + ti->llx += (face->glyph->metrics.vertBearingY - bbox.xMin) * + 1000 / fnt->units_per_em; + ti->lly -= 1000 * fnt->y_offset; + ti->urx += (face->glyph->metrics.vertBearingY - bbox.xMin) * + 1000 / fnt->units_per_em; + ti->ury -= 1000 * fnt->y_offset; + } + + /* + * We need to avoid negative heights or depths. They break accents + * in math mode, among other things. + */ + + if (ti->lly > 0) + ti->lly = 0; + if (ti->ury < 0) + ti->ury = 0; + if (fnt->rotate) + ti->width = face->glyph->metrics.vertAdvance * 1000 / fnt->units_per_em; + else + ti->width = transform(face->glyph->metrics.horiAdvance * 1000 / fnt->units_per_em, + 0, fnt->efactor, fnt->slant); + + if (!quiet) + printf("%5ld %05lx %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", + Num, index, ti->adobename, + ti->width, + ti->llx, ti->lly, ti->urx, ti->ury); + + if (j < 256) + { + fnt->inencptrs[j] = ti; + ti->incode = j; + } + j++; + } + } + + /* + * Now we load glyphs without a cmap entry, provided some slots are + * still free -- we skip this if we have to compute a range or use + * PS names. + */ + + if (!only_range && !fnt->PSnames) + { + for (i = 1; i <= face->num_glyphs; i++) + { + const char *an; + + + if (index_array[i] == 0) + { + error = FT_Load_Glyph(face, i, flags); + if (!error) + error = FT_Outline_Get_BBox(&face->glyph->outline, &bbox); + if (!error) + { + an = code_to_adobename(i | 0x1000000); + + ti = newchar(fnt); + ti->charcode = i | 0x1000000; + ti->glyphindex = i; + ti->adobename = an; + ti->llx = bbox.xMin * 1000 / fnt->units_per_em; + ti->lly = bbox.yMin * 1000 / fnt->units_per_em; + ti->urx = bbox.xMax * 1000 / fnt->units_per_em; + ti->ury = bbox.yMax * 1000 / fnt->units_per_em; + + if (ti->lly > 0) + ti->lly = 0; + if (ti->ury < 0) + ti->ury = 0; + ti->width = transform(face->glyph->metrics.horiAdvance*1000 / fnt->units_per_em, + 0, fnt->efactor, fnt->slant); + + if (!quiet) + printf("%5d %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", + i, ti->adobename, + ti->width, + ti->llx, ti->lly, ti->urx, ti->ury); + + if (j < 256) + { + fnt->inencptrs[j] = ti; + ti->incode = j; + } + else + break; + j++; + } + } + } + } + + /* Finally, we construct a `Germandbls' glyph if necessary */ + + if (!only_range) + { + if (NULL == findadobe("Germandbls", fnt->charlist) && + NULL != (Ti = findadobe("S", fnt->charlist))) + { + pcc *np, *nq; + + + ti = newchar(fnt); + ti->charcode = face->num_glyphs | 0x1000000; + ti->glyphindex = face->num_glyphs; + ti->adobename = "Germandbls"; + ti->width = Ti->width << 1; + ti->llx = Ti->llx; + ti->lly = Ti->lly; + ti->urx = Ti->width + Ti->urx; + ti->ury = Ti->ury; + ti->kerns = Ti->kerns; + + np = newpcc(); + np->partname = "S"; + nq = newpcc(); + nq->partname = "S"; + nq->xoffset = Ti->width; + np->next = nq; + ti->pccs = np; + ti->constructed = True; + + if (!quiet) + printf("* %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", + ti->adobename, + ti->width, + ti->llx, ti->lly, ti->urx, ti->ury); + } + } + + /* kerning between subfonts isn't available */ + if (!only_range) + readttf_kern(fnt); +} + + +/* end */ |