Leptonica 1.84.1
Image processing and image analysis suite
Loading...
Searching...
No Matches
bmf.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
69#ifdef HAVE_CONFIG_H
70#include <config_auto.h>
71#endif /* HAVE_CONFIG_H */
72
73#include <string.h>
74#include "allheaders.h"
75#include "pix_internal.h"
76#include "bmfdata.h"
77
78static const l_float32 VertFractSep = 0.3f;
79
80#ifndef NO_CONSOLE_IO
81#define DEBUG_BASELINE 0
82#define DEBUG_CHARS 0
83#define DEBUG_FONT_GEN 0
84#endif /* ~NO_CONSOLE_IO */
85
86static PIXA *pixaGenerateFontFromFile(const char *dir, l_int32 fontsize,
87 l_int32 *pbl0, l_int32 *pbl1,
88 l_int32 *pbl2);
89static PIXA *pixaGenerateFontFromString(l_int32 fontsize, l_int32 *pbl0,
90 l_int32 *pbl1, l_int32 *pbl2);
91static PIXA *pixaGenerateFont(PIX *pixs, l_int32 fontsize, l_int32 *pbl0,
92 l_int32 *pbl1, l_int32 *pbl2);
93static l_int32 pixGetTextBaseline(PIX *pixs, l_int32 *tab8, l_int32 *py);
94static l_int32 bmfMakeAsciiTables(L_BMF *bmf);
95
96/*---------------------------------------------------------------------*/
97/* Bmf create/destroy */
98/*---------------------------------------------------------------------*/
117L_BMF *
118bmfCreate(const char *dir,
119 l_int32 fontsize)
120{
121L_BMF *bmf;
122PIXA *pixa;
123
124 if (fontsize < 4 || fontsize > 20 || (fontsize % 2))
125 return (L_BMF *)ERROR_PTR("fontsize must be in {4, 6, ..., 20}",
126 __func__, NULL);
127
128 bmf = (L_BMF *)LEPT_CALLOC(1, sizeof(L_BMF));
129
130 if (!dir) { /* Generate from a string */
131 pixa = pixaGenerateFontFromString(fontsize, &bmf->baseline1,
132 &bmf->baseline2, &bmf->baseline3);
133 } else { /* Look for the pixa in a directory */
134 pixa = pixaGetFont(dir, fontsize, &bmf->baseline1, &bmf->baseline2,
135 &bmf->baseline3);
136 if (!pixa) { /* Not found; make it from a file */
137 L_INFO("Generating pixa of bitmap fonts from file\n", __func__);
138 pixa = pixaGenerateFontFromFile(dir, fontsize, &bmf->baseline1,
139 &bmf->baseline2, &bmf->baseline3);
140 if (!pixa) { /* Not made; make it from a string after all */
141 L_ERROR("Failed to make font; use string\n", __func__);
142 pixa = pixaGenerateFontFromString(fontsize, &bmf->baseline1,
143 &bmf->baseline2, &bmf->baseline3);
144 }
145 }
146 }
147
148 if (!pixa) {
149 bmfDestroy(&bmf);
150 return (L_BMF *)ERROR_PTR("font pixa not made", __func__, NULL);
151 }
152
153 bmf->pixa = pixa;
154 bmf->size = fontsize;
155 if (dir) bmf->directory = stringNew(dir);
157 return bmf;
158}
159
160
167void
169{
170L_BMF *bmf;
171
172 if (pbmf == NULL) {
173 L_WARNING("ptr address is null!\n", __func__);
174 return;
175 }
176
177 if ((bmf = *pbmf) == NULL)
178 return;
179
180 pixaDestroy(&bmf->pixa);
181 LEPT_FREE(bmf->directory);
182 LEPT_FREE(bmf->fonttab);
183 LEPT_FREE(bmf->baselinetab);
184 LEPT_FREE(bmf->widthtab);
185 LEPT_FREE(bmf);
186 *pbmf = NULL;
187}
188
189
190/*---------------------------------------------------------------------*/
191/* Bmf accessors */
192/*---------------------------------------------------------------------*/
200PIX *
202 char chr)
203{
204l_int32 i, index;
205PIXA *pixa;
206
207 if ((index = (l_int32)chr) == 10) /* NL */
208 return NULL;
209 if (!bmf)
210 return (PIX *)ERROR_PTR("bmf not defined", __func__, NULL);
211
212 i = bmf->fonttab[index];
213 if (i == UNDEF) {
214 L_ERROR("no bitmap representation for %d\n", __func__, index);
215 return NULL;
216 }
217
218 if ((pixa = bmf->pixa) == NULL)
219 return (PIX *)ERROR_PTR("pixa not found", __func__, NULL);
220
221 return pixaGetPix(pixa, i, L_CLONE);
222}
223
224
233l_ok
235 char chr,
236 l_int32 *pw)
237{
238l_int32 i, index;
239PIXA *pixa;
240
241 if (!pw)
242 return ERROR_INT("&w not defined", __func__, 1);
243 *pw = -1;
244 if (!bmf)
245 return ERROR_INT("bmf not defined", __func__, 1);
246 if ((index = (l_int32)chr) == 10) /* NL */
247 return 0;
248
249 i = bmf->fonttab[index];
250 if (i == UNDEF) {
251 L_ERROR("no bitmap representation for %d\n", __func__, index);
252 return 1;
253 }
254
255 if ((pixa = bmf->pixa) == NULL)
256 return ERROR_INT("pixa not found", __func__, 1);
257
258 return pixaGetPixDimensions(pixa, i, pw, NULL, NULL);
259}
260
261
270l_ok
272 char chr,
273 l_int32 *pbaseline)
274{
275l_int32 bl, index;
276
277 if (!pbaseline)
278 return ERROR_INT("&baseline not defined", __func__, 1);
279 *pbaseline = 0;
280 if (!bmf)
281 return ERROR_INT("bmf not defined", __func__, 1);
282 if ((index = (l_int32)chr) == 10) /* NL */
283 return 0;
284
285 bl = bmf->baselinetab[index];
286 if (bl == UNDEF) {
287 L_ERROR("no bitmap representation for %d\n", __func__, index);
288 return 1;
289 }
290
291 *pbaseline = bl;
292 return 0;
293}
294
295
296/*---------------------------------------------------------------------*/
297/* Font bitmap acquisition and generation */
298/*---------------------------------------------------------------------*/
314PIXA *
315pixaGetFont(const char *dir,
316 l_int32 fontsize,
317 l_int32 *pbl0,
318 l_int32 *pbl1,
319 l_int32 *pbl2)
320{
321char *pathname;
322l_int32 fileno;
323PIXA *pixa;
324
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];
333
334 pathname = pathJoin(dir, outputfonts[fileno]);
335 pixa = pixaRead(pathname);
336 LEPT_FREE(pathname);
337
338 if (!pixa)
339 L_WARNING("pixa of char bitmaps not found\n", __func__);
340 return pixa;
341}
342
343
362l_ok
363pixaSaveFont(const char *indir,
364 const char *outdir,
365 l_int32 fontsize)
366{
367char *pathname;
368l_int32 bl1, bl2, bl3;
369PIXA *pixa;
370
371 if (fontsize < 4 || fontsize > 20 || (fontsize % 2))
372 return ERROR_INT("fontsize must be in {4, 6, ..., 20}", __func__, 1);
373
374 if (!indir) /* Generate from a string */
375 pixa = pixaGenerateFontFromString(fontsize, &bl1, &bl2, &bl3);
376 else /* Generate from an image file */
377 pixa = pixaGenerateFontFromFile(indir, fontsize, &bl1, &bl2, &bl3);
378 if (!pixa)
379 return ERROR_INT("pixa not made", __func__, 1);
380
381 pathname = pathJoin(outdir, outputfonts[(fontsize - 4) / 2]);
382 pixaWrite(pathname, pixa);
383
384#if DEBUG_FONT_GEN
385 L_INFO("Found %d chars in font size %d\n", __func__, pixaGetCount(pixa),
386 fontsize);
387 L_INFO("Baselines are at: %d, %d, %d\n", __func__, bl1, bl2, bl3);
388#endif /* DEBUG_FONT_GEN */
389
390 LEPT_FREE(pathname);
391 pixaDestroy(&pixa);
392 return 0;
393}
394
395
422static PIXA *
424 l_int32 fontsize,
425 l_int32 *pbl0,
426 l_int32 *pbl1,
427 l_int32 *pbl2)
428{
429char *pathname;
430l_int32 fileno;
431PIX *pix;
432PIXA *pixa;
433
434 if (!pbl0 || !pbl1 || !pbl2)
435 return (PIXA *)ERROR_PTR("&bl not all defined", __func__, NULL);
436 *pbl0 = *pbl1 = *pbl2 = 0;
437 if (!dir)
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);
442
443 pathname = pathJoin(dir, inputfonts[fileno]);
444 pix = pixRead(pathname);
445 LEPT_FREE(pathname);
446 if (!pix) {
447 L_ERROR("pix not found for font size %d\n", __func__, fontsize);
448 return NULL;
449 }
450
451 pixa = pixaGenerateFont(pix, fontsize, pbl0, pbl1, pbl2);
452 pixDestroy(&pix);
453 return pixa;
454}
455
456
471static PIXA *
473 l_int32 *pbl0,
474 l_int32 *pbl1,
475 l_int32 *pbl2)
476{
477l_uint8 *data;
478l_int32 redsize, nbytes;
479PIX *pix;
480PIXA *pixa;
481
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);
488
489 if (fontsize == 4) {
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);
505 } else { /* fontsize == 20 */
506 data = decodeBase64(fontdata_20, strlen(fontdata_20), &nbytes);
507 }
508 if (!data)
509 return (PIXA *)ERROR_PTR("data not made", __func__, NULL);
510
511 pix = pixReadMem(data, nbytes);
512 LEPT_FREE(data);
513 if (!pix)
514 return (PIXA *)ERROR_PTR("pix not made", __func__, NULL);
515
516 pixa = pixaGenerateFont(pix, fontsize, pbl0, pbl1, pbl2);
517 pixDestroy(&pix);
518 return pixa;
519}
520
521
540static PIXA *
542 l_int32 fontsize,
543 l_int32 *pbl0,
544 l_int32 *pbl1,
545 l_int32 *pbl2)
546{
547l_int32 i, j, nrows, nrowchars, nchars, h, yval;
548l_int32 width, height;
549l_int32 baseline[3];
550l_int32 *tab = NULL;
551BOX *box, *box1, *box2;
552BOXA *boxar, *boxac, *boxacs;
553PIX *pix1, *pix2, *pixr, *pixrc, *pixc;
554PIXA *pixa;
555l_int32 n, w, inrow, top;
556l_int32 *ia;
557NUMA *na;
558
559 if (!pbl0 || !pbl1 || !pbl2)
560 return (PIXA *)ERROR_PTR("&bl not all defined", __func__, NULL);
561 *pbl0 = *pbl1 = *pbl2 = 0;
562 if (!pixs)
563 return (PIXA *)ERROR_PTR("pixs not defined", __func__, NULL);
564
565 /* Locate the 3 rows of characters */
566 w = pixGetWidth(pixs);
567 na = pixCountPixelsByRow(pixs, NULL);
568 boxar = boxaCreate(0);
569 n = numaGetCount(na);
570 ia = numaGetIArray(na);
571 inrow = 0;
572 for (i = 0; i < n; i++) {
573 if (!inrow && ia[i] > 0) {
574 inrow = 1;
575 top = i;
576 } else if (inrow && ia[i] == 0) {
577 inrow = 0;
578 box = boxCreate(0, top, w, i - top);
579 boxaAddBox(boxar, box, L_INSERT);
580 }
581 }
582 LEPT_FREE(ia);
583 numaDestroy(&na);
584 nrows = boxaGetCount(boxar);
585#if DEBUG_FONT_GEN
586 L_INFO("For fontsize %s, have %d rows\n", __func__, fontsize, nrows);
587#endif /* DEBUG_FONT_GEN */
588 if (nrows != 3) {
589 L_INFO("nrows = %d; skipping fontsize %d\n", __func__, nrows, fontsize);
590 boxaDestroy(&boxar);
591 return (PIXA *)ERROR_PTR("3 rows not generated", __func__, NULL);
592 }
593
594 /* Grab the character images and baseline data */
595#if DEBUG_BASELINE
596 lept_rmdir("baseline");
597 lept_mkdir("baseline");
598#endif /* DEBUG_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); /* row of chars */
604 pixGetTextBaseline(pixr, tab, &yval);
605 baseline[i] = yval;
606
607#if DEBUG_BASELINE
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,
613 if (i == 0 )
614 pixWriteDebug("/tmp/baseline/row0.png", pix1, IFF_PNG);
615 else if (i == 1)
616 pixWriteDebug("/tmp/baseline/row1.png", pix1, IFF_PNG);
617 else
618 pixWriteDebug("/tmp/baseline/row2.png", pix1, IFF_PNG);
619 pixDestroy(&pix1);
620#endif /* DEBUG_BASELINE */
621
622 boxDestroy(&box);
623 pixrc = pixCloseSafeBrick(NULL, pixr, 1, 35);
624 boxac = pixConnComp(pixrc, NULL, 8);
625 boxacs = boxaSort(boxac, L_SORT_BY_X, L_SORT_INCREASING, NULL);
626 if (i == 0) { /* consolidate the two components of '"' */
627 box1 = boxaGetBox(boxacs, 1, L_CLONE);
628 box2 = boxaGetBox(boxacs, 2, L_CLONE);
629 box1->w = box2->x + box2->w - box1->x; /* increase width */
630 boxDestroy(&box1);
631 boxDestroy(&box2);
632 boxaRemoveBox(boxacs, 2);
633 }
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) { /* skip 1x1, 2x1 components */
639 boxDestroy(&box);
640 continue;
641 }
642 box->y = 0;
643 box->h = h - 1;
644 pixc = pixClipRectangle(pixr, box, NULL);
645 boxDestroy(&box);
646 if (i == 0 && j == 0) /* add a pix for the space; change later */
647 pixaAddPix(pixa, pixc, L_COPY);
648 if (i == 2 && j == 0) /* add a pix for the '\'; change later */
649 pixaAddPix(pixa, pixc, L_COPY);
650 pixaAddPix(pixa, pixc, L_INSERT);
651 }
652 pixDestroy(&pixr);
653 pixDestroy(&pixrc);
654 boxaDestroy(&boxac);
655 boxaDestroy(&boxacs);
656 }
657 LEPT_FREE(tab);
658
659 nchars = pixaGetCount(pixa);
660 if (nchars != 95)
661 return (PIXA *)ERROR_PTR("95 chars not generated", __func__, NULL);
662
663 *pbl0 = baseline[0];
664 *pbl1 = baseline[1];
665 *pbl2 = baseline[2];
666
667 /* Fix the space character up; it should have no ON pixels,
668 * and be about twice as wide as the '!' character. */
669 pix1 = pixaGetPix(pixa, 0, L_CLONE);
670 width = 2 * pixGetWidth(pix1);
671 height = pixGetHeight(pix1);
672 pixDestroy(&pix1);
673 pix1 = pixCreate(width, height, 1);
674 pixaReplacePix(pixa, 0, pix1, NULL);
675
676 /* Fix up the '\' character; use a LR flip of the '/' char */
677 pix1 = pixaGetPix(pixa, 15, L_CLONE);
678 pix2 = pixFlipLR(NULL, pix1);
679 pixDestroy(&pix1);
680 pixaReplacePix(pixa, 60, pix2, NULL);
681
682#if DEBUG_CHARS
683 pix1 = pixaDisplayTiled(pixa, 1500, 0, 10);
684 pixDisplay(pix1, 100 * i, 200);
685 pixDestroy(&pix1);
686#endif /* DEBUG_CHARS */
687
688 boxaDestroy(&boxar);
689 return pixa;
690}
691
692
709static l_int32
711 l_int32 *tab8,
712 l_int32 *py)
713{
714l_int32 i, h, val1, val2, diff, diffmax, ymax;
715l_int32 *tab;
716NUMA *na;
717
718 if (!pixs)
719 return ERROR_INT("pixs not defined", __func__, 1);
720 if (!py)
721 return ERROR_INT("&y not defined", __func__, 1);
722 *py = 0;
723 if (!tab8)
724 tab = makePixelSumTab8();
725 else
726 tab = tab8;
727
728 na = pixCountPixelsByRow(pixs, tab);
729 h = numaGetCount(na);
730 diffmax = 0;
731 ymax = 0;
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) {
737 diffmax = diff;
738 ymax = i - 1; /* upper raster line */
739 }
740 }
741 *py = ymax;
742
743 if (!tab8)
744 LEPT_FREE(tab);
745 numaDestroy(&na);
746 return 0;
747}
748
749
782static l_int32
784{
785l_int32 i, maxh, height, charwidth, xwidth, kernwidth;
786l_int32 *fonttab, *baselinetab, *widthtab;
787PIX *pix;
788
789 if (!bmf)
790 return ERROR_INT("bmf not defined", __func__, 1);
791
792 /* First get the fonttab; we use this later for the char widths */
793 fonttab = (l_int32 *)LEPT_CALLOC(128, sizeof(l_int32));
794 bmf->fonttab = fonttab;
795 for (i = 0; i < 128; i++)
796 fonttab[i] = UNDEF;
797 for (i = 32; i < 127; i++)
798 fonttab[i] = i - 32;
799
800 baselinetab = (l_int32 *)LEPT_CALLOC(128, sizeof(l_int32));
801 bmf->baselinetab = baselinetab;
802 for (i = 0; i < 128; i++)
803 baselinetab[i] = UNDEF;
804 for (i = 32; i <= 57; i++)
805 baselinetab[i] = bmf->baseline1;
806 for (i = 58; i <= 91; i++)
807 baselinetab[i] = bmf->baseline2;
808 baselinetab[92] = bmf->baseline1; /* the '\' char */
809 for (i = 93; i < 127; i++)
810 baselinetab[i] = bmf->baseline3;
811
812 /* Generate array of character widths; req's fonttab to exist */
813 widthtab = (l_int32 *)LEPT_CALLOC(128, sizeof(l_int32));
814 bmf->widthtab = widthtab;
815 for (i = 0; i < 128; i++)
816 widthtab[i] = UNDEF;
817 for (i = 32; i < 127; i++) {
818 bmfGetWidth(bmf, i, &charwidth);
819 widthtab[i] = charwidth;
820 }
821
822 /* Get the line height of text characters, from the highest
823 * ascender to the lowest descender; req's fonttab to exist. */
824 pix = bmfGetPix(bmf, 32);
825 maxh = pixGetHeight(pix);
826 pixDestroy(&pix);
827 pix = bmfGetPix(bmf, 58);
828 height = pixGetHeight(pix);
829 pixDestroy(&pix);
830 maxh = L_MAX(maxh, height);
831 pix = bmfGetPix(bmf, 93);
832 height = pixGetHeight(pix);
833 pixDestroy(&pix);
834 maxh = L_MAX(maxh, height);
835 bmf->lineheight = maxh;
836
837 /* Get the kern width (distance between characters).
838 * We let it be the same for all characters in a given
839 * font size, and scale it linearly with the size;
840 * req's fonttab to be built first. */
841 bmfGetWidth(bmf, 120, &xwidth);
842 kernwidth = (l_int32)(0.08 * (l_float32)xwidth + 0.5);
843 bmf->kernwidth = L_MAX(1, kernwidth);
844
845 /* Save the space width (between words) */
846 bmfGetWidth(bmf, 32, &charwidth);
847 bmf->spacewidth = charwidth;
848
849 /* Save the extra vertical space between lines */
850 bmf->vertlinesep = (l_int32)(VertFractSep * bmf->lineheight + 0.5);
851
852 return 0;
853}
void bmfDestroy(L_BMF **pbmf)
bmfDestroy()
Definition bmf.c:168
static PIXA * pixaGenerateFontFromFile(const char *dir, l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2)
pixaGenerateFontFromFile()
Definition bmf.c:423
L_BMF * bmfCreate(const char *dir, l_int32 fontsize)
bmfCreate()
Definition bmf.c:118
static PIXA * pixaGenerateFont(PIX *pixs, l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2)
pixaGenerateFont()
Definition bmf.c:541
static PIXA * pixaGenerateFontFromString(l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2)
pixaGenerateFontFromString()
Definition bmf.c:472
PIXA * pixaGetFont(const char *dir, l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2)
pixaGetFont()
Definition bmf.c:315
l_ok bmfGetBaseline(L_BMF *bmf, char chr, l_int32 *pbaseline)
bmfGetBaseline()
Definition bmf.c:271
static l_int32 bmfMakeAsciiTables(L_BMF *bmf)
bmfMakeAsciiTables
Definition bmf.c:783
l_ok pixaSaveFont(const char *indir, const char *outdir, l_int32 fontsize)
pixaSaveFont()
Definition bmf.c:363
static l_int32 pixGetTextBaseline(PIX *pixs, l_int32 *tab8, l_int32 *py)
pixGetTextBaseline()
Definition bmf.c:710
l_ok bmfGetWidth(L_BMF *bmf, char chr, l_int32 *pw)
bmfGetWidth()
Definition bmf.c:234
PIX * bmfGetPix(L_BMF *bmf, char chr)
bmfGetPix()
Definition bmf.c:201
@ L_FLIP_PIXELS
Definition pix.h:567
@ L_SORT_BY_X
Definition pix.h:528
@ L_COPY
Definition pix.h:505
@ L_CLONE
Definition pix.h:506
@ L_INSERT
Definition pix.h:504
@ L_SORT_INCREASING
Definition pix.h:522
l_int32 y
l_int32 x
l_int32 w
l_int32 h
Definition bmf.h:47
l_int32 * baselinetab
Definition bmf.h:59
l_int32 baseline3
Definition bmf.h:53
l_int32 * fonttab
Definition bmf.h:58
l_int32 * widthtab
Definition bmf.h:60
char * directory
Definition bmf.h:50
l_int32 baseline1
Definition bmf.h:51
l_int32 spacewidth
Definition bmf.h:56
l_int32 vertlinesep
Definition bmf.h:57
struct Pixa * pixa
Definition bmf.h:48
l_int32 size
Definition bmf.h:49
l_int32 kernwidth
Definition bmf.h:55
l_int32 baseline2
Definition bmf.h:52
l_int32 lineheight
Definition bmf.h:54