psgeom.c revision 0e20ee16
10e20ee16Smrg/* $Xorg: psgeom.c,v 1.4 2000/08/17 19:54:50 cpqbld Exp $ */ 20e20ee16Smrg/************************************************************ 30e20ee16Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 40e20ee16Smrg 50e20ee16Smrg Permission to use, copy, modify, and distribute this 60e20ee16Smrg software and its documentation for any purpose and without 70e20ee16Smrg fee is hereby granted, provided that the above copyright 80e20ee16Smrg notice appear in all copies and that both that copyright 90e20ee16Smrg notice and this permission notice appear in supporting 100e20ee16Smrg documentation, and that the name of Silicon Graphics not be 110e20ee16Smrg used in advertising or publicity pertaining to distribution 120e20ee16Smrg of the software without specific prior written permission. 130e20ee16Smrg Silicon Graphics makes no representation about the suitability 140e20ee16Smrg of this software for any purpose. It is provided "as is" 150e20ee16Smrg without any express or implied warranty. 160e20ee16Smrg 170e20ee16Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 180e20ee16Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 190e20ee16Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 200e20ee16Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 210e20ee16Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 220e20ee16Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 230e20ee16Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 240e20ee16Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 250e20ee16Smrg 260e20ee16Smrg ********************************************************/ 270e20ee16Smrg/* $XFree86: xc/programs/xkbprint/psgeom.c,v 1.5 2001/07/25 15:05:25 dawes Exp $ */ 280e20ee16Smrg 290e20ee16Smrg#define XK_TECHNICAL 300e20ee16Smrg#define XK_PUBLISHING 310e20ee16Smrg#define XK_KATAKANA 320e20ee16Smrg#include <stdio.h> 330e20ee16Smrg#include <ctype.h> 340e20ee16Smrg#include <X11/X.h> 350e20ee16Smrg#include <X11/Xlib.h> 360e20ee16Smrg#include <X11/XKBlib.h> 370e20ee16Smrg#include <X11/extensions/XKBgeom.h> 380e20ee16Smrg#include <X11/extensions/XKM.h> 390e20ee16Smrg#include <X11/extensions/XKBfile.h> 400e20ee16Smrg#include <X11/keysym.h> 410e20ee16Smrg#include <X11/Xutil.h> 420e20ee16Smrg 430e20ee16Smrg#if defined(sgi) 440e20ee16Smrg#include <malloc.h> 450e20ee16Smrg#endif 460e20ee16Smrg 470e20ee16Smrg#define DEBUG_VAR_NOT_LOCAL 480e20ee16Smrg#define DEBUG_VAR debugFlags 490e20ee16Smrg#include <stdlib.h> 500e20ee16Smrg 510e20ee16Smrg#include "utils.h" 520e20ee16Smrg#include "xkbprint.h" 530e20ee16Smrg#include "isokeys.h" 540e20ee16Smrg 550e20ee16Smrg#define FONT_NONE -1 560e20ee16Smrg#define FONT_TEXT 0 570e20ee16Smrg#define FONT_LATIN1 1 580e20ee16Smrg#define FONT_SYMBOL 2 590e20ee16Smrg#define FONT_ISOCAPS 3 600e20ee16Smrg#define FONT_MOUSECAPS 4 610e20ee16Smrg 620e20ee16Smrgtypedef struct { 630e20ee16Smrg Display * dpy; 640e20ee16Smrg XkbDescPtr xkb; 650e20ee16Smrg XkbGeometryPtr geom; 660e20ee16Smrg int totalKB; 670e20ee16Smrg int kbPerPage; 680e20ee16Smrg int black; 690e20ee16Smrg int white; 700e20ee16Smrg int color; 710e20ee16Smrg int font; 720e20ee16Smrg int fontSize; 730e20ee16Smrg int nPages; 740e20ee16Smrg int x1,y1; 750e20ee16Smrg int x2,y2; 760e20ee16Smrg XKBPrintArgs * args; 770e20ee16Smrg} PSState; 780e20ee16Smrg 790e20ee16Smrg#define G1L1 0 800e20ee16Smrg#define G1L2 1 810e20ee16Smrg#define G2L1 2 820e20ee16Smrg#define G2L2 3 830e20ee16Smrg#define CENTER 4 840e20ee16Smrg 850e20ee16Smrg#define G1L1_MASK (1<<G1L1) 860e20ee16Smrg#define G1L2_MASK (1<<G1L2) 870e20ee16Smrg#define G2L1_MASK (1<<G2L1) 880e20ee16Smrg#define G2L2_MASK (1<<G2L2) 890e20ee16Smrg#define CENTER_MASK (1<<CENTER) 900e20ee16Smrg 910e20ee16Smrg#define LABEL_MASK (0x1f) 920e20ee16Smrg#define GXL1_MASK (G1L1_MASK|G2L1_MASK) 930e20ee16Smrg#define GXL2_MASK (G1L2_MASK|G2L2_MASK) 940e20ee16Smrg#define G1LX_MASK (G1L1_MASK|G1L2_MASK) 950e20ee16Smrg#define G2LX_MASK (G2L1_MASK|G2L2_MASK) 960e20ee16Smrg#define GXLX_MASK (0x0f) 970e20ee16Smrg 980e20ee16Smrg#define NLABELS 5 990e20ee16Smrg#define LABEL_LEN 30 1000e20ee16Smrg 1010e20ee16Smrg#define SZ_AUTO 0 1020e20ee16Smrg#define SZ_TINY 1 1030e20ee16Smrg#define SZ_SMALL 2 1040e20ee16Smrg#define SZ_MEDIUM 3 1050e20ee16Smrg#define SZ_LARGE 4 1060e20ee16Smrg#define SZ_XLARGE 5 1070e20ee16Smrg 1080e20ee16Smrgtypedef struct { 1090e20ee16Smrg unsigned present; 1100e20ee16Smrg Bool alpha[2]; 1110e20ee16Smrg char label[NLABELS][LABEL_LEN]; 1120e20ee16Smrg int font[NLABELS]; 1130e20ee16Smrg int size[NLABELS]; 1140e20ee16Smrg} KeyTop; 1150e20ee16Smrg 1160e20ee16Smrg#define DFLT_LABEL_FONT "Helvetica-Narrow-Bold" 1170e20ee16Smrg#define DFLT_LABEL_FONT_SIZE 10 1180e20ee16Smrg 1190e20ee16Smrg/***====================================================================***/ 1200e20ee16Smrg 1210e20ee16Smrgtypedef struct _PSFontDef { 1220e20ee16Smrg char *name; 1230e20ee16Smrg char **def; 1240e20ee16Smrg} PSFontDef; 1250e20ee16Smrg 1260e20ee16Smrgstatic PSFontDef internalFonts[] = { 1270e20ee16Smrg { "IsoKeyCaps", IsoKeyCaps } 1280e20ee16Smrg}; 1290e20ee16Smrgstatic int nInternalFonts = (sizeof(internalFonts)/sizeof(PSFontDef)); 1300e20ee16Smrg 1310e20ee16Smrgstatic void 1320e20ee16SmrgListInternalFonts(FILE *out, int first, int indent) 1330e20ee16Smrg{ 1340e20ee16Smrgregister int i,n,nThisLine; 1350e20ee16Smrg 1360e20ee16Smrg for (n=0;n<first;n++) { 1370e20ee16Smrg putc(' ',out); 1380e20ee16Smrg } 1390e20ee16Smrg 1400e20ee16Smrg for (nThisLine=i=0;i<nInternalFonts;i++) { 1410e20ee16Smrg if (nThisLine==4) { 1420e20ee16Smrg fprintf(out,",\n"); 1430e20ee16Smrg for (n=0;n<indent;n++) { 1440e20ee16Smrg putc(' ',out); 1450e20ee16Smrg } 1460e20ee16Smrg nThisLine= 0; 1470e20ee16Smrg } 1480e20ee16Smrg if (nThisLine==0) 1490e20ee16Smrg fprintf(out,"%s",internalFonts[i].name); 1500e20ee16Smrg else fprintf(out,", %s",internalFonts[i].name); 1510e20ee16Smrg nThisLine++; 1520e20ee16Smrg } 1530e20ee16Smrg if (nThisLine!=0) 1540e20ee16Smrg fprintf(out,"\n"); 1550e20ee16Smrg return; 1560e20ee16Smrg} 1570e20ee16Smrg 1580e20ee16Smrgstatic Bool 1590e20ee16SmrgPSIncludeFont(FILE *out, char *font) 1600e20ee16Smrg{ 1610e20ee16Smrgchar ** pstr; 1620e20ee16Smrgregister int i; 1630e20ee16Smrg 1640e20ee16Smrg pstr= NULL; 1650e20ee16Smrg for (i=0;(i<nInternalFonts)&&(pstr==NULL);i++) { 1660e20ee16Smrg if (uStringEqual(internalFonts[i].name,font)) 1670e20ee16Smrg pstr= internalFonts[i].def; 1680e20ee16Smrg } 1690e20ee16Smrg if (pstr!=NULL) { 1700e20ee16Smrg fprintf(out,"%%%%BeginFont: %s\n",font); 1710e20ee16Smrg while (*pstr!=NULL) { 1720e20ee16Smrg fprintf(out,"%s\n",*pstr); 1730e20ee16Smrg pstr++; 1740e20ee16Smrg } 1750e20ee16Smrg fprintf(out,"%%%%EndFont\n"); 1760e20ee16Smrg return True; 1770e20ee16Smrg } 1780e20ee16Smrg return False; 1790e20ee16Smrg} 1800e20ee16Smrg 1810e20ee16SmrgBool 1820e20ee16SmrgDumpInternalFont(FILE *out, char *fontName) 1830e20ee16Smrg{ 1840e20ee16Smrg if (strcmp(fontName,"IsoKeyCaps")!=0) { 1850e20ee16Smrg uError("No internal font named \"%s\"\n",fontName); 1860e20ee16Smrg uAction("No font dumped\n"); 1870e20ee16Smrg fprintf(stderr,"Current internal fonts are: "); 1880e20ee16Smrg ListInternalFonts(stderr,0,8); 1890e20ee16Smrg return False; 1900e20ee16Smrg } 1910e20ee16Smrg PSIncludeFont(out,fontName); 1920e20ee16Smrg return True; 1930e20ee16Smrg} 1940e20ee16Smrg 1950e20ee16Smrg/***====================================================================***/ 1960e20ee16Smrg 1970e20ee16Smrgstatic void 1980e20ee16SmrgPSColorDef(FILE *out, PSState *state, XkbColorPtr color) 1990e20ee16Smrg{ 2000e20ee16Smrgint tmp; 2010e20ee16Smrg 2020e20ee16Smrg fprintf(out,"/C%03d ",color->pixel); 2030e20ee16Smrg if (uStrCaseEqual(color->spec,"black")) { 2040e20ee16Smrg state->black= color->pixel; 2050e20ee16Smrg fprintf(out,"{ 0 setgray } def %% %s\n",color->spec); 2060e20ee16Smrg } 2070e20ee16Smrg else if (uStrCaseEqual(color->spec,"white")) { 2080e20ee16Smrg state->white= color->pixel; 2090e20ee16Smrg fprintf(out,"{ 1 setgray } def %% %s\n",color->spec); 2100e20ee16Smrg } 2110e20ee16Smrg else if ((sscanf(color->spec,"grey%d",&tmp)==1)|| 2120e20ee16Smrg (sscanf(color->spec,"gray%d",&tmp)==1)|| 2130e20ee16Smrg (sscanf(color->spec,"Grey%d",&tmp)==1)|| 2140e20ee16Smrg (sscanf(color->spec,"Gray%d",&tmp)==1)) { 2150e20ee16Smrg fprintf(out,"{ %f setgray } def %% %s\n",1.0-(((float)tmp)/100.0), 2160e20ee16Smrg color->spec); 2170e20ee16Smrg } 2180e20ee16Smrg else if ((tmp=(uStrCaseEqual(color->spec,"red")*100))|| 2190e20ee16Smrg (sscanf(color->spec,"red%d",&tmp)==1)) { 2200e20ee16Smrg fprintf(out,"{ %f 0 0 setrgbcolor } def %% %s\n",(((float)tmp)/100.0), 2210e20ee16Smrg color->spec); 2220e20ee16Smrg } 2230e20ee16Smrg else if ((tmp=(uStrCaseEqual(color->spec,"green")*100))|| 2240e20ee16Smrg (sscanf(color->spec,"green%d",&tmp)==1)) { 2250e20ee16Smrg fprintf(out,"{ 0 %f 0 setrgbcolor } def %% %s\n",(((float)tmp)/100.0), 2260e20ee16Smrg color->spec); 2270e20ee16Smrg } 2280e20ee16Smrg else if ((tmp=(uStrCaseEqual(color->spec,"blue")*100))|| 2290e20ee16Smrg (sscanf(color->spec,"blue%d",&tmp)==1)) { 2300e20ee16Smrg fprintf(out,"{ 0 0 %f setrgbcolor } def %% %s\n",(((float)tmp)/100.0), 2310e20ee16Smrg color->spec); 2320e20ee16Smrg } 2330e20ee16Smrg else fprintf(out,"{ 0.9 setgray } def %% BOGUS! %s\n",color->spec); 2340e20ee16Smrg} 2350e20ee16Smrg 2360e20ee16Smrgstatic void 2370e20ee16SmrgPSSetColor(FILE *out,PSState *state,int color) 2380e20ee16Smrg{ 2390e20ee16Smrg if ((state->args->wantColor)&&(state->color!=color)) { 2400e20ee16Smrg fprintf(out,"C%03d %% set color\n",color); 2410e20ee16Smrg state->color= color; 2420e20ee16Smrg } 2430e20ee16Smrg return; 2440e20ee16Smrg} 2450e20ee16Smrg 2460e20ee16Smrgstatic void 2470e20ee16SmrgPSGSave(FILE *out, PSState *state) 2480e20ee16Smrg{ 2490e20ee16Smrg fprintf(out,"gsave\n"); 2500e20ee16Smrg return; 2510e20ee16Smrg} 2520e20ee16Smrg 2530e20ee16Smrgstatic void 2540e20ee16SmrgPSGRestore(FILE *out, PSState *state) 2550e20ee16Smrg{ 2560e20ee16Smrg fprintf(out,"grestore\n"); 2570e20ee16Smrg state->color= -1; 2580e20ee16Smrg state->font= FONT_NONE; 2590e20ee16Smrg state->fontSize= -1; 2600e20ee16Smrg return; 2610e20ee16Smrg} 2620e20ee16Smrg 2630e20ee16Smrgstatic void 2640e20ee16SmrgPSShapeDef(FILE *out, PSState *state, XkbShapePtr shape) 2650e20ee16Smrg{ 2660e20ee16Smrgint o,p; 2670e20ee16SmrgXkbOutlinePtr ol; 2680e20ee16Smrg 2690e20ee16Smrg fprintf(out,"/%s {\n",XkbAtomGetString(state->dpy,shape->name)); 2700e20ee16Smrg fprintf(out," gsave translate rotate /SOLID exch def\n"); 2710e20ee16Smrg for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) { 2720e20ee16Smrg XkbPointPtr pt; 2730e20ee16Smrg if ((shape->num_outlines>1)&&(ol==shape->approx)) 2740e20ee16Smrg continue; 2750e20ee16Smrg pt=ol->points; 2760e20ee16Smrg fprintf(out,"%% Outline %d\n",o+1); 2770e20ee16Smrg if (ol->num_points==1) { 2780e20ee16Smrg if (ol->corner_radius<1) { 2790e20ee16Smrg fprintf(out," 0 0 moveto\n"); 2800e20ee16Smrg fprintf(out," %3d 0 lineto\n",pt->x); 2810e20ee16Smrg fprintf(out," %3d %3d lineto\n",pt->x,pt->y); 2820e20ee16Smrg fprintf(out," 0 %3d lineto\n",pt->y); 2830e20ee16Smrg fprintf(out," 0 0 lineto\n"); 2840e20ee16Smrg fprintf(out," SOLID { fill } { stroke } ifelse\n"); 2850e20ee16Smrg } 2860e20ee16Smrg else { 2870e20ee16Smrg fprintf(out," mark\n"); 2880e20ee16Smrg fprintf(out," %3d 0 moveto\n",ol->corner_radius); 2890e20ee16Smrg fprintf(out," %3d 0 %3d %3d %3d arcto\n",pt->x,pt->x,pt->y, 2900e20ee16Smrg ol->corner_radius); 2910e20ee16Smrg fprintf(out," %3d %3d 0 %3d %3d arcto\n",pt->x,pt->y,pt->y, 2920e20ee16Smrg ol->corner_radius); 2930e20ee16Smrg fprintf(out," 0 %3d 0 0 %3d arcto\n",pt->y, 2940e20ee16Smrg ol->corner_radius); 2950e20ee16Smrg fprintf(out," 0 0 %3d 0 %3d arcto\n",pt->x, 2960e20ee16Smrg ol->corner_radius); 2970e20ee16Smrg fprintf(out," SOLID { fill } { stroke } ifelse\n"); 2980e20ee16Smrg fprintf(out," cleartomark\n"); 2990e20ee16Smrg } 3000e20ee16Smrg } 3010e20ee16Smrg else if (ol->num_points==2) { 3020e20ee16Smrg if (ol->corner_radius<1) { 3030e20ee16Smrg fprintf(out," %3d %3d moveto\n",pt[0].x,pt[0].y); 3040e20ee16Smrg fprintf(out," %3d %3d lineto\n",pt[1].x,pt[0].y); 3050e20ee16Smrg fprintf(out," %3d %3d lineto\n",pt[1].x,pt[1].y); 3060e20ee16Smrg fprintf(out," %3d %3d lineto\n",pt[0].x,pt[1].y); 3070e20ee16Smrg fprintf(out," %3d %3d lineto\n",pt[0].x,pt[0].y); 3080e20ee16Smrg fprintf(out," SOLID { fill } { stroke } ifelse\n"); 3090e20ee16Smrg } 3100e20ee16Smrg else { 3110e20ee16Smrg fprintf(out," mark\n"); 3120e20ee16Smrg fprintf(out," %3d %3d moveto\n",pt[0].x,pt[0].y); 3130e20ee16Smrg fprintf(out," %3d %3d %3d %3d %3d arcto\n",pt[1].x,pt[0].y, 3140e20ee16Smrg pt[1].x,pt[1].y, 3150e20ee16Smrg ol->corner_radius); 3160e20ee16Smrg fprintf(out," %3d %3d %3d %3d %3d arcto\n",pt[1].x,pt[1].y, 3170e20ee16Smrg pt[0].x,pt[1].y, 3180e20ee16Smrg ol->corner_radius); 3190e20ee16Smrg fprintf(out," %3d %3d %3d %3d %3d arcto\n",pt[0].x,pt[1].y, 3200e20ee16Smrg pt[0].x,pt[0].y, 3210e20ee16Smrg ol->corner_radius); 3220e20ee16Smrg fprintf(out," %3d %3d %3d %3d %3d arcto\n",pt[0].x,pt[0].y, 3230e20ee16Smrg pt[1].x,pt[0].y, 3240e20ee16Smrg ol->corner_radius); 3250e20ee16Smrg fprintf(out," SOLID { fill } { stroke } ifelse\n"); 3260e20ee16Smrg fprintf(out," cleartomark\n"); 3270e20ee16Smrg } 3280e20ee16Smrg } 3290e20ee16Smrg else { 3300e20ee16Smrg if (ol->corner_radius<1) { 3310e20ee16Smrg fprintf(out," %3d %3d moveto\n",pt->x,pt->y); 3320e20ee16Smrg pt++; 3330e20ee16Smrg for (p=1;p<ol->num_points;p++,pt++) { 3340e20ee16Smrg fprintf(out," %3d %3d lineto\n",pt->x,pt->y); 3350e20ee16Smrg } 3360e20ee16Smrg if ((pt->x!=ol->points[0].x)||(pt->y!=ol->points[0].y)) 3370e20ee16Smrg fprintf(out," closepath\n"); 3380e20ee16Smrg fprintf(out," SOLID { fill } { stroke } ifelse\n"); 3390e20ee16Smrg } 3400e20ee16Smrg else { 3410e20ee16Smrg XkbPointPtr last; 3420e20ee16Smrg last= &pt[ol->num_points-1]; 3430e20ee16Smrg if ((last->x==pt->x)&&(last->y==pt->y)) 3440e20ee16Smrg last--; 3450e20ee16Smrg fprintf(out," mark\n"); 3460e20ee16Smrg fprintf(out," %% Determine tangent point of first corner\n"); 3470e20ee16Smrg fprintf(out," %3d %3d moveto %d %d %d %d %d arcto\n", 3480e20ee16Smrg last->x,last->y, 3490e20ee16Smrg pt[0].x,pt[0].y,pt[1].x,pt[1].y, 3500e20ee16Smrg ol->corner_radius); 3510e20ee16Smrg fprintf(out," /TY exch def /TX exch def pop pop newpath\n"); 3520e20ee16Smrg fprintf(out," %% Now draw the shape\n"); 3530e20ee16Smrg fprintf(out," TX TY moveto\n"); 3540e20ee16Smrg for (p=1;p<ol->num_points;p++) { 3550e20ee16Smrg if (p<(ol->num_points-1)) last= &pt[p+1]; 3560e20ee16Smrg else last= &pt[0]; 3570e20ee16Smrg fprintf(out," %3d %3d %3d %3d %3d arcto\n", 3580e20ee16Smrg pt[p].x,pt[p].y, 3590e20ee16Smrg last->x,last->y, 3600e20ee16Smrg ol->corner_radius); 3610e20ee16Smrg } 3620e20ee16Smrg last= &pt[ol->num_points-1]; 3630e20ee16Smrg if ((last->x!=pt->x)||(last->y!=pt->y)) { 3640e20ee16Smrg fprintf(out," %3d %3d %3d %3d %3d arcto\n", 3650e20ee16Smrg pt[0].x,pt[0].y, 3660e20ee16Smrg pt[1].x,pt[1].y, 3670e20ee16Smrg ol->corner_radius); 3680e20ee16Smrg } 3690e20ee16Smrg fprintf(out," SOLID { fill } { stroke } ifelse\n"); 3700e20ee16Smrg fprintf(out," cleartomark\n"); 3710e20ee16Smrg } 3720e20ee16Smrg } 3730e20ee16Smrg } 3740e20ee16Smrg fprintf(out," grestore\n"); 3750e20ee16Smrg fprintf(out,"} def\n"); 3760e20ee16Smrg return; 3770e20ee16Smrg} 3780e20ee16Smrg 3790e20ee16Smrg/***====================================================================***/ 3800e20ee16Smrg 3810e20ee16Smrgtypedef struct { 3820e20ee16Smrg char * foundry; 3830e20ee16Smrg char * face; 3840e20ee16Smrg char * weight; 3850e20ee16Smrg char * slant; 3860e20ee16Smrg char * setWidth; 3870e20ee16Smrg char * variant; 3880e20ee16Smrg int pixelSize; 3890e20ee16Smrg int ptSize; 3900e20ee16Smrg int resX; 3910e20ee16Smrg int resY; 3920e20ee16Smrg char * spacing; 3930e20ee16Smrg int avgWidth; 3940e20ee16Smrg char * encoding; 3950e20ee16Smrg} FontStuff; 3960e20ee16Smrg 3970e20ee16Smrgstatic void 3980e20ee16SmrgClearFontStuff(FontStuff *stuff) 3990e20ee16Smrg{ 4000e20ee16Smrg if (stuff && stuff->foundry) 4010e20ee16Smrg uFree(stuff->foundry); 4020e20ee16Smrg bzero(stuff,sizeof(FontStuff)); 4030e20ee16Smrg return; 4040e20ee16Smrg} 4050e20ee16Smrg 4060e20ee16Smrgstatic Bool 4070e20ee16SmrgCrackXLFDName(char *name, FontStuff *stuff) 4080e20ee16Smrg{ 4090e20ee16Smrgchar *tmp; 4100e20ee16Smrg if ((name==NULL)||(stuff==NULL)) 4110e20ee16Smrg return False; 4120e20ee16Smrg if (name[0]=='-') tmp= uStringDup(&name[1]); 4130e20ee16Smrg else tmp= uStringDup(name); 4140e20ee16Smrg if (tmp==NULL) 4150e20ee16Smrg return False; 4160e20ee16Smrg stuff->foundry= tmp; 4170e20ee16Smrg 4180e20ee16Smrg if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 4190e20ee16Smrg else *tmp++= '\0'; 4200e20ee16Smrg stuff->face= tmp; 4210e20ee16Smrg 4220e20ee16Smrg if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 4230e20ee16Smrg else *tmp++= '\0'; 4240e20ee16Smrg stuff->weight= tmp; 4250e20ee16Smrg 4260e20ee16Smrg if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 4270e20ee16Smrg else *tmp++= '\0'; 4280e20ee16Smrg stuff->slant= tmp; 4290e20ee16Smrg 4300e20ee16Smrg if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 4310e20ee16Smrg else *tmp++= '\0'; 4320e20ee16Smrg stuff->setWidth= tmp; 4330e20ee16Smrg 4340e20ee16Smrg if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 4350e20ee16Smrg else *tmp++= '\0'; 4360e20ee16Smrg stuff->variant= tmp; 4370e20ee16Smrg 4380e20ee16Smrg if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 4390e20ee16Smrg else *tmp++= '\0'; 4400e20ee16Smrg if (*tmp=='*') stuff->pixelSize= 0; 4410e20ee16Smrg else if (sscanf(tmp,"%i",&stuff->pixelSize)!=1) goto BAILOUT; 4420e20ee16Smrg 4430e20ee16Smrg if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 4440e20ee16Smrg else *tmp++= '\0'; 4450e20ee16Smrg if (*tmp=='*') stuff->ptSize= 0; 4460e20ee16Smrg else if (sscanf(tmp,"%i",&stuff->ptSize)!=1) goto BAILOUT; 4470e20ee16Smrg 4480e20ee16Smrg if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 4490e20ee16Smrg else *tmp++= '\0'; 4500e20ee16Smrg if (*tmp=='*') stuff->resX= 0; 4510e20ee16Smrg else if (sscanf(tmp,"%i",&stuff->resX)!=1) goto BAILOUT; 4520e20ee16Smrg 4530e20ee16Smrg if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 4540e20ee16Smrg else *tmp++= '\0'; 4550e20ee16Smrg if (*tmp=='*') stuff->resY= 0; 4560e20ee16Smrg else if (sscanf(tmp,"%i",&stuff->resY)!=1) goto BAILOUT; 4570e20ee16Smrg 4580e20ee16Smrg if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 4590e20ee16Smrg else *tmp++= '\0'; 4600e20ee16Smrg stuff->spacing= tmp; 4610e20ee16Smrg 4620e20ee16Smrg if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 4630e20ee16Smrg else *tmp++= '\0'; 4640e20ee16Smrg if (*tmp=='*') stuff->avgWidth= 0; 4650e20ee16Smrg else if (sscanf(tmp,"%i",&stuff->avgWidth)!=1) goto BAILOUT; 4660e20ee16Smrg 4670e20ee16Smrg if ((tmp= index(tmp,'-'))==NULL) goto BAILOUT; 4680e20ee16Smrg else *tmp++= '\0'; 4690e20ee16Smrg stuff->encoding= tmp; 4700e20ee16Smrg return True; 4710e20ee16SmrgBAILOUT: 4720e20ee16Smrg ClearFontStuff(stuff); 4730e20ee16Smrg return False; 4740e20ee16Smrg} 4750e20ee16Smrg 4760e20ee16Smrgstatic void 4770e20ee16SmrgPSSetUpForLatin1(FILE *out, PSState *state) 4780e20ee16Smrg{ 4790e20ee16Smrg fprintf(out,"save\n"); 4800e20ee16Smrg fprintf(out,"/ISOLatin1Encoding where {pop save true}{false} ifelse\n"); 4810e20ee16Smrg fprintf(out,"/ISOLatin1Encoding [\n"); 4820e20ee16Smrg fprintf(out," /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"); 4830e20ee16Smrg fprintf(out," /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"); 4840e20ee16Smrg fprintf(out," /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"); 4850e20ee16Smrg fprintf(out," /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"); 4860e20ee16Smrg fprintf(out," /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"); 4870e20ee16Smrg fprintf(out," /.notdef /.notdef /space /exclam /quotedbl /numbersign\n"); 4880e20ee16Smrg fprintf(out," /dollar /percent /ampersand /quoteright /parenleft\n"); 4890e20ee16Smrg fprintf(out," /parenright /asterisk /plus /comma /minus /period\n"); 4900e20ee16Smrg fprintf(out," /slash /zero /one /two /three /four /five /six /seven\n"); 4910e20ee16Smrg fprintf(out," /eight /nine /colon /semicolon /less /equal /greater\n"); 4920e20ee16Smrg fprintf(out," /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M\n"); 4930e20ee16Smrg fprintf(out," /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft\n"); 4940e20ee16Smrg fprintf(out," /backslash /bracketright /asciicircum /underscore\n"); 4950e20ee16Smrg fprintf(out," /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m\n"); 4960e20ee16Smrg fprintf(out," /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft\n"); 4970e20ee16Smrg fprintf(out," /bar /braceright /asciitilde /guilsinglright /fraction\n"); 4980e20ee16Smrg fprintf(out," /florin /quotesingle /quotedblleft /guilsinglleft /fi\n"); 4990e20ee16Smrg fprintf(out," /fl /endash /dagger /daggerdbl /bullet /quotesinglbase\n"); 5000e20ee16Smrg fprintf(out," /quotedblbase /quotedblright /ellipsis /trademark\n"); 5010e20ee16Smrg fprintf(out," /perthousand /grave /scaron /circumflex /Scaron /tilde\n"); 5020e20ee16Smrg fprintf(out," /breve /zcaron /dotaccent /dotlessi /Zcaron /ring\n"); 5030e20ee16Smrg fprintf(out," /hungarumlaut /ogonek /caron /emdash /space /exclamdown\n"); 5040e20ee16Smrg fprintf(out," /cent /sterling /currency /yen /brokenbar /section\n"); 5050e20ee16Smrg fprintf(out," /dieresis /copyright /ordfeminine /guillemotleft\n"); 5060e20ee16Smrg fprintf(out," /logicalnot /hyphen /registered /macron /degree\n"); 5070e20ee16Smrg fprintf(out," /plusminus /twosuperior /threesuperior /acute /mu\n"); 5080e20ee16Smrg fprintf(out," /paragraph /periodcentered /cedilla /onesuperior\n"); 5090e20ee16Smrg fprintf(out," /ordmasculine /guillemotright /onequarter /onehalf\n"); 5100e20ee16Smrg fprintf(out," /threequarters /questiondown /Agrave /Aacute\n"); 5110e20ee16Smrg fprintf(out," /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n"); 5120e20ee16Smrg fprintf(out," /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute\n"); 5130e20ee16Smrg fprintf(out," /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute\n"); 5140e20ee16Smrg fprintf(out," /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n"); 5150e20ee16Smrg fprintf(out," /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n"); 5160e20ee16Smrg fprintf(out," /germandbls /agrave /aacute /acircumflex /atilde\n"); 5170e20ee16Smrg fprintf(out," /adieresis /aring /ae /ccedilla /egrave /eacute\n"); 5180e20ee16Smrg fprintf(out," /ecircumflex /edieresis /igrave /iacute /icircumflex\n"); 5190e20ee16Smrg fprintf(out," /idieresis /eth /ntilde /ograve /oacute /ocircumflex\n"); 5200e20ee16Smrg fprintf(out," /otilde /odieresis /divide /oslash /ugrave /uacute\n"); 5210e20ee16Smrg fprintf(out," /ucircumflex /udieresis /yacute /thorn /ydieresis\n"); 5220e20ee16Smrg fprintf(out,"] def {restore} if\n"); 5230e20ee16Smrg fprintf(out,"/reencodeISO-1 {\n"); 5240e20ee16Smrg fprintf(out," dup length dict begin\n"); 5250e20ee16Smrg fprintf(out," {1 index /FID ne {def}{pop pop} ifelse} forall\n"); 5260e20ee16Smrg fprintf(out," /Encoding ISOLatin1Encoding def\n"); 5270e20ee16Smrg fprintf(out," currentdict\n"); 5280e20ee16Smrg fprintf(out," end\n"); 5290e20ee16Smrg fprintf(out,"} def\n"); 5300e20ee16Smrg} 5310e20ee16Smrg 5320e20ee16Smrgstatic void 5330e20ee16SmrgPSReencodeLatin1Font(FILE *out, char *font) 5340e20ee16Smrg{ 5350e20ee16Smrg fprintf(out,"/%s findfont reencodeISO-1\n",font); 5360e20ee16Smrg fprintf(out," /%s-8859-1 exch definefont pop\n",font); 5370e20ee16Smrg return; 5380e20ee16Smrg} 5390e20ee16Smrg 5400e20ee16Smrgstatic void 5410e20ee16SmrgPSSetUpFonts(FILE *out, char *textFont, int size) 5420e20ee16Smrg{ 5430e20ee16Smrg fprintf(out,"/F%d { /%s findfont exch scalefont setfont } def\n", 5440e20ee16Smrg FONT_TEXT,textFont); 5450e20ee16Smrg fprintf(out,"/F%d { /%s-8859-1 findfont exch scalefont setfont } def\n", 5460e20ee16Smrg FONT_LATIN1,textFont); 5470e20ee16Smrg fprintf(out,"/F%d { /%s findfont exch scalefont setfont } def\n", 5480e20ee16Smrg FONT_SYMBOL,"Symbol"); 5490e20ee16Smrg fprintf(out,"/F%d { /%s findfont exch scalefont setfont } def\n", 5500e20ee16Smrg FONT_ISOCAPS,"IsoKeyCaps"); 5510e20ee16Smrg return; 5520e20ee16Smrg} 5530e20ee16Smrg 5540e20ee16Smrgstatic void 5550e20ee16SmrgPSSetFont(FILE *out, PSState *state, int font, int size, int pts) 5560e20ee16Smrg{ 5570e20ee16Smrg if ((state->font!=font)||(state->fontSize!=size)) { 5580e20ee16Smrg fprintf(out,"%d %sF%d\n",size,(pts?"pts ":""),font); 5590e20ee16Smrg state->font= font; 5600e20ee16Smrg state->fontSize= size; 5610e20ee16Smrg } 5620e20ee16Smrg return; 5630e20ee16Smrg} 5640e20ee16Smrg 5650e20ee16Smrg 5660e20ee16Smrgstatic void 5670e20ee16SmrgPSProlog(FILE *out, PSState *state) 5680e20ee16Smrg{ 5690e20ee16Smrgregister int i; 5700e20ee16Smrg 5710e20ee16Smrg if (!state->args->wantEPS) { 5720e20ee16Smrg fprintf(out,"%%!PS-Adobe-2.0\n"); 5730e20ee16Smrg fprintf(out,"%%%%Creator: xkbprint\n"); 5740e20ee16Smrg if (state->geom->name!=None) 5750e20ee16Smrg fprintf(out,"%%%%Title: %s\n", 5760e20ee16Smrg XkbAtomGetString(state->dpy,state->geom->name)); 5770e20ee16Smrg fprintf(out,"%%%%BoundingBox: (atend)\n"); 5780e20ee16Smrg fprintf(out,"%%%%Pages: 1\n"); 5790e20ee16Smrg fprintf(out,"%%%%PageOrder: Ascend\n"); 5800e20ee16Smrg fprintf(out,"%%%%DocumentFonts: (atend)\n"); 5810e20ee16Smrg fprintf(out,"%%%%DocumentData: Clean7Bit\n"); 5820e20ee16Smrg fprintf(out,"%%%%Orientation: Landscape\n"); 5830e20ee16Smrg fprintf(out,"%%%%EndComments\n"); 5840e20ee16Smrg fprintf(out,"%%%%BeginProlog\n"); 5850e20ee16Smrg fprintf(out,"%% Resolution is 1/10mm -- need pt sizes for fonts\n"); 5860e20ee16Smrg fprintf(out,"clippath pathbbox\n"); 5870e20ee16Smrg fprintf(out," /ury exch def /urx exch def\n"); 5880e20ee16Smrg fprintf(out," /llx exch def /lly exch def\n"); 5890e20ee16Smrg fprintf(out," newpath\n"); 5900e20ee16Smrg fprintf(out,"/devwidth urx llx sub def\n"); 5910e20ee16Smrg fprintf(out,"/devheight ury lly sub def\n"); 5920e20ee16Smrg } 5930e20ee16Smrg else { 5940e20ee16Smrg int w,h; 5950e20ee16Smrg int pw,ph; 5960e20ee16Smrg 5970e20ee16Smrg w= (((state->geom->width_mm*72)/254)*11)/10; 5980e20ee16Smrg h= (((state->geom->height_mm*72)/254)*11)/10; 5990e20ee16Smrg if (state->kbPerPage>1) 6000e20ee16Smrg h*= (state->kbPerPage+1); 6010e20ee16Smrg 6020e20ee16Smrg if (w<=h) { 6030e20ee16Smrg pw= 7.5*72; 6040e20ee16Smrg ph= 10*72; 6050e20ee16Smrg } 6060e20ee16Smrg else { 6070e20ee16Smrg pw= 10*72; 6080e20ee16Smrg ph= 7.5*72; 6090e20ee16Smrg } 6100e20ee16Smrg while ((w>pw)||(h>ph)) { 6110e20ee16Smrg w= (w*9)/10; 6120e20ee16Smrg h= (h*9)/10; 6130e20ee16Smrg } 6140e20ee16Smrg 6150e20ee16Smrg fprintf(out,"%%!PS-Adobe-2.0 EPSF-2.0\n"); 6160e20ee16Smrg fprintf(out,"%%%%BoundingBox: 0 0 %d %d\n",w,h); 6170e20ee16Smrg fprintf(out,"%%%%Creator: xkbprint\n"); 6180e20ee16Smrg if (state->geom->name!=None) 6190e20ee16Smrg fprintf(out,"%%%%Title: %s\n", 6200e20ee16Smrg XkbAtomGetString(state->dpy,state->geom->name)); 6210e20ee16Smrg fprintf(out,"%%%%Pages: 1\n"); 6220e20ee16Smrg fprintf(out,"%%%%EndComments\n"); 6230e20ee16Smrg fprintf(out,"%%%%BeginProlog\n"); 6240e20ee16Smrg fprintf(out,"/ury 0 def /urx 0 def\n"); 6250e20ee16Smrg fprintf(out,"/llx %d def /lly %d def\n",w,h); 6260e20ee16Smrg fprintf(out,"/devwidth %d def /devheight %d def\n",w,h); 6270e20ee16Smrg } 6280e20ee16Smrg fprintf(out,"/kbdwidth %d def\n",state->geom->width_mm); 6290e20ee16Smrg fprintf(out,"/kbdheight %d def\n",state->geom->height_mm); 6300e20ee16Smrg fprintf(out,"/pts { 254 mul 72 div } def\n"); 6310e20ee16Smrg fprintf(out,"/mm10 { 72 mul 254 div } def\n"); 6320e20ee16Smrg fprintf(out,"/landscape? {\n"); 6330e20ee16Smrg fprintf(out," devheight devwidth gt {\n"); 6340e20ee16Smrg fprintf(out," /pwidth devheight def /pheight devwidth def\n"); 6350e20ee16Smrg fprintf(out," 0 devheight translate\n"); 6360e20ee16Smrg fprintf(out," -90 rotate\n"); 6370e20ee16Smrg fprintf(out," } {\n"); 6380e20ee16Smrg fprintf(out," /pwidth devwidth def /pheight devheight def\n"); 6390e20ee16Smrg fprintf(out," } ifelse\n"); 6400e20ee16Smrg fprintf(out," 0 pheight translate\n"); 6410e20ee16Smrg fprintf(out," 1 -1 scale\n"); 6420e20ee16Smrg fprintf(out,"} def\n"); 6430e20ee16Smrg fprintf(out,"/centeroffset {\n"); 6440e20ee16Smrg fprintf(out," /S exch def\n"); 6450e20ee16Smrg fprintf(out," /HEIGHT exch def\n"); 6460e20ee16Smrg fprintf(out," /WIDTH exch def\n"); 6470e20ee16Smrg fprintf(out," S stringwidth /SH exch def /SW exch def\n"); 6480e20ee16Smrg fprintf(out," WIDTH SW sub 2 div\n"); 6490e20ee16Smrg fprintf(out," HEIGHT SH sub 2 div\n"); 6500e20ee16Smrg fprintf(out,"} def\n"); 6510e20ee16Smrg PSSetUpForLatin1(out,state); 6520e20ee16Smrg PSReencodeLatin1Font(out,DFLT_LABEL_FONT); 6530e20ee16Smrg if (state->args->wantColor) { 6540e20ee16Smrg XkbGeometryPtr geom= state->geom; 6550e20ee16Smrg for (i=0;i<geom->num_colors;i++) { 6560e20ee16Smrg PSColorDef(out,state,&geom->colors[i]); 6570e20ee16Smrg } 6580e20ee16Smrg if (state->black<0) { 6590e20ee16Smrg XkbColorPtr color; 6600e20ee16Smrg if (!(color= XkbAddGeomColor(geom,"black",geom->num_colors))) 6610e20ee16Smrg uFatalError("Couldn't allocate black color!\n"); 6620e20ee16Smrg PSColorDef(out,state,color); 6630e20ee16Smrg } 6640e20ee16Smrg if (state->white<0) { 6650e20ee16Smrg XkbColorPtr color; 6660e20ee16Smrg if (!(color= XkbAddGeomColor(geom,"white",geom->num_colors))) 6670e20ee16Smrg uFatalError("Couldn't allocate white color!\n"); 6680e20ee16Smrg PSColorDef(out,state,color); 6690e20ee16Smrg } 6700e20ee16Smrg } 6710e20ee16Smrg for (i=0;i<state->geom->num_shapes;i++) { 6720e20ee16Smrg PSShapeDef(out,state,&state->geom->shapes[i]); 6730e20ee16Smrg } 6740e20ee16Smrg if (state->args->label==LABEL_SYMBOLS) { 6750e20ee16Smrg PSIncludeFont(out,"IsoKeyCaps"); 6760e20ee16Smrg } 6770e20ee16Smrg PSSetUpFonts(out,DFLT_LABEL_FONT, DFLT_LABEL_FONT_SIZE); 6780e20ee16Smrg fprintf(out,"%%%%EndProlog\n"); 6790e20ee16Smrg return; 6800e20ee16Smrg} 6810e20ee16Smrg 6820e20ee16Smrgstatic void 6830e20ee16SmrgPSFileTrailer(FILE *out, PSState *state) 6840e20ee16Smrg{ 6850e20ee16Smrg fprintf(out,"restore\n"); 6860e20ee16Smrg if (!state->args->wantEPS) 6870e20ee16Smrg fprintf(out,"%%%%Trailer\n"); 6880e20ee16Smrg fprintf(out,"%%%%EOF\n"); 6890e20ee16Smrg#ifdef NOTYET 6900e20ee16Smrg fprintf(out,"%%%%BoundingBox %d %d\n"); 6910e20ee16Smrg fprintf(out,"%%%%DocumentFonts: \n"); 6920e20ee16Smrg#endif 6930e20ee16Smrg return; 6940e20ee16Smrg} 6950e20ee16Smrg 6960e20ee16Smrgstatic void 6970e20ee16SmrgPSPageSetup(FILE *out, PSState *state, Bool drawBorder) 6980e20ee16Smrg{ 6990e20ee16SmrgXkbGeometryPtr geom; 7000e20ee16Smrg 7010e20ee16Smrg geom= state->geom; 7020e20ee16Smrg if (state->kbPerPage==1) { 7030e20ee16Smrg fprintf(out,"%%%%Page: %d %d\n",state->nPages+1,state->nPages+1); 7040e20ee16Smrg fprintf(out,"%%%%BeginPageSetup\n"); 7050e20ee16Smrg } 7060e20ee16Smrg else if ((state->nPages&1)==0) { /* even page */ 7070e20ee16Smrg int realPage; 7080e20ee16Smrg realPage= state->nPages/2+1; 7090e20ee16Smrg fprintf(out,"%%%%Page: %d %d\n",realPage,realPage); 7100e20ee16Smrg fprintf(out,"%%%%BeginPageSetup\n"); 7110e20ee16Smrg fprintf(out,"%% Keyboard %d\n",state->nPages+1); 7120e20ee16Smrg if (state->nPages==0) { 7130e20ee16Smrg fprintf(out,"/realwidth devwidth def\n"); 7140e20ee16Smrg fprintf(out,"/realheight devheight def\n"); 7150e20ee16Smrg fprintf(out,"/devheight realheight 3 div def\n"); 7160e20ee16Smrg } 7170e20ee16Smrg fprintf(out,"0 devheight dup 2 div add translate\n"); 7180e20ee16Smrg } 7190e20ee16Smrg else { 7200e20ee16Smrg fprintf(out,"%% Keyboard %d\n",state->nPages+1); 7210e20ee16Smrg } 7220e20ee16Smrg fprintf(out,"save\n"); 7230e20ee16Smrg fprintf(out,"landscape?\n"); 7240e20ee16Smrg if (state->args->scaleToFit) { 7250e20ee16Smrg fprintf(out,"%% Scale keyboard to fit on the page\n"); 7260e20ee16Smrg fprintf(out,"/kbdscale pwidth 72 sub kbdwidth div def\n"); 7270e20ee16Smrg fprintf(out,"/kbdscalewidth kbdwidth kbdscale mul def\n"); 7280e20ee16Smrg fprintf(out,"/kbdscaleheight kbdheight kbdscale mul def\n"); 7290e20ee16Smrg fprintf(out,"/kbx 36 def\n"); 7300e20ee16Smrg fprintf(out,"/kby pheight kbdscaleheight sub 2 div def\n"); 7310e20ee16Smrg PSGSave(out,state); 7320e20ee16Smrg fprintf(out,"kbx kby translate\n"); 7330e20ee16Smrg fprintf(out,"kbdscale kbdscale scale\n"); 7340e20ee16Smrg } 7350e20ee16Smrg else { 7360e20ee16Smrg fprintf(out,"%% Draw keyboard full size\n"); 7370e20ee16Smrg fprintf(out,"/kbdscale 1 def\n"); 7380e20ee16Smrg fprintf(out,"/kbdscalewidth kbdwidth mm10 def\n"); 7390e20ee16Smrg fprintf(out,"/kbdscaleheight kbdheight mm10 def\n"); 7400e20ee16Smrg fprintf(out,"/kbx pwidth kbdscalewidth sub 2 div def\n"); 7410e20ee16Smrg fprintf(out,"/kby pheight kbdscaleheight sub 2 div def\n"); 7420e20ee16Smrg PSGSave(out,state); 7430e20ee16Smrg fprintf(out,"kbx kby translate\n"); 7440e20ee16Smrg fprintf(out,"72 254 div dup scale\n"); 7450e20ee16Smrg } 7460e20ee16Smrg if (drawBorder) { 7470e20ee16Smrg if (state->args->wantColor) { 7480e20ee16Smrg PSSetColor(out,state,geom->base_color->pixel); 7490e20ee16Smrg fprintf(out," 0 0 moveto\n"); 7500e20ee16Smrg fprintf(out,"%3d 0 lineto\n",geom->width_mm); 7510e20ee16Smrg fprintf(out,"%3d %3d lineto\n",geom->width_mm,geom->height_mm); 7520e20ee16Smrg fprintf(out," 0 %3d lineto\n",geom->height_mm); 7530e20ee16Smrg fprintf(out,"closepath fill\n"); 7540e20ee16Smrg } 7550e20ee16Smrg PSSetColor(out,state,state->black); 7560e20ee16Smrg fprintf(out," 0 0 moveto\n"); 7570e20ee16Smrg fprintf(out,"%3d 0 lineto\n",geom->width_mm); 7580e20ee16Smrg fprintf(out,"%3d %3d lineto\n",geom->width_mm,geom->height_mm); 7590e20ee16Smrg fprintf(out," 0 %3d lineto\n",geom->height_mm); 7600e20ee16Smrg fprintf(out,"closepath stroke\n"); 7610e20ee16Smrg } 7620e20ee16Smrg fprintf(out,"%%%%EndPageSetup\n"); 7630e20ee16Smrg return; 7640e20ee16Smrg} 7650e20ee16Smrg 7660e20ee16Smrgstatic void 7670e20ee16SmrgPSPageTrailer(FILE *out, PSState *state) 7680e20ee16Smrg{ 7690e20ee16Smrgchar * name; 7700e20ee16SmrgXkbDescPtr xkb; 7710e20ee16SmrgXkbGeometryPtr geom; 7720e20ee16SmrgXkbPropertyPtr prop; 7730e20ee16Smrgint p,baseline; 7740e20ee16Smrg 7750e20ee16Smrg xkb= state->xkb; 7760e20ee16Smrg geom= state->geom; 7770e20ee16Smrg if (state->args->grid>0) { 7780e20ee16Smrg fprintf(out,"%% Draw a %dmm grid\n",state->args->grid); 7790e20ee16Smrg fprintf(out,"0 setlinewidth\n"); 7800e20ee16Smrg fprintf(out,"0.25 setgray\n"); 7810e20ee16Smrg fprintf(out," 0 %d %d {\n",state->args->grid*10,geom->width_mm); 7820e20ee16Smrg fprintf(out," /GX exch def\n"); 7830e20ee16Smrg fprintf(out," GX 0 moveto GX %d lineto stroke\n",geom->height_mm); 7840e20ee16Smrg fprintf(out,"} for\n"); 7850e20ee16Smrg fprintf(out," 0 %d %d {\n",state->args->grid*10,geom->height_mm); 7860e20ee16Smrg fprintf(out," /GY exch def\n"); 7870e20ee16Smrg fprintf(out," 0 GY moveto %d GY lineto stroke\n",geom->width_mm); 7880e20ee16Smrg fprintf(out,"} for\n"); 7890e20ee16Smrg } 7900e20ee16Smrg PSGRestore(out,state); 7910e20ee16Smrg name= NULL; 7920e20ee16Smrg for (p=0,prop=geom->properties;p<geom->num_properties;p++,prop++) { 7930e20ee16Smrg if ((prop->value!=NULL)&&(uStrCaseEqual(prop->name,"description"))) { 7940e20ee16Smrg name= prop->value; 7950e20ee16Smrg break; 7960e20ee16Smrg } 7970e20ee16Smrg } 7980e20ee16Smrg if ((!state->args->wantEPS)&& 7990e20ee16Smrg ((state->kbPerPage==1)||((state->nPages&1)==1)|| 8000e20ee16Smrg (state->nPages==state->totalKB))) { 8010e20ee16Smrg if ((name==NULL)&&(geom->name!=None)) 8020e20ee16Smrg name= XkbAtomGetString(state->dpy,geom->name); 8030e20ee16Smrg 8040e20ee16Smrg baseline= 16; 8050e20ee16Smrg if ((name!=NULL)||(state->args->label==LABEL_SYMBOLS)) { 8060e20ee16Smrg PSSetColor(out,state,state->black); 8070e20ee16Smrg PSSetFont(out,state,FONT_LATIN1,14,False); 8080e20ee16Smrg } 8090e20ee16Smrg if (state->args->label==LABEL_SYMBOLS) { 8100e20ee16Smrg char buf[40],*sName= NULL, *lbuf; 8110e20ee16Smrg Atom sAtom; 8120e20ee16Smrg 8130e20ee16Smrg if (state->args->nLabelGroups==1) 8140e20ee16Smrg sprintf(buf,"Group %d",state->args->baseLabelGroup+1); 8150e20ee16Smrg else sprintf(buf,"Groups %d-%d",state->args->baseLabelGroup+1, 8160e20ee16Smrg state->args->baseLabelGroup+state->args->nLabelGroups); 8170e20ee16Smrg fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",buf); 8180e20ee16Smrg fprintf(out," kby kbdscaleheight add %d add\n",baseline); 8190e20ee16Smrg fprintf(out," moveto\n"); 8200e20ee16Smrg fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",buf); 8210e20ee16Smrg baseline+= 16; 8220e20ee16Smrg 8230e20ee16Smrg if (xkb->names!=NULL) sAtom= xkb->names->symbols; 8240e20ee16Smrg else sAtom= None; 8250e20ee16Smrg if (sAtom!=None) 8260e20ee16Smrg sName= XkbAtomGetString(state->dpy,sAtom); 8270e20ee16Smrg if (sName==NULL) 8280e20ee16Smrg sName= "(unknown)"; 8290e20ee16Smrg 8300e20ee16Smrg lbuf = uAlloc(10+strlen(sName)); 8310e20ee16Smrg if (!lbuf) { 8320e20ee16Smrg uFatalError("Can't allocate memory for string\n"); 8330e20ee16Smrg } 8340e20ee16Smrg sprintf(lbuf,"Layout: %s",sName); 8350e20ee16Smrg fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",lbuf); 8360e20ee16Smrg fprintf(out," kby kbdscaleheight add %d add\n",baseline); 8370e20ee16Smrg fprintf(out," moveto\n"); 8380e20ee16Smrg fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",lbuf); 8390e20ee16Smrg baseline+= 16; 8400e20ee16Smrg free(lbuf); 8410e20ee16Smrg } 8420e20ee16Smrg if (name!=NULL) { 8430e20ee16Smrg fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",name); 8440e20ee16Smrg fprintf(out," kby kbdscaleheight add %d add\n",baseline); 8450e20ee16Smrg fprintf(out," moveto\n"); 8460e20ee16Smrg fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",name); 8470e20ee16Smrg baseline+= 16; 8480e20ee16Smrg } 8490e20ee16Smrg if (state->args->label==LABEL_KEYCODE) { 8500e20ee16Smrg char *sName= NULL, *lbuf; 8510e20ee16Smrg Atom sAtom; 8520e20ee16Smrg 8530e20ee16Smrg if (xkb->names!=NULL) sAtom= xkb->names->keycodes; 8540e20ee16Smrg else sAtom= None; 8550e20ee16Smrg if (sAtom!=None) 8560e20ee16Smrg sName= XkbAtomGetString(state->dpy,sAtom); 8570e20ee16Smrg if (sName==NULL) 8580e20ee16Smrg sName= "(unknown)"; 8590e20ee16Smrg 8600e20ee16Smrg lbuf = uAlloc(12+strlen(sName)); 8610e20ee16Smrg if (!lbuf) { 8620e20ee16Smrg uFatalError("Can't allocate memory for string\n"); 8630e20ee16Smrg } 8640e20ee16Smrg sprintf(lbuf,"Keycodes: %s",sName); 8650e20ee16Smrg fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",lbuf); 8660e20ee16Smrg fprintf(out," kby kbdscaleheight add %d add\n",baseline); 8670e20ee16Smrg fprintf(out," moveto\n"); 8680e20ee16Smrg fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",lbuf); 8690e20ee16Smrg baseline+= 16; 8700e20ee16Smrg free(lbuf); 8710e20ee16Smrg } 8720e20ee16Smrg if (state->args->copies>1) { 8730e20ee16Smrg for (p=1;p<state->args->copies;p++) 8740e20ee16Smrg fprintf(out,"copypage\n"); 8750e20ee16Smrg } 8760e20ee16Smrg fprintf(out,"showpage\n"); 8770e20ee16Smrg fprintf(out,"restore\n"); 8780e20ee16Smrg fprintf(out,"%% Done with keyboard/page %d\n",state->nPages+1); 8790e20ee16Smrg } 8800e20ee16Smrg else { 8810e20ee16Smrg if ((!state->args->wantEPS)&&(state->args->label==LABEL_SYMBOLS)) { 8820e20ee16Smrg char buf[40]; 8830e20ee16Smrg baseline= 16; 8840e20ee16Smrg PSSetColor(out,state,state->black); 8850e20ee16Smrg PSSetFont(out,state,FONT_LATIN1,14,False); 8860e20ee16Smrg if (state->args->nLabelGroups==1) 8870e20ee16Smrg sprintf(buf,"Group %d",state->args->baseLabelGroup+1); 8880e20ee16Smrg else sprintf(buf,"Groups %d-%d",state->args->baseLabelGroup+1, 8890e20ee16Smrg state->args->baseLabelGroup+state->args->nLabelGroups+1); 8900e20ee16Smrg fprintf(out,"kbx kbdscalewidth 0 (%s) centeroffset pop add\n",buf); 8910e20ee16Smrg fprintf(out," kby kbdscaleheight add %d add\n",baseline); 8920e20ee16Smrg fprintf(out," moveto\n"); 8930e20ee16Smrg fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",buf); 8940e20ee16Smrg baseline+= 16; 8950e20ee16Smrg } 8960e20ee16Smrg fprintf(out,"restore\n"); 8970e20ee16Smrg fprintf(out,"%% Done with keyboard %d\n",state->nPages+1); 8980e20ee16Smrg fprintf(out,"0 devheight -1 mul translate %% next keyboard\n"); 8990e20ee16Smrg } 9000e20ee16Smrg state->nPages++; 9010e20ee16Smrg state->color= state->black; 9020e20ee16Smrg state->font= -1; 9030e20ee16Smrg return; 9040e20ee16Smrg} 9050e20ee16Smrg 9060e20ee16Smrgstatic void 9070e20ee16SmrgPSDoodad(FILE *out, PSState *state, XkbDoodadPtr doodad) 9080e20ee16Smrg{ 9090e20ee16SmrgXkbDescPtr xkb; 9100e20ee16Smrgchar *name,*dname; 9110e20ee16Smrgint sz,leading; 9120e20ee16Smrg 9130e20ee16Smrg xkb= state->xkb; 9140e20ee16Smrg if (doodad->any.name!=None) 9150e20ee16Smrg dname= XkbAtomGetString(xkb->dpy,doodad->any.name); 9160e20ee16Smrg else dname= "NoName"; 9170e20ee16Smrg switch (doodad->any.type) { 9180e20ee16Smrg case XkbOutlineDoodad: 9190e20ee16Smrg case XkbSolidDoodad: 9200e20ee16Smrg name= XkbAtomGetString(xkb->dpy, 9210e20ee16Smrg XkbShapeDoodadShape(xkb->geom,&doodad->shape)->name); 9220e20ee16Smrg if (state->args->wantColor) { 9230e20ee16Smrg PSSetColor(out,state,doodad->shape.color_ndx); 9240e20ee16Smrg if (doodad->any.type!=XkbOutlineDoodad) { 9250e20ee16Smrg fprintf(out,"true %d %d %d %s %% Doodad %s\n", 9260e20ee16Smrg doodad->shape.angle, 9270e20ee16Smrg doodad->shape.left,doodad->shape.top, 9280e20ee16Smrg name,dname); 9290e20ee16Smrg PSSetColor(out,state,state->black); 9300e20ee16Smrg } 9310e20ee16Smrg fprintf(out,"false %d %d %d %s %% Doodad %s\n", 9320e20ee16Smrg doodad->shape.angle, 9330e20ee16Smrg doodad->shape.left,doodad->shape.top, 9340e20ee16Smrg name,dname); 9350e20ee16Smrg } 9360e20ee16Smrg else { 9370e20ee16Smrg fprintf(out,"false %d %d %d %s %% Doodad %s\n", 9380e20ee16Smrg doodad->shape.angle, 9390e20ee16Smrg doodad->shape.left,doodad->shape.top, 9400e20ee16Smrg name,dname); 9410e20ee16Smrg } 9420e20ee16Smrg break; 9430e20ee16Smrg case XkbTextDoodad: 9440e20ee16Smrg fprintf(out,"%% Doodad %s\n",dname); 9450e20ee16Smrg PSSetColor(out,state,doodad->text.color_ndx); 9460e20ee16Smrg PSGSave(out,state); 9470e20ee16Smrg fprintf(out,"%d %d translate\n",doodad->text.left,doodad->text.top); 9480e20ee16Smrg if (doodad->text.angle!=0) 9490e20ee16Smrg fprintf(out,"%s rotate\n", 9500e20ee16Smrg XkbGeomFPText(doodad->text.angle,XkbMessage)); 9510e20ee16Smrg sz= 14; 9520e20ee16Smrg if (doodad->text.font) { 9530e20ee16Smrg FontStuff stuff; 9540e20ee16Smrg if (CrackXLFDName(doodad->text.font,&stuff)) { 9550e20ee16Smrg if (stuff.ptSize>0) 9560e20ee16Smrg sz= stuff.ptSize/10; 9570e20ee16Smrg ClearFontStuff(&stuff); 9580e20ee16Smrg } 9590e20ee16Smrg } 9600e20ee16Smrg PSSetFont(out,state,FONT_LATIN1,sz,True); 9610e20ee16Smrg leading= (sz*12)/10; 9620e20ee16Smrg if (strchr(doodad->text.text,'\n')==NULL) { 9630e20ee16Smrg fprintf(out,"0 %d pts moveto 1 -1 scale\n",(leading*8)/10); 9640e20ee16Smrg fprintf(out,"(%s) show\n",doodad->text.text); 9650e20ee16Smrg } 9660e20ee16Smrg else { 9670e20ee16Smrg char *tmp,*buf,*end; 9680e20ee16Smrg int offset= (leading*8/10); 9690e20ee16Smrg tmp= buf= uStringDup(doodad->text.text); 9700e20ee16Smrg while (tmp!=NULL) { 9710e20ee16Smrg end= strchr(tmp,'\n'); 9720e20ee16Smrg if (end!=NULL) 9730e20ee16Smrg *end++= '\0'; 9740e20ee16Smrg fprintf(out,"0 %d pts moveto 1 -1 scale\n",offset); 9750e20ee16Smrg fprintf(out,"(%s) show 1 -1 scale\n",tmp); 9760e20ee16Smrg offset+= leading; 9770e20ee16Smrg tmp= end; 9780e20ee16Smrg } 9790e20ee16Smrg free(buf); 9800e20ee16Smrg } 9810e20ee16Smrg PSGRestore(out,state); 9820e20ee16Smrg break; 9830e20ee16Smrg case XkbIndicatorDoodad: 9840e20ee16Smrg name= XkbAtomGetString(xkb->dpy, 9850e20ee16Smrg XkbIndicatorDoodadShape(xkb->geom,&doodad->indicator)->name); 9860e20ee16Smrg if (state->args->wantColor) { 9870e20ee16Smrg PSSetColor(out,state,doodad->indicator.off_color_ndx); 9880e20ee16Smrg fprintf(out,"true 0 %d %d %s %% Doodad %s\n", 9890e20ee16Smrg doodad->indicator.left,doodad->indicator.top, 9900e20ee16Smrg name,dname); 9910e20ee16Smrg PSSetColor(out,state,state->black); 9920e20ee16Smrg } 9930e20ee16Smrg fprintf(out,"false 0 %d %d %s %% Doodad %s\n", 9940e20ee16Smrg doodad->indicator.left,doodad->indicator.top, 9950e20ee16Smrg name,dname); 9960e20ee16Smrg break; 9970e20ee16Smrg case XkbLogoDoodad: 9980e20ee16Smrg name= XkbAtomGetString(xkb->dpy, 9990e20ee16Smrg XkbLogoDoodadShape(xkb->geom,&doodad->logo)->name); 10000e20ee16Smrg if (state->args->wantColor) 10010e20ee16Smrg PSSetColor(out,state,doodad->shape.color_ndx); 10020e20ee16Smrg fprintf(out,"false %d %d %d %s %% Doodad %s\n", 10030e20ee16Smrg doodad->shape.angle, 10040e20ee16Smrg doodad->shape.left,doodad->shape.top, 10050e20ee16Smrg name,dname); 10060e20ee16Smrg break; 10070e20ee16Smrg } 10080e20ee16Smrg return; 10090e20ee16Smrg} 10100e20ee16Smrg 10110e20ee16Smrg/***====================================================================***/ 10120e20ee16Smrg 10130e20ee16Smrgstatic Bool 10140e20ee16SmrgPSKeycapsSymbol(KeySym sym, unsigned char *buf, 10150e20ee16Smrg int *font_rtrn, int *sz_rtrn, PSState *state) 10160e20ee16Smrg{ 10170e20ee16Smrg if (state->args->wantSymbols==NO_SYMBOLS) 10180e20ee16Smrg return False; 10190e20ee16Smrg 10200e20ee16Smrg if (font_rtrn!=NULL) 10210e20ee16Smrg *font_rtrn= FONT_ISOCAPS; 10220e20ee16Smrg if (sz_rtrn!=NULL) 10230e20ee16Smrg *sz_rtrn= SZ_LARGE; 10240e20ee16Smrg buf[1]= '\0'; 10250e20ee16Smrg switch (sym) { 10260e20ee16Smrg case XK_Shift_L: case XK_Shift_R: 10270e20ee16Smrg buf[0]= XKC_ISO_Shift; return True; 10280e20ee16Smrg case XK_Shift_Lock: 10290e20ee16Smrg buf[0]= XKC_ISO_Shift_Lock; return True; 10300e20ee16Smrg case XK_ISO_Lock: 10310e20ee16Smrg buf[0]= XKC_ISO_Caps_Lock; return True; 10320e20ee16Smrg case XK_BackSpace: 10330e20ee16Smrg buf[0]= XKC_ISO_Backspace; return True; 10340e20ee16Smrg case XK_Return: 10350e20ee16Smrg buf[0]= XKC_ISO_Return; return True; 10360e20ee16Smrg case XK_Up: case XK_KP_Up: 10370e20ee16Smrg buf[0]= XKC_ISO_Up; return True; 10380e20ee16Smrg case XK_Down: case XK_KP_Down: 10390e20ee16Smrg buf[0]= XKC_ISO_Down; return True; 10400e20ee16Smrg case XK_Left: case XK_KP_Left: 10410e20ee16Smrg buf[0]= XKC_ISO_Left; return True; 10420e20ee16Smrg case XK_Right: case XK_KP_Right: 10430e20ee16Smrg buf[0]= XKC_ISO_Right; return True; 10440e20ee16Smrg case XK_Tab: 10450e20ee16Smrg buf[0]= XKC_ISO_Tab; return True; 10460e20ee16Smrg case XK_ISO_Left_Tab: 10470e20ee16Smrg buf[0]= XKC_ISO_Left_Tab; return True; 10480e20ee16Smrg } 10490e20ee16Smrg if (state->args->wantSymbols!=ALL_SYMBOLS) 10500e20ee16Smrg return False; 10510e20ee16Smrg switch (sym) { 10520e20ee16Smrg case XK_Caps_Lock: 10530e20ee16Smrg buf[0]= XKC_ISO_Caps_Lock; return True; 10540e20ee16Smrg case XK_Num_Lock: 10550e20ee16Smrg buf[0]= XKC_ISO_Num_Lock; return True; 10560e20ee16Smrg case XK_ISO_Level3_Shift: 10570e20ee16Smrg buf[0]= XKC_ISO_Level3_Shift; return True; 10580e20ee16Smrg case XK_ISO_Level3_Lock: 10590e20ee16Smrg buf[0]= XKC_ISO_Level3_Lock; return True; 10600e20ee16Smrg case XK_ISO_Next_Group: case XK_ISO_Group_Shift: 10610e20ee16Smrg buf[0]= XKC_ISO_Next_Group; return True; 10620e20ee16Smrg case XK_ISO_Next_Group_Lock: 10630e20ee16Smrg buf[0]= XKC_ISO_Next_Group_Lock;return True; 10640e20ee16Smrg case XK_space: 10650e20ee16Smrg buf[0]= XKC_ISO_Space; return True; 10660e20ee16Smrg case XK_nobreakspace: 10670e20ee16Smrg buf[0]= XKC_ISO_No_Break_Space; return True; 10680e20ee16Smrg case XK_Insert: 10690e20ee16Smrg buf[0]= XKC_ISO_Insert; return True; 10700e20ee16Smrg case XK_ISO_Continuous_Underline: 10710e20ee16Smrg buf[0]= XKC_ISO_Continuous_Underline;return True; 10720e20ee16Smrg case XK_ISO_Discontinuous_Underline: 10730e20ee16Smrg buf[0]= XKC_ISO_Discontinuous_Underline;return True; 10740e20ee16Smrg case XK_ISO_Emphasize: 10750e20ee16Smrg buf[0]= XKC_ISO_Emphasize; return True; 10760e20ee16Smrg case XK_Multi_key: 10770e20ee16Smrg buf[0]= XKC_ISO_Compose; return True; 10780e20ee16Smrg case XK_ISO_Center_Object: 10790e20ee16Smrg buf[0]= XKC_ISO_Center_Object; return True; 10800e20ee16Smrg case XK_Delete: 10810e20ee16Smrg buf[0]= XKC_ISO_Delete; return True; 10820e20ee16Smrg case XK_Clear: 10830e20ee16Smrg buf[0]= XKC_ISO_Clear_Screen; return True; 10840e20ee16Smrg case XK_Scroll_Lock: 10850e20ee16Smrg buf[0]= XKC_ISO_Scroll_Lock; return True; 10860e20ee16Smrg case XK_Help: 10870e20ee16Smrg buf[0]= XKC_ISO_Help; return True; 10880e20ee16Smrg case XK_Print: 10890e20ee16Smrg buf[0]= XKC_ISO_Print_Screen; return True; 10900e20ee16Smrg case XK_ISO_Enter: 10910e20ee16Smrg buf[0]= XKC_ISO_Enter; return True; 10920e20ee16Smrg case XK_Alt_L: case XK_Alt_R: 10930e20ee16Smrg buf[0]= XKC_ISO_Alt; return True; 10940e20ee16Smrg case XK_Control_L: case XK_Control_R: 10950e20ee16Smrg buf[0]= XKC_ISO_Control; return True; 10960e20ee16Smrg case XK_Pause: 10970e20ee16Smrg buf[0]= XKC_ISO_Pause; return True; 10980e20ee16Smrg case XK_Break: 10990e20ee16Smrg buf[0]= XKC_ISO_Break; return True; 11000e20ee16Smrg case XK_Escape: 11010e20ee16Smrg buf[0]= XKC_ISO_Escape; return True; 11020e20ee16Smrg case XK_Undo: 11030e20ee16Smrg buf[0]= XKC_ISO_Undo; return True; 11040e20ee16Smrg case XK_ISO_Fast_Cursor_Up: 11050e20ee16Smrg buf[0]= XKC_ISO_Fast_Cursor_Up; return True; 11060e20ee16Smrg case XK_ISO_Fast_Cursor_Down: 11070e20ee16Smrg buf[0]= XKC_ISO_Fast_Cursor_Down;return True; 11080e20ee16Smrg case XK_ISO_Fast_Cursor_Left: 11090e20ee16Smrg buf[0]= XKC_ISO_Fast_Cursor_Left;return True; 11100e20ee16Smrg case XK_ISO_Fast_Cursor_Right: 11110e20ee16Smrg buf[0]= XKC_ISO_Fast_Cursor_Right;return True; 11120e20ee16Smrg case XK_Home: 11130e20ee16Smrg buf[0]= XKC_ISO_Home; return True; 11140e20ee16Smrg case XK_End: 11150e20ee16Smrg buf[0]= XKC_ISO_End; return True; 11160e20ee16Smrg case XK_Page_Up: 11170e20ee16Smrg buf[0]= XKC_ISO_Page_Up; return True; 11180e20ee16Smrg case XK_Page_Down: 11190e20ee16Smrg buf[0]= XKC_ISO_Page_Down; return True; 11200e20ee16Smrg case XK_ISO_Move_Line_Up: 11210e20ee16Smrg buf[0]= XKC_ISO_Move_Line_Up; return True; 11220e20ee16Smrg case XK_ISO_Move_Line_Down: 11230e20ee16Smrg buf[0]= XKC_ISO_Move_Line_Down; return True; 11240e20ee16Smrg case XK_ISO_Partial_Line_Up: 11250e20ee16Smrg buf[0]= XKC_ISO_Partial_Line_Up;return True; 11260e20ee16Smrg case XK_ISO_Partial_Line_Down: 11270e20ee16Smrg buf[0]= XKC_ISO_Partial_Line_Down;return True; 11280e20ee16Smrg case XK_ISO_Partial_Space_Left: 11290e20ee16Smrg buf[0]= XKC_ISO_Partial_Space_Left;return True; 11300e20ee16Smrg case XK_ISO_Partial_Space_Right: 11310e20ee16Smrg buf[0]= XKC_ISO_Partial_Space_Right;return True; 11320e20ee16Smrg case XK_ISO_Set_Margin_Left: 11330e20ee16Smrg buf[0]= XKC_ISO_Set_Margin_Left;return True; 11340e20ee16Smrg case XK_ISO_Set_Margin_Right: 11350e20ee16Smrg buf[0]= XKC_ISO_Set_Margin_Right;return True; 11360e20ee16Smrg case XK_ISO_Release_Margin_Left: 11370e20ee16Smrg buf[0]= XKC_ISO_Release_Margin_Left;return True; 11380e20ee16Smrg case XK_ISO_Release_Margin_Right: 11390e20ee16Smrg buf[0]= XKC_ISO_Release_Margin_Right;return True; 11400e20ee16Smrg case XK_ISO_Release_Both_Margins: 11410e20ee16Smrg buf[0]= XKC_ISO_Release_Both_Margins;return True; 11420e20ee16Smrg case XK_ISO_Prev_Group: 11430e20ee16Smrg buf[0]= XKC_ISO_Prev_Group; return True; 11440e20ee16Smrg case XK_ISO_Prev_Group_Lock: 11450e20ee16Smrg buf[0]= XKC_ISO_Prev_Group_Lock; return True; 11460e20ee16Smrg } 11470e20ee16Smrg#ifdef NOTYET 11480e20ee16Smrg if (font_rtrn!=NULL) 11490e20ee16Smrg font_rtrn= FONT_MOUSECAPS; 11500e20ee16Smrg switch (sym) { 11510e20ee16Smrg case XK_Pointer_Up: 11520e20ee16Smrg buf[0]= XKC_Mouse_Pointer_Up; return True; 11530e20ee16Smrg case XK_Pointer_Down: 11540e20ee16Smrg buf[0]= XKC_Mouse_Pointer_Down; return True; 11550e20ee16Smrg case XK_Pointer_Left: 11560e20ee16Smrg buf[0]= XKC_Mouse_Pointer_Left; return True; 11570e20ee16Smrg case XK_Pointer_Right: 11580e20ee16Smrg buf[0]= XKC_Mouse_Pointer_Right;return True; 11590e20ee16Smrg case XK_Pointer_Button1: 11600e20ee16Smrg buf[0]= XKC_Mouse_Pointer_Button1;return True; 11610e20ee16Smrg case XK_Pointer_Button2: 11620e20ee16Smrg buf[0]= XKC_Mouse_Pointer_Button2;return True; 11630e20ee16Smrg case XK_Pointer_Button3: 11640e20ee16Smrg buf[0]= XKC_Mouse_Pointer_Button3;return True; 11650e20ee16Smrg case XK_Pointer_Button4: 11660e20ee16Smrg buf[0]= XKC_Mouse_Pointer_Button4;return True; 11670e20ee16Smrg } 11680e20ee16Smrg#endif 11690e20ee16Smrg return False; 11700e20ee16Smrg} 11710e20ee16Smrg 11720e20ee16Smrgstatic Bool 11730e20ee16SmrgPSNonLatin1Symbol(KeySym sym, unsigned char *buf, 11740e20ee16Smrg int *font_rtrn, int *sz_rtrn, PSState *state) 11750e20ee16Smrg{ 11760e20ee16Smrg if (state->args->wantSymbols==NO_SYMBOLS) 11770e20ee16Smrg return False; 11780e20ee16Smrg 11790e20ee16Smrg if (font_rtrn!=NULL) 11800e20ee16Smrg *font_rtrn= FONT_TEXT; 11810e20ee16Smrg if (sz_rtrn!=NULL) 11820e20ee16Smrg *sz_rtrn= SZ_LARGE; 11830e20ee16Smrg buf[1]= '\0'; 11840e20ee16Smrg switch (sym) { 11850e20ee16Smrg case XK_breve: buf[0]= 0xC6; return True; 11860e20ee16Smrg case XK_abovedot: buf[0]= 0xC7; return True; 11870e20ee16Smrg case XK_doubleacute: buf[0]= 0xCD; return True; 11880e20ee16Smrg case XK_ogonek: buf[0]= 0xCE; return True; 11890e20ee16Smrg case XK_caron: buf[0]= 0xCF; return True; 11900e20ee16Smrg case XK_Lstroke: buf[0]= 0xE8; return True; 11910e20ee16Smrg case XK_idotless: buf[0]= 0xF5; return True; 11920e20ee16Smrg case XK_lstroke: buf[0]= 0xF8; return True; 11930e20ee16Smrg } 11940e20ee16Smrg if (font_rtrn!=NULL) 11950e20ee16Smrg *font_rtrn= FONT_SYMBOL; 11960e20ee16Smrg if (sz_rtrn!=NULL) 11970e20ee16Smrg *sz_rtrn= SZ_MEDIUM; 11980e20ee16Smrg if ((sym&(~0xff))==0x700) { 11990e20ee16Smrg switch (sym) { 12000e20ee16Smrg /* Greek symbol */ 12010e20ee16Smrg case XK_Greek_ALPHA: buf[0]= 0x41; return True; 12020e20ee16Smrg case XK_Greek_BETA: buf[0]= 0x42; return True; 12030e20ee16Smrg case XK_Greek_CHI: buf[0]= 0x43; return True; 12040e20ee16Smrg case XK_Greek_DELTA: buf[0]= 0x44; return True; 12050e20ee16Smrg case XK_Greek_EPSILON: buf[0]= 0x45; return True; 12060e20ee16Smrg case XK_Greek_PHI: buf[0]= 0x46; return True; 12070e20ee16Smrg case XK_Greek_GAMMA: buf[0]= 0x47; return True; 12080e20ee16Smrg case XK_Greek_ETA: buf[0]= 0x48; return True; 12090e20ee16Smrg case XK_Greek_IOTA: buf[0]= 0x49; return True; 12100e20ee16Smrg case XK_Greek_KAPPA: buf[0]= 0x4B; return True; 12110e20ee16Smrg case XK_Greek_LAMDA: buf[0]= 0x4C; return True; 12120e20ee16Smrg case XK_Greek_MU: buf[0]= 0x4D; return True; 12130e20ee16Smrg case XK_Greek_NU: buf[0]= 0x4E; return True; 12140e20ee16Smrg case XK_Greek_OMICRON: buf[0]= 0x4F; return True; 12150e20ee16Smrg case XK_Greek_PI: buf[0]= 0x50; return True; 12160e20ee16Smrg case XK_Greek_THETA: buf[0]= 0x51; return True; 12170e20ee16Smrg case XK_Greek_RHO: buf[0]= 0x52; return True; 12180e20ee16Smrg case XK_Greek_SIGMA: buf[0]= 0x53; return True; 12190e20ee16Smrg case XK_Greek_TAU: buf[0]= 0x54; return True; 12200e20ee16Smrg case XK_Greek_UPSILON: buf[0]= 0x55; return True; 12210e20ee16Smrg case XK_Greek_OMEGA: buf[0]= 0x57; return True; 12220e20ee16Smrg case XK_Greek_XI: buf[0]= 0x58; return True; 12230e20ee16Smrg case XK_Greek_PSI: buf[0]= 0x59; return True; 12240e20ee16Smrg case XK_Greek_ZETA: buf[0]= 0x5A; return True; 12250e20ee16Smrg 12260e20ee16Smrg case XK_Greek_alpha: buf[0]= 0x61; return True; 12270e20ee16Smrg case XK_Greek_beta: buf[0]= 0x62; return True; 12280e20ee16Smrg case XK_Greek_chi: buf[0]= 0x63; return True; 12290e20ee16Smrg case XK_Greek_delta: buf[0]= 0x64; return True; 12300e20ee16Smrg case XK_Greek_epsilon: buf[0]= 0x65; return True; 12310e20ee16Smrg case XK_Greek_phi: buf[0]= 0x66; return True; 12320e20ee16Smrg case XK_Greek_gamma: buf[0]= 0x67; return True; 12330e20ee16Smrg case XK_Greek_eta: buf[0]= 0x68; return True; 12340e20ee16Smrg case XK_Greek_iota: buf[0]= 0x69; return True; 12350e20ee16Smrg case XK_Greek_kappa: buf[0]= 0x6B; return True; 12360e20ee16Smrg case XK_Greek_lamda: buf[0]= 0x6C; return True; 12370e20ee16Smrg case XK_Greek_mu: buf[0]= 0x6D; return True; 12380e20ee16Smrg case XK_Greek_nu: buf[0]= 0x6E; return True; 12390e20ee16Smrg case XK_Greek_omicron: buf[0]= 0x6F; return True; 12400e20ee16Smrg case XK_Greek_pi: buf[0]= 0x70; return True; 12410e20ee16Smrg case XK_Greek_theta: buf[0]= 0x71; return True; 12420e20ee16Smrg case XK_Greek_rho: buf[0]= 0x72; return True; 12430e20ee16Smrg case XK_Greek_sigma: buf[0]= 0x73; return True; 12440e20ee16Smrg case XK_Greek_tau: buf[0]= 0x74; return True; 12450e20ee16Smrg case XK_Greek_upsilon: buf[0]= 0x75; return True; 12460e20ee16Smrg case XK_Greek_omega: buf[0]= 0x77; return True; 12470e20ee16Smrg case XK_Greek_xi: buf[0]= 0x78; return True; 12480e20ee16Smrg case XK_Greek_psi: buf[0]= 0x79; return True; 12490e20ee16Smrg case XK_Greek_zeta: buf[0]= 0x7A; return True; 12500e20ee16Smrg } 12510e20ee16Smrg } 12520e20ee16Smrg switch (sym) { 12530e20ee16Smrg case XK_leftarrow: buf[0]= 0xAC; return True; 12540e20ee16Smrg case XK_uparrow: buf[0]= 0xAD; return True; 12550e20ee16Smrg case XK_rightarrow: buf[0]= 0xAE; return True; 12560e20ee16Smrg case XK_downarrow: buf[0]= 0xAF; return True; 12570e20ee16Smrg case XK_horizconnector: buf[0]= 0xBE; return True; 12580e20ee16Smrg case XK_trademark: buf[0]= 0xE4; return True; 12590e20ee16Smrg } 12600e20ee16Smrg return False; 12610e20ee16Smrg} 12620e20ee16Smrg 12630e20ee16Smrgstatic KeySym 12640e20ee16SmrgCheckSymbolAlias(KeySym sym, PSState *state) 12650e20ee16Smrg{ 12660e20ee16Smrg if (XkbKSIsKeypad(sym)) { 12670e20ee16Smrg if ((sym>=XK_KP_0)&&(sym<=XK_KP_9)) 12680e20ee16Smrg sym= (sym-XK_KP_0)+XK_0; 12690e20ee16Smrg else switch (sym) { 12700e20ee16Smrg case XK_KP_Space: return XK_space; 12710e20ee16Smrg case XK_KP_Tab: return XK_Tab; 12720e20ee16Smrg case XK_KP_Enter: return XK_Return; 12730e20ee16Smrg case XK_KP_F1: return XK_F1; 12740e20ee16Smrg case XK_KP_F2: return XK_F2; 12750e20ee16Smrg case XK_KP_F3: return XK_F3; 12760e20ee16Smrg case XK_KP_F4: return XK_F4; 12770e20ee16Smrg case XK_KP_Home: return XK_Home; 12780e20ee16Smrg case XK_KP_Left: return XK_Left; 12790e20ee16Smrg case XK_KP_Up: return XK_Up; 12800e20ee16Smrg case XK_KP_Right: return XK_Right; 12810e20ee16Smrg case XK_KP_Down: return XK_Down; 12820e20ee16Smrg case XK_KP_Page_Up: return XK_Page_Up; 12830e20ee16Smrg case XK_KP_Page_Down: return XK_Page_Down; 12840e20ee16Smrg case XK_KP_End: return XK_End; 12850e20ee16Smrg case XK_KP_Begin: return XK_Begin; 12860e20ee16Smrg case XK_KP_Insert: return XK_Insert; 12870e20ee16Smrg case XK_KP_Delete: return XK_Delete; 12880e20ee16Smrg case XK_KP_Equal: return XK_equal; 12890e20ee16Smrg case XK_KP_Multiply: return XK_asterisk; 12900e20ee16Smrg case XK_KP_Add: return XK_plus; 12910e20ee16Smrg case XK_KP_Subtract: return XK_minus; 12920e20ee16Smrg case XK_KP_Divide: return XK_slash; 12930e20ee16Smrg } 12940e20ee16Smrg } 12950e20ee16Smrg else if (XkbKSIsDeadKey(sym)) { 12960e20ee16Smrg switch (sym) { 12970e20ee16Smrg case XK_dead_grave: sym= XK_grave; break; 12980e20ee16Smrg case XK_dead_acute: sym= XK_acute; break; 12990e20ee16Smrg case XK_dead_circumflex: sym= XK_asciicircum; break; 13000e20ee16Smrg case XK_dead_tilde: sym= XK_asciitilde; break; 13010e20ee16Smrg case XK_dead_macron: sym= XK_macron; break; 13020e20ee16Smrg case XK_dead_breve: sym= XK_breve; break; 13030e20ee16Smrg case XK_dead_abovedot: sym= XK_abovedot; break; 13040e20ee16Smrg case XK_dead_diaeresis: sym= XK_diaeresis; break; 13050e20ee16Smrg case XK_dead_abovering: sym= XK_degree; break; 13060e20ee16Smrg case XK_dead_doubleacute: sym= XK_doubleacute; break; 13070e20ee16Smrg case XK_dead_caron: sym= XK_caron; break; 13080e20ee16Smrg case XK_dead_cedilla: sym= XK_cedilla; break; 13090e20ee16Smrg case XK_dead_ogonek: sym= XK_ogonek; break; 13100e20ee16Smrg case XK_dead_iota: sym= XK_Greek_iota; break; 13110e20ee16Smrg case XK_dead_voiced_sound: 13120e20ee16Smrg sym= XK_voicedsound; 13130e20ee16Smrg break; 13140e20ee16Smrg case XK_dead_semivoiced_sound: 13150e20ee16Smrg sym= XK_semivoicedsound; 13160e20ee16Smrg break; 13170e20ee16Smrg } 13180e20ee16Smrg } 13190e20ee16Smrg return sym; 13200e20ee16Smrg} 13210e20ee16Smrg 13220e20ee16Smrgstatic Bool 13230e20ee16SmrgFindKeysymsByName(XkbDescPtr xkb, char *name, PSState *state, KeyTop *top) 13240e20ee16Smrg{ 13250e20ee16Smrgstatic unsigned char buf[30]; 13260e20ee16Smrgint kc; 13270e20ee16SmrgKeySym sym,*syms,topSyms[NLABELS]; 13280e20ee16Smrgint level,group; 13290e20ee16Smrgint eG,nG,gI,l,g; 13300e20ee16Smrg 13310e20ee16Smrg bzero(top,sizeof(KeyTop)); 13320e20ee16Smrg kc= XkbFindKeycodeByName(xkb,name,True); 13330e20ee16Smrg if (state->args!=NULL) { 13340e20ee16Smrg level= state->args->labelLevel; 13350e20ee16Smrg group= state->args->baseLabelGroup; 13360e20ee16Smrg } 13370e20ee16Smrg else level= group= 0; 13380e20ee16Smrg syms= XkbKeySymsPtr(xkb,kc); 13390e20ee16Smrg eG= group; 13400e20ee16Smrg nG= XkbKeyNumGroups(xkb,kc); 13410e20ee16Smrg gI= XkbKeyGroupInfo(xkb,kc); 13420e20ee16Smrg if ((state->args->wantDiffs)&&(eG>=XkbKeyNumGroups(xkb,kc))) 13430e20ee16Smrg return False; /* XXX was a return with no value */ 13440e20ee16Smrg if (nG==0) { 13450e20ee16Smrg return False; 13460e20ee16Smrg } 13470e20ee16Smrg else if (nG==1) { 13480e20ee16Smrg eG= 0; 13490e20ee16Smrg } 13500e20ee16Smrg else if (eG>=XkbKeyNumGroups(xkb,kc)) { 13510e20ee16Smrg switch (XkbOutOfRangeGroupAction(gI)) { 13520e20ee16Smrg default: 13530e20ee16Smrg eG%= nG; 13540e20ee16Smrg break; 13550e20ee16Smrg case XkbClampIntoRange: 13560e20ee16Smrg eG= nG-1; 13570e20ee16Smrg break; 13580e20ee16Smrg case XkbRedirectIntoRange: 13590e20ee16Smrg eG= XkbOutOfRangeGroupNumber(gI); 13600e20ee16Smrg if (eG>=nG) 13610e20ee16Smrg eG= 0; 13620e20ee16Smrg break; 13630e20ee16Smrg } 13640e20ee16Smrg } 13650e20ee16Smrg for (g=0;g<state->args->nLabelGroups;g++) { 13660e20ee16Smrg if ((eG+g)>=nG) 13670e20ee16Smrg continue; 13680e20ee16Smrg for (l=0;l<2;l++) { 13690e20ee16Smrg int font,sz; 13700e20ee16Smrg if (level+l>=XkbKeyGroupWidth(xkb,kc,(eG+g))) 13710e20ee16Smrg continue; 13720e20ee16Smrg sym= syms[((eG+g)*XkbKeyGroupsWidth(xkb,kc))+(level+l)]; 13730e20ee16Smrg 13740e20ee16Smrg if (state->args->wantSymbols!=NO_SYMBOLS) 13750e20ee16Smrg sym= CheckSymbolAlias(sym,state); 13760e20ee16Smrg topSyms[(g*2)+l]= sym; 13770e20ee16Smrg 13780e20ee16Smrg if (PSKeycapsSymbol(sym,buf,&font,&sz,state)) { 13790e20ee16Smrg top->font[(g*2)+l]= font; 13800e20ee16Smrg top->size[(g*2)+l]= sz; 13810e20ee16Smrg } 13820e20ee16Smrg else if (((sym&(~0xff))==0)&&isprint(sym)&&(!isspace(sym))) { 13830e20ee16Smrg if (sym=='(') sprintf((char *)buf,"\\("); 13840e20ee16Smrg else if (sym==')') sprintf((char *)buf,"\\)"); 13850e20ee16Smrg else if (sym=='\\') sprintf((char *)buf,"\\\\"); 13860e20ee16Smrg else sprintf((char *)buf,"%c",(char)sym); 13870e20ee16Smrg top->font[(g*2)+l]= FONT_LATIN1; 13880e20ee16Smrg top->size[(g*2)+l]= SZ_MEDIUM; 13890e20ee16Smrg switch (buf[0]) { 13900e20ee16Smrg case '.': case ':': case ',': case ';': 13910e20ee16Smrg case '\'': case '"': case '`': case '~': 13920e20ee16Smrg case '^': case '\250': case '\270': case '\267': 13930e20ee16Smrg case '\260': case '\252': case '\272': case '\271': 13940e20ee16Smrg case '\262': case '\263': case '\264': case '\255': 13950e20ee16Smrg case '\254': case '\257': 13960e20ee16Smrg top->size[(g*2)+l]= SZ_LARGE; 13970e20ee16Smrg break; 13980e20ee16Smrg } 13990e20ee16Smrg } 14000e20ee16Smrg else if (PSNonLatin1Symbol(sym,buf,&font,&sz,state)) { 14010e20ee16Smrg top->font[(g*2)+l]= font; 14020e20ee16Smrg top->size[(g*2)+l]= sz; 14030e20ee16Smrg } 14040e20ee16Smrg else { 14050e20ee16Smrg char *tmp; 14060e20ee16Smrg tmp= XKeysymToString(sym); 14070e20ee16Smrg if (tmp!=NULL) strcpy((char *)buf,tmp); 14080e20ee16Smrg else sprintf((char *)buf,"(%ld)",sym); 14090e20ee16Smrg top->font[(g*2)+l]= FONT_LATIN1; 14100e20ee16Smrg if (strlen((char *)buf)<9) 14110e20ee16Smrg top->size[(g*2)+l]= SZ_SMALL; 14120e20ee16Smrg else top->size[(g*2)+l]= SZ_TINY; 14130e20ee16Smrg } 14140e20ee16Smrg top->present|= (1<<((g*2)+l)); 14150e20ee16Smrg strncpy(top->label[(g*2)+l],(char *)buf,LABEL_LEN-1); 14160e20ee16Smrg top->label[(g*2)+l][LABEL_LEN-1]= '\0'; 14170e20ee16Smrg } 14180e20ee16Smrg if (((g==0)&&(top->present&G1LX_MASK)==G1LX_MASK)|| 14190e20ee16Smrg ((g==1)&&(top->present&G2LX_MASK)==G2LX_MASK)) { 14200e20ee16Smrg KeySym lower,upper; 14210e20ee16Smrg XConvertCase(topSyms[(g*2)],&lower,&upper); 14220e20ee16Smrg if ((topSyms[(g*2)]==lower)&&(topSyms[(g*2)+1]==upper)) { 14230e20ee16Smrg top->alpha[g]= True; 14240e20ee16Smrg } 14250e20ee16Smrg } 14260e20ee16Smrg } 14270e20ee16Smrg return True; 14280e20ee16Smrg} 14290e20ee16Smrg 14300e20ee16Smrgstatic void 14310e20ee16SmrgPSDrawLabel(FILE *out, char *label, int x, int y, int w, int h) 14320e20ee16Smrg{ 14330e20ee16Smrg fprintf(out,"%d %d (%s) centeroffset\n",w,h,label); 14340e20ee16Smrg fprintf(out,"%d add exch\n",y); 14350e20ee16Smrg fprintf(out,"%d add exch moveto\n",x); 14360e20ee16Smrg fprintf(out,"1 -1 scale (%s) show 1 -1 scale\n",label); 14370e20ee16Smrg return; 14380e20ee16Smrg} 14390e20ee16Smrg 14400e20ee16Smrg#define TOP_ROW 0 14410e20ee16Smrg#define BOTTOM_ROW 1 14420e20ee16Smrg#define CENTER_ROW 2 14430e20ee16Smrg 14440e20ee16Smrg#define LEFT_COL 0 14450e20ee16Smrg#define RIGHT_COL 1 14460e20ee16Smrg#define CENTER_COL 2 14470e20ee16Smrg 14480e20ee16Smrgstatic void 14490e20ee16SmrgPSLabelKey(FILE *out, PSState *state, KeyTop *top, int x, int y, 14500e20ee16Smrg XkbBoundsPtr bounds, int kc, int btm) 14510e20ee16Smrg{ 14520e20ee16Smrgchar keycode[10]; 14530e20ee16Smrgint w,h,i; 14540e20ee16Smrgint row_y[3]; 14550e20ee16Smrgint col_x[3]; 14560e20ee16Smrgint row_h[3]; 14570e20ee16Smrgint col_w[3]; 14580e20ee16SmrgBool present[NLABELS]; 14590e20ee16Smrgint sym_row[NLABELS]; 14600e20ee16Smrgint sym_col[NLABELS]; 14610e20ee16Smrg 14620e20ee16Smrg w= XkbBoundsWidth(bounds); 14630e20ee16Smrg h= XkbBoundsHeight(bounds); 14640e20ee16Smrg row_y[TOP_ROW]= y+bounds->y1+(h/10); 14650e20ee16Smrg row_y[BOTTOM_ROW]= y+bounds->y1+(h/2)+(h/10); 14660e20ee16Smrg row_y[CENTER_ROW]= y+bounds->y1+(h/10); 14670e20ee16Smrg row_h[TOP_ROW]= h/2; 14680e20ee16Smrg row_h[BOTTOM_ROW]= h/2; 14690e20ee16Smrg row_h[CENTER_ROW]= h; 14700e20ee16Smrg 14710e20ee16Smrg col_x[LEFT_COL]= x+bounds->x1; 14720e20ee16Smrg col_x[RIGHT_COL]= x+bounds->x1+w/2; 14730e20ee16Smrg col_x[CENTER_COL]= x+bounds->x1; 14740e20ee16Smrg col_w[LEFT_COL]= w/2; 14750e20ee16Smrg col_w[RIGHT_COL]= w/2; 14760e20ee16Smrg col_w[CENTER_COL]= w; 14770e20ee16Smrg 14780e20ee16Smrg present[G1L1]= False; 14790e20ee16Smrg sym_row[G1L1]= BOTTOM_ROW; 14800e20ee16Smrg sym_col[G1L1]= LEFT_COL; 14810e20ee16Smrg 14820e20ee16Smrg present[G1L2]= False; 14830e20ee16Smrg sym_row[G1L2]= TOP_ROW; 14840e20ee16Smrg sym_col[G1L2]= LEFT_COL; 14850e20ee16Smrg 14860e20ee16Smrg present[G2L1]= False; 14870e20ee16Smrg sym_row[G2L1]= BOTTOM_ROW; 14880e20ee16Smrg sym_col[G2L1]= RIGHT_COL; 14890e20ee16Smrg 14900e20ee16Smrg present[G2L2]= False; 14910e20ee16Smrg sym_row[G2L2]= TOP_ROW; 14920e20ee16Smrg sym_col[G2L2]= RIGHT_COL; 14930e20ee16Smrg 14940e20ee16Smrg present[CENTER]= False; 14950e20ee16Smrg sym_row[CENTER]= CENTER_ROW; 14960e20ee16Smrg sym_col[CENTER]= CENTER_COL; 14970e20ee16Smrg 14980e20ee16Smrg if (top->present&CENTER_MASK) { 14990e20ee16Smrg present[CENTER]= True; 15000e20ee16Smrg } 15010e20ee16Smrg else switch (top->present&GXLX_MASK) { 15020e20ee16Smrg case G1L1_MASK: 15030e20ee16Smrg present[G1L1]= True; 15040e20ee16Smrg sym_row[G1L1]= CENTER_ROW; 15050e20ee16Smrg sym_col[G1L1]= CENTER_COL; 15060e20ee16Smrg break; 15070e20ee16Smrg case G1LX_MASK: 15080e20ee16Smrg present[G1L2]= True; 15090e20ee16Smrg if (!top->alpha[0]) { 15100e20ee16Smrg present[G1L1]= True; 15110e20ee16Smrg if ((strlen(top->label[G1L1])>1)&&(top->label[G1L1][0]!='\\')) 15120e20ee16Smrg sym_col[G1L1]= CENTER_COL; 15130e20ee16Smrg if ((strlen(top->label[G1L2])>1)&&(top->label[G1L1][0]!='\\')) 15140e20ee16Smrg sym_col[G1L2]= CENTER_COL; 15150e20ee16Smrg } 15160e20ee16Smrg break; 15170e20ee16Smrg default: 15180e20ee16Smrg if ((top->present&G1LX_MASK)==G1LX_MASK) { 15190e20ee16Smrg present[G1L2]= True; 15200e20ee16Smrg if (!top->alpha[0]) 15210e20ee16Smrg present[G1L1]= True; 15220e20ee16Smrg } 15230e20ee16Smrg else if ((top->present&G1LX_MASK)==G1L1_MASK) { 15240e20ee16Smrg present[G1L1]= True; 15250e20ee16Smrg } 15260e20ee16Smrg else if ((top->present&G1LX_MASK)==G1L2_MASK) { 15270e20ee16Smrg present[G1L2]= True; 15280e20ee16Smrg } 15290e20ee16Smrg if ((top->present&G2LX_MASK)==G2LX_MASK) { 15300e20ee16Smrg present[G2L2]= True; 15310e20ee16Smrg if (!top->alpha[1]) 15320e20ee16Smrg present[G2L1]= True; 15330e20ee16Smrg } 15340e20ee16Smrg else if ((top->present&G2LX_MASK)==G2L1_MASK) { 15350e20ee16Smrg present[G2L1]= True; 15360e20ee16Smrg } 15370e20ee16Smrg else if ((top->present&G2LX_MASK)==G2L2_MASK) { 15380e20ee16Smrg present[G2L2]= True; 15390e20ee16Smrg } 15400e20ee16Smrg break; 15410e20ee16Smrg case 0: 15420e20ee16Smrg return; 15430e20ee16Smrg } 15440e20ee16Smrg for (i=0;i<NLABELS;i++) { 15450e20ee16Smrg if (present[i]) { 15460e20ee16Smrg int len,size; 15470e20ee16Smrg if (top->size[i]==SZ_AUTO) { 15480e20ee16Smrg len= strlen(top->label[i]); 15490e20ee16Smrg if (len==1) { 15500e20ee16Smrg if (top->font[i]==FONT_ISOCAPS) 15510e20ee16Smrg size= 18; 15520e20ee16Smrg else size= 14; 15530e20ee16Smrg } 15540e20ee16Smrg else if (len<10) size= 12; 15550e20ee16Smrg else size= 10; 15560e20ee16Smrg } 15570e20ee16Smrg else if (top->size[i]==SZ_TINY) 15580e20ee16Smrg size= 10; 15590e20ee16Smrg else if (top->size[i]==SZ_SMALL) 15600e20ee16Smrg size= 12; 15610e20ee16Smrg else if (top->size[i]==SZ_LARGE) 15620e20ee16Smrg size= 18; 15630e20ee16Smrg else if (top->size[i]==SZ_XLARGE) 15640e20ee16Smrg size= 24; 15650e20ee16Smrg else size= 14; 15660e20ee16Smrg PSSetFont(out,state,top->font[i],size,True); 15670e20ee16Smrg PSDrawLabel(out,top->label[i],col_x[sym_col[i]],row_y[sym_row[i]], 15680e20ee16Smrg col_w[sym_col[i]],row_h[sym_row[i]]); 15690e20ee16Smrg } 15700e20ee16Smrg } 15710e20ee16Smrg if (state->args->wantKeycodes) { 15720e20ee16Smrg sprintf(keycode,"%d",kc); 15730e20ee16Smrg PSSetFont(out,state,FONT_LATIN1,8,True); 15740e20ee16Smrg PSDrawLabel(out,keycode,x+bounds->x1,y+btm-5,w,0); 15750e20ee16Smrg } 15760e20ee16Smrg return; 15770e20ee16Smrg} 15780e20ee16Smrg 15790e20ee16Smrgstatic void 15800e20ee16SmrgPSSection(FILE *out, PSState *state, XkbSectionPtr section) 15810e20ee16Smrg{ 15820e20ee16Smrgint r,offset; 15830e20ee16SmrgXkbRowPtr row; 15840e20ee16SmrgDisplay * dpy; 15850e20ee16SmrgXkbDescPtr xkb; 15860e20ee16Smrg 15870e20ee16Smrg xkb= state->xkb; 15880e20ee16Smrg dpy= xkb->dpy; 15890e20ee16Smrg fprintf(out,"%% Begin Section '%s'\n",(section->name!=None? 15900e20ee16Smrg XkbAtomGetString(dpy,section->name): 15910e20ee16Smrg "NoName")); 15920e20ee16Smrg PSGSave(out,state); 15930e20ee16Smrg fprintf(out,"%d %d translate\n",section->left,section->top); 15940e20ee16Smrg if (section->angle!=0) 15950e20ee16Smrg fprintf(out,"%s rotate\n",XkbGeomFPText(section->angle,XkbMessage)); 15960e20ee16Smrg if (section->doodads) { 15970e20ee16Smrg XkbDrawablePtr first,draw; 15980e20ee16Smrg first= draw= XkbGetOrderedDrawables(NULL,section); 15990e20ee16Smrg while (draw) { 16000e20ee16Smrg if (draw->type==XkbDW_Section) 16010e20ee16Smrg PSSection(out,state,draw->u.section); 16020e20ee16Smrg else PSDoodad(out,state,draw->u.doodad); 16030e20ee16Smrg draw= draw->next; 16040e20ee16Smrg } 16050e20ee16Smrg XkbFreeOrderedDrawables(first); 16060e20ee16Smrg } 16070e20ee16Smrg for (r=0,row=section->rows;r<section->num_rows;r++,row++) { 16080e20ee16Smrg int k; 16090e20ee16Smrg XkbKeyPtr key; 16100e20ee16Smrg XkbShapePtr shape; 16110e20ee16Smrg if (row->vertical) offset= row->top; 16120e20ee16Smrg else offset= row->left; 16130e20ee16Smrg fprintf(out,"%% Begin %s %d\n",row->vertical?"column":"row",r+1); 16140e20ee16Smrg for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 16150e20ee16Smrg shape= XkbKeyShape(xkb->geom,key); 16160e20ee16Smrg offset+= key->gap; 16170e20ee16Smrg if (row->vertical) { 16180e20ee16Smrg if (state->args->wantColor) { 16190e20ee16Smrg if (key->color_ndx!=state->white) { 16200e20ee16Smrg PSSetColor(out,state,key->color_ndx); 16210e20ee16Smrg fprintf(out,"true 0 %d %d %s %% %s\n", 16220e20ee16Smrg row->left,offset, 16230e20ee16Smrg XkbAtomGetString(dpy,shape->name), 16240e20ee16Smrg XkbKeyNameText(key->name.name,XkbMessage)); 16250e20ee16Smrg } 16260e20ee16Smrg PSSetColor(out,state,state->black); 16270e20ee16Smrg } 16280e20ee16Smrg fprintf(out,"false 0 %d %d %s %% %s\n",row->left,offset, 16290e20ee16Smrg XkbAtomGetString(dpy,shape->name), 16300e20ee16Smrg XkbKeyNameText(key->name.name,XkbMessage)); 16310e20ee16Smrg offset+= shape->bounds.y2; 16320e20ee16Smrg } 16330e20ee16Smrg else { 16340e20ee16Smrg if (state->args->wantColor) { 16350e20ee16Smrg if (key->color_ndx!=state->white) { 16360e20ee16Smrg PSSetColor(out,state,key->color_ndx); 16370e20ee16Smrg fprintf(out,"true 0 %d %d %s %% %s\n",offset,row->top, 16380e20ee16Smrg XkbAtomGetString(dpy,shape->name), 16390e20ee16Smrg XkbKeyNameText(key->name.name,XkbMessage)); 16400e20ee16Smrg } 16410e20ee16Smrg PSSetColor(out,state,state->black); 16420e20ee16Smrg } 16430e20ee16Smrg fprintf(out,"false 0 %d %d %s %% %s\n",offset,row->top, 16440e20ee16Smrg XkbAtomGetString(dpy,shape->name), 16450e20ee16Smrg XkbKeyNameText(key->name.name,XkbMessage)); 16460e20ee16Smrg offset+= shape->bounds.x2; 16470e20ee16Smrg } 16480e20ee16Smrg } 16490e20ee16Smrg } 16500e20ee16Smrg for (r=0,row=section->rows;r<section->num_rows;r++,row++) { 16510e20ee16Smrg int k,kc=0; 16520e20ee16Smrg XkbKeyPtr key; 16530e20ee16Smrg XkbShapePtr shape; 16540e20ee16Smrg XkbBoundsRec bounds; 16550e20ee16Smrg if (state->args->label==LABEL_NONE) 16560e20ee16Smrg break; 16570e20ee16Smrg if (row->vertical) offset= row->top; 16580e20ee16Smrg else offset= row->left; 16590e20ee16Smrg fprintf(out,"%% Begin %s %d labels\n",row->vertical?"column":"row",r+1); 16600e20ee16Smrg PSSetColor(out,state,xkb->geom->label_color->pixel); 16610e20ee16Smrg PSSetFont(out,state,FONT_LATIN1,12,True); 16620e20ee16Smrg for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 16630e20ee16Smrg char * name,*name2,buf[30],buf2[30]; 16640e20ee16Smrg int x,y; 16650e20ee16Smrg KeyTop top; 16660e20ee16Smrg 16670e20ee16Smrg shape= XkbKeyShape(xkb->geom,key); 16680e20ee16Smrg XkbComputeShapeTop(shape,&bounds); 16690e20ee16Smrg offset+= key->gap; 16700e20ee16Smrg name= name2= NULL; 16710e20ee16Smrg if (state->args->label==LABEL_SYMBOLS) { 16720e20ee16Smrg if (!FindKeysymsByName(xkb,key->name.name,state,&top)) { 16730e20ee16Smrg fprintf(out,"%% No label for %s\n", 16740e20ee16Smrg XkbKeyNameText(key->name.name,XkbMessage)); 16750e20ee16Smrg } 16760e20ee16Smrg } 16770e20ee16Smrg else { 16780e20ee16Smrg char *olKey; 16790e20ee16Smrg 16800e20ee16Smrg if (section->num_overlays>0) 16810e20ee16Smrg olKey= XkbFindOverlayForKey(xkb->geom,section, 16820e20ee16Smrg key->name.name); 16830e20ee16Smrg else olKey= NULL; 16840e20ee16Smrg 16850e20ee16Smrg if (state->args->label==LABEL_KEYNAME) { 16860e20ee16Smrg name= XkbKeyNameText(key->name.name,XkbMessage); 16870e20ee16Smrg if (olKey) 16880e20ee16Smrg name2= XkbKeyNameText(olKey,XkbMessage); 16890e20ee16Smrg } 16900e20ee16Smrg else if (state->args->label==LABEL_KEYCODE) { 16910e20ee16Smrg name= buf; 16920e20ee16Smrg sprintf(name,"%d",XkbFindKeycodeByName(xkb,key->name.name, 16930e20ee16Smrg True)); 16940e20ee16Smrg if (olKey) { 16950e20ee16Smrg name2= buf2; 16960e20ee16Smrg sprintf(name,"%d",XkbFindKeycodeByName(xkb,olKey,True)); 16970e20ee16Smrg } 16980e20ee16Smrg } 16990e20ee16Smrg bzero(&top,sizeof(KeyTop)); 17000e20ee16Smrg if (name2!=NULL) { 17010e20ee16Smrg top.present|= G1LX_MASK; 17020e20ee16Smrg strncpy(top.label[G1L1],name,LABEL_LEN-1); 17030e20ee16Smrg top.label[G1L1][LABEL_LEN-1]= '\0'; 17040e20ee16Smrg strncpy(top.label[G1L2],name2,LABEL_LEN-1); 17050e20ee16Smrg top.label[G1L2][LABEL_LEN-1]= '\0'; 17060e20ee16Smrg } 17070e20ee16Smrg else if (name!=NULL) { 17080e20ee16Smrg top.present|= CENTER_MASK; 17090e20ee16Smrg strncpy(top.label[CENTER],name,LABEL_LEN-1); 17100e20ee16Smrg top.label[CENTER][LABEL_LEN-1]= '\0'; 17110e20ee16Smrg } 17120e20ee16Smrg else { 17130e20ee16Smrg fprintf(out,"%% No label for %s\n", 17140e20ee16Smrg XkbKeyNameText(key->name.name,XkbMessage)); 17150e20ee16Smrg } 17160e20ee16Smrg } 17170e20ee16Smrg if (row->vertical) { 17180e20ee16Smrg x= row->left; 17190e20ee16Smrg y= offset; 17200e20ee16Smrg offset+= shape->bounds.y2; 17210e20ee16Smrg } 17220e20ee16Smrg else { 17230e20ee16Smrg x= offset; 17240e20ee16Smrg y= row->top; 17250e20ee16Smrg offset+= shape->bounds.x2; 17260e20ee16Smrg } 17270e20ee16Smrg name= key->name.name; 17280e20ee16Smrg fprintf(out,"%% %s\n",XkbKeyNameText(name,XkbMessage)); 17290e20ee16Smrg if (state->args->wantKeycodes) 17300e20ee16Smrg kc= XkbFindKeycodeByName(xkb,key->name.name,True); 17310e20ee16Smrg PSLabelKey(out,state,&top,x,y,&bounds,kc,shape->bounds.y2); 17320e20ee16Smrg } 17330e20ee16Smrg } 17340e20ee16Smrg PSGRestore(out,state); 17350e20ee16Smrg return; 17360e20ee16Smrg} 17370e20ee16Smrg 17380e20ee16SmrgBool 17390e20ee16SmrgGeometryToPostScript(FILE *out, XkbFileInfo *pResult, XKBPrintArgs *args) 17400e20ee16Smrg{ 17410e20ee16SmrgXkbDrawablePtr first,draw; 17420e20ee16SmrgPSState state; 17430e20ee16SmrgBool dfltBorder; 17440e20ee16Smrgint i; 17450e20ee16Smrg 17460e20ee16Smrg if ((!pResult)||(!pResult->xkb)||(!pResult->xkb->geom)) 17470e20ee16Smrg return False; 17480e20ee16Smrg state.xkb= pResult->xkb; 17490e20ee16Smrg state.dpy= pResult->xkb->dpy; 17500e20ee16Smrg state.geom= pResult->xkb->geom; 17510e20ee16Smrg state.color= state.black= state.white= -1; 17520e20ee16Smrg state.font= -1; 17530e20ee16Smrg state.nPages= 0; 17540e20ee16Smrg state.totalKB= 1; 17550e20ee16Smrg state.kbPerPage= 1; 17560e20ee16Smrg state.x1= state.y1= state.x2= state.y2= 0; 17570e20ee16Smrg state.args= args; 17580e20ee16Smrg 17590e20ee16Smrg if ((args->label==LABEL_SYMBOLS)&&(pResult->xkb->ctrls)) { 17600e20ee16Smrg if (args->nTotalGroups==0) 17610e20ee16Smrg state.totalKB= pResult->xkb->ctrls->num_groups/args->nLabelGroups; 17620e20ee16Smrg else state.totalKB= args->nTotalGroups; 17630e20ee16Smrg if (state.totalKB<1) 17640e20ee16Smrg state.totalKB= 1; 17650e20ee16Smrg else if (state.totalKB>1) 17660e20ee16Smrg state.kbPerPage= 2; 17670e20ee16Smrg } 17680e20ee16Smrg if (args->nKBPerPage!=0) 17690e20ee16Smrg state.kbPerPage= args->nKBPerPage; 17700e20ee16Smrg 17710e20ee16Smrg PSProlog(out,&state); 17720e20ee16Smrg first= XkbGetOrderedDrawables(state.geom,NULL); 17730e20ee16Smrg 17740e20ee16Smrg for (draw=first,dfltBorder=True;draw!=NULL;draw=draw->next) { 17750e20ee16Smrg if ((draw->type!=XkbDW_Section)&& 17760e20ee16Smrg ((draw->u.doodad->any.type==XkbOutlineDoodad)|| 17770e20ee16Smrg (draw->u.doodad->any.type==XkbSolidDoodad))) { 17780e20ee16Smrg char *name; 17790e20ee16Smrg name= XkbAtomGetString(state.dpy,draw->u.doodad->any.name); 17800e20ee16Smrg if ((name!=NULL)&&(uStrCaseEqual(name,"edges"))) { 17810e20ee16Smrg dfltBorder= False; 17820e20ee16Smrg break; 17830e20ee16Smrg } 17840e20ee16Smrg } 17850e20ee16Smrg } 17860e20ee16Smrg for (i=0;i<state.totalKB;i++) { 17870e20ee16Smrg PSPageSetup(out,&state,dfltBorder); 17880e20ee16Smrg for (draw=first;draw!=NULL;draw=draw->next) { 17890e20ee16Smrg if (draw->type==XkbDW_Section) 17900e20ee16Smrg PSSection(out,&state,draw->u.section); 17910e20ee16Smrg else { 17920e20ee16Smrg PSDoodad(out,&state,draw->u.doodad); 17930e20ee16Smrg } 17940e20ee16Smrg } 17950e20ee16Smrg PSPageTrailer(out,&state); 17960e20ee16Smrg state.args->baseLabelGroup+= state.args->nLabelGroups; 17970e20ee16Smrg } 17980e20ee16Smrg XkbFreeOrderedDrawables(first); 17990e20ee16Smrg PSFileTrailer(out,&state); 18000e20ee16Smrg return True; 18010e20ee16Smrg} 1802