revert between 56095 -> 55830 in arch
[AROS.git] / workbench / system / ftmanager / cli.c
blobb3428655ad562a8727587d3cf1e537ccc06e8bf4
1 /*
2 Copyright (C) 2018-2019, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <proto/exec.h>
7 #include <proto/dos.h>
8 #include <proto/alib.h>
10 #include <aros/debug.h>
12 #include "globals.h"
13 #include "fontinfo_class.h"
14 #include "fontbitmap_class.h"
16 #define ARG_TEMPLATE "COPY/S,TTFFONT/A,CODEPAGE/K,TO/K,FONTDIR/K,OUTFONT/K"
18 enum
20 ARG_COPY,
21 ARG_TTFFONT,
22 ARG_CODEPAGE,
23 ARG_TO,
24 ARG_FONTDIR,
25 ARG_OUTFONT,
26 ARG_COUNT
29 ULONG fiWriteFiles_real(FontInfoData *dat, STRPTR base, ULONG size);
31 static void usage(void)
33 BPTR out = ErrorOutput();
34 char myname[256];
35 APTR a[2];
37 GetProgramName(myname, sizeof(myname));
38 a[0]=(APTR) myname;
39 a[1]=0;
40 VFPrintf(out, "Usage: %s " ARG_TEMPLATE "\n", (APTR) a);
42 VFPrintf(out, "\n", NULL);
43 VFPrintf(out, " COPY/S: copy ttf font file (default: no)\n", NULL);
44 VFPrintf(out, " TTFFONT/A: ttf font file to install\n", NULL);
45 VFPrintf(out, " CODEPAGE/A: codepage to install (not yet supported)\n", NULL);
46 VFPrintf(out, " TO/K: target directory for COPY operation (default: \"FONTS:TrueType\")\n", NULL);
47 VFPrintf(out, " FONTDIR/K: directory in which the .otag and .font files\n", NULL);
48 VFPrintf(out, " will be installed (default: \"FONTS:\")\n", NULL);
49 VFPrintf(out, " OUTFONT/K: baseame for the .otag and .font files\n", NULL);
50 VFPrintf(out, " (default: TTFFont filename without extension)\n", NULL);
53 /*****************************************************************************
54 * get_basename
56 * If OUTFONT was supplied by command line, use outfont.
57 * If not, build basename based on filename of TTF Font
58 *****************************************************************************/
59 static void get_basename(STRPTR basename, STRPTR outfont, STRPTR ttf_name)
61 /* get basename for .otag/.font files */
62 if(outfont != NULL)
64 strncpy(basename, outfont, 255);
66 else
68 STRPTR b = FilePart(ttf_name);
69 STRPTR dot = strrchr(b, '.');
70 if(dot == NULL)
72 strncpy(basename, b, 255);
74 else
76 /* use TTFFont filename without extension */
77 strncpy(basename, b, dot-b);
78 basename[dot-b]=(char) 0;
81 D(bug("basename: >%s<\n", basename));
84 /*****************************************************************************
85 * copy_file(source, target)
87 * simple file copy
88 *****************************************************************************/
89 static BOOL copy_file_handle(BPTR s, BPTR t)
91 char buffer[BUFSIZ]; /* BUFSIZ is from stdio.h */
92 LONG bytes;
94 for(;;)
96 bytes = Read(s, buffer, sizeof(buffer) );
97 if( bytes < 0)
99 /* error */
100 return FALSE;
102 if( bytes == 0)
104 /* nothing more to read */
105 return TRUE;
108 if(Write(t, buffer, bytes) == -1)
110 return FALSE;
114 return TRUE;
117 static BOOL copy_file(STRPTR source, STRPTR target)
119 BPTR in, out;
120 BOOL ret;
122 if (!(in = Open(source, MODE_OLDFILE)))
124 printf("ERROR: Unable to open \"%s\"\n", source);
125 return FALSE;
128 if (!(out = Open(target, MODE_NEWFILE)))
130 Close(in);
131 printf("ERROR: Unable to open \"%s\"\n", target);
132 return FALSE;
135 ret=copy_file_handle(in, out);
136 if(!ret)
138 /* clean up eventually unfinished file */
139 DeleteFile(target);
142 Close(in);
143 Close(out);
145 return ret;
148 /*****************************************************************************
149 * ftmanager_cli
151 * FTmanager does not really distinguish between gui and functionality.
152 * So create a faked struct FontInfoData usually used by the Zune GUI and
153 * use it to call fiWriteFiles().
154 *****************************************************************************/
155 int ftmanager_cli(void)
157 struct RDArgs *rdargs;
158 struct FontInfoData *dat;
159 BOOL copy = TRUE;
160 TT_OS2 *os2;
161 FT_Error error;
162 IPTR args[] = { (IPTR) FALSE,
163 (IPTR) NULL,
164 (IPTR) NULL,
165 (IPTR) NULL,
166 (IPTR) NULL,
167 (IPTR) NULL,
168 (IPTR) NULL };
169 char basename[256];
170 char ttf_source[256];
172 rdargs = ReadArgs(ARG_TEMPLATE, args, NULL);
174 if(rdargs == NULL)
176 usage();
177 return RETURN_ERROR;
180 if(args[ARG_CODEPAGE] != 0)
182 printf("WARNING: Option Codepage ignored (not implemented)\n");
185 if(args[ARG_COPY] == 0)
187 copy = FALSE;
190 D(bug("COPY : %d\n", copy));
191 D(bug("TTFFont : %s\n", args[ARG_TTFFONT]));
192 D(bug("CODEPAGE: %s\n", args[ARG_CODEPAGE]));
193 D(bug("TO : %s\n", args[ARG_TO]));
194 D(bug("FONTDIR : %s\n", args[ARG_FONTDIR]));
195 D(bug("OUTFONT : %s\n", args[ARG_OUTFONT]));
197 if(args[ARG_TO] != 0 && !copy)
199 printf("ERROR: TO parameter only allowed, if COPY is used\n");
200 usage();
201 return RETURN_ERROR;
204 dat=(struct FontInfoData *) AllocVec(sizeof(struct FontInfoData), MEMF_CLEAR);
205 if(dat == NULL)
207 printf("ERROR: Out of memory\n");
208 return RETURN_ERROR;
212 /* copy must copy the .ttf file to the target directory and use the new
213 * file in the .otag
215 if(!copy)
217 dat->Filename=(STRPTR) args[ARG_TTFFONT];
219 else
221 if(args[ARG_TO] != 0)
223 strncpy(ttf_source, (STRPTR) args[ARG_TO], 255);
225 else
227 strcpy(ttf_source, "FONTS:TrueType");
229 D(bug("copy %s to %s\n", (STRPTR) args[ARG_TTFFONT], ttf_source));
230 AddPart(ttf_source, FilePart((STRPTR) args[ARG_TTFFONT]), 255);
232 if(copy_file((STRPTR) args[ARG_TTFFONT], ttf_source))
234 dat->Filename=ttf_source;
236 else
238 FreeVec(dat);
239 return RETURN_ERROR;
243 if (FT_Init_FreeType(&ftlibrary) != 0)
245 FreeVec(dat);
246 printf("ERROR: Init FreeType library failed \n");
247 return RETURN_ERROR;
250 get_basename(basename, (STRPTR) args[ARG_OUTFONT], dat->Filename);
253 if(error=FT_New_Face(ftlibrary, dat->Filename, 0, &dat->Face))
255 printf("ERROR: opening \"%s\" failed (error code: %d)\n", dat->Filename, error);
256 FT_Done_FreeType(ftlibrary);
257 FreeVec(dat);
258 return RETURN_ERROR;
261 /* fill in tags for .otag file */
262 os2 = FT_Get_Sfnt_Table(dat->Face, ft_sfnt_os2);
264 /* for all the magic here, please also see fontinfo_class.c */
265 struct TagItem *tag = dat->OTags;
267 tag->ti_Tag = OT_FileIdent;
268 ++tag;
270 tag->ti_Tag = OT_Engine;
271 tag->ti_Data = (IPTR) "freetype2";
272 ++tag;
274 tag->ti_Tag = OT_Family;
275 tag->ti_Data = (IPTR) dat->Face->family_name;
276 D(bug("Family name: %s\n", dat->Face->family_name));
277 ++tag;
279 tag->ti_Tag = OT_YSizeFactor;
280 tag->ti_Data = 1 | (1 << 16);
281 ++tag;
283 tag->ti_Tag = OT_SpaceWidth;
284 tag->ti_Data = dat->Face->max_advance_width * 250.0 / 72.307;
285 D(bug("Space width: %d\n", tag->ti_Data));
286 ++tag;
288 tag->ti_Tag = OT_IsFixed;
289 tag->ti_Data = FT_IS_FIXED_WIDTH(dat->Face);
290 D(bug("Fixed size: %d\n", tag->ti_Data));
291 ++tag;
293 tag->ti_Tag = OT_SerifFlag;
294 tag->ti_Data = os2 && (unsigned) (((os2->sFamilyClass >> 8) & 0xff) - 1) < 5;
295 D(bug("Serif: %d\n", tag->ti_Data));
296 ++tag;
298 /* use default for:
299 tag->ti_Tag = OT_StemWeight;
300 tag->ti_Tag = OT_SlantStyle;
301 tag->ti_Tag = OT_HorizStyle;
304 tag->ti_Tag = OT_SpaceFactor;
305 tag->ti_Data = 0x10000;
306 ++tag;
308 tag->ti_Tag = OT_InhibitAlgoStyle;
309 tag->ti_Data = FSF_UNDERLINED | FSF_BOLD;
310 ++tag;
312 tag->ti_Tag = OT_SpecCount;
313 tag->ti_Data = 4;
314 ++tag;
316 tag->ti_Tag = OT_Spec1_FontFile;
317 tag->ti_Data = (IPTR)dat->Filename;
318 ++tag;
320 /* use default for:
321 tag->ti_Tag = OT_Spec3_AFMFile;
322 tag->ti_Tag = OT_Spec4_Metric;
323 tag->ti_Tag = OT_Spec5_BBox;
326 /* TODO: CodePage
327 tag->ti_Tag = OT_Spec2_CodePage;
330 tag->ti_Tag = TAG_END;
332 dat->AvailSizes[0] = AROS_WORD2BE(2); // <- number of entries...
333 dat->AvailSizes[1] = AROS_WORD2BE(10);
334 dat->AvailSizes[2] = AROS_WORD2BE(15);
336 if(args[ARG_FONTDIR] == 0)
338 fiWriteFiles(dat, basename, "FONTS:", sizeof(ULONG) + (tag - dat->OTags + 2) * sizeof(UQUAD));
340 else
342 fiWriteFiles(dat, basename, (STRPTR) args[ARG_FONTDIR], sizeof(ULONG) + (tag - dat->OTags + 2) * sizeof(UQUAD));
345 FT_Done_Face(dat->Face);
346 FreeVec(dat);
347 FT_Done_FreeType(ftlibrary);
349 return RETURN_OK;