⛏️ index : haiku.git

/*
 * Copyright 2007, Axel DΓΆrfler, axeld@pinc-software.de. All rights reserved.
 * Copyright 2004, FranΓ§ois Revol. All rights reserved.
 * Distributed under the terms of the MIT License.
 */


#include <getopt.h>
#include <stdio.h>

#include <Application.h>
#include <Font.h>
#include <String.h>


static struct option const kLongOptions[] = {
	{"styles", no_argument, 0, 's'},
	{"long", no_argument, 0, 'l'},
	{"tuned", no_argument, 0, 't'},
	{"help", no_argument, 0, 'h'},
	{NULL}
};

extern const char *__progname;
static const char *sProgramName = __progname;


void
usage(void)
{
	printf("%s [-s] [-l]\n", sProgramName);
	printf("lists currently installed font families.\n");
	printf("\t-s  --styles  list styles for each family\n");
	printf("\t-l  --long    long listing with more info (spacing, encoding,\n"
		"\t\t\theight (ascent/descent/leading), ...)\n");
	printf("\t-t  --tuned   display tuned fonts\n");
#ifndef __HAIKU__
	printf("\t-u            update font families\n");
#endif
}


int
main(int argc, char **argv)
{
	// parse command line parameters

	bool displayStyles = false;
	bool displayLong = false;
	bool displayTuned = false;
#ifndef __HAIKU__
	bool updateFamilies = false;
#endif

	int c;
	while ((c = getopt_long(argc, argv, "sltuh", kLongOptions, NULL)) != -1) {
		switch (c) {
			case 0:
				break;
			case 'h':
				usage();
				return 0;
			default:
				usage();
				return 1;

			case 't':
				displayTuned = true;
			case 'l':
				displayLong = true;
			case 's':
				displayStyles = true;
				break;
#ifndef __HAIKU__
			case 'u':
				updateFamilies = true;
				break;
#endif
		}
	}

	BApplication app("application/x-vnd.Haiku-listfont");

#ifndef __HAIKU__
	if (updateFamilies) {
		bool changed = update_font_families(true);
		printf("font families %s.\n", changed ? "changed" : "did not change");
		return 0;
	}
#endif

	int32 familyCount = count_font_families();

	if (displayLong) {
		printf("name/style                            face  spc. enc. "
			"height (a, d, l)  flags\n\n");
	}

	for (int32 f = 0; f < familyCount; f++) {
		font_family family;
		if (get_font_family(f, &family) < B_OK)
			continue;
		if (!displayStyles) {
			printf("%s\n", family);
			continue;
		}

		int32 styleCount = count_font_styles(family);

		for (int32 s = 0; s < styleCount; s++) {
			font_style style;
			uint16 face;
			uint32 flags;
			if (get_font_style(family, s, &style, &face, &flags) < B_OK)
				continue;

			if (!displayLong) {
				printf("%s/%s\n", family, style);
				continue;
			}

			BString fontName;
			fontName << family << "/" << style;
			printf("%-37s", fontName.String());

			BFont font;
			font.SetFamilyAndStyle(family, style);
			printf(" 0x%02x  %-4d %-4d", face, font.Spacing(), font.Encoding());

			font_height fh;
			font.GetHeight(&fh);
			printf(" %5.2f, %4.2f, %4.2f ", fh.ascent, fh.descent, fh.leading);
			if ((flags & B_IS_FIXED) != 0)
				printf("fixed");

			if ((flags & B_HAS_TUNED_FONT) != 0) {
				if (displayTuned)
					printf("\n    ");
				else if ((flags & B_IS_FIXED) != 0)
					printf(", ");

				int32 tunedCount = font.CountTuned();
				printf("%" B_PRId32 " tuned", tunedCount);

				if (displayTuned) {
					printf(":");
					for (int32 i = 0; i < tunedCount; i++) {
						tuned_font_info info;
						font.GetTunedInfo(i, &info);
						printf("\n\t(size %4.1f, "
							"shear %5.3f, "
							"rot. %5.3f, "
							"flags 0x%" B_PRIx32 ", "
							"face 0x%x)",
								info.size,
								info.shear,
								info.rotation,
								info.flags,
								info.face);
					}
				}
			}
			putchar('\n');
		}
	}
	return 0;
}