summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/font/tt_glyf.c
diff options
context:
space:
mode:
authorTaco Hoekwater <taco@elvenkind.com>2010-04-04 13:55:46 +0000
committerTaco Hoekwater <taco@elvenkind.com>2010-04-04 13:55:46 +0000
commitf372862c42d234710b6057449b46818e63181c90 (patch)
treea9ebec66dd31ac37aed442502ebd1b9fe76245ec /Build/source/texk/web2c/luatexdir/font/tt_glyf.c
parent2dad291ab056f30816e0aea61970f38033c2f6a5 (diff)
import luatex 0.60.0 (with small local changes, see luatexdir/ChangeLog)
and do an autoreconf git-svn-id: svn://tug.org/texlive/trunk@17680 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/font/tt_glyf.c')
-rw-r--r--Build/source/texk/web2c/luatexdir/font/tt_glyf.c651
1 files changed, 0 insertions, 651 deletions
diff --git a/Build/source/texk/web2c/luatexdir/font/tt_glyf.c b/Build/source/texk/web2c/luatexdir/font/tt_glyf.c
deleted file mode 100644
index 1ca35e8800f..00000000000
--- a/Build/source/texk/web2c/luatexdir/font/tt_glyf.c
+++ /dev/null
@@ -1,651 +0,0 @@
-/* tt_glyf.c
-
- Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata,
- the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-/*
- * Subsetting glyf, updating loca, hmtx, ...
- *
- */
-
-#include "ptexlib.h"
-
-#include "sfnt.h"
-#include "tt_table.h"
-#include "tt_glyf.h"
-#include "writettf.h"
-
-static const char _svn_version[] =
- "$Id: tt_glyf.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/tt_glyf.c $";
-
-#define NUM_GLYPH_LIMIT 65534
-#define TABLE_DATA_ALLOC_SIZE 40960
-#define GLYPH_ARRAY_ALLOC_SIZE 256
-
-static USHORT find_empty_slot(struct tt_glyphs *g)
-{
- USHORT gid;
-
- ASSERT(g);
-
- for (gid = 0; gid < NUM_GLYPH_LIMIT; gid++) {
- if (!(g->used_slot[gid / 8] & (1 << (7 - (gid % 8)))))
- break;
- }
- if (gid == NUM_GLYPH_LIMIT)
- TT_ERROR("No empty glyph slot available.");
-
- return gid;
-}
-
-USHORT tt_find_glyph(struct tt_glyphs * g, USHORT gid)
-{
- USHORT idx, new_gid = 0;
-
- ASSERT(g);
-
- for (idx = 0; idx < g->num_glyphs; idx++) {
- if (gid == g->gd[idx].ogid) {
- new_gid = g->gd[idx].gid;
- break;
- }
- }
-
- return new_gid;
-}
-
-USHORT tt_get_index(struct tt_glyphs * g, USHORT gid)
-{
- USHORT idx;
-
- ASSERT(g);
-
- for (idx = 0; idx < g->num_glyphs; idx++) {
- if (gid == g->gd[idx].gid)
- break;
- }
- if (idx == g->num_glyphs)
- idx = 0;
-
- return idx;
-}
-
-USHORT tt_add_glyph(struct tt_glyphs * g, USHORT gid, USHORT new_gid)
-{
- ASSERT(g);
-
- if (g->used_slot[new_gid / 8] & (1 << (7 - (new_gid % 8)))) {
- WARN("Slot %u already used.", new_gid);
- } else {
- if (g->num_glyphs + 1 >= NUM_GLYPH_LIMIT)
- TT_ERROR("Too many glyphs.");
-
- if (g->num_glyphs >= g->max_glyphs) {
- g->max_glyphs += GLYPH_ARRAY_ALLOC_SIZE;
- g->gd = RENEW(g->gd, g->max_glyphs, struct tt_glyph_desc);
- }
- g->gd[g->num_glyphs].gid = new_gid;
- g->gd[g->num_glyphs].ogid = gid;
- g->gd[g->num_glyphs].length = 0;
- g->gd[g->num_glyphs].data = NULL;
- g->used_slot[new_gid / 8] |= (1 << (7 - (new_gid % 8)));
- g->num_glyphs += 1;
- }
-
- if (new_gid > g->last_gid) {
- g->last_gid = new_gid;
- }
-
- return new_gid;
-}
-
-/*
- * Initialization
- */
-struct tt_glyphs *tt_build_init(void)
-{
- struct tt_glyphs *g;
-
- g = NEW(1, struct tt_glyphs);
-
- g->num_glyphs = 0;
- g->max_glyphs = 0;
- g->last_gid = 0;
- g->emsize = 1;
- g->default_advh = 0;
- g->default_tsb = 0;
- g->gd = NULL;
- g->used_slot = NEW(8192, unsigned char);
- memset(g->used_slot, 0, 8192);
- tt_add_glyph(g, 0, 0);
-
- return g;
-}
-
-void tt_build_finish(struct tt_glyphs *g)
-{
- if (g) {
- if (g->gd) {
- USHORT idx;
- for (idx = 0; idx < g->num_glyphs; idx++) {
- if (g->gd[idx].data)
- RELEASE(g->gd[idx].data);
- }
- RELEASE(g->gd);
- }
- if (g->used_slot)
- RELEASE(g->used_slot);
- RELEASE(g);
- }
-}
-
-static int glyf_cmp(const void *v1, const void *v2)
-{
- int cmp = 0;
- const struct tt_glyph_desc *sv1, *sv2;
-
- sv1 = (const struct tt_glyph_desc *) v1;
- sv2 = (const struct tt_glyph_desc *) v2;
-
- if (sv1->gid == sv2->gid)
- cmp = 0;
- else if (sv1->gid < sv2->gid)
- cmp = -1;
- else
- cmp = 1;
-
- return cmp;
-}
-
-int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
-{
- char *hmtx_table_data = NULL, *loca_table_data = NULL;
- char *glyf_table_data = NULL;
- ULONG hmtx_table_size, loca_table_size, glyf_table_size;
- /* some information available from other TrueType table */
- struct tt_head_table *head = NULL;
- struct tt_hhea_table *hhea = NULL;
- struct tt_maxp_table *maxp = NULL;
- struct tt_longMetrics *hmtx, *vmtx = NULL;
- struct tt_os2__table *os2;
- /* temp */
- ULONG *location, offset;
- long i;
- USHORT *w_stat; /* Estimate most frequently appeared width */
-
- ASSERT(g);
-
- if (sfont->type != SFNT_TYPE_TRUETYPE && sfont->type != SFNT_TYPE_TTC)
- TT_ERROR("Invalid font type");
-
- if (g->num_glyphs > NUM_GLYPH_LIMIT)
- TT_ERROR("Too many glyphs.");
-
- /*
- * Read head, hhea, maxp, loca:
- *
- * unitsPerEm --> head
- * numHMetrics --> hhea
- * indexToLocFormat --> head
- * numGlyphs --> maxp
- */
- head = tt_read_head_table(sfont);
- hhea = tt_read_hhea_table(sfont);
- maxp = tt_read_maxp_table(sfont);
-
- if (hhea->metricDataFormat != 0)
- TT_ERROR("Unknown metricDataFormat.");
-
- g->emsize = head->unitsPerEm;
-
- sfnt_locate_table(sfont, "hmtx");
- hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numberOfHMetrics);
-
- os2 = tt_read_os2__table(sfont);
- if (os2) {
- g->default_advh = os2->sTypoAscender - os2->sTypoDescender;
- g->default_tsb = g->default_advh - os2->sTypoAscender;
-
- /* dvipdfmx does this elsewhere! */
- fd_cur->font_dim[STEMV_CODE].val =
- (os2->usWeightClass / 65) * (os2->usWeightClass / 65) + 50;
- }
-
- if (sfnt_find_table_pos(sfont, "vmtx") > 0) {
- struct tt_vhea_table *vhea;
- vhea = tt_read_vhea_table(sfont);
- sfnt_locate_table(sfont, "vmtx");
- vmtx =
- tt_read_longMetrics(sfont, maxp->numGlyphs,
- vhea->numOfLongVerMetrics);
- RELEASE(vhea);
- } else {
- vmtx = NULL;
- }
-
- sfnt_locate_table(sfont, "loca");
- location = NEW(maxp->numGlyphs + 1, ULONG);
- if (head->indexToLocFormat == 0) {
- for (i = 0; i <= maxp->numGlyphs; i++)
- location[i] = 2 * ((ULONG) sfnt_get_ushort(sfont));
- } else if (head->indexToLocFormat == 1) {
- for (i = 0; i <= maxp->numGlyphs; i++)
- location[i] = sfnt_get_ulong(sfont);
- } else {
- TT_ERROR("Unknown IndexToLocFormat.");
- }
-
- w_stat = NEW(g->emsize + 2, USHORT);
- memset(w_stat, 0, sizeof(USHORT) * (g->emsize + 2));
- /*
- * Read glyf table.
- */
- offset = sfnt_locate_table(sfont, "glyf");
- /*
- * The num_glyphs may grow when composite glyph is found.
- * A component of glyph refered by a composite glyph is appended
- * to used_glyphs if it is not already registered in used_glyphs.
- * Glyph programs of composite glyphs are modified so that it
- * correctly refer to new gid of their components.
- */
- for (i = 0; i < NUM_GLYPH_LIMIT; i++) {
- USHORT gid; /* old gid */
- ULONG loc, len;
- BYTE *p, *endptr;
- SHORT number_of_contours;
-
- if (i >= g->num_glyphs) /* finished */
- break;
-
- gid = g->gd[i].ogid;
- if (gid >= maxp->numGlyphs)
- TT_ERROR("Invalid glyph index (gid %u)", gid);
-
- loc = location[gid];
- len = location[gid + 1] - loc;
- g->gd[i].advw = hmtx[gid].advance;
- g->gd[i].lsb = hmtx[gid].sideBearing;
- if (vmtx) {
- g->gd[i].advh = vmtx[gid].advance;
- g->gd[i].tsb = vmtx[gid].sideBearing;
- } else {
- g->gd[i].advh = g->default_advh;
- g->gd[i].tsb = g->default_tsb;
- }
- g->gd[i].length = len;
- g->gd[i].data = NULL;
- if (g->gd[i].advw <= g->emsize) {
- w_stat[g->gd[i].advw] += 1;
- } else {
- w_stat[g->emsize + 1] += 1; /* larger than em */
- }
-
- if (len == 0) { /* Does not contains any data. */
- continue;
- } else if (len < 10) {
- TT_ERROR("Invalid TrueType glyph data (gid %u).", gid);
- }
-
- g->gd[i].data = p = NEW(len, BYTE);
- endptr = p + len;
-
- sfnt_seek_set(sfont, offset + loc);
- number_of_contours = sfnt_get_short(sfont);
- p += sfnt_put_short(p, number_of_contours);
-
- /* BoundingBox: FWord x 4 */
- g->gd[i].llx = sfnt_get_short(sfont);
- g->gd[i].lly = sfnt_get_short(sfont);
- g->gd[i].urx = sfnt_get_short(sfont);
- g->gd[i].ury = sfnt_get_short(sfont);
- /* _FIXME_ */
-#if 1
- if (!vmtx) /* vertOriginY == sTypeAscender */
- g->gd[i].tsb = g->default_advh - g->default_tsb - g->gd[i].ury;
-#endif
- p += sfnt_put_short(p, g->gd[i].llx);
- p += sfnt_put_short(p, g->gd[i].lly);
- p += sfnt_put_short(p, g->gd[i].urx);
- p += sfnt_put_short(p, g->gd[i].ury);
-
- /* Read evrything else. */
- sfnt_read(p, len - 10, sfont);
- /*
- * Fix GIDs of composite glyphs.
- */
- if (number_of_contours < 0) {
- USHORT flags, cgid, new_gid; /* flag, gid of a component */
- do {
- if (p >= endptr)
- TT_ERROR("Invalid TrueType glyph data (gid %u): %u bytes",
- gid, (unsigned int) len);
- /*
- * Flags and gid of component glyph are both USHORT.
- */
- flags = ((*p) << 8) | *(p + 1);
- p += 2;
- cgid = ((*p) << 8) | *(p + 1);
- if (cgid >= maxp->numGlyphs) {
- TT_ERROR("Invalid gid (%u > %u) in composite glyph %u.",
- cgid, maxp->numGlyphs, gid);
- }
- new_gid = tt_find_glyph(g, cgid);
- if (new_gid == 0) {
- new_gid = tt_add_glyph(g, cgid, find_empty_slot(g));
- }
- p += sfnt_put_ushort(p, new_gid);
- /*
- * Just skip remaining part.
- */
- p += (flags & ARG_1_AND_2_ARE_WORDS) ? 4 : 2;
- if (flags & WE_HAVE_A_SCALE) /* F2Dot14 */
- p += 2;
- else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) /* F2Dot14 x 2 */
- p += 4;
- else if (flags & WE_HAVE_A_TWO_BY_TWO) /* F2Dot14 x 4 */
- p += 8;
- } while (flags & MORE_COMPONENTS);
- /*
- * TrueType instructions comes here:
- * length_of_instruction (ushort)
- * instruction (byte * length_of_instruction)
- */
- }
- }
- RELEASE(location);
- RELEASE(hmtx);
- if (vmtx)
- RELEASE(vmtx);
-
- {
- int max_count = -1;
-
- g->dw = g->gd[0].advw;
- for (i = 0; i < g->emsize + 1; i++) {
- if (w_stat[i] > max_count) {
- max_count = w_stat[i];
- g->dw = i;
- }
- }
- }
- RELEASE(w_stat);
-
- qsort(g->gd, g->num_glyphs, sizeof(struct tt_glyph_desc), glyf_cmp);
- {
- USHORT prev, last_advw;
- char *p, *q;
- int padlen, num_hm_known;
-
- glyf_table_size = 0UL;
- num_hm_known = 0;
- last_advw = g->gd[g->num_glyphs - 1].advw;
- for (i = g->num_glyphs - 1; i >= 0; i--) {
- padlen = (g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0;
- glyf_table_size += g->gd[i].length + padlen;
- if (!num_hm_known && last_advw != g->gd[i].advw) {
- hhea->numberOfHMetrics = g->gd[i].gid + 2;
- num_hm_known = 1;
- }
- }
- /* All advance widths are same. */
- if (!num_hm_known) {
- hhea->numberOfHMetrics = 1;
- }
- hmtx_table_size = hhea->numberOfHMetrics * 2 + (g->last_gid + 1) * 2;
-
- /*
- * Choosing short format does not always give good result
- * when compressed. Sometimes increases size.
- */
- if (glyf_table_size < 0x20000UL) {
- head->indexToLocFormat = 0;
- loca_table_size = (g->last_gid + 2) * 2;
- } else {
- head->indexToLocFormat = 1;
- loca_table_size = (g->last_gid + 2) * 4;
- }
-
- hmtx_table_data = p = NEW(hmtx_table_size, char);
- loca_table_data = q = NEW(loca_table_size, char);
- glyf_table_data = NEW(glyf_table_size, char);
-
- offset = 0UL;
- prev = 0;
- for (i = 0; i < g->num_glyphs; i++) {
- long gap, j;
- gap = (long) g->gd[i].gid - prev - 1;
- for (j = 1; j <= gap; j++) {
- if (prev + j == hhea->numberOfHMetrics - 1) {
- p += sfnt_put_ushort(p, last_advw);
- } else if (prev + j < hhea->numberOfHMetrics) {
- p += sfnt_put_ushort(p, 0);
- }
- p += sfnt_put_short(p, 0);
- if (head->indexToLocFormat == 0) {
- q += sfnt_put_ushort(q, (USHORT) (offset / 2));
- } else {
- q += sfnt_put_ulong(q, offset);
- }
- }
- padlen = (g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0;
- if (g->gd[i].gid < hhea->numberOfHMetrics) {
- p += sfnt_put_ushort(p, g->gd[i].advw);
- }
- p += sfnt_put_short(p, g->gd[i].lsb);
- if (head->indexToLocFormat == 0) {
- q += sfnt_put_ushort(q, (USHORT) (offset / 2));
- } else {
- q += sfnt_put_ulong(q, offset);
- }
- memset(glyf_table_data + offset, 0, g->gd[i].length + padlen);
- memcpy(glyf_table_data + offset, g->gd[i].data, g->gd[i].length);
- offset += g->gd[i].length + padlen;
- prev = g->gd[i].gid;
- /* free data here since it consume much memory */
- RELEASE(g->gd[i].data);
- g->gd[i].length = 0;
- g->gd[i].data = NULL;
- }
- if (head->indexToLocFormat == 0) {
- q += sfnt_put_ushort(q, (USHORT) (offset / 2));
- } else {
- q += sfnt_put_ulong(q, offset);
- }
-
- sfnt_set_table(sfont, "hmtx", (char *) hmtx_table_data,
- hmtx_table_size);
- sfnt_set_table(sfont, "loca", (char *) loca_table_data,
- loca_table_size);
- sfnt_set_table(sfont, "glyf", (char *) glyf_table_data,
- glyf_table_size);
- }
-
- head->checkSumAdjustment = 0;
- maxp->numGlyphs = g->last_gid + 1;
-
- /* TODO */
- sfnt_set_table(sfont, "maxp", tt_pack_maxp_table(maxp), TT_MAXP_TABLE_SIZE);
- sfnt_set_table(sfont, "hhea", tt_pack_hhea_table(hhea), TT_HHEA_TABLE_SIZE);
- sfnt_set_table(sfont, "head", tt_pack_head_table(head), TT_HEAD_TABLE_SIZE);
- RELEASE(maxp);
- RELEASE(hhea);
- RELEASE(head);
- if (os2)
- RELEASE(os2);
-
- return 0;
-}
-
-int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g)
-{
- struct tt_head_table *head = NULL;
- struct tt_hhea_table *hhea = NULL;
- struct tt_maxp_table *maxp = NULL;
- struct tt_longMetrics *hmtx, *vmtx = NULL;
- struct tt_os2__table *os2;
- /* temp */
- ULONG *location, offset;
- long i;
- USHORT *w_stat;
-
- ASSERT(g);
-
- if (sfont == NULL ||
-#ifdef XETEX
- sfont->ft_face == NULL
-#elif defined(pdfTeX)
- sfont->buffer == NULL
-#else
- sfont->stream == NULL
-#endif
- )
- TT_ERROR("File not opened.");
-
- if (sfont->type != SFNT_TYPE_TRUETYPE && sfont->type != SFNT_TYPE_TTC)
- TT_ERROR("Invalid font type");
-
- /*
- * Read head, hhea, maxp, loca:
- *
- * unitsPerEm --> head
- * numHMetrics --> hhea
- * indexToLocFormat --> head
- * numGlyphs --> maxp
- */
- head = tt_read_head_table(sfont);
- hhea = tt_read_hhea_table(sfont);
- maxp = tt_read_maxp_table(sfont);
-
- if (hhea->metricDataFormat != 0)
- TT_ERROR("Unknown metricDataFormat.");
-
- g->emsize = head->unitsPerEm;
-
- sfnt_locate_table(sfont, "hmtx");
- hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numberOfHMetrics);
-
- os2 = tt_read_os2__table(sfont);
- g->default_advh = os2->sTypoAscender - os2->sTypoDescender;
- g->default_tsb = g->default_advh - os2->sTypoAscender;
-
- if (sfnt_find_table_pos(sfont, "vmtx") > 0) {
- struct tt_vhea_table *vhea;
- vhea = tt_read_vhea_table(sfont);
- sfnt_locate_table(sfont, "vmtx");
- vmtx =
- tt_read_longMetrics(sfont, maxp->numGlyphs,
- vhea->numOfLongVerMetrics);
- RELEASE(vhea);
- } else {
- vmtx = NULL;
- }
-
- sfnt_locate_table(sfont, "loca");
- location = NEW(maxp->numGlyphs + 1, ULONG);
- if (head->indexToLocFormat == 0) {
- for (i = 0; i <= maxp->numGlyphs; i++)
- location[i] = 2 * ((ULONG) sfnt_get_ushort(sfont));
- } else if (head->indexToLocFormat == 1) {
- for (i = 0; i <= maxp->numGlyphs; i++)
- location[i] = sfnt_get_ulong(sfont);
- } else {
- TT_ERROR("Unknown IndexToLocFormat.");
- }
-
- w_stat = NEW(g->emsize + 2, USHORT);
- memset(w_stat, 0, sizeof(USHORT) * (g->emsize + 2));
- /*
- * Read glyf table.
- */
- offset = sfnt_locate_table(sfont, "glyf");
- for (i = 0; i < g->num_glyphs; i++) {
- USHORT gid; /* old gid */
- ULONG loc, len;
- SHORT number_of_contours;
-
- gid = g->gd[i].ogid;
- if (gid >= maxp->numGlyphs)
- TT_ERROR("Invalid glyph index (gid %u)", gid);
-
- loc = location[gid];
- len = location[gid + 1] - loc;
- g->gd[i].advw = hmtx[gid].advance;
- g->gd[i].lsb = hmtx[gid].sideBearing;
- if (vmtx) {
- g->gd[i].advh = vmtx[gid].advance;
- g->gd[i].tsb = vmtx[gid].sideBearing;
- } else {
- g->gd[i].advh = g->default_advh;
- g->gd[i].tsb = g->default_tsb;
- }
- g->gd[i].length = len;
- g->gd[i].data = NULL;
-
- if (g->gd[i].advw <= g->emsize) {
- w_stat[g->gd[i].advw] += 1;
- } else {
- w_stat[g->emsize + 1] += 1; /* larger than em */
- }
-
- if (len == 0) { /* Does not contains any data. */
- continue;
- } else if (len < 10) {
- TT_ERROR("Invalid TrueType glyph data (gid %u).", gid);
- }
-
- sfnt_seek_set(sfont, offset + loc);
- number_of_contours = sfnt_get_short(sfont);
-
- /* BoundingBox: FWord x 4 */
- g->gd[i].llx = sfnt_get_short(sfont);
- g->gd[i].lly = sfnt_get_short(sfont);
- g->gd[i].urx = sfnt_get_short(sfont);
- g->gd[i].ury = sfnt_get_short(sfont);
- /* _FIXME_ */
-#if 1
- if (!vmtx) /* vertOriginY == sTypeAscender */
- g->gd[i].tsb = g->default_advh - g->default_tsb - g->gd[i].ury;
-#endif
- }
- RELEASE(location);
- RELEASE(hmtx);
- RELEASE(maxp);
- RELEASE(hhea);
- RELEASE(head);
- RELEASE(os2);
-
- if (vmtx)
- RELEASE(vmtx);
-
- {
- int max_count = -1;
-
- g->dw = g->gd[0].advw;
- for (i = 0; i < g->emsize + 1; i++) {
- if (w_stat[i] > max_count) {
- max_count = w_stat[i];
- g->dw = i;
- }
- }
- }
- RELEASE(w_stat);
-
-
- return 0;
-}