70#include <config_auto.h>
74#include "allheaders.h"
78static const l_float32 VertFractSep = 0.3;
81#define DEBUG_BASELINE 0
83#define DEBUG_FONT_GEN 0
87 l_int32 *pbl0, l_int32 *pbl1,
90 l_int32 *pbl1, l_int32 *pbl2);
92 l_int32 *pbl1, l_int32 *pbl2);
124 if (fontsize < 4 || fontsize > 20 || (fontsize % 2))
125 return (
L_BMF *)ERROR_PTR(
"fontsize must be in {4, 6, ..., 20}",
137 L_INFO(
"Generating pixa of bitmap fonts from file\n", __func__);
141 L_ERROR(
"Failed to make font; use string\n", __func__);
150 return (
L_BMF *)ERROR_PTR(
"font pixa not made", __func__, NULL);
154 bmf->
size = fontsize;
155 if (dir) bmf->
directory = stringNew(dir);
173 L_WARNING(
"ptr address is null!\n", __func__);
177 if ((bmf = *pbmf) == NULL)
180 pixaDestroy(&bmf->
pixa);
207 if ((index = (l_int32)chr) == 10)
210 return (
PIX *)ERROR_PTR(
"bmf not defined", __func__, NULL);
214 L_ERROR(
"no bitmap representation for %d\n", __func__, index);
218 if ((pixa = bmf->
pixa) == NULL)
219 return (
PIX *)ERROR_PTR(
"pixa not found", __func__, NULL);
221 return pixaGetPix(pixa, i,
L_CLONE);
242 return ERROR_INT(
"&w not defined", __func__, 1);
245 return ERROR_INT(
"bmf not defined", __func__, 1);
246 if ((index = (l_int32)chr) == 10)
251 L_ERROR(
"no bitmap representation for %d\n", __func__, index);
255 if ((pixa = bmf->
pixa) == NULL)
256 return ERROR_INT(
"pixa not found", __func__, 1);
258 return pixaGetPixDimensions(pixa, i, pw, NULL, NULL);
278 return ERROR_INT(
"&baseline not defined", __func__, 1);
281 return ERROR_INT(
"bmf not defined", __func__, 1);
282 if ((index = (l_int32)chr) == 10)
287 L_ERROR(
"no bitmap representation for %d\n", __func__, index);
325 fileno = (fontsize / 2) - 2;
326 if (fileno < 0 || fileno >= NUM_FONTS)
327 return (
PIXA *)ERROR_PTR(
"font size invalid", __func__, NULL);
328 if (!pbl0 || !pbl1 || !pbl2)
329 return (
PIXA *)ERROR_PTR(
"&bl not all defined", __func__, NULL);
330 *pbl0 = baselines[fileno][0];
331 *pbl1 = baselines[fileno][1];
332 *pbl2 = baselines[fileno][2];
334 pathname = pathJoin(dir, outputfonts[fileno]);
335 pixa = pixaRead(pathname);
339 L_WARNING(
"pixa of char bitmaps not found\n", __func__);
368l_int32 bl1, bl2, bl3;
371 if (fontsize < 4 || fontsize > 20 || (fontsize % 2))
372 return ERROR_INT(
"fontsize must be in {4, 6, ..., 20}", __func__, 1);
379 return ERROR_INT(
"pixa not made", __func__, 1);
381 pathname = pathJoin(outdir, outputfonts[(fontsize - 4) / 2]);
382 pixaWrite(pathname, pixa);
385 L_INFO(
"Found %d chars in font size %d\n", __func__, pixaGetCount(pixa),
387 L_INFO(
"Baselines are at: %d, %d, %d\n", __func__, bl1, bl2, bl3);
434 if (!pbl0 || !pbl1 || !pbl2)
435 return (
PIXA *)ERROR_PTR(
"&bl not all defined", __func__, NULL);
436 *pbl0 = *pbl1 = *pbl2 = 0;
438 return (
PIXA *)ERROR_PTR(
"dir not defined", __func__, NULL);
439 fileno = (fontsize / 2) - 2;
440 if (fileno < 0 || fileno >= NUM_FONTS)
441 return (
PIXA *)ERROR_PTR(
"font size invalid", __func__, NULL);
443 pathname = pathJoin(dir, inputfonts[fileno]);
444 pix = pixRead(pathname);
447 L_ERROR(
"pix not found for font size %d\n", __func__, fontsize);
478l_int32 redsize, nbytes;
482 if (!pbl0 || !pbl1 || !pbl2)
483 return (
PIXA *)ERROR_PTR(
"&bl not all defined", __func__, NULL);
484 *pbl0 = *pbl1 = *pbl2 = 0;
485 redsize = (fontsize / 2) - 2;
486 if (redsize < 0 || redsize >= NUM_FONTS)
487 return (
PIXA *)ERROR_PTR(
"invalid font size", __func__, NULL);
490 data = decodeBase64(fontdata_4, strlen(fontdata_4), &nbytes);
491 }
else if (fontsize == 6) {
492 data = decodeBase64(fontdata_6, strlen(fontdata_6), &nbytes);
493 }
else if (fontsize == 8) {
494 data = decodeBase64(fontdata_8, strlen(fontdata_8), &nbytes);
495 }
else if (fontsize == 10) {
496 data = decodeBase64(fontdata_10, strlen(fontdata_10), &nbytes);
497 }
else if (fontsize == 12) {
498 data = decodeBase64(fontdata_12, strlen(fontdata_12), &nbytes);
499 }
else if (fontsize == 14) {
500 data = decodeBase64(fontdata_14, strlen(fontdata_14), &nbytes);
501 }
else if (fontsize == 16) {
502 data = decodeBase64(fontdata_16, strlen(fontdata_16), &nbytes);
503 }
else if (fontsize == 18) {
504 data = decodeBase64(fontdata_18, strlen(fontdata_18), &nbytes);
506 data = decodeBase64(fontdata_20, strlen(fontdata_20), &nbytes);
509 return (
PIXA *)ERROR_PTR(
"data not made", __func__, NULL);
511 pix = pixReadMem(data, nbytes);
514 return (
PIXA *)ERROR_PTR(
"pix not made", __func__, NULL);
547l_int32 i, j, nrows, nrowchars, nchars, h, yval;
548l_int32 width, height;
551BOX *box, *box1, *box2;
552BOXA *boxar, *boxac, *boxacs;
553PIX *pix1, *pix2, *pixr, *pixrc, *pixc;
555l_int32 n, w, inrow, top;
559 if (!pbl0 || !pbl1 || !pbl2)
560 return (
PIXA *)ERROR_PTR(
"&bl not all defined", __func__, NULL);
561 *pbl0 = *pbl1 = *pbl2 = 0;
563 return (
PIXA *)ERROR_PTR(
"pixs not defined", __func__, NULL);
566 w = pixGetWidth(pixs);
567 na = pixCountPixelsByRow(pixs, NULL);
568 boxar = boxaCreate(0);
569 n = numaGetCount(na);
570 ia = numaGetIArray(na);
572 for (i = 0; i < n; i++) {
573 if (!inrow && ia[i] > 0) {
576 }
else if (inrow && ia[i] == 0) {
578 box = boxCreate(0, top, w, i - top);
584 nrows = boxaGetCount(boxar);
586 L_INFO(
"For fontsize %s, have %d rows\n", __func__, fontsize, nrows);
589 L_INFO(
"nrows = %d; skipping fontsize %d\n", __func__, nrows, fontsize);
591 return (
PIXA *)ERROR_PTR(
"3 rows not generated", __func__, NULL);
596 lept_rmdir(
"baseline");
597 lept_mkdir(
"baseline");
599 tab = makePixelSumTab8();
600 pixa = pixaCreate(95);
601 for (i = 0; i < nrows; i++) {
602 box = boxaGetBox(boxar, i,
L_CLONE);
603 pixr = pixClipRectangle(pixs, box, NULL);
608 L_INFO(
"Baseline info: row %d, yval = %d, h = %d\n", __func__,
609 i, yval, pixGetHeight(pixr));
610 pix1 = pixCopy(NULL, pixr);
611 pixRenderLine(pix1, 0, yval, pixGetWidth(pix1), yval, 1,
614 pixWriteDebug(
"/tmp/baseline/row0.png", pix1, IFF_PNG);
616 pixWriteDebug(
"/tmp/baseline/row1.png", pix1, IFF_PNG);
618 pixWriteDebug(
"/tmp/baseline/row2.png", pix1, IFF_PNG);
623 pixrc = pixCloseSafeBrick(NULL, pixr, 1, 35);
624 boxac = pixConnComp(pixrc, NULL, 8);
627 box1 = boxaGetBox(boxacs, 1,
L_CLONE);
628 box2 = boxaGetBox(boxacs, 2,
L_CLONE);
629 box1->
w = box2->
x + box2->
w - box1->
x;
632 boxaRemoveBox(boxacs, 2);
634 h = pixGetHeight(pixr);
635 nrowchars = boxaGetCount(boxacs);
636 for (j = 0; j < nrowchars; j++) {
637 box = boxaGetBox(boxacs, j,
L_COPY);
638 if (box->
w <= 2 && box->
h == 1) {
644 pixc = pixClipRectangle(pixr, box, NULL);
646 if (i == 0 && j == 0)
647 pixaAddPix(pixa, pixc,
L_COPY);
648 if (i == 2 && j == 0)
649 pixaAddPix(pixa, pixc,
L_COPY);
655 boxaDestroy(&boxacs);
659 nchars = pixaGetCount(pixa);
661 return (
PIXA *)ERROR_PTR(
"95 chars not generated", __func__, NULL);
669 pix1 = pixaGetPix(pixa, 0,
L_CLONE);
670 width = 2 * pixGetWidth(pix1);
671 height = pixGetHeight(pix1);
673 pix1 = pixCreate(width, height, 1);
674 pixaReplacePix(pixa, 0, pix1, NULL);
677 pix1 = pixaGetPix(pixa, 15,
L_CLONE);
678 pix2 = pixFlipLR(NULL, pix1);
680 pixaReplacePix(pixa, 60, pix2, NULL);
683 pix1 = pixaDisplayTiled(pixa, 1500, 0, 10);
684 pixDisplay(pix1, 100 * i, 200);
714l_int32 i, h, val1, val2, diff, diffmax, ymax;
719 return ERROR_INT(
"pixs not defined", __func__, 1);
721 return ERROR_INT(
"&y not defined", __func__, 1);
724 tab = makePixelSumTab8();
728 na = pixCountPixelsByRow(pixs, tab);
729 h = numaGetCount(na);
732 for (i = 1; i < h; i++) {
733 numaGetIValue(na, i - 1, &val1);
734 numaGetIValue(na, i, &val2);
735 diff = L_MAX(0, val1 - val2);
736 if (diff > diffmax) {
785l_int32 i, maxh, height, charwidth, xwidth, kernwidth;
786l_int32 *fonttab, *baselinetab, *widthtab;
790 return ERROR_INT(
"bmf not defined", __func__, 1);
793 fonttab = (l_int32 *)LEPT_CALLOC(128,
sizeof(l_int32));
795 for (i = 0; i < 128; i++)
797 for (i = 32; i < 127; i++)
800 baselinetab = (l_int32 *)LEPT_CALLOC(128,
sizeof(l_int32));
802 for (i = 0; i < 128; i++)
803 baselinetab[i] = UNDEF;
804 for (i = 32; i <= 57; i++)
806 for (i = 58; i <= 91; i++)
809 for (i = 93; i < 127; i++)
813 widthtab = (l_int32 *)LEPT_CALLOC(128,
sizeof(l_int32));
815 for (i = 0; i < 128; i++)
817 for (i = 32; i < 127; i++) {
819 widthtab[i] = charwidth;
825 maxh = pixGetHeight(pix);
828 height = pixGetHeight(pix);
830 maxh = L_MAX(maxh, height);
832 height = pixGetHeight(pix);
834 maxh = L_MAX(maxh, height);
842 kernwidth = (l_int32)(0.08 * (l_float32)xwidth + 0.5);
void bmfDestroy(L_BMF **pbmf)
bmfDestroy()
static PIXA * pixaGenerateFontFromFile(const char *dir, l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2)
pixaGenerateFontFromFile()
L_BMF * bmfCreate(const char *dir, l_int32 fontsize)
bmfCreate()
static PIXA * pixaGenerateFont(PIX *pixs, l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2)
pixaGenerateFont()
static PIXA * pixaGenerateFontFromString(l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2)
pixaGenerateFontFromString()
PIXA * pixaGetFont(const char *dir, l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2)
pixaGetFont()
l_ok bmfGetBaseline(L_BMF *bmf, char chr, l_int32 *pbaseline)
bmfGetBaseline()
static l_int32 bmfMakeAsciiTables(L_BMF *bmf)
bmfMakeAsciiTables
l_ok pixaSaveFont(const char *indir, const char *outdir, l_int32 fontsize)
pixaSaveFont()
static l_int32 pixGetTextBaseline(PIX *pixs, l_int32 *tab8, l_int32 *py)
pixGetTextBaseline()
l_ok bmfGetWidth(L_BMF *bmf, char chr, l_int32 *pw)
bmfGetWidth()
PIX * bmfGetPix(L_BMF *bmf, char chr)
bmfGetPix()