/* Copyright (C) 2017-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk4fontc.ctr */ /** @file dk4fontc.c The dk4fontc module. */ #line 169 "dk4fontc.ctr" #include "dk4conf.h" #ifndef DK4FONTC_H_INCLUDED #include "dk4fontc.h" #endif #ifndef DK4MEM_H_INCLUDED #include "dk4mem.h" #endif #ifndef DK4UNUSED_H_INCLUDED #include "dk4unused.h" #endif #ifndef DK4MATH_H_INCLUDED #include "dk4math.h" #endif #ifndef DK4NUMCO_H_INCLUDED #include "dk4numco.h" #endif #if DK4_HAVE_MATH_H #ifndef MATH_H_INCLUDED #if DK4_ON_WINDOWS #ifndef _USE_MATH_DEFINES #define _USE_MATH_DEFINES 1 #endif #endif #include #define MATH_H_INCLUDED 1 #endif #endif #ifndef GRA_H_INCLUDED #include "gra.h" #endif #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif /** Minimum size difference required to see different font sizes. */ #define FNT_EPS 1.0e-4 #line 222 "dk4fontc.ctr" /** Initialize a font item. @param ptr Item to initialize. */ static void dk4fontc_item_init(dk4_font_item_t *ptr) { #line 233 "dk4fontc.ctr" #if DK4_USE_ASSERT assert(NULL != ptr); #endif dk4mem_reset(ptr, sizeof(dk4_font_item_t), NULL); ptr->fsz = 0.0; ptr->nf = (size_t)0UL; ptr->fno = DK4_FONT_TIMES_ROMAN; ptr->fex = DK4_GRA_TF_NONE_NONE; #line 242 "dk4fontc.ctr" } static int dk4_font_item_equal_fex( const dk4_font_item_t *pl, const dk4_font_item_t *pr ) { int back = 0; if (DK4_GRA_TF_NONE_NONE != pl->fex) { switch (pl->fex) { case DK4_GRA_TF_NONE_NONE : { /* Intentionally empty to avoid compiler warnings. */ } break; case DK4_GRA_TF_EXACT_SIZE : case DK4_GRA_TF_SIMILAR_SIZE : { if (pl->fno > pr->fno) { back = 1; } else { if (pl->fno < pr->fno) { back = -1; } } if (0 == back) { if (isgreater(pl->fsz, (FNT_EPS + pr->fsz))) { back = 1; } else { if (isgreater(pr->fsz, (FNT_EPS + pl->fsz))) { back = -1; } } } } break; case DK4_GRA_TF_EXACT_NONE : case DK4_GRA_TF_SIMILAR_NONE : { if (pl->fno > pr->fno) { back = 1; } else { if (pl->fno < pr->fno) { back = -1; } } } break; default : { /* DK4_GRA_TF_NONE_SIZE */ if (isgreater(pl->fsz, (FNT_EPS + pr->fsz))) { back = 1; } else { if (isgreater(pr->fsz, (FNT_EPS + pl->fsz))) { back = -1; } } } break; } } return back; } /** Compare two font items by font number or by font id. @param l Left font item. @param r Right font item. @param cr Comparison criteria (1=by number,0=normal). @return Comparison result. */ static int dk4_font_item_compare_by_fontno_and_size( const void *l, const void *r, int cr ) { int back = 0; const dk4_font_item_t *pl; /* Left object */ const dk4_font_item_t *pr; /* Right object */ #line 325 "dk4fontc.ctr" pl = (const dk4_font_item_t *)l; pr = (const dk4_font_item_t *)r; if (NULL != pl) { if (NULL != pr) { switch (cr) { case 1 : { if (pl->nf > pr->nf) { back = 1; } else { if (pl->nf < pr->nf) { back = -1; } } } break; default : { /* First check domain (exact font or similar font) */ if (pl->fex > pr->fex) { back = 1; } else { if (pl->fex < pr->fex) { back = -1; } } if (0 == back) { back = dk4_font_item_equal_fex(pl, pr); } } break; } } else { back = 1; } } else { if (NULL != pr) { back = -1; } } #line 368 "dk4fontc.ctr" return back; } /** Initialize new font collector. @param ptr Font collector to initialize. */ static void dk4fontc_init(dk4_font_collector_t *ptr) { #line 381 "dk4fontc.ctr" #if DK4_USE_ASSERT assert(NULL != ptr); #endif ptr->s_fo = ptr->s_fn = NULL; ptr->i_fo = ptr->i_fn = NULL; ptr->nfonts = 0; #line 388 "dk4fontc.ctr" } void dk4fontc_close( dk4_font_collector_t *fc ) { dk4_font_item_t *fi; /* Current font item to release */ #line 400 "dk4fontc.ctr" #if DK4_USE_ASSERT assert(NULL != fc); #endif if (NULL != fc) { /* s_fn only contains copy */ if (NULL != fc->s_fn) { if (NULL != fc->i_fn) { dk4sto_it_close(fc->i_fn); } dk4sto_close(fc->s_fn); } fc->s_fn = NULL; fc->i_fn = NULL; /* s_fo contains the real data, we must delete here */ if (NULL != fc->s_fo) { if (NULL != fc->i_fo) { dk4sto_it_reset(fc->i_fo); do { fi = (dk4_font_item_t *)dk4sto_it_next(fc->i_fo); if (NULL != fi) { #line 425 "dk4fontc.ctr" dk4mem_free(fi); } } while(NULL != fi); } dk4sto_close(fc->s_fo); } fc->s_fo = NULL; fc->i_fo = NULL; dk4fontc_init(fc); dk4mem_free(fc); } #line 437 "dk4fontc.ctr" } dk4_font_collector_t * dk4fontc_open( dk4_er_t *erp ) { dk4_font_collector_t *back = NULL; int ok = 0; #line 450 "dk4fontc.ctr" back = dk4mem_new(dk4_font_collector_t,1,erp); if (NULL != back) { dk4fontc_init(back); back->s_fo = dk4sto_open(erp); back->s_fn = dk4sto_open(erp); if ((NULL != back->s_fo) && (NULL != back->s_fn)) { dk4sto_set_comp( back->s_fo, dk4_font_item_compare_by_fontno_and_size, 0 ); dk4sto_set_comp( back->s_fn, dk4_font_item_compare_by_fontno_and_size, 1 ); back->i_fo = dk4sto_it_open(back->s_fo, erp); back->i_fn = dk4sto_it_open(back->s_fn, erp); if ((NULL != back->i_fo) && (NULL != back->i_fn)) { ok = 1; } } if (0 == ok) { dk4fontc_close(back); back = NULL; } } #line 474 "dk4fontc.ctr" return back; } int dk4fontc_add_font( size_t *pdst, dk4_font_collector_t *fc, int fno, double fsz, int fex, dk4_er_t *erp ) { dk4_font_item_t tv; /* Test value */ dk4_font_item_t *ptr; /* Item found */ dk4_font_number_t rfno; /* Real font number */ int back = 0; /* Function result */ #line 495 "dk4fontc.ctr" #if DK4_USE_ASSERT assert(NULL != fc); assert(NULL != pdst); assert(0 <= fno); assert(0.0 < fsz); #endif /* Check command line arguments */ if ((NULL == pdst) || (NULL == fc) || (0 > fno) || (0.0 >= fsz)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } else { /* Initialize search record */ dk4fontc_item_init(&tv); tv.fsz = fsz; tv.nf = 0; tv.fex = fex; rfno = dk4font_number_from_int(fno); switch (fex) { case DK4_GRA_TF_SIMILAR_NONE : case DK4_GRA_TF_SIMILAR_SIZE : { tv.fno = dk4font_get_features(rfno); } break; default : { tv.fno = fno; } break; } /* Search */ ptr = (dk4_font_item_t *)dk4sto_it_find_like(fc->i_fo, &tv, 0); /* Success if found, otherwise create new entry */ if (NULL != ptr) { back = 1; *pdst = ptr->nf; } else { if (SIZE_MAX > fc->nfonts) { ptr = dk4mem_new(dk4_font_item_t,1,erp); if (NULL != ptr) { DK4_MEMCPY(ptr,&tv,sizeof(dk4_font_item_t)); ptr->nf = fc->nfonts; if (0 != dk4sto_add(fc->s_fo, ptr, erp)) { fc->nfonts += 1; if (0 != dk4sto_add(fc->s_fn, ptr, erp)) { back = 1; *pdst = ptr->nf; } } else { dk4mem_free(ptr); } } } else { dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); } } } #line 558 "dk4fontc.ctr" return back; } /* vim: set ai sw=4 ts=4 : */