/* Copyright 1996 Acorn Computers Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /************************************************************************/ /* � Acorn Computers Ltd, 1992. */ /* */ /* This file forms part of an unsupported source release of RISC_OSLib. */ /* */ /* It may be freely used to create executable images for saleable */ /* products but cannot be sold in source form or as an object library */ /* without the prior written consent of Acorn Computers Ltd. */ /* */ /* If this file is re-distributed (even if modified) it should retain */ /* this copyright notice. */ /* */ /************************************************************************/ /* * Title : c.font * Purpose: access to RISC OS font facilities * History: IDJ: 06-Feb-92: prepared for source release */ #include <stddef.h> #include <stdlib.h> #include <string.h> #include "os.h" #include "trace.h" #include "msgs.h" #include "wimp.h" #include "font.h" #include "VerIntern/messages.h" /* F O N T S W I 's */ #define CacheAddr 0x40080 #define FindFont 0x40081 #define LoseFont 0x40082 #define ReadDefn 0x40083 #define ReadInfo 0x40084 #define StringWidth 0x40085 #define Paint 0x40086 #define Caret 0x40087 #define ConverttoOS 0x40088 #define Converttopoints 0x40089 #define SetFont 0x4008A #define CurrentFont 0x4008B #define FutureFont 0x4008C #define FindCaret 0x4008D #define CharBBox 0x4008E #define ReadScaleFactor 0x4008F #define SetScaleFactor 0x40090 #define ListFonts 0x40091 #define SetFontColours 0x40092 #define SetPalette 0x40093 #define ReadThresholds 0x40094 #define SetThresholds 0x40095 #define FindCaretJ 0x40096 #define StringBBox 0x40097 #define ReadColourTable 0x40098 #define MakeBitmap 0x40099 #define UnCacheFile 0x4009A #define SetFontMax 0x4009B #define ReadFontMax 0x4009C #define ReadFontPrefix 0x4009D #define SwitchOutputToBuffer 0x4009E #define ReadFontMetrics 0x4009F #define DecodeMenu 0x400A0 #define ScanString 0x400A1 #define SetColourTable 0x400A2 #pragma -s1 #ifndef UROM os_error *font_cacheaddress(int *version, int *cacheused, int *cachesize) { os_regset r; os_error *e; r.r[0] = 0; e = os_swix(CacheAddr, &r); if (!e) { *version = r.r[0]; *cacheused = r.r[1]; *cachesize = r.r[2]; } return e; } #endif os_error *font_find(char *name, int xsize, int ysize, int xres, int yres, font *fontadd) { os_regset r; os_error *e; r.r[1] = (int)name; r.r[2] = xsize; r.r[3] = ysize; r.r[4] = xres; r.r[5] = yres; e = os_swix(FindFont, &r); *fontadd = (font) r.r[0]; return e; } os_error *font_lose(font f) { os_regset r; os_error *e; r.r[0] = f; e = os_swix(LoseFont, &r); return e; } #ifndef UROM os_error * font_readdef(font f, font_def *d) { os_regset r; os_error *e; r.r[0] = (int)f; r.r[1] = (int)&d->name; e = os_swix(ReadDefn, &r); d->xsize = r.r[2]; d->ysize = r.r[3]; d->xres = r.r[4]; d->yres = r.r[5]; d->usage = r.r[6]; d->age = r.r[7]; return(e); } #endif os_error *font_readinfo(font f, font_info *i) { os_regset r; os_error *e; r.r[0] = f; e = os_swix(ReadInfo, &r); i->minx = r.r[1]; i->miny = r.r[2]; i->maxx = r.r[3]; i->maxy = r.r[4]; return e; } os_error *font_strwidth(font_string *fs) { os_regset r; os_error *e; r.r[1] = (int)fs->s; r.r[2] = fs->x; r.r[3] = fs->y; r.r[4] = fs->split; r.r[5] = fs->term; e = os_swix(StringWidth, &r); fs->x = r.r[2]; fs->y = r.r[3]; fs->split = r.r[4]; fs->term = r.r[5]; return e; } os_error *font_paint(char *s, int options, int x, int y) { os_regset r; os_error *e; r.r[1] = (int)s; r.r[2] = options; r.r[3] = x; r.r[4] = y; e = os_swix(Paint, &r); return e; } #ifndef UROM os_error *font_caret(int colour, int height, int flags, int x, int y) { os_regset r; os_error *e; r.r[0] = colour; r.r[1] = height; r.r[2] = flags; r.r[3] = x; r.r[4] = y; e = os_swix(Caret, &r); return e; } #endif os_error *font_converttoos(int x_inch, int y_inch, int *x_os, int *y_os) { os_regset r; os_error *e; r.r[1] = x_inch; r.r[2] = y_inch; e = os_swix(ConverttoOS, &r); *x_os = r.r[1]; *y_os = r.r[2]; return e; } #ifndef UROM os_error *font_converttopoints(int x_os, int y_os, int *x_inch, int *y_inch) { os_regset r; os_error *e; r.r[1] = x_os; r.r[2] = y_os; e = os_swix(Converttopoints, &r); *x_inch = r.r[1]; *y_inch = r.r[2]; return e; } #endif os_error *font_setfont(font f) { os_regset r; os_error *e; r.r[0] = f; e = os_swix(SetFont, &r); return(e); } #ifndef UROM os_error *font_current(font_state *f) { os_regset r; os_error *e; e = os_swix(CurrentFont, &r); f->f = r.r[0]; f->back_colour = r.r[1]; f->fore_colour = r.r[2]; f->offset = r.r[3]; return(e); } #endif #ifndef UROM os_error *font_future(font_state *f) { os_regset r; os_error *e; e = os_swix(FutureFont, &r); f->f = r.r[0]; f->back_colour = r.r[1]; f->fore_colour = r.r[2]; f->offset = r.r[3]; return(e); } #endif os_error *font_findcaret(font_string *fs) { os_regset r; os_error *e; r.r[1] = (int)fs->s; r.r[2] = fs->x; r.r[3] = fs->y; e = os_swix(FindCaret, &r); fs->x = r.r[2]; fs->y = r.r[3]; fs->split = r.r[4]; fs->term = r.r[5]; return e; } os_error *font_charbbox(font f, char ch, int options, font_info *i) { os_regset r; os_error *e; r.r[0] = f; r.r[1] = ch; r.r[2] = options; e = os_swix(CharBBox, &r); i->minx = r.r[1]; i->miny = r.r[2]; i->maxx = r.r[3]; i->maxy = r.r[4]; return e; } #ifndef UROM os_error *font_readscalefactor(int *x, int *y) { os_regset r; os_error *e; e = os_swix(ReadScaleFactor, &r); *x = r.r[1]; *y = r.r[2]; return e; } #endif #ifndef UROM os_error *font_setscalefactor(int x, int y) { os_regset r; os_error *e; r.r[1] = x; r.r[2] = y; e = os_swix(SetScaleFactor, &r); return e; } #endif #ifndef UROM os_error *font_list(char *a, int *count) { os_regset r; os_error *e; int i; r.r[1] = (int)a; r.r[2] = *count; r.r[3] = -1; e = os_swix(ListFonts, &r); if (!e) { *count = r.r[2]; i = 0; while (a[i] >= 32 && i <= 99) ++i; a[i] = 0; } else /* error return: probably some filing system error */ *count = -1; /* signal end of list */ return e; } #endif os_error *font_setcolour(font f, int background, int foreground, int offset) { os_regset r; os_error *e; r.r[0] = f; r.r[1] = background; r.r[2] = foreground; r.r[3] = offset; e = os_swix(SetFontColours, &r); return e; } #ifndef UROM os_error *font_setpalette(int background, int foreground, int offset, int physical_back, int physical_fore) { os_regset r; os_error *e; r.r[1] = background; r.r[2] = foreground; r.r[3] = offset; r.r[4] = physical_back; r.r[5] = physical_fore; e = os_swix(SetPalette, &r); return e; } #endif #ifndef UROM os_error *font_readthresholds(font_threshold *th) { os_regset r; os_error *e; r.r[1] = (int)th; e = os_swix(ReadThresholds, &r); return e; } #endif #ifndef UROM os_error *font_setthresholds(font_threshold *th) { os_regset r; os_error *e; r.r[1] = (int)th; e = os_swix(SetThresholds, &r); return e; } #endif #ifndef UROM os_error *font_findcaretj(font_string *fs, int offset_x, int offset_y) { os_regset r; os_error *e; r.r[1] = (int)fs->s; r.r[2] = fs->x; r.r[3] = fs->y; r.r[4] = offset_x; r.r[5] = offset_y; e = os_swix(FindCaretJ, &r); fs->x = r.r[2]; fs->y = r.r[3]; fs->split = r.r[4]; fs->term = r.r[5]; return e; } #endif os_error *font_stringbbox(char *s, font_info *fi) { os_regset r; os_error *e; r.r[1] = (int)s; e = os_swix(StringBBox, &r); fi->minx = r.r[1]; fi->miny = r.r[2]; fi->maxx = r.r[3]; fi->maxy = r.r[4]; return e; } /*-----------------------------------------------------------------*/ /*Routines for conversion of fonts to Draw module path objects. See the documentation of SWI Font_SwitchOutputToBuffer.*/ os_error *font_output_to_null ( BOOL add_hints, BOOL output_skeleton, font_action_on_bitmap action_on_bitmap ) /*Redirects the output from font_paint to nowhere, in preparation for font_output_size.*/ { os_regset reg_set; os_error *error; tracef0 ("font_output_to_null\n"); reg_set.r [0] = 1 /*no output*/ + (add_hints? 1 << 1: 0) + (output_skeleton? 1 << 2: 0) + ( action_on_bitmap == font_ERROR? 1 << 4: action_on_bitmap == font_CONVERT? 1 << 3: 0 ); reg_set.r [1] = 8; if ((error = os_swix (SwitchOutputToBuffer, ®_set)) != NULL) return error; return NULL; } /*-----------------------------------------------------------------*/ os_error *font_output_size (size_t *size_ptr) /*Counts the size of the buffer that would have been written if the output had been to a buffer.*/ { os_regset reg_set; os_error *error; tracef0 ("font_output_size\n"); reg_set.r [0] = 0; reg_set.r [1] = -1; if ((error = os_swix (SwitchOutputToBuffer, ®_set)) != NULL) return error; *size_ptr = reg_set.r [1]; tracef1 ("font_output_size: made %d bytes of path\n", *size_ptr); return NULL; } /*-----------------------------------------------------------------*/ os_error *font_output_to_buffer ( drawmod_buffer *buff_ptr, BOOL add_hints, BOOL output_skeleton, font_action_on_bitmap action_on_bitmap ) /*Redirects the output to a buffer. A series of draw paths or groups is written.*/ { os_regset reg_set; os_error *error; tracef0 ("font_output_to_buffer\n"); reg_set.r [0] = (add_hints? 1 << 1: 0) + (output_skeleton? 1 << 2: 0) + ( action_on_bitmap == font_ERROR? 1 << 4: action_on_bitmap == font_CONVERT? 1 << 3: 0 ); reg_set.r [1] = (int) buff_ptr; tracef1 ("font_output_to_buffer: path going to 0x%p\n", buff_ptr); if ((error = os_swix (SwitchOutputToBuffer, ®_set)) != NULL) return error; return NULL; } /*-----------------------------------------------------------------*/ os_error *font_output_to_screen (void) /*Redirects the output to the screen.*/ { os_regset reg_set; os_error *error; tracef0 ("font_output_to_screen\n"); reg_set.r [0] = 0; reg_set.r [1] = 0; if ((error = os_swix (SwitchOutputToBuffer, ®_set)) != NULL) return error; return NULL; } #pragma -s0 /*-----------------------------------------------------------------*/ static os_error errbuff={0}; os_error *font_makemenu(wimp_menustr ** menup, char * tickitem, fontmenu_flags flags) { os_regset r; os_error *error; tracef3 ("font_makemenu: *menup=0x%p, tickitem=0x%p, flags=%d\n", *menup, tickitem, flags); switch(flags) { case fontmenu_WithoutSystemFont: r.r[2] = (1<<19) + (1<<21); break; case fontmenu_WithSystemFont: r.r[2] = (1<<19) + (1<<20) + (1<<21); break; case fontmenu_Delete: if (*menup) { free(*menup); *menup = NULL; } return NULL; default: errbuff.errnum = 1; strcpy(errbuff.errmess,msgs_lookup(MSGS_fontmenu1)); return(&errbuff); } r.r[1] = 0; /* return size of buffer in R3 */ r.r[4] = 0; /* return size of buffer in R5 */ r.r[6] = (int) tickitem; if ((error = os_swix (ListFonts, &r)) != NULL) return error; r.r[1] = (int) realloc(*menup,r.r[3] + r.r[5]); if (r.r[1]) { *menup = (wimp_menustr *)r.r[1]; } else { errbuff.errnum = 1; strcpy(errbuff.errmess,msgs_lookup(MSGS_fontmenu2)); return(&errbuff); } r.r[4] = r.r[1] + r.r[3]; error = os_swix (ListFonts, &r); if (r.r[3] && !error) { *menup = (void *)r.r[1]; } else { free(*menup); *menup = NULL; } return(error); } /*-----------------------------------------------------------------*/ extern os_error *font_decodemenu(wimp_menustr * menu, int * selections, char **resultp) { os_regset r; os_error *error; tracef3 ("font_decodemenu: menu=0x%p, selection[0]=%d, old buffer=0x%p\n", menu, selections[0], *resultp); r.r[0] = 0; r.r[1] = (int) menu; r.r[2] = (int) selections; r.r[3] = 0; if ((error = os_swix(DecodeMenu,&r)) != NULL) return error; r.r[0] = 0; r.r[1] = (int) menu; r.r[2] = (int) selections; r.r[3] = (int) realloc(*resultp, r.r[4]); if (r.r [4] == 0) { /*No selection made.*/ *resultp = NULL; return NULL; } if (r.r[3]) { *resultp = (char *)r.r[3]; } else { errbuff.errnum = 1; strcpy(errbuff.errmess,msgs_lookup(MSGS_fontmenu3)); return(&errbuff); } return(os_swix(DecodeMenu,&r)); }