summaryrefslogtreecommitdiff
path: root/Build/source/texk/ttf2pk2/ttflib.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/ttf2pk2/ttflib.c')
-rw-r--r--Build/source/texk/ttf2pk2/ttflib.c391
1 files changed, 391 insertions, 0 deletions
diff --git a/Build/source/texk/ttf2pk2/ttflib.c b/Build/source/texk/ttf2pk2/ttflib.c
new file mode 100644
index 00000000000..0d7f9ead9e7
--- /dev/null
+++ b/Build/source/texk/ttf2pk2/ttflib.c
@@ -0,0 +1,391 @@
+/*
+ * ttflib.c
+ *
+ * This file is part of the ttf2pk package.
+ *
+ * Copyright 1997-1999, 2000 by
+ * Loyer Frederic <loyer@ensta.fr>
+ * Werner Lemberg <wl@gnu.org>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h> /* libc ANSI */
+#include <ctype.h>
+
+#include "pklib.h" /* for the `byte' type */
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_OUTLINE_H
+#include FT_BBOX_H
+#include "ttfenc.h"
+#include "ttflib.h"
+#include "errormsg.h"
+#include "newobj.h"
+#include "ttf2tfm.h"
+#include "ftlib.h"
+
+
+FT_BBox bbox;
+
+FT_Bitmap Bit;
+unsigned char *Bitp;
+
+int ppem;
+
+
+
+static void
+SetRasterArea(int quiet)
+{
+ int temp1_x, temp1_y, temp2_x, temp2_y;
+
+
+ temp1_x = bbox.xMin / 64; /* scaling F16.6 -> int */
+ temp1_y = bbox.yMin / 64;
+ temp2_x = (bbox.xMax + 63) / 64;
+ temp2_y = (bbox.yMax + 63) / 64;
+
+ if (!quiet)
+ printf(" off = (%d, %d)", 5 - temp1_x, 5 - temp1_y);
+
+ if (!quiet)
+ printf(" bbox = (%d, %d) <-> (%d, %d)\n",
+ temp1_x, temp1_y, temp2_x, temp2_y);
+
+ Bit.rows = temp2_y - temp1_y + 10;
+ Bit.width = temp2_x - temp1_x + 10;
+
+ Bit.pitch = (Bit.width + 7) / 8; /* convert to # of bytes */
+
+ /*
+ * We allocate one more row to have valid pointers for comparison
+ * purposes in pklib.c, making `gcc -fbounds-checking' happy.
+ */
+ if (Bitp)
+ free(Bitp);
+ Bitp = mymalloc(Bit.rows*Bit.pitch + Bit.pitch);
+ Bit.buffer = Bitp;
+}
+
+static void
+CopyBit(FT_Bitmap *b2,FT_Bitmap *b1)
+{
+ int y;
+ char *p1, *p2;
+
+ p1 = (char *)b1->buffer; /* source */
+ p2 = (char *)b2->buffer; /* dest */
+
+ for (y = 0; y < b1->rows; y++)
+ {
+ memcpy(p2, p1, b1->pitch);
+ p1 += b1->pitch;
+ p2 += b2->pitch;
+ }
+}
+
+#if 0
+
+static void
+Output(FT_Bitmap Bit)
+{
+ int x;
+ int y;
+ int i;
+
+ char *p, b;
+
+
+ p = Bit.buffer;
+ printf("====\n");
+
+ for (y = 0; y < Bit.rows; y++)
+ {
+ printf("%3d:", y);
+ for (x = 0; x < Bit.pitch; x++)
+ {
+ b = *p++;
+ for(i = 0x80; i; i >>= 1)
+ printf((b & i) ? "x" : ".");
+ }
+ printf("\n");
+ }
+}
+
+#endif /* 0 */
+
+
+void
+TTFopen(char *filename, Font *fnt, int new_dpi, int new_ptsize, Boolean quiet)
+{
+ dpi = new_dpi;
+ ptsize = new_ptsize;
+ ppem = (dpi * ptsize + 36) / 72;
+
+ if (!quiet)
+ printf("dpi = %d, ptsize = %d, ppem = %d\n\n", dpi, ptsize, ppem);
+
+ FTopen(filename, fnt, False, quiet);
+}
+
+
+static FT_Error
+LoadTrueTypeChar(Font *fnt,
+ int idx,
+ Boolean hint,
+ Boolean quiet)
+{
+ FT_Error error;
+ int flags;
+
+
+ flags = FT_LOAD_DEFAULT;
+ if (hint)
+ flags |= FT_LOAD_FORCE_AUTOHINT;
+
+ error = FT_Load_Glyph(face, idx, 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)
+ FT_Outline_Translate(&face->glyph->outline,
+ face->glyph->metrics.vertBearingY - bbox.xMin,
+ -fnt->y_offset * ppem * 64);
+ }
+ }
+ if (!error)
+ error = FT_Outline_Get_BBox(&face->glyph->outline, &bbox);
+ if (!error)
+ {
+ FT_Outline_Get_CBox(&face->glyph->outline, &bbox); /* for the case of BBox != CBox */
+ SetRasterArea(quiet);
+ }
+ return error;
+}
+
+
+Boolean
+TTFprocess(Font *fnt,
+ long Code,
+ byte **bitmap,
+ int *width, int *height,
+ int *hoff, int *voff,
+ Boolean hinting,
+ Boolean quiet)
+{
+ int Num;
+ FT_Error error;
+
+
+ if (!bitmap || !width || !height || !hoff || !voff)
+ oops("Invalid parameter in call to TTFprocess()");
+
+ if (Code >= 0x1000000)
+ Num = Code & 0xFFFFFF;
+ else
+ {
+ Num = FT_Get_Char_Index(face, Code);
+
+ /* now we try to get a vertical glyph form */
+ if (has_gsub)
+ Num = Get_Vert(Num);
+ }
+
+ if ((error = LoadTrueTypeChar(fnt, Num, hinting, quiet)) == FT_Err_Ok)
+ {
+ error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
+ if (error) {
+ warning("Cannot Render to Bitmap");
+ return False;
+ }
+
+ memset(Bit.buffer, 0, Bit.rows*Bit.pitch);
+ CopyBit(&Bit, &face->glyph->bitmap);
+
+ *bitmap = Bit.buffer;
+ *width = Bit.width;
+ *height = face->glyph->bitmap.rows;
+ *hoff = -face->glyph->bitmap_left;
+ *voff = *height + 1 - face->glyph->bitmap_top;
+ /* Output(Bit); */
+ return True;
+ }
+ else
+ return False;
+}
+
+
+/*
+ * We collect first all glyphs addressed via the cmap. Then we fill the
+ * array up with glyphs not in the cmap.
+ *
+ * If PSnames is set to `Only', we get the first 256 glyphs which have
+ * names different from `.notdef', `.null', and `nonmarkingreturn'.
+ *
+ * For nicer output, we return the glyph names in an encoding array.
+ */
+
+encoding *
+TTFget_first_glyphs(Font *fnt, long *array)
+{
+ unsigned int i, j, Num=0;
+ unsigned int index_array[257]; /* we ignore glyph index 0 */
+ char buff[128];
+ const char *n;
+ encoding *e = (encoding *)mymalloc(sizeof (encoding));
+
+
+ if (!array)
+ oops("Invalid parameter in call to TTFget_first_glyphs()");
+
+ for (i = 0; i < 257; i++)
+ index_array[i] = 0;
+
+ j = 0;
+ if (fnt->PSnames != Only)
+ {
+ for (i = 0; i <= 0x16FFFF; i++)
+ {
+ Num = FT_Get_Char_Index(face, i);
+ if (Num == 0)
+ continue;
+ if (Num <= 256)
+ index_array[Num] = 1;
+
+ if (fnt->PSnames)
+ {
+ (void)FT_Get_Glyph_Name(face,Num,buff,128);
+ n = newstring(buff);
+ }
+ else
+ n = code_to_adobename(i);
+ if (strcmp(n, ".notdef") == 0)
+ continue;
+ if (strcmp(n, ".null") == 0)
+ continue;
+ if (strcmp(n, "nonmarkingreturn") == 0)
+ continue;
+
+ if (j < 256)
+ {
+ array[j] = i;
+ e->vec[j] = n;
+ }
+ else
+ return e;
+ j++;
+ }
+
+ if (!fnt->PSnames)
+ {
+ for (i = 1; i < face->num_glyphs; i++)
+ {
+ if (index_array[i] == 0)
+ {
+ if (j < 256)
+ {
+ array[j] = i | 0x1000000;
+ e->vec[j] = code_to_adobename(i | 0x1000000);
+ }
+ else
+ return e;
+ j++;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < face->num_glyphs; i++)
+ {
+ (void)FT_Get_Glyph_Name(face,Num,buff,128);
+ n = newstring(buff);
+
+ if (strcmp(n, ".notdef") == 0)
+ continue;
+ if (strcmp(n, ".null") == 0)
+ continue;
+ if (strcmp(n, "nonmarkingreturn") == 0)
+ continue;
+
+ if (j < 256)
+ {
+ array[j] = i | 0x1000000;
+ e->vec[j] = n;
+ }
+ else
+ return e;
+ j++;
+ }
+ }
+
+ return NULL; /* never reached */
+}
+
+
+/*
+ * This routine fills `array' with the subfont character codes;
+ * additionally, it tests for valid glyph indices.
+ */
+
+void
+TTFget_subfont(Font *fnt, long *array)
+{
+ int i, j, Num;
+
+
+ if (!fnt || !array)
+ oops("Invalid parameter in call to TTFget_subfont()");
+
+ for (i = 0; i <= 0xFF; i++)
+ {
+ j = fnt->sf_code[i];
+
+ if (j < 0)
+ array[i] = j;
+ else
+ {
+ Num = FT_Get_Char_Index(face, j);
+ if (Num < 0)
+ oops("cmap mapping failure.");
+ else
+ array[i] = j;
+ }
+ }
+}
+
+
+long
+TTFsearch_PS_name(const char *name)
+{
+ unsigned int i;
+ char buff[128];
+
+
+ for (i = 0; i < face->num_glyphs; i++)
+ {
+ FT_Get_Glyph_Name(face, i, buff, 128);
+ if (strcmp(name, buff) == 0)
+ break;
+ }
+
+ if (i == face->num_glyphs)
+ return -1L;
+ else
+ return (long)i;
+}
+
+
+/* end */