Edit

IABSD.fr/xenocara/font/util/bdftruncate.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2026-05-08 09:59:06
    Hash : 1677254e
    Message : Update to font-util 1.4.2

  • font/util/bdftruncate.c
  • /*-
     * Copyright (c) 2006 Martin Husemann.
     * Copyright (c) 2007 Joerg Sonnenberger.
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     * 1. Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     * 2. The name of the author may not be used to endorse or promote
     *    products derived from this software without specific prior
     *    written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     * POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     * This program is derived (in a straight forward way) from
     * bdftruncate.pl -- Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/>
     *
     * This utility allows you to generate from an ISO10646-1 encoded
     * BDF font other ISO10646-1 BDF fonts in which all characters above
     * a threshold code value are stored unencoded.
     */
    
    #include "config.h"
    
    #include <ctype.h>
    #include <errno.h>
    #include <limits.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #ifndef __has_attribute
    # define __has_attribute(x) 0  /* Compatibility with older compilers. */
    #endif
    #ifndef __has_c_attribute
    # define __has_c_attribute(x) 0  /* Compatibility with pre-C23 compilers. */
    #endif
    
    #if __has_c_attribute(noreturn)
    # define ATTR_NORETURN [[noreturn]]
    #elif __has_attribute(noreturn) \
        || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
        || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
    # define ATTR_NORETURN __attribute((noreturn))
    #else
    # define ATTR_NORETURN
    #endif
    
    static int iswide(unsigned int);
    ATTR_NORETURN static void usage(int);
    static int parse_threshold(const char *str, unsigned long *threshold);
    
    static int
    parse_threshold(const char *str, unsigned long *threshold)
    {
    	int base;
    	char *end_ptr;
    
    	if (!isdigit((unsigned char)*str))
    		return 1;
    	if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
    		base = 16;
    	else
    		base = 10;
    
    	errno = 0;
    	*threshold = strtoul(str, &end_ptr, base);
    	if (errno != 0 || *threshold == 0)
    		return 1;
    	return 0;
    }
    
    static void
    process_line(const char *line, int removewide, unsigned long threshold)
    {
    	if (strncmp(line, "ENCODING", 8) == 0) {
    		unsigned long enc;
    		const char *v;
    
    		v = line + 9;
    
    		while (*v && isspace((unsigned char)(*v)))
    			++v;
    		enc = strtoul(v, NULL, 10);
    		/* XXX Check for line-ending? */
    		if (enc >= threshold || (removewide && iswide(enc))) {
    			printf("ENCODING -1\n");
    		} else {
    			fputs(line, stdout);
    		}
    		return;
    	}
    	if (strncmp(line, "STARTFONT", 9) == 0) {
    		fputs(line, stdout);
    		printf("COMMENT AUTOMATICALLY GENERATED FILE. DO NOT EDIT!\n"
    		    "COMMENT In this version of the font file, "
    		    "all characters >= U+%04lx are\n"
    		    "COMMENT not encoded to keep XFontStruct small.\n",
    		    threshold);
    		return;
    	}
    	if (strncmp(line, "COMMENT", 7) == 0) {
    		const char *v = line + 8;
    
    		while (*v && isspace((unsigned char)(*v)))
    			v++;
    		if (strncmp(v, "$id: ", 5) == 0 ||
    		    strncmp(v, "$Id: ", 5) == 0) {
    		    	const char *id = strchr(v+1, '$');
    		    	if (id) {
    		    		printf("COMMENT Derived from %.*s",
    				     (int)(id - v - 4), v + 5);
    				return;
    		    	}
    		}
    	}
    	fputs(line, stdout);
    }
    
    int
    main(int argc, char **argv)
    {
    	int removewide;
    	unsigned long threshold;
    	int opt_minus_w = 0;
    	int opt_plus_w = 0;
    	char *line, *input_ptr;
    	size_t line_len, rest_len;
    
    	--argc;
    	++argv;
    	if (argc == 0)
    		usage(EXIT_FAILURE);
    
    	if (strcmp(*argv, "-w") == 0 || strcmp(*argv, "+w") == 0) {
    		if (**argv == '-')
    			opt_minus_w = 1;
    		else
    			opt_plus_w = 1;
    		--argc;
    		++argv;
    	}
    	else if (strcmp(*argv, "--help") == 0) {
    		usage(EXIT_SUCCESS);
    	}
    	else if (strcmp(*argv, "--version") == 0) {
    		puts(PACKAGE_STRING);
    		exit(EXIT_SUCCESS);
    	}
    
    	if (argc != 1 || (opt_plus_w && opt_minus_w))
    		usage(EXIT_FAILURE);
    	if (parse_threshold(*argv, &threshold)) {
    		fprintf(stderr, "Illegal threshold %s\n", *argv);
    		usage(EXIT_FAILURE);
    	}
    
    	if (opt_minus_w)
    		removewide = 1;
    	else if (opt_plus_w)
    		removewide = 0;
    	else
    		removewide = (threshold <= 0x3200);
    
    	line_len = 1024;
    	if ((line = malloc(line_len)) == NULL) {
    		fprintf(stderr, "malloc failed");
    		exit(EXIT_FAILURE);
    	}
    
    	for (;;) {
    		if (fgets(line, line_len, stdin) == NULL)
    		     break;
    		while (strlen(line) == line_len - 1 && !feof(stdin)) {
    			if (line_len > SSIZE_MAX) {
    				fprintf(stderr, "input line too large");
    				exit(EXIT_FAILURE);
    			}
    			line = realloc(line, line_len * 2);
    			if (line == NULL) {
    				fprintf(stderr, "realloc failed");
    				exit(EXIT_FAILURE);
    			}
    			input_ptr = line + line_len - 1;
    			rest_len = line_len + 1;
    			line_len *= 2;
    			if (fgets(input_ptr, rest_len, stdin) == NULL) {
    				/* Should not happen, but handle as EOF */
    				break;
    			}
    		}
    		process_line(line, removewide, threshold);
    	}
    
    	return EXIT_SUCCESS;
    }
    
    /*
     * Subroutine to identify whether the ISO 10646/Unicode character code
     * ucs belongs into the East Asian Wide (W) or East Asian FullWidth
     * (F) category as defined in Unicode Technical Report #11.
     */
    static int
    iswide(unsigned int ucs)
    {
        return (ucs >= 0x1100 &&
                (ucs <= 0x115f ||                   /* Hangul Jamo */
                 (ucs >= 0x2e80 && ucs <= 0xa4cf &&
                  (ucs & ~0x0011) != 0x300a && ucs != 0x303f) || /* CJK .. Yi */
                 (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
                 (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Comp. Ideographs */
                 (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Comp. Forms */
                 (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */
                 (ucs >= 0xffe0 && ucs <= 0xffe6) ||
                 (ucs >= 0x20000 && ucs <= 0x2ffff)));
    }
    
    static void
    usage(int exitstatus)
    {
    	fprintf(stderr,
    	    "Usage: bdftruncate [+w|-w] threshold <source.bdf >destination.bdf\n"
                "   or: bdftruncate [--help|--version]\n"
    	    "\n"
    	    "Example:\n"
    	    "\n"
    	    "  bdftruncate 0x3200 <6x13.bdf >6x13t.bdf\n"
    	    "\n"
    	    "will generate the file 6x13t.bdf in which all glyphs with codes\n"
    	    ">= 0x3200 will only be stored unencoded (i.e., ENCODING -1).\n"
    	    "Option -w removes East Asian Wide and East Asian FullWidth characters\n"
    	    "(default if threshold <= 0x3200), and option +w keeps them.\n");
    	exit(exitstatus);
    }