|
Packit |
daac2c |
/* otftobdf.c -- Generate BDF font from OpenType font.
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
Copyright (C) 2003, 2004
|
|
Packit |
daac2c |
National Institute of Advanced Industrial Science and Technology (AIST)
|
|
Packit |
daac2c |
Registration Number H15PRO167
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
This file is part of libotf.
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
Libotf is free software; you can redistribute it and/or modify it
|
|
Packit |
daac2c |
under the terms of the GNU Lesser General Public License as published
|
|
Packit |
daac2c |
by the Free Software Foundation; either version 2.1 of the License, or
|
|
Packit |
daac2c |
(at your option) any later version.
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
Libotf is distributed in the hope that it will be useful, but WITHOUT
|
|
Packit |
daac2c |
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
Packit |
daac2c |
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
Packit |
daac2c |
License for more details.
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
daac2c |
License along with this library, in a file named COPYING; if not,
|
|
Packit |
daac2c |
write to the Free Software Foundation, Inc., 59 Temple Place, Suite
|
|
Packit |
daac2c |
330, Boston, MA 02111-1307, USA. */
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
#include <stdio.h>
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
#include <ft2build.h>
|
|
Packit |
daac2c |
#include FT_FREETYPE_H
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
#include "config.h"
|
|
Packit |
daac2c |
#ifdef HAVE_ALLOCA_H
|
|
Packit |
daac2c |
#include <alloca.h>
|
|
Packit |
daac2c |
#endif
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
#define DEFAULT_PIXEL_SIZE 16
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
FT_Face face;
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
/* Format MSG by FMT and print the result to the stderr, and exit. */
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
#define FATAL_ERROR(fmt, arg) \
|
|
Packit |
daac2c |
do { \
|
|
Packit |
daac2c |
fprintf (stderr, fmt, arg); \
|
|
Packit |
daac2c |
exit (1); \
|
|
Packit |
daac2c |
} while (0)
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
char *registry;
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
void
|
|
Packit |
daac2c |
dump_header (FT_Face face, char *foundry, int nchars, int pixel_size)
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
int width = ((face->bbox.xMax - face->bbox.xMin)
|
|
Packit |
daac2c |
* pixel_size / face->units_per_EM);
|
|
Packit |
daac2c |
int height = ((face->bbox.yMax - face->bbox.yMin)
|
|
Packit |
daac2c |
* pixel_size / face->units_per_EM);
|
|
Packit |
daac2c |
int x = face->bbox.xMin * pixel_size / face->units_per_EM;
|
|
Packit |
daac2c |
int y = face->bbox.yMin * pixel_size / face->units_per_EM;
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
printf ("STARTFONT 2.1\n");
|
|
Packit |
daac2c |
printf ("FONT -%s-%s-%s-R-Normal--%d-%d-72-72-C-%d-%s\n",
|
|
Packit |
daac2c |
foundry, face->family_name, face->style_name,
|
|
Packit |
daac2c |
pixel_size, pixel_size * 10, pixel_size * 10, registry);
|
|
Packit |
daac2c |
printf ("SIZE %d 72 72\n", pixel_size);
|
|
Packit |
daac2c |
printf ("FONTBOUNDINGBOX %d %d %d %d\n", width, height, x, y);
|
|
Packit |
daac2c |
printf ("STARTPROPERTIES 2\n");
|
|
Packit |
daac2c |
printf ("FONT_ASCENT %d\n", y + height);
|
|
Packit |
daac2c |
printf ("FONT_DESCENT %d\n", -y);
|
|
Packit |
daac2c |
printf ("ENDPROPERTIES 0\n");
|
|
Packit |
daac2c |
printf ("CHARS %d\n", nchars);
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
void
|
|
Packit |
daac2c |
dump_tailer ()
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
printf ("ENDFONT\n");
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
void
|
|
Packit |
daac2c |
dump_image (int pixel_size, int index, int code, int full)
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
int err = FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
|
|
Packit |
daac2c |
int i,j;
|
|
Packit |
daac2c |
unsigned char *buf;
|
|
Packit |
daac2c |
FT_GlyphSlot glyph;
|
|
Packit |
daac2c |
int dwidth, x, y;
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
if (err)
|
|
Packit |
daac2c |
return;
|
|
Packit |
daac2c |
glyph = face->glyph;
|
|
Packit |
daac2c |
if (glyph->bitmap.rows * glyph->bitmap.width == 0)
|
|
Packit |
daac2c |
return;
|
|
Packit |
daac2c |
printf ("STARTCHAR U+%04X\n", code);
|
|
Packit |
daac2c |
printf ("ENCODING %d\n", code);
|
|
Packit |
daac2c |
printf ("SWIDTH %d 0\n",
|
|
Packit |
daac2c |
(int) (glyph->metrics.horiAdvance >> 6) * 1000 / pixel_size);
|
|
Packit |
daac2c |
if (full)
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
dwidth = glyph->bitmap.width;
|
|
Packit |
daac2c |
x = 0;
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
else
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
dwidth = glyph->metrics.horiAdvance >> 6;
|
|
Packit |
daac2c |
x = glyph->metrics.horiBearingX >> 6;
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
y = (glyph->metrics.horiBearingY - glyph->metrics.height) >> 6;
|
|
Packit |
daac2c |
printf ("DWIDTH %d 0\n", dwidth);
|
|
Packit |
daac2c |
printf ("BBX %d %d %d %d\n", glyph->bitmap.width, glyph->bitmap.rows, x, y);
|
|
Packit |
daac2c |
printf ("BITMAP\n");
|
|
Packit |
daac2c |
buf = (unsigned char *) glyph->bitmap.buffer;
|
|
Packit |
daac2c |
for (i = 0; i < glyph->bitmap.rows; i++)
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
for (j = 0; j < (glyph->bitmap.width + 7) / 8; j++)
|
|
Packit |
daac2c |
printf ("%02X", buf[i * glyph->bitmap.pitch + j]);
|
|
Packit |
daac2c |
printf ("\n");
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
printf ("ENDCHAR\n");
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
int
|
|
Packit |
daac2c |
main (int argc, char **argv)
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
FT_Library library;
|
|
Packit |
daac2c |
int err;
|
|
Packit |
daac2c |
int i;
|
|
Packit |
daac2c |
int pixel_size = DEFAULT_PIXEL_SIZE;
|
|
Packit |
daac2c |
FT_UInt code_table[0x10000];
|
|
Packit |
daac2c |
int nchars;
|
|
Packit |
daac2c |
char *filename;
|
|
Packit |
daac2c |
int platform_id, encoding_id;
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
if (argc <= 1)
|
|
Packit |
daac2c |
FATAL_ERROR ("Usage: %s ENCODING OTF-FILE\n", argv[0]);
|
|
Packit |
daac2c |
if (sscanf (argv[1], "%d-%d", &platform_id, &encoding_id) != 2)
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
platform_id = -1;
|
|
Packit |
daac2c |
filename = argv[1];
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
else
|
|
Packit |
daac2c |
filename = argv[2];
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
if ((err = FT_Init_FreeType (&library)))
|
|
Packit |
daac2c |
FATAL_ERROR ("%s\n", "FT_Init_FreeType: error");
|
|
Packit |
daac2c |
err = FT_New_Face (library, filename, 0, &face);
|
|
Packit |
daac2c |
if (err == FT_Err_Unknown_File_Format)
|
|
Packit |
daac2c |
FATAL_ERROR ("%s\n", "FT_New_Face: unknown file format");
|
|
Packit |
daac2c |
else if (err)
|
|
Packit |
daac2c |
FATAL_ERROR ("%s\n", "FT_New_Face: unknown error");
|
|
Packit |
daac2c |
if (platform_id >= 0)
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
for (i = 0; i < face->num_charmaps; i++)
|
|
Packit |
daac2c |
if (face->charmaps[i]->platform_id == platform_id
|
|
Packit |
daac2c |
&& face->charmaps[i]->encoding_id == encoding_id)
|
|
Packit |
daac2c |
break;
|
|
Packit |
daac2c |
if (i == face->num_charmaps)
|
|
Packit |
daac2c |
FATAL_ERROR ("Unknown ENCODING: %s\n", argv[1]);
|
|
Packit |
daac2c |
FT_Set_Charmap (face, face->charmaps[i]);
|
|
Packit |
daac2c |
if (platform_id == 0)
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
if (encoding_id == 3)
|
|
Packit |
daac2c |
registry = "iso10646-1";
|
|
Packit |
daac2c |
else if (face->charmaps[i]->encoding_id == 4)
|
|
Packit |
daac2c |
registry = "iso10646-full";
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
else if (face->charmaps[i]->platform_id == 3)
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
if (face->charmaps[i]->encoding_id == 1)
|
|
Packit |
daac2c |
registry = "iso10646-1";
|
|
Packit |
daac2c |
else if (face->charmaps[i]->encoding_id == 10)
|
|
Packit |
daac2c |
registry = "iso10646-full";
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
else
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
registry = alloca (256);
|
|
Packit |
daac2c |
sprintf (registry, "%d-%d", platform_id, encoding_id);
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
else
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
registry = "raw-glyph";
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
char *str = getenv ("PIXEL_SIZE");
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
if (str && (i = atoi (str)) > 0)
|
|
Packit |
daac2c |
pixel_size = i;
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
if ((err = FT_Set_Pixel_Sizes (face, 0, pixel_size)))
|
|
Packit |
daac2c |
FATAL_ERROR ("%s\n", "FT_Set_Pixel_Sizes: error");
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
/*
|
|
Packit |
daac2c |
for (i = nchars = 0; i < 0x10000; i++)
|
|
Packit |
daac2c |
if (! FT_Load_Glyph (face, i, FT_LOAD_RENDER | FT_LOAD_MONOCHROME)
|
|
Packit |
daac2c |
&& face->glyph->bitmap.rows * face->glyph->bitmap.width)
|
|
Packit |
daac2c |
nchars++;
|
|
Packit |
daac2c |
*/
|
|
Packit |
daac2c |
for (i = 0; i < 0x10000; i++)
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
if (platform_id >= 0)
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
code_table[i] = FT_Get_Char_Index (face, (FT_ULong) i);
|
|
Packit |
daac2c |
if (! code_table[i])
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
code_table[i] = -1;
|
|
Packit |
daac2c |
continue;
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
else
|
|
Packit |
daac2c |
{
|
|
Packit |
daac2c |
code_table[i] = i;
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
if (! FT_Load_Glyph (face, code_table[i],
|
|
Packit |
daac2c |
FT_LOAD_RENDER | FT_LOAD_MONOCHROME)
|
|
Packit |
daac2c |
&& face->glyph->bitmap.rows * face->glyph->bitmap.width)
|
|
Packit |
daac2c |
nchars++;
|
|
Packit |
daac2c |
else
|
|
Packit |
daac2c |
code_table[i] = -1;
|
|
Packit |
daac2c |
}
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
dump_header (face, "unknown", nchars, pixel_size);
|
|
Packit |
daac2c |
for (i = 0; i < 0x10000; i++)
|
|
Packit |
daac2c |
if (code_table[i] >= 0)
|
|
Packit |
daac2c |
dump_image (pixel_size, code_table[i], i, 0);
|
|
Packit |
daac2c |
dump_tailer ();
|
|
Packit |
daac2c |
|
|
Packit |
daac2c |
exit (0);
|
|
Packit |
daac2c |
}
|