/*!
 *  bmfCreate()
 *
 *      Input:  dir (<optional> directory holding pixa of character set)
 *              fontsize (4, 6, 8, ... , 20)
 *      Return: bmf (holding the bitmap font and associated information)
 *
 *  Notes:
 *      (1) If @dir == null, this generates the font bitmaps from a
 *          compiled string.
 *      (2) Otherwise, this tries to read a pre-computed pixa file with the
 *          95 ascii chars in it.  If the file is not found, it then
 *          attempts to generate the pixa and associated baseline
 *          data from a tiff image containing all the characters.  If
 *          that fails, it uses the compiled string.
 */
L_BMF *
bmfCreate(const char  *dir,
          l_int32      fontsize)
{
L_BMF   *bmf;
PIXA  *pixa;

    PROCNAME("bmfCreate");

    if (fontsize < 4 || fontsize > 20 || (fontsize % 2))
        return (L_BMF *)ERROR_PTR("fontsize must be in {4, 6, ..., 20}",
                                  procName, NULL);
    if ((bmf = (L_BMF *)CALLOC(1, sizeof(L_BMF))) == NULL)
        return (L_BMF *)ERROR_PTR("bmf not made", procName, NULL);

    if (!dir) {  /* Generate from a string */
        L_INFO("Generating pixa of bitmap fonts from string\n", procName);
        pixa = pixaGenerateFontFromString(fontsize, &bmf->baseline1,
                                          &bmf->baseline2, &bmf->baseline3);
    } else {  /* Look for the pixa in a directory */
        L_INFO("Locating pixa of bitmap fonts in a file\n", procName);
        pixa = pixaGetFont(dir, fontsize, &bmf->baseline1, &bmf->baseline2,
                           &bmf->baseline3);
        if (!pixa) {  /* Not found; make it from a file */
            L_INFO("Generating pixa of bitmap fonts from file\n", procName);
            pixa = pixaGenerateFontFromFile(dir, fontsize, &bmf->baseline1,
                                            &bmf->baseline2, &bmf->baseline3);
            if (!pixa) {  /* Not made; make it from a string after all */
                L_ERROR("Failed to make font; use string\n", procName);
                pixa = pixaGenerateFontFromString(fontsize, &bmf->baseline1,
                                          &bmf->baseline2, &bmf->baseline3);
            }
        }
    }

    if (!pixa) {
        bmfDestroy(&bmf);
        return (L_BMF *)ERROR_PTR("font pixa not made", procName, NULL);
    }

    bmf->pixa = pixa;
    bmf->size = fontsize;
    if (dir) bmf->directory = stringNew(dir);
    bmfMakeAsciiTables(bmf);
    return bmf;
}
/*!
 *  pixaSaveFont()
 *
 *      Input:  indir (<optional> directory holding image of character set)
 *              outdir (directory into which the output pixa file
 *                      will be written)
 *              fontsize (in pts, at 300 ppi)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This saves a font of a particular size.
 *      (2) If @dir == null, this generates the font bitmaps from a
 *          compiled string.
 *      (3) prog/genfonts calls this function for each of the
 *          nine font sizes, to generate all the font pixa files.
 */
l_int32
pixaSaveFont(const char  *indir,
             const char  *outdir,
             l_int32      fontsize)
{
char    *pathname;
l_int32  bl1, bl2, bl3;
PIXA    *pixa;

    PROCNAME("pixaSaveFont");

    if (fontsize < 4 || fontsize > 20 || (fontsize % 2))
        return ERROR_INT("fontsize must be in {4, 6, ..., 20}", procName, 1);

    if (!indir) {  /* Generate from a string */
        L_INFO("Generating pixa of bitmap fonts from string\n", procName);
        pixa = pixaGenerateFontFromString(fontsize, &bl1, &bl2, &bl3);
    } else {  /* Generate from an image file */
        L_INFO("Generating pixa of bitmap fonts from a file\n", procName);
        pixa = pixaGenerateFontFromFile(indir, fontsize, &bl1, &bl2, &bl3);
    }
    if (!pixa)
        return ERROR_INT("pixa not made", procName, 1);

    pathname = genPathname(outdir, outputfonts[(fontsize - 4) / 2]);
    pixaWrite(pathname, pixa);

#if  DEBUG_FONT_GEN
    L_INFO("Found %d chars in font size %d\n", procName, pixaGetCount(pixa),
           fontsize);
    L_INFO("Baselines are at: %d, %d, %d\n", procName, bl1, bl2, bl3);
#endif  /* DEBUG_FONT_GEN */

    FREE(pathname);
    pixaDestroy(&pixa);
    return 0;
}
Beispiel #3
0
int main(int    argc,
         char **argv)
{
char          buf[512];
char         *pathname, *datastr, *formstr;
l_uint8      *data1, *data2;
l_int32       i, bl1, bl2, bl3, sbytes, formbytes, fontsize, rbytes;
size_t        nbytes;
PIX          *pix1, *pix2, *pixd;
PIXA         *pixa;
L_REGPARAMS  *rp;

    if (regTestSetup(argc, argv, &rp))
        return 1;

    /* ------------  Generate pixa char bitmap files from file ----------- */
    lept_rmdir("filefonts");
    lept_mkdir("filefonts");
    for (i = 0; i < 9; i++) {
        pixaSaveFont("fonts", "/tmp/filefonts", sizes[i]);
        pathname = genPathname("/tmp/filefonts", outputfonts[i]);
        pixa = pixaRead(pathname);
        if (rp->display) {
            fprintf(stderr, "Found %d chars in font size %d\n",
                    pixaGetCount(pixa), sizes[i]);
        }
        pixd = pixaDisplayTiled(pixa, 1500, 0, 15);
        regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 0 - 8 */
        if (i == 2) pixDisplayWithTitle(pixd, 100, 0, NULL, rp->display);
        pixDestroy(&pixd);
        pixaDestroy(&pixa);
        lept_free(pathname);
    }
    lept_rmdir("filefonts");

    /* ----------  Generate pixa char bitmap files from string --------- */
    lept_rmdir("strfonts");
    lept_mkdir("strfonts");
    for (i = 0; i < 9; i++) {
        pixaSaveFont(NULL, "/tmp/strfonts", sizes[i]);
        pathname = genPathname("/tmp/strfonts", outputfonts[i]);
        pixa = pixaRead(pathname);
        if (rp->display) {
            fprintf(stderr, "Found %d chars in font size %d\n",
                    pixaGetCount(pixa), sizes[i]);
        }
        pixd = pixaDisplayTiled(pixa, 1500, 0, 15);
        regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 9 - 17 */
        if (i == 2) pixDisplayWithTitle(pixd, 100, 150, NULL, rp->display);
        pixDestroy(&pixd);
        pixaDestroy(&pixa);
        lept_free(pathname);
    }

    /* -----  Use pixaGetFont() and write the result out  -----*/
    lept_rmdir("pafonts");
    lept_mkdir("pafonts");
    for (i = 0; i < 9; i++) {
        pixa = pixaGetFont("/tmp/strfonts", sizes[i], &bl1, &bl2, &bl3);
        fprintf(stderr, "Baselines are at: %d, %d, %d\n", bl1, bl2, bl3);
        snprintf(buf, sizeof(buf), "/tmp/pafonts/chars-%d.pa", sizes[i]);
        pixaWrite(buf, pixa);
        if (i == 2) {
            pixd = pixaDisplayTiled(pixa, 1500, 0, 15);
            pixDisplayWithTitle(pixd, 100, 300, NULL, rp->display);
            pixDestroy(&pixd);
        }
        pixaDestroy(&pixa);
    }
    lept_rmdir("pafonts");

    /* -------  Generate 4/3 encoded ascii strings from tiff files ------ */
    lept_rmdir("fontencode");
    lept_mkdir("fontencode");
    for (i = 0; i < 9; i++) {
        fontsize = 2 * i + 4;
        pathname = genPathname("fonts", inputfonts[i]);
        data1 = l_binaryRead(pathname, &nbytes);
        datastr = encodeBase64(data1, nbytes, &sbytes);
        if (rp->display)
            fprintf(stderr, "nbytes = %lu, sbytes = %d\n",
                    (unsigned long)nbytes, sbytes);
        formstr = reformatPacked64(datastr, sbytes, 4, 72, 1, &formbytes);
        snprintf(buf, sizeof(buf), "/tmp/fontencode/formstr_%d.txt", fontsize);
        l_binaryWrite(buf, "w", formstr, formbytes);
        regTestCheckFile(rp, buf);  /* 18-26 */
        if (i == 8)
            pix1 = pixReadMem(data1, nbytes);  /* original */
        FREE(data1);

        data2 = decodeBase64(datastr, sbytes, &rbytes);
        snprintf(buf, sizeof(buf), "/tmp/fontencode/image_%d.tif", fontsize);
        l_binaryWrite(buf, "w", data2, rbytes);
        if (i == 8) {
            pix2 = pixReadMem(data2, rbytes);  /* encode/decode */
            regTestComparePix(rp, pix1, pix2);  /* 27 */
            pixDestroy(&pix1);
            pixDestroy(&pix2);
        }
        FREE(data2);

        FREE(pathname);
        FREE(datastr);
        FREE(formstr);
    }

    /* ------------  Get timing for font generation ----------- */
    startTimer();
    for (i = 0; i < 100; i++) {
        pixa = pixaGenerateFontFromString(sizes[5], &bl1, &bl2, &bl3);
        pixaDestroy(&pixa);
    }
    fprintf(stderr, "Time for font gen = %7.4f sec\n", stopTimer() / 100.0);

    return regTestCleanup(rp);
}