Leptonica 1.85.0
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);
185 *pbmf = NULL;
186}
187
188
189/*---------------------------------------------------------------------*/
190/* Bmf accessors */
191/*---------------------------------------------------------------------*/
199PIX *
201 char chr)
202{
203l_int32 i, index;
204PIXA *pixa;
205
206 if ((index = (l_int32)chr) == 10) /* NL */
207 return NULL;
208 if (!bmf)
209 return (PIX *)ERROR_PTR("bmf not defined", __func__, NULL);
210 if (index < 32 || index >= 127)
211 return (PIX *)ERROR_PTR("invalid index", __func__, NULL);
212
213 i = bmf->fonttab[index];
214 if (i == UNDEF) {
215 L_ERROR("no bitmap representation for %d\n", __func__, index);
216 return NULL;
217 }
218
219 if ((pixa = bmf->pixa) == NULL)
220 return (PIX *)ERROR_PTR("pixa not found", __func__, NULL);
221
222 return pixaGetPix(pixa, i, L_CLONE);
223}
224
225
234l_ok
236 char chr,
237 l_int32 *pw)
238{
239l_int32 i, index;
240PIXA *pixa;
241
242 if (!pw)
243 return ERROR_INT("&w not defined", __func__, 1);
244 *pw = -1;
245 if (!bmf)
246 return ERROR_INT("bmf not defined", __func__, 1);
247 if ((index = (l_int32)chr) == 10) /* NL */
248 return 0;
249 if (index < 32 || index >= 127)
250 return ERROR_INT("invalid index", __func__, 1);
251
252 i = bmf->fonttab[index];
253 if (i == UNDEF) {
254 L_ERROR("no bitmap representation for %d\n", __func__, index);
255 return 1;
256 }
257
258 if ((pixa = bmf->pixa) == NULL)
259 return ERROR_INT("pixa not found", __func__, 1);
260
261 return pixaGetPixDimensions(pixa, i, pw, NULL, NULL);
262}
263
264
273l_ok
275 char chr,
276 l_int32 *pbaseline)
277{
278l_int32 bl, index;
279
280 if (!pbaseline)
281 return ERROR_INT("&baseline not defined", __func__, 1);
282 *pbaseline = 0;
283 if (!bmf)
284 return ERROR_INT("bmf not defined", __func__, 1);
285 if ((index = (l_int32)chr) == 10) /* NL */
286 return 0;
287 if (index < 32 || index >= 127)
288 return ERROR_INT("invalid index", __func__, 1);
289
290 bl = bmf->baselinetab[index];
291 if (bl == UNDEF) {
292 L_ERROR("no bitmap representation for %d\n", __func__, index);
293 return 1;
294 }
295
296 *pbaseline = bl;
297 return 0;
298}
299
300
301/*---------------------------------------------------------------------*/
302/* Font bitmap acquisition and generation */
303/*---------------------------------------------------------------------*/
319PIXA *
320pixaGetFont(const char *dir,
321 l_int32 fontsize,
322 l_int32 *pbl0,
323 l_int32 *pbl1,
324 l_int32 *pbl2)
325{
326char *pathname;
327l_int32 fileno;
328PIXA *pixa;
329
330 fileno = (fontsize / 2) - 2;
331 if (fileno < 0 || fileno >= NUM_FONTS)
332 return (PIXA *)ERROR_PTR("font size invalid", __func__, NULL);
333 if (!pbl0 || !pbl1 || !pbl2)
334 return (PIXA *)ERROR_PTR("&bl not all defined", __func__, NULL);
335 *pbl0 = baselines[fileno][0];
336 *pbl1 = baselines[fileno][1];
337 *pbl2 = baselines[fileno][2];
338
339 pathname = pathJoin(dir, outputfonts[fileno]);
340 pixa = pixaRead(pathname);
341 LEPT_FREE(pathname);
342
343 if (!pixa)
344 L_WARNING("pixa of char bitmaps not found\n", __func__);
345 return pixa;
346}
347
348
367l_ok
368pixaSaveFont(const char *indir,
369 const char *outdir,
370 l_int32 fontsize)
371{
372char *pathname;
373l_int32 bl1, bl2, bl3;
374PIXA *pixa;
375
376 if (fontsize < 4 || fontsize > 20 || (fontsize % 2))
377 return ERROR_INT("fontsize must be in {4, 6, ..., 20}", __func__, 1);
378
379 if (!indir) /* Generate from a string */
380 pixa = pixaGenerateFontFromString(fontsize, &bl1, &bl2, &bl3);
381 else /* Generate from an image file */
382 pixa = pixaGenerateFontFromFile(indir, fontsize, &bl1, &bl2, &bl3);
383 if (!pixa)
384 return ERROR_INT("pixa not made", __func__, 1);
385
386 pathname = pathJoin(outdir, outputfonts[(fontsize - 4) / 2]);
387 pixaWrite(pathname, pixa);
388
389#if DEBUG_FONT_GEN
390 L_INFO("Found %d chars in font size %d\n", __func__, pixaGetCount(pixa),
391 fontsize);
392 L_INFO("Baselines are at: %d, %d, %d\n", __func__, bl1, bl2, bl3);
393#endif /* DEBUG_FONT_GEN */
394
395 LEPT_FREE(pathname);
396 pixaDestroy(&pixa);
397 return 0;
398}
399
400
427static PIXA *
429 l_int32 fontsize,
430 l_int32 *pbl0,
431 l_int32 *pbl1,
432 l_int32 *pbl2)
433{
434char *pathname;
435l_int32 fileno;
436PIX *pix;
437PIXA *pixa;
438
439 if (!pbl0 || !pbl1 || !pbl2)
440 return (PIXA *)ERROR_PTR("&bl not all defined", __func__, NULL);
441 *pbl0 = *pbl1 = *pbl2 = 0;
442 if (!dir)
443 return (PIXA *)ERROR_PTR("dir not defined", __func__, NULL);
444 fileno = (fontsize / 2) - 2;
445 if (fileno < 0 || fileno >= NUM_FONTS)
446 return (PIXA *)ERROR_PTR("font size invalid", __func__, NULL);
447
448 pathname = pathJoin(dir, inputfonts[fileno]);
449 pix = pixRead(pathname);
450 LEPT_FREE(pathname);
451 if (!pix) {
452 L_ERROR("pix not found for font size %d\n", __func__, fontsize);
453 return NULL;
454 }
455
456 pixa = pixaGenerateFont(pix, fontsize, pbl0, pbl1, pbl2);
457 pixDestroy(&pix);
458 return pixa;
459}
460
461
476static PIXA *
478 l_int32 *pbl0,
479 l_int32 *pbl1,
480 l_int32 *pbl2)
481{
482l_uint8 *data;
483l_int32 redsize, nbytes;
484PIX *pix;
485PIXA *pixa;
486
487 if (!pbl0 || !pbl1 || !pbl2)
488 return (PIXA *)ERROR_PTR("&bl not all defined", __func__, NULL);
489 *pbl0 = *pbl1 = *pbl2 = 0;
490 redsize = (fontsize / 2) - 2;
491 if (redsize < 0 || redsize >= NUM_FONTS)
492 return (PIXA *)ERROR_PTR("invalid font size", __func__, NULL);
493
494 if (fontsize == 4) {
495 data = decodeBase64(fontdata_4, strlen(fontdata_4), &nbytes);
496 } else if (fontsize == 6) {
497 data = decodeBase64(fontdata_6, strlen(fontdata_6), &nbytes);
498 } else if (fontsize == 8) {
499 data = decodeBase64(fontdata_8, strlen(fontdata_8), &nbytes);
500 } else if (fontsize == 10) {
501 data = decodeBase64(fontdata_10, strlen(fontdata_10), &nbytes);
502 } else if (fontsize == 12) {
503 data = decodeBase64(fontdata_12, strlen(fontdata_12), &nbytes);
504 } else if (fontsize == 14) {
505 data = decodeBase64(fontdata_14, strlen(fontdata_14), &nbytes);
506 } else if (fontsize == 16) {
507 data = decodeBase64(fontdata_16, strlen(fontdata_16), &nbytes);
508 } else if (fontsize == 18) {
509 data = decodeBase64(fontdata_18, strlen(fontdata_18), &nbytes);
510 } else { /* fontsize == 20 */
511 data = decodeBase64(fontdata_20, strlen(fontdata_20), &nbytes);
512 }
513 if (!data)
514 return (PIXA *)ERROR_PTR("data not made", __func__, NULL);
515
516 pix = pixReadMem(data, nbytes);
517 LEPT_FREE(data);
518 if (!pix)
519 return (PIXA *)ERROR_PTR("pix not made", __func__, NULL);
520
521 pixa = pixaGenerateFont(pix, fontsize, pbl0, pbl1, pbl2);
522 pixDestroy(&pix);
523 return pixa;
524}
525
526
545static PIXA *
547 l_int32 fontsize,
548 l_int32 *pbl0,
549 l_int32 *pbl1,
550 l_int32 *pbl2)
551{
552l_int32 i, j, nrows, nrowchars, nchars, h, yval;
553l_int32 width, height;
554l_int32 baseline[3];
555l_int32 *tab = NULL;
556BOX *box, *box1, *box2;
557BOXA *boxar, *boxac, *boxacs;
558PIX *pix1, *pix2, *pixr, *pixrc, *pixc;
559PIXA *pixa;
560l_int32 n, w, inrow, top;
561l_int32 *ia;
562NUMA *na;
563
564 if (!pbl0 || !pbl1 || !pbl2)
565 return (PIXA *)ERROR_PTR("&bl not all defined", __func__, NULL);
566 *pbl0 = *pbl1 = *pbl2 = 0;
567 if (!pixs)
568 return (PIXA *)ERROR_PTR("pixs not defined", __func__, NULL);
569
570 /* Locate the 3 rows of characters */
571 w = pixGetWidth(pixs);
572 na = pixCountPixelsByRow(pixs, NULL);
573 boxar = boxaCreate(0);
574 n = numaGetCount(na);
575 ia = numaGetIArray(na);
576 inrow = 0;
577 for (i = 0; i < n; i++) {
578 if (!inrow && ia[i] > 0) {
579 inrow = 1;
580 top = i;
581 } else if (inrow && ia[i] == 0) {
582 inrow = 0;
583 box = boxCreate(0, top, w, i - top);
584 boxaAddBox(boxar, box, L_INSERT);
585 }
586 }
587 LEPT_FREE(ia);
588 numaDestroy(&na);
589 nrows = boxaGetCount(boxar);
590#if DEBUG_FONT_GEN
591 L_INFO("For fontsize %s, have %d rows\n", __func__, fontsize, nrows);
592#endif /* DEBUG_FONT_GEN */
593 if (nrows != 3) {
594 L_INFO("nrows = %d; skipping fontsize %d\n", __func__, nrows, fontsize);
595 boxaDestroy(&boxar);
596 return (PIXA *)ERROR_PTR("3 rows not generated", __func__, NULL);
597 }
598
599 /* Grab the character images and baseline data */
600#if DEBUG_BASELINE
601 lept_rmdir("baseline");
602 lept_mkdir("baseline");
603#endif /* DEBUG_BASELINE */
604 tab = makePixelSumTab8();
605 pixa = pixaCreate(95);
606 for (i = 0; i < nrows; i++) {
607 box = boxaGetBox(boxar, i, L_CLONE);
608 pixr = pixClipRectangle(pixs, box, NULL); /* row of chars */
609 pixGetTextBaseline(pixr, tab, &yval);
610 baseline[i] = yval;
611
612#if DEBUG_BASELINE
613 L_INFO("Baseline info: row %d, yval = %d, h = %d\n", __func__,
614 i, yval, pixGetHeight(pixr));
615 pix1 = pixCopy(NULL, pixr);
616 pixRenderLine(pix1, 0, yval, pixGetWidth(pix1), yval, 1,
618 if (i == 0 )
619 pixWriteDebug("/tmp/baseline/row0.png", pix1, IFF_PNG);
620 else if (i == 1)
621 pixWriteDebug("/tmp/baseline/row1.png", pix1, IFF_PNG);
622 else
623 pixWriteDebug("/tmp/baseline/row2.png", pix1, IFF_PNG);
624 pixDestroy(&pix1);
625#endif /* DEBUG_BASELINE */
626
627 boxDestroy(&box);
628 pixrc = pixCloseSafeBrick(NULL, pixr, 1, 35);
629 boxac = pixConnComp(pixrc, NULL, 8);
630 boxacs = boxaSort(boxac, L_SORT_BY_X, L_SORT_INCREASING, NULL);
631 if (i == 0) { /* consolidate the two components of '"' */
632 box1 = boxaGetBox(boxacs, 1, L_CLONE);
633 box2 = boxaGetBox(boxacs, 2, L_CLONE);
634 box1->w = box2->x + box2->w - box1->x; /* increase width */
635 boxDestroy(&box1);
636 boxDestroy(&box2);
637 boxaRemoveBox(boxacs, 2);
638 }
639 h = pixGetHeight(pixr);
640 nrowchars = boxaGetCount(boxacs);
641 for (j = 0; j < nrowchars; j++) {
642 box = boxaGetBox(boxacs, j, L_COPY);
643 if (box->w <= 2 && box->h == 1) { /* skip 1x1, 2x1 components */
644 boxDestroy(&box);
645 continue;
646 }
647 box->y = 0;
648 box->h = h - 1;
649 pixc = pixClipRectangle(pixr, box, NULL);
650 boxDestroy(&box);
651 if (i == 0 && j == 0) /* add a pix for the space; change later */
652 pixaAddPix(pixa, pixc, L_COPY);
653 if (i == 2 && j == 0) /* add a pix for the '\'; change later */
654 pixaAddPix(pixa, pixc, L_COPY);
655 pixaAddPix(pixa, pixc, L_INSERT);
656 }
657 pixDestroy(&pixr);
658 pixDestroy(&pixrc);
659 boxaDestroy(&boxac);
660 boxaDestroy(&boxacs);
661 }
662 LEPT_FREE(tab);
663
664 nchars = pixaGetCount(pixa);
665 if (nchars != 95)
666 return (PIXA *)ERROR_PTR("95 chars not generated", __func__, NULL);
667
668 *pbl0 = baseline[0];
669 *pbl1 = baseline[1];
670 *pbl2 = baseline[2];
671
672 /* Fix the space character up; it should have no ON pixels,
673 * and be about twice as wide as the '!' character. */
674 pix1 = pixaGetPix(pixa, 0, L_CLONE);
675 width = 2 * pixGetWidth(pix1);
676 height = pixGetHeight(pix1);
677 pixDestroy(&pix1);
678 pix1 = pixCreate(width, height, 1);
679 pixaReplacePix(pixa, 0, pix1, NULL);
680
681 /* Fix up the '\' character; use a LR flip of the '/' char */
682 pix1 = pixaGetPix(pixa, 15, L_CLONE);
683 pix2 = pixFlipLR(NULL, pix1);
684 pixDestroy(&pix1);
685 pixaReplacePix(pixa, 60, pix2, NULL);
686
687#if DEBUG_CHARS
688 pix1 = pixaDisplayTiled(pixa, 1500, 0, 10);
689 pixDisplay(pix1, 100 * i, 200);
690 pixDestroy(&pix1);
691#endif /* DEBUG_CHARS */
692
693 boxaDestroy(&boxar);
694 return pixa;
695}
696
697
714static l_int32
716 l_int32 *tab8,
717 l_int32 *py)
718{
719l_int32 i, h, val1, val2, diff, diffmax, ymax;
720l_int32 *tab;
721NUMA *na;
722
723 if (!pixs)
724 return ERROR_INT("pixs not defined", __func__, 1);
725 if (!py)
726 return ERROR_INT("&y not defined", __func__, 1);
727 *py = 0;
728 if (!tab8)
729 tab = makePixelSumTab8();
730 else
731 tab = tab8;
732
733 na = pixCountPixelsByRow(pixs, tab);
734 h = numaGetCount(na);
735 diffmax = 0;
736 ymax = 0;
737 for (i = 1; i < h; i++) {
738 numaGetIValue(na, i - 1, &val1);
739 numaGetIValue(na, i, &val2);
740 diff = L_MAX(0, val1 - val2);
741 if (diff > diffmax) {
742 diffmax = diff;
743 ymax = i - 1; /* upper raster line */
744 }
745 }
746 *py = ymax;
747
748 if (!tab8)
749 LEPT_FREE(tab);
750 numaDestroy(&na);
751 return 0;
752}
753
754
784static l_int32
786{
787l_int32 i, maxh, height, charwidth, xwidth, kernwidth;
788l_int32 *fonttab, *baselinetab;
789PIX *pix;
790
791 if (!bmf)
792 return ERROR_INT("bmf not defined", __func__, 1);
793
794 /* First get the fonttab; we use this later for the char widths */
795 fonttab = (l_int32 *)LEPT_CALLOC(128, sizeof(l_int32));
796 bmf->fonttab = fonttab;
797 for (i = 0; i < 128; i++)
798 fonttab[i] = UNDEF;
799 for (i = 32; i < 127; i++)
800 fonttab[i] = i - 32;
801
802 baselinetab = (l_int32 *)LEPT_CALLOC(128, sizeof(l_int32));
803 bmf->baselinetab = baselinetab;
804 for (i = 0; i < 128; i++)
805 baselinetab[i] = UNDEF;
806 for (i = 32; i <= 57; i++)
807 baselinetab[i] = bmf->baseline1;
808 for (i = 58; i <= 91; i++)
809 baselinetab[i] = bmf->baseline2;
810 baselinetab[92] = bmf->baseline1; /* the '\' char */
811 for (i = 93; i < 127; i++)
812 baselinetab[i] = bmf->baseline3;
813
814 /* Get the line height of text characters, from the highest
815 * ascender to the lowest descender; req's fonttab to exist. */
816 pix = bmfGetPix(bmf, 32);
817 maxh = pixGetHeight(pix);
818 pixDestroy(&pix);
819 pix = bmfGetPix(bmf, 58);
820 height = pixGetHeight(pix);
821 pixDestroy(&pix);
822 maxh = L_MAX(maxh, height);
823 pix = bmfGetPix(bmf, 93);
824 height = pixGetHeight(pix);
825 pixDestroy(&pix);
826 maxh = L_MAX(maxh, height);
827 bmf->lineheight = maxh;
828
829 /* Get the kern width (distance between characters).
830 * We let it be the same for all characters in a given
831 * font size, and scale it linearly with the size;
832 * req's fonttab to be built first. */
833 bmfGetWidth(bmf, 120, &xwidth);
834 kernwidth = (l_int32)(0.08 * (l_float32)xwidth + 0.5);
835 bmf->kernwidth = L_MAX(1, kernwidth);
836
837 /* Save the space width (between words) */
838 bmfGetWidth(bmf, 32, &charwidth);
839 bmf->spacewidth = charwidth;
840
841 /* Save the extra vertical space between lines */
842 bmf->vertlinesep = (l_int32)(VertFractSep * bmf->lineheight + 0.5);
843
844 return 0;
845}
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:428
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:546
static PIXA * pixaGenerateFontFromString(l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2)
pixaGenerateFontFromString()
Definition bmf.c:477
PIXA * pixaGetFont(const char *dir, l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2)
pixaGetFont()
Definition bmf.c:320
l_ok bmfGetBaseline(L_BMF *bmf, char chr, l_int32 *pbaseline)
bmfGetBaseline()
Definition bmf.c:274
static l_int32 bmfMakeAsciiTables(L_BMF *bmf)
bmfMakeAsciiTables
Definition bmf.c:785
l_ok pixaSaveFont(const char *indir, const char *outdir, l_int32 fontsize)
pixaSaveFont()
Definition bmf.c:368
static l_int32 pixGetTextBaseline(PIX *pixs, l_int32 *tab8, l_int32 *py)
pixGetTextBaseline()
Definition bmf.c:715
l_ok bmfGetWidth(L_BMF *bmf, char chr, l_int32 *pw)
bmfGetWidth()
Definition bmf.c:235
PIX * bmfGetPix(L_BMF *bmf, char chr)
bmfGetPix()
Definition bmf.c:200
@ 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
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