From d449c410a7ca823910ac416ca5dd9604b16cdd89 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Fri, 6 Oct 2006 09:54:57 +0000 Subject: added xdv2pdf driver for xetex (on OS X only) git-svn-id: svn://tug.org/texlive/trunk@2246 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/xdv2pdf/DVIops.h | 77 + Build/source/texk/xdv2pdf/LICENSE.txt | 31 + Build/source/texk/xdv2pdf/Makefile.in | 78 + Build/source/texk/xdv2pdf/SimplePSInterpreter.h | 21 + Build/source/texk/xdv2pdf/SimplePSInterpreter.m | 851 ++++++++ Build/source/texk/xdv2pdf/T1Wrap.m | 746 +++++++ Build/source/texk/xdv2pdf/acconfig.h | 37 + Build/source/texk/xdv2pdf/acconfig.h.in | 45 + Build/source/texk/xdv2pdf/appleGlyphNames.c | 272 +++ Build/source/texk/xdv2pdf/c-auto.in | 4 + Build/source/texk/xdv2pdf/config.h.in | 68 + Build/source/texk/xdv2pdf/configure | 2298 ++++++++++++++++++++++ Build/source/texk/xdv2pdf/configure.in | 66 + Build/source/texk/xdv2pdf/xdv2pdf.cpp | 2348 +++++++++++++++++++++++ Build/source/texk/xdv2pdf/xdv2pdf_globals.h | 142 ++ Build/source/texk/xdv2pdf/xdv2pdf_main.c | 227 +++ Build/source/texk/xdv2pdf/xdv2pdf_mergemarks | 205 ++ Build/source/texk/xdv2pdf/xdv2pdf_specials.cpp | 770 ++++++++ Build/source/texk/xdv2pdf/xdv_kpse_formats.h | 16 + 19 files changed, 8302 insertions(+) create mode 100755 Build/source/texk/xdv2pdf/DVIops.h create mode 100644 Build/source/texk/xdv2pdf/LICENSE.txt create mode 100644 Build/source/texk/xdv2pdf/Makefile.in create mode 100644 Build/source/texk/xdv2pdf/SimplePSInterpreter.h create mode 100644 Build/source/texk/xdv2pdf/SimplePSInterpreter.m create mode 100644 Build/source/texk/xdv2pdf/T1Wrap.m create mode 100644 Build/source/texk/xdv2pdf/acconfig.h create mode 100644 Build/source/texk/xdv2pdf/acconfig.h.in create mode 100644 Build/source/texk/xdv2pdf/appleGlyphNames.c create mode 100644 Build/source/texk/xdv2pdf/c-auto.in create mode 100644 Build/source/texk/xdv2pdf/config.h.in create mode 100755 Build/source/texk/xdv2pdf/configure create mode 100644 Build/source/texk/xdv2pdf/configure.in create mode 100755 Build/source/texk/xdv2pdf/xdv2pdf.cpp create mode 100644 Build/source/texk/xdv2pdf/xdv2pdf_globals.h create mode 100755 Build/source/texk/xdv2pdf/xdv2pdf_main.c create mode 100755 Build/source/texk/xdv2pdf/xdv2pdf_mergemarks create mode 100644 Build/source/texk/xdv2pdf/xdv2pdf_specials.cpp create mode 100644 Build/source/texk/xdv2pdf/xdv_kpse_formats.h (limited to 'Build') diff --git a/Build/source/texk/xdv2pdf/DVIops.h b/Build/source/texk/xdv2pdf/DVIops.h new file mode 100755 index 00000000000..5a86d4e8cf1 --- /dev/null +++ b/Build/source/texk/xdv2pdf/DVIops.h @@ -0,0 +1,77 @@ +/****************************************************************************\ + Part of the XeTeX typesetting system + copyright (c) 1994-2005 by SIL International + written by Jonathan Kew + + This software is distributed under the terms of the Common Public License, + version 1.0. + For details, see or the file + cpl1.0.txt included with the software. +\****************************************************************************/ + +#define DVI_SETCHAR0 0 +#define DVI_SET1 128 +#define DVI_SET2 129 +#define DVI_SET3 130 +#define DVI_SET4 131 +#define DVI_SETRULE 132 +#define DVI_PUT1 133 +#define DVI_PUT2 134 +#define DVI_PUT3 135 +#define DVI_PUT4 136 +#define DVI_PUTRULE 137 +#define DVI_NOP 138 +#define DVI_BOP 139 +#define DVI_EOP 140 +#define DVI_PUSH 141 +#define DVI_POP 142 +#define DVI_RIGHT1 143 +#define DVI_RIGHT2 144 +#define DVI_RIGHT3 145 +#define DVI_RIGHT4 146 +#define DVI_W0 147 +#define DVI_W1 148 +#define DVI_W2 149 +#define DVI_W3 150 +#define DVI_W4 151 +#define DVI_X0 152 +#define DVI_X1 153 +#define DVI_X2 154 +#define DVI_X3 155 +#define DVI_X4 156 +#define DVI_DOWN1 157 +#define DVI_DOWN2 158 +#define DVI_DOWN3 159 +#define DVI_DOWN4 160 +#define DVI_Y0 161 +#define DVI_Y1 162 +#define DVI_Y2 163 +#define DVI_Y3 164 +#define DVI_Y4 165 +#define DVI_Z0 166 +#define DVI_Z1 167 +#define DVI_Z2 168 +#define DVI_Z3 169 +#define DVI_Z4 170 +#define DVI_FNTNUM0 171 +#define DVI_FNT1 235 +#define DVI_FNT2 236 +#define DVI_FNT3 237 +#define DVI_FNT4 238 +#define DVI_XXX1 239 +#define DVI_XXX2 240 +#define DVI_XXX3 241 +#define DVI_XXX4 242 +#define DVI_FNTDEF1 243 +#define DVI_FNTDEF2 244 +#define DVI_FNTDEF3 245 +#define DVI_FNTDEF4 246 +#define DVI_PRE 247 +#define DVI_POST 248 +#define DVI_POSTPOST 249 +#define DVI_TRAILER 223 + +#define XDV_GLYPH_STRING 254 +#define XDV_GLYPH_ARRAY 253 +#define XDV_NATIVE_FONT_DEF 252 +#define XDV_PIC_FILE 251 diff --git a/Build/source/texk/xdv2pdf/LICENSE.txt b/Build/source/texk/xdv2pdf/LICENSE.txt new file mode 100644 index 00000000000..ed7486edc2e --- /dev/null +++ b/Build/source/texk/xdv2pdf/LICENSE.txt @@ -0,0 +1,31 @@ +/****************************************************************************\ + The XeTeX typesetting system + (an extended version of Donald Knuth's TeX) + written by Jonathan Kew + + The XeTeX changes/additions are copyright (c) 1994-2006 by SIL International + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL SIL INTERNATIONAL BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of SIL International +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in this Software without prior written +authorization from SIL International. +\****************************************************************************/ diff --git a/Build/source/texk/xdv2pdf/Makefile.in b/Build/source/texk/xdv2pdf/Makefile.in new file mode 100644 index 00000000000..71e452f4e53 --- /dev/null +++ b/Build/source/texk/xdv2pdf/Makefile.in @@ -0,0 +1,78 @@ +kpse_include ../make/paths.mk +kpse_include ../make/common.mk +kpse_include ../make/programs.mk + +CXX = c++ +OBJC = cc +CXXLD = $(CXX) +cxx_link_command = $(CXXLD) -o $@ $(LDFLAGS) +kpathsea_cxx_link = $(LIBTOOL) --mode=link $(cxx_link_command) + +ALL_CXXFLAGS = @CXXFLAGS@ @DEFS@ $(XXCFLAGS) -I. -I$(srcdir) +ALL_OBJCFLAGS = @DEFS@ $(XXOBJCFLAGS) -I. -I$(srcdir) + +.SUFFIXES: .cpp .o .m +.cpp.o: + $(CXX) $(ALL_CXXFLAGS) -c $< +.m.o: + $(OBJC) $(ALL_OBJCFLAGS) -c $< + +FRAMEWORKS = \ + -framework Carbon \ + -framework QuickTime + +FRAMEWORKS_t1w = -framework Cocoa +LIBS_t1w = -lm + +program = xdv2pdf +t1wrap = T1Wrap +programs = $(program) $(t1wrap) +default all: $(programs) + +objects=xdv2pdf_main.o xdv2pdf.o xdv2pdf_specials.o + +objects_t1w=T1Wrap.o SimplePSInterpreter.o + +$(objects): Makefile +$(objects_t1m): Makefile + +$(program): $(objects) $(kpathsea) $(ALL_LIBS_DEP) + $(kpathsea_cxx_link) $(objects) $(FRAMEWORKS) $(LOADLIBES) + +$(t1wrap): $(objects_t1w) + $(CC) -o $@ $(objects_t1w) $(FRAMEWORKS_t1w) $(LIBS_t1w) + +T1Wrap.o: $(srcdir)/T1Wrap.m + $(OBJC) $(ALL_OBJCFLAGS) -c $< + +SimplePSInterpreter.o: $(srcdir)/SimplePSInterpreter.m + $(OBJC) $(ALL_OBJCFLAGS) -c $< + +kpse_include ../make/tkpathsea.mk + +install: install-exec install-data +uninstall: uninstall-exec uninstall-data + +distclean:: + $(RM) config.h + +install-exec: + $(SHELL) $(top_srcdir)/../mkinstalldirs $(bindir) + $(INSTALL_LIBTOOL_PROG) $(program) $(bindir) + $(INSTALL) $(t1wrap) $(bindir) + +uninstall-exec: + cd $(bindir); rm -f $(programs) + +install-data: + $(SHELL) $(top_srcdir)/../mkinstalldirs $(man1dir) + +uninstall-data: + +kpse_include ../make/config.mk + +info dvi check: + +kpse_include ../make/clean.mk +kpse_include ../make/rdepend.mk +kpse_include depend.mk diff --git a/Build/source/texk/xdv2pdf/SimplePSInterpreter.h b/Build/source/texk/xdv2pdf/SimplePSInterpreter.h new file mode 100644 index 00000000000..47ececa38d5 --- /dev/null +++ b/Build/source/texk/xdv2pdf/SimplePSInterpreter.h @@ -0,0 +1,21 @@ +// +// SimplePSInterpreter.h +// T1Wrap +// +// Created by Massimiliano Gubinelli on 10/02/2005. +// Copyright 2005 Massimilano Gubinelli. All rights reserved. +// + +#import + + +@interface SimplePSInterpreter : NSObject { + NSMutableArray *stack, *dicts; + NSMutableDictionary *fontDir; + NSMutableString *inputStream; + NSScanner *sc; + int nStoringProc; +} +- (void)doString:(NSString *)anInputString; +- (NSDictionary*)fontDir; +@end diff --git a/Build/source/texk/xdv2pdf/SimplePSInterpreter.m b/Build/source/texk/xdv2pdf/SimplePSInterpreter.m new file mode 100644 index 00000000000..230bb98a49c --- /dev/null +++ b/Build/source/texk/xdv2pdf/SimplePSInterpreter.m @@ -0,0 +1,851 @@ +// +// SimplePSInterpreter.m +// T1Wrap +// +// Created by Massimiliano Gubinelli on 10/02/2005. +// Copyright 2005 Massimiliano Gubinelli. All rights reserved. +// + +// Based on a Perl script by Jonathan Kew (February 2005) + +#import "SimplePSInterpreter.h" + +static NSString *SimplePSInterpreterException = @"SimplePSInterpreterException"; + +@interface NSMutableArray (Stack) +- pop; +@end + +@implementation NSMutableArray (Stack) +- pop +{ + id value = [[[self lastObject] retain] autorelease]; + [self removeLastObject]; + return value; +} +@end + +@interface SimplePSInterpreter (Private) +- (void) execProc:(NSArray *)proc; +- (void) execObj:(id)obj; +- (void) execName:(NSString *)identifier; + +// PS operators +- (void) opString; +- (void) opReadstring; +- (void) opDef; +- (void) opNot; +- (void) opDict; +- (void) opBegin; +- (void) opEnd; +- (void) opPop; +- (void) opDup; +- (void) opNop; +- (void) opGet; +- (void) opPut; +- (void) opGetinterval; +- (void) opPutinterval; +- (void) opArray; +- (void) opMark; +- (void) opCleartomark; +- (void) opExch; +- (void) opIndex; +- (void) opFor; +- (void) opKnown; +- (void) opIf; +- (void) opIfelse; +- (void) opCurrentdict; +- (void) opCurrentfile; +- (void) opClosefile; +- (void) opDefinefont; +- (void) opEexec; +- (void) opExec; +- (void) opNe; +- (void) opEq; +- (void) initializeInterpreter; +@end // interface + +@implementation SimplePSInterpreter + +static NSString *StackMarkObject = @" MARK "; +static NSString *NullPSObject = @"[NIL]"; + +- (void) opString +{ + int n = 0; + id obj = [stack pop]; + if (![obj isKindOfClass:[NSNumber class]]) + [NSException raise:SimplePSInterpreterException format:@"string parameter is not a number"]; + else n = [obj intValue]; +#if 0 + NSMutableString *emptyString = [NSMutableString stringWithCapacity:[(NSNumber*)obj intValue]]; + while (n--) [emptyString appendString:@" "]; + [stack addObject:emptyString]; +#else +// char *ss = alloca(n+1); + char *ss = alloca(n); +// ss[n] = 0x0; + int i = n; + while (i) ss[--i] = ' '; +// [stack addObject:[NSString stringWithCString:ss length:n]]; + [stack addObject:[[NSString alloc] initWithBytes:ss length:n encoding:NSMacOSRomanStringEncoding]]; +#endif + +} + +- (void) opReadstring +{ + id stringobj = [stack pop]; + id fileobj = [stack pop]; + if (![fileobj isKindOfClass:[NSString class]] || ![stringobj isKindOfClass:[NSString class]] ) + [NSException raise:SimplePSInterpreterException format:@"wrong arguments in readstring"]; + if (![(NSString*)fileobj isEqualToString:@" "]) + [NSException raise:SimplePSInterpreterException format:@"cannot read string from file %@",fileobj]; + int len = [(NSString*)stringobj length]; + + NSString *dataString = [inputStream substringWithRange:NSMakeRange([sc scanLocation]+1,len)]; + [sc setScanLocation:[sc scanLocation]+1+len]; // skip whitespace & data string + [stack addObject:dataString]; + [stack addObject:[NSNumber numberWithInt:1]]; +} + +- (void) opDef +{ + id obj = [stack pop]; + id nameobj = [stack pop]; + if (![nameobj isKindOfClass:[NSString class]]) + [NSException raise:SimplePSInterpreterException format:@"defining non name"]; + else { + NSString *name = nameobj; + if ([name characterAtIndex:0] != '/') NSLog(@"Warning: defining non literal name"); + [(NSMutableDictionary*)[dicts lastObject] setObject:obj forKey:name]; + [(NSMutableArray*)[(NSDictionary*)[dicts lastObject] objectForKey:@"[KEY ORDER]"] addObject:name]; + } +} + +- (void) opNot +{ + id myBool = [stack pop]; + if ([myBool isKindOfClass:[NSNumber class]]) { + [stack addObject:[NSNumber numberWithInt:([(NSNumber*)myBool intValue]? 0 : 1)]]; + } + else [NSException raise:SimplePSInterpreterException format:@"cannot apply to non-boolean object"]; +} + +- (void) opNe +{ + id a = [stack pop]; + id b = [stack pop]; + [stack addObject:[NSNumber numberWithInt:([a isEqualTo:b] ? 0 : 1 )]]; +} + + +- (void) opEq +{ + id a = [stack pop]; + id b = [stack pop]; + [stack addObject:[NSNumber numberWithInt:([a isEqualTo:b] ? 1 : 0 )]]; +} + +- (void) execProc:(NSArray *)procwrapper +{ + NSArray *proc = [procwrapper objectAtIndex:1]; + NSEnumerator *en = [proc objectEnumerator]; + id obj; + while ((obj = [en nextObject])) { + [self execObj:obj]; + } +} + +- (void) execObj:(id)obj +{ + if ([obj isKindOfClass:[NSInvocation class]]) + { + [(NSInvocation*)obj setTarget:self]; + [(NSInvocation*)obj invoke]; + } else if ([obj isKindOfClass:[NSArray class]]) + { +#if 1 + NSString *type = [(NSArray*)obj objectAtIndex:0]; + if ([type isEqualToString:@"proc"]) [self execProc:obj]; + else +#endif + [stack addObject:obj]; + + } else if ([obj isKindOfClass:[NSString class]]) + { + NSString *identifier = obj; + if ([identifier characterAtIndex:0]=='/') + [stack addObject:identifier]; + else + [self execName:identifier]; + } else + [stack addObject:obj]; +} + +- (void) execName:(NSString *)identifier +{ + NSEnumerator *en = [dicts reverseObjectEnumerator]; + NSDictionary *d; + id value = nil; + while (d = [en nextObject]) { + if (!(value = [d objectForKey:identifier])) value = [d objectForKey:[@"/" stringByAppendingString:identifier]]; + if (value) break; + } + + if (value) { + [self execObj: value]; + } + else { + [stack addObject:identifier]; + } +} + +- (void) opDict +{ + id obj = [stack pop]; + if (![obj isKindOfClass:[NSNumber class]]) + [NSException raise:SimplePSInterpreterException format:@"wrong type argument for dict"]; + NSMutableDictionary *newDict = [NSMutableDictionary dictionaryWithCapacity:[(NSNumber*)obj intValue]+1]; + [newDict setObject:[NSMutableArray arrayWithCapacity:[(NSNumber*)obj intValue]] + forKey:@"[KEY ORDER]"]; // KEY ORDER auxiliary array + [stack addObject:newDict]; +} + + +- (void) opBegin +{ + id obj = [stack pop]; + if (![obj isKindOfClass:[NSDictionary class]]) + [NSException raise:SimplePSInterpreterException format:@"wrong type argument for begin, expecting a dictionary"]; + [dicts addObject:obj]; +} + + +- (void) opEnd +{ + if ([dicts count]==0) + [NSException raise:SimplePSInterpreterException format:@"dictionary stack underflow"]; + [dicts removeLastObject]; +} + +- (void) opPop +{ + [stack removeLastObject]; +} + +- (void) opDup +{ +#if 0 + id aCopy = [[stack lastObject] copy]; + [stack addObject:aCopy]; + [aCopy release]; +#else + id aCopy = [stack lastObject]; + [stack addObject:aCopy]; +#endif +} + +- (void) opNop +{ +} + +- (void) opGet +{ + id key = [stack pop]; + id target = [stack pop]; + if ([target isKindOfClass:[NSArray class]]) + { + if (![key isKindOfClass:[NSNumber class]]) + [NSException raise:SimplePSInterpreterException + format:@"wrong type argument for get, key should be a number"]; + + [stack addObject:[(NSArray*)[(NSArray*)target objectAtIndex:1] objectAtIndex:[(NSNumber*)key intValue]]]; + } else if ([target isKindOfClass:[NSDictionary class]]) { + if (![key isKindOfClass:[NSString class]]) + [NSException raise:SimplePSInterpreterException + format:@"wrong type argument for get, key should be a number"]; + if ([(NSString*)key characterAtIndex:0] != '/') + [NSException raise:SimplePSInterpreterException + format:@"expecting literal dictionary key for get"]; + id value = [(NSDictionary*)target objectForKey:key]; + if (value) + [stack addObject:value]; + else + [stack addObject:NullPSObject]; + } else + [NSException raise:SimplePSInterpreterException + format:@"applying get to nonarray/dict"]; +} + +- (void) opPut +{ + id value = [stack pop]; + id key = [stack pop]; + id target = [stack pop]; + if ([target isKindOfClass:[NSArray class]]) + { + if (![key isKindOfClass:[NSNumber class]]) + [NSException raise:SimplePSInterpreterException + format:@"wrong type argument for put, key should be a number"]; + + [(NSMutableArray*)[(NSArray*)target objectAtIndex:1] replaceObjectAtIndex:[(NSNumber*)key intValue] + withObject:value]; + } else if ([target isKindOfClass:[NSDictionary class]]) { + if (![key isKindOfClass:[NSString class]]) + [NSException raise:SimplePSInterpreterException + format:@"wrong type argument for put, key should be a number"]; + if ([(NSString*)key characterAtIndex:0] != '/') + [NSException raise:SimplePSInterpreterException + format:@"expecting literal dictionary key for put"]; + + [(NSMutableDictionary*)target setObject:value forKey:key]; + [(NSMutableArray*)[(NSMutableDictionary*)target objectForKey:@"[KEY ORDER]"] + addObject:key]; + } else + [NSException raise:SimplePSInterpreterException + format:@"applying put to nonarray/dict"]; + +} + + +- (void) opGetinterval +{ + id count = [stack pop]; + id index = [stack pop]; + id array = [stack pop]; + if ([array isKindOfClass:[NSArray class]]) { + if ([count isKindOfClass:[NSNumber class]] && [index isKindOfClass:[NSNumber class]]) + [stack addObject:[NSArray arrayWithObjects:@"array",[(NSArray*)[(NSArray*)array objectAtIndex:1] subarrayWithRange: + NSMakeRange([(NSNumber*)index intValue],[(NSNumber*)count intValue])],nil]]; + else + [NSException raise:SimplePSInterpreterException + format:@"applying getinterval with nonnumber count or index"]; + } + else + [NSException raise:SimplePSInterpreterException + format:@"applying getinterval to nonarray"]; + +} + +- (void) opPutinterval +{ + id array2 = [stack pop]; + id index = [stack pop]; + id array = [stack pop]; + if ([array isKindOfClass:[NSArray class]]) { + if (![array2 isKindOfClass:[NSArray class]]) + [NSException raise:SimplePSInterpreterException + format:@"using putinterval with nonarray source"]; + if (![index isKindOfClass:[NSNumber class]]) + [NSException raise:SimplePSInterpreterException + format:@"using putinterval with nonnumber index"]; + NSArray *source = [(NSArray*)array2 objectAtIndex:1]; + int count = [array2 count]; + [(NSMutableArray*)[(NSArray*)array objectAtIndex:1] + replaceObjectsInRange:NSMakeRange([(NSNumber*)index intValue],count) + withObjectsFromArray:source + range:NSMakeRange(0,count)]; + } + else + [NSException raise:SimplePSInterpreterException + format:@"applying putinterval to nonarray"]; +} + +- (void) opArray +{ + id countobj = [stack pop]; + if (![countobj isKindOfClass:[NSNumber class]]) + [NSException raise:SimplePSInterpreterException + format:@"using array with nonnumber count"]; + int count = [countobj intValue]; + NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:count]; + while(count--) [array addObject:NullPSObject]; + [stack addObject:[NSArray arrayWithObjects:@"array",array,nil]]; + [array release]; +} + +- (void) opMark +{ + [stack addObject:StackMarkObject]; +} + +- (void) opCleartomark +{ + id obj; + while ((obj = [stack lastObject])) { + if (obj == StackMarkObject) break; + [stack removeLastObject]; + } + if (obj) [stack removeLastObject]; +} + +- (void) opExch +{ + id a = [stack pop]; + id b = [stack pop]; + [stack addObject:a]; + [stack addObject:b]; +} + +- (void) opIndex +{ + id index = [stack pop]; + if (![index isKindOfClass:[NSNumber class]]) + [NSException raise:SimplePSInterpreterException + format:@"using index with nonnumber count"]; + [stack addObject:[stack objectAtIndex:[stack count]-[(NSNumber*)index intValue]-1]]; +} + +- (void) opFor +{ + id proc = [stack pop]; + id limitobj = [stack pop]; + id stepobj = [stack pop]; + id startobj = [stack pop]; + if ([limitobj isKindOfClass:[NSNumber class]] && + [stepobj isKindOfClass:[NSNumber class]] && + [startobj isKindOfClass:[NSNumber class]] && + [proc isKindOfClass:[NSArray class]] ) { + int limit = [(NSNumber*)limitobj intValue]; + int step = [(NSNumber*)stepobj intValue]; + int start = [(NSNumber*)startobj intValue]; + for ( ;start <= limit;start += step) { + [stack addObject:[NSNumber numberWithInt:start]]; + [self execProc: proc]; + }; + } + else + [NSException raise:SimplePSInterpreterException + format:@"wrong arguments in for"]; + +} + + +- (void) opKnown +{ + id key = [stack pop]; + id dict = [stack pop]; + [stack addObject:[NSNumber numberWithInt:([(NSDictionary*)dict objectForKey:key] ? 1 : 0)]]; +} + +- (void) opIf +{ + id trueproc = [stack pop]; + id condition = [stack pop]; + + if (![condition isKindOfClass:[NSNumber class]]) + [NSException raise:SimplePSInterpreterException + format:@"condition in if is not a boolean"]; + + if ([(NSNumber*)condition intValue]) [self execProc:trueproc]; +} + +- (void) opIfelse +{ + id falseproc = [stack pop]; + id trueproc = [stack pop]; + id condition = [stack pop]; + + if (![condition isKindOfClass:[NSNumber class]]) + [NSException raise:SimplePSInterpreterException + format:@"condition in ifelse is not a boolean"]; + + if ([(NSNumber*)condition intValue]) + [self execProc:trueproc]; + else [self execProc:falseproc]; +} + +- (void) opCurrentdict +{ + [stack addObject:[dicts lastObject]]; +} + +- (void) opCurrentfile +{ + [stack addObject:@" "]; +} + +- (void) opClosefile +{ + [stack pop]; +} + +- (void) opDefinefont +{ + id font = [stack pop]; + id key = [stack pop]; + [fontDir setObject:font forKey:key]; + [stack addObject:font]; +} + +NSString *decryptString(NSString *inString) +{ + unsigned const char *inbuf = [inString cString]; + unsigned long insize = [inString cStringLength]; + NSMutableData *result = [NSMutableData dataWithLength:insize]; + unsigned char *outbuf = [result mutableBytes]; + unsigned short R = 55665; /* key */ + unsigned short c1 = 52845; + unsigned short c2 = 22719; + unsigned long counter; + + for(counter = 0; counter < insize; counter++) { + outbuf[counter] = (inbuf[counter] ^ (R>>8)); + R = (inbuf[counter] + R) * c1 + c2; + } +// NSString *resString = [NSString stringWithCString:outbuf length:insize]; + NSString *resString = [[NSString alloc] initWithData:result encoding:NSMacOSRomanStringEncoding]; + return resString; +} + +- (void) opEexec +{ + id fileobj = [stack pop]; + [sc scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] + intoString:nil]; + int startLoc = [sc scanLocation]; + NSString *dataString; + if ([sc scanUpToString:@"00000000000000000000" intoString:&dataString]) + { + NSString *decryptedStream = decryptString(dataString); + [inputStream deleteCharactersInRange:NSMakeRange(startLoc,[inputStream length]-startLoc)]; + [inputStream appendString:[decryptedStream substringFromIndex:4]]; // skip first 4 characters + [sc setScanLocation:startLoc]; + } else + [NSException raise:SimplePSInterpreterException + format:@"cannot find end of stream in eexec"]; +} + + + +- (void) opExec +{ + id obj = [stack pop]; + if ([obj isKindOfClass:[NSString class]]) [self execName:obj]; + if ([obj isKindOfClass:[NSArray class]] && [(NSString*)[(NSArray*)obj objectAtIndex:0] isEqualToString:@"proc"]) + { + [self execProc:obj]; + } + else [NSException raise:SimplePSInterpreterException + format:@"unimplemented exec feature"]; +} + +- (void) opCount +{ + [stack addObject:[NSNumber numberWithInt:[stack count]]]; +} + +- (void) opType +{ + id obj = [stack pop]; + NSString *type = @"/nulltype"; + if ([obj isKindOfClass:[NSNumber class]]) + type = @"/integertype"; + else if ([obj isKindOfClass:[NSDictionary class]]) + type = @"/dicttype"; + else if ([obj isKindOfClass:[NSArray class]]) { + NSString *head = [(NSArray*)obj objectAtIndex:0]; + if ([head isEqualToString:@"array"]) + type = @"/arraytype"; + else + type = @"/arraytype"; // not quite correct... + } else if ([obj isKindOfClass:[NSString class]]) { + if ([obj characterAtIndex:0] == '/') type = @"/nametype" ; + else + type = @"/stringtype"; + } + + [stack addObject:type]; +} + +- (NSInvocation *) makeInvocationForOp:(SEL) theSelector +{ + NSMethodSignature *aSignature; + NSInvocation *anInvocation; + aSignature = [[self class] instanceMethodSignatureForSelector:theSelector]; + anInvocation = [NSInvocation invocationWithMethodSignature:aSignature]; + [anInvocation setSelector:theSelector]; + return anInvocation; +} + +- (void)initializeInterpreter +{ + if (stack) [stack release]; + if (dicts) [dicts release]; + if (fontDir) [fontDir release]; + if (inputStream) [inputStream release]; + if (sc) [sc release]; + + stack = [[NSMutableArray arrayWithCapacity:10000] retain]; + dicts = [[NSMutableArray arrayWithCapacity:10] retain]; + fontDir = [[NSMutableDictionary dictionaryWithCapacity:10] retain]; + inputStream = nil; + sc = nil; + nStoringProc = 0; + + NSArray *standardEncoding = [NSArray arrayWithObjects: + @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", + @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", + @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", + @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", + @"/space", @"/exclam", @"/quotedbl", @"/numbersign", @"/dollar", @"/percent", @"/ampersand", @"/quoteright", + @"/parenleft", @"/parenright", @"/asterisk", @"/plus", @"/comma", @"/hyphen", @"/period", @"/slash", + @"/zero", @"/one", @"/two", @"/three", @"/four", @"/five", @"/six", @"/seven", + @"/eight", @"/nine", @"/colon", @"/semicolon", @"/less", @"/equal", @"/greater", @"/question", + @"/at", @"/A", @"/B", @"/C", @"/D", @"/E", @"/F", @"/G", + @"/H", @"/I", @"/J", @"/K", @"/L", @"/M", @"/N", @"/O", + @"/P", @"/Q", @"/R", @"/S", @"/T", @"/U", @"/V", @"/W", + @"/X", @"/Y", @"/Z", @"/bracketleft", @"/backslash", @"/bracketright", @"/asciicircum", @"/underscore", + @"/quoteleft", @"/a", @"/b", @"/c", @"/d", @"/e", @"/f", @"/g", + @"/h", @"/i", @"/j", @"/k", @"/l", @"/m", @"/n", @"/o", + @"/p", @"/q", @"/r", @"/s", @"/t", @"/u", @"/v", @"/w", + @"/x", @"/y", @"/z", @"/braceleft", @"/bar", @"/braceright", @"/asciitilde", @"/.notdef", + @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", + @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", + @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", + @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", + @"/.notdef", @"/exclamdown", @"/cent", @"/sterling", @"/fraction", @"/yen", @"/florin", @"/section", + @"/currency", @"/quotesingle", @"/quotedblleft", @"/guillemotleft", @"/guilsinglleft", @"/guilsinglright", @"/fi", @"/fl", + @"/.notdef", @"/endash", @"/dagger", @"/daggerdbl", @"/periodcentered", @"/.notdef", @"/paragraph", + @"/bullet", @"/quotesinglbase", @"/quotedblbase", @"/quotedblright", @"/guillemotright", @"/ellipsis", @"/perthousand", @"/.notdef", @"/questiondown", + @"/.notdef", @"/grave", @"/acute", @"/circumflex", @"/tilde", @"/macron", @"/breve", @"/dotaccent", + @"/dieresis", @"/.notdef", @"/ring", @"/cedilla", @"/.notdef", @"/hungarumlaut", @"/ogonek", @"/caron", + @"/emdash", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", + @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", + @"/.notdef", @"/AE", @"/.notdef", @"/ordfeminine", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", + @"/Lslash", @"/Oslash", @"/OE", @"/ordmasculine", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", + @"/.notdef", @"/ae", @"/.notdef", @"/.notdef", @"/.notdef", @"/dotlessi", @"/.notdef", @"/.notdef", + @"/lslash", @"/oslash", @"/oe", @"/germandbls", @"/.notdef", @"/.notdef", @"/.notdef", @"/.notdef", nil + ]; + + NSMutableDictionary *userdict = [[NSDictionary dictionaryWithObjectsAndKeys: + fontDir, @"/FontDirectory", + [NSArray arrayWithObjects: @"array", standardEncoding, nil], @"/StandardEncoding", + nil + ] mutableCopy]; + + NSMutableDictionary *systemdict = [NSMutableDictionary dictionaryWithCapacity:1000]; + NSMutableDictionary *errordict = [NSMutableDictionary dictionaryWithCapacity:10]; + + NSDictionary *auxDict = [NSDictionary dictionaryWithObjectsAndKeys: + [self makeInvocationForOp:@selector(opDef)], @"def", + [self makeInvocationForOp:@selector(opDup)], @"dup", + [self makeInvocationForOp:@selector(opIndex)], @"index", + [self makeInvocationForOp:@selector(opExch)], @"exch", + [self makeInvocationForOp:@selector(opFor)], @"for", + [self makeInvocationForOp:@selector(opDict)], @"dict", + [self makeInvocationForOp:@selector(opArray)], @"array", + [self makeInvocationForOp:@selector(opMark)], @"mark", + [self makeInvocationForOp:@selector(opCleartomark)], @"cleartomark", + [self makeInvocationForOp:@selector(opBegin)], @"begin", + [self makeInvocationForOp:@selector(opEnd)], @"end", + [self makeInvocationForOp:@selector(opExec)], @"exec", + [self makeInvocationForOp:@selector(opGet)], @"get", + [self makeInvocationForOp:@selector(opPut)], @"put", + [self makeInvocationForOp:@selector(opGetinterval)], @"getinterval", + [self makeInvocationForOp:@selector(opPutinterval)], @"putinterval", + [self makeInvocationForOp:@selector(opPop)], @"pop", + [self makeInvocationForOp:@selector(opString)], @"string", + [self makeInvocationForOp:@selector(opReadstring)], @"readstring", + [self makeInvocationForOp:@selector(opNop)], @"readonly", + [self makeInvocationForOp:@selector(opNop)], @"executeonly", + [self makeInvocationForOp:@selector(opNop)], @"noaccess", + [self makeInvocationForOp:@selector(opNop)], @"bind", + [self makeInvocationForOp:@selector(opIf)], @"if", + [self makeInvocationForOp:@selector(opIfelse)], @"ifelse", + [self makeInvocationForOp:@selector(opKnown)], @"known", + [self makeInvocationForOp:@selector(opNot)], @"not", + [self makeInvocationForOp:@selector(opCurrentdict)], @"currentdict", + [self makeInvocationForOp:@selector(opCurrentfile)], @"currentfile", + [self makeInvocationForOp:@selector(opClosefile)], @"closefile", + [self makeInvocationForOp:@selector(opEexec)], @"eexec", + [self makeInvocationForOp:@selector(opDefinefont)], @"definefont", + /* more operators */ + [self makeInvocationForOp:@selector(opNe)], @"ne", + [self makeInvocationForOp:@selector(opEq)], @"eq", + [self makeInvocationForOp:@selector(opCount)], @"count", + [self makeInvocationForOp:@selector(opType)], @"type", + /* some variables */ + [NSNumber numberWithInt:1], @"true", + [NSNumber numberWithInt:0], @"false", + userdict, @"userdict", + systemdict, @"systemdict", + errordict, @"errordict", + nil]; + + [errordict setObject:[NSArray arrayWithObjects:@"proc", + [NSArray arrayWithObjects:@"pop",nil],nil] + forKey:@"/invalidaccess"]; + + [systemdict addEntriesFromDictionary:auxDict]; + + [dicts addObject:systemdict]; + [dicts addObject:userdict]; + +} + + +- (void)doString:(NSString *)anInputString +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + + inputStream = [[anInputString mutableCopy] retain]; + + NSString *identifierString; + + if (sc) [sc release]; + sc = [[NSScanner scannerWithString:inputStream] retain]; + +// NSCharacterSet *sCS= [NSCharacterSet whitespaceAndNewlineCharacterSet]; + NSCharacterSet *sCS= [NSCharacterSet characterSetWithCharactersInString:@" \t\n\r"]; + NSCharacterSet *idCS= [NSCharacterSet characterSetWithCharactersInString:@" \t\n\r[]{}()%/"]; + NSCharacterSet *nlCS= [NSCharacterSet characterSetWithCharactersInString:@"\n\r"]; + NSCharacterSet *parCS= [NSCharacterSet characterSetWithCharactersInString:@"()"]; + float tmpFloat; + + while (![sc isAtEnd]) { + unichar ch; + + /* + BUG? + [sc scanCharactersFromSet:sCS intoString:nil]; does not scan through /r at + the beginning of the string. Actually it does not scan through ANY of the + characters in cCS!!! + we must do it by hand ... + */ + + while (1) { + [sc scanCharactersFromSet:sCS intoString:nil]; + ch =[inputStream characterAtIndex:[sc scanLocation]]; + if (ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t') + [sc setScanLocation:(int)[sc scanLocation]+1]; + else break; + }; + switch (ch) + { + case '%' : // comment + [sc scanUpToCharactersFromSet:nlCS intoString:nil]; + [sc setScanLocation:[sc scanLocation]+1]; + continue; + case '/' : // literal + [sc scanString:@"/" intoString:nil]; + if ([sc scanUpToCharactersFromSet:idCS intoString:&identifierString]) { + [stack addObject:[@"/" stringByAppendingString:identifierString]]; + } + continue; + case '(' : // string + { + int nesting = 0; + NSMutableString *curString = [NSMutableString stringWithCapacity:100]; + NSString *fragment; + [sc scanString:@"(" intoString:nil]; + while (1) { + [sc scanUpToCharactersFromSet:parCS intoString:&fragment]; + [curString appendString:fragment]; + if ([inputStream characterAtIndex:[sc scanLocation]] == '(') + { + nesting++; [curString appendString:@"("]; [sc scanString:@"(" intoString:nil]; + } + else { + [sc scanString:@")" intoString:nil]; + if (nesting) { + nesting--; [curString appendString:@")"]; + } + else break; + } + } + [stack addObject:curString]; + } + continue; + case '{' : // begin proc + [sc scanString:@"{" intoString:nil]; + nStoringProc++; + [stack addObject:StackMarkObject]; + continue; + case '}' : // end proc + { + [sc scanString:@"}" intoString:nil]; + nStoringProc--; + id obj; + NSMutableArray *proc = [NSMutableArray arrayWithCapacity:100]; + while ((obj = [stack lastObject]) != StackMarkObject) { + [proc insertObject:obj atIndex:0]; + [stack removeLastObject]; + } + if (obj == StackMarkObject) [stack removeLastObject]; + [stack addObject:[NSArray arrayWithObjects:@"proc",proc,nil]]; + } + continue; + case '[' : // begin array + [sc scanString:@"[" intoString:nil]; + [stack addObject:StackMarkObject]; + continue; + case ']' : // end array + { + [sc scanString:@"]" intoString:nil]; + id obj; + NSMutableArray *array = [NSMutableArray arrayWithCapacity:100]; + while ((obj = [stack lastObject]) != StackMarkObject) { + [array insertObject:obj atIndex:0]; + [stack removeLastObject]; + } + if (obj == StackMarkObject) [stack removeLastObject]; + [stack addObject:[NSArray arrayWithObjects:@"array",array,nil]]; + } + continue; + + case '<' : // hex string + [NSException raise:SimplePSInterpreterException format:@"hexstring not yet implemented!"]; + continue; + + default : // check if it is a number or a symbol + + if ([sc scanFloat:&tmpFloat]) { + [stack addObject:[NSNumber numberWithFloat:tmpFloat]]; + } else if ([sc scanUpToCharactersFromSet:idCS intoString:&identifierString]) { + if (nStoringProc) { + [stack addObject:identifierString]; + } else { + [self execName:identifierString]; + } + } else + [NSException raise:SimplePSInterpreterException format:@"Exhausted possible cases. I'm lost!"]; + } + } + + [sc release]; + [inputStream release]; + sc = nil; + inputStream = nil; + + [pool release]; +} + + +- init +{ + self = [super init]; + if (self) { + [self initializeInterpreter]; + } + return self; +} + +- (void) dealloc +{ + [stack release]; + [fontDir release]; + [dicts release]; + + [super dealloc]; +} + + +- (NSDictionary*)fontDir +{ + return fontDir; +} + +@end diff --git a/Build/source/texk/xdv2pdf/T1Wrap.m b/Build/source/texk/xdv2pdf/T1Wrap.m new file mode 100644 index 00000000000..b982eabe81f --- /dev/null +++ b/Build/source/texk/xdv2pdf/T1Wrap.m @@ -0,0 +1,746 @@ +#import +//#import // you need ApplicationServices.framework + +#import "SimplePSInterpreter.h" + +#import // for getopt() + +#include "config.h" + +static inline UInt16 +SWAP16(UInt16 v) +{ +#ifdef WORDS_BIGENDIAN + return v; +#else + return (v >> 8) | (v << 8); +#endif +} + +static inline UInt32 +SWAP32(UInt32 v) +{ +#ifdef WORDS_BIGENDIAN + return v; +#else + return (v >> 24) | ((v >> 8) & 0x0000FF00) | ((v << 8) & 0x00FF0000) | (v << 24); +#endif +} + +static NSString *T1WrapExceptionName = @"T1WrapException"; + +/* typ1 Table */ +enum { + typ1TableTag = 0x54595031 // 'TYP1' +}; + +typedef struct { + FourCharCode version; + UInt16 flags; + UInt16 glyphCount; + UInt32 totalLength; + UInt32 asciiLength; + UInt32 binaryLength; + SInt32 subrMaxLength; +} typ1Header; + +/* HFMX Table */ +enum { + HFMXTableTag = 0x48464D58 // 'HFMX' +}; + +typedef struct { + Fixed Version; + SInt16 Ascent; + SInt16 Descent; + SInt16 LineGap; + SInt16 CaretSlopeRise; + SInt16 CaretSlopeRun; + SInt16 CaretOffset; +} HFMXHeader; + +// format 6 subheader structure +struct sfntCMapSubHeader6 { + UInt16 format; + UInt16 length; + UInt16 languageID; /* base-1 */ + UInt16 firstCode; + UInt16 entryCount; +}; +typedef struct sfntCMapSubHeader6 sfntCMapSubHeader6; +enum { + sizeof_sfntCMapSubHeader6 = 10 +}; + + +/* post Table */ +enum { + postTableTag = 0x706F7374 // 'post' +}; + +struct sfntPostHeader { + Fixed version; /* format version number */ + Fixed italicAngle; /* italic angle in degrees */ + SInt16 underlinePosition; /* underline position (in FUnits) */ + SInt16 underlineThickness; /* underline thickness (in FUnits) */ + UInt16 isFixedPitch; /* font is monospaced */ + UInt16 reserved; + UInt32 minMemType42; /* Minimum memory usage when a TrueType font is downloaded */ + UInt32 maxMemType42; /* Maximum memory usage when a TrueType font is downloaded as a Type 1 font */ + UInt32 minMemType1; /* Minimum memory usage when a TrueType font is downloaded as a Type 1 font */ + UInt32 maxMemType1; /* Maximum memory usage when a TrueType font is downloaded as a Type 1 font */ +// UInt16 glyphCount; /* this is for version 2.0 post header */ +}; + +typedef struct sfntPostHeader sfntPostHeader; +enum { + sizeof_sfntPostHeader = 32 +}; +/* BUG?: I do not know if it is a bug but it happens that sizeof(sfntPostHeader) = 36 !?! */ +/* No, it's not a bug, that would be due to long-alignment of the structure. + But the glyphCount field is not strictly part of the 'post' table header, + it is part of the format-specific data for 'post' format 2.0. + So I've removed that, and it is handled separately below. */ + +unsigned long getPfbLong(const unsigned char *ptr) +{ + unsigned long c0 = ptr[0]; + unsigned long c1 = ptr[1]; + unsigned long c2 = ptr[2]; + unsigned long c3 = ptr[3]; + + return (c0 | (c1 << 8) | (c2 <<16) | (c3<<24)); +} + + + +NSData *decrypt(const unsigned char* inbuf, unsigned int insize) +{ + NSMutableData *result = [NSMutableData dataWithLength:insize]; + unsigned char *outbuf = [result mutableBytes]; + + unsigned short R = 55665; /* key */ + unsigned short c1 = 52845; + unsigned short c2 = 22719; + unsigned long counter; + + for(counter = 0; counter < insize; counter++) { + outbuf[counter] = (inbuf[counter] ^ (R>>8)); + R = (inbuf[counter] + R) * c1 + c2; + } + + return result; +} + +/* provide strnstr here because it's not available on 10.2 */ +char *strnstr(const char *big, const char *little, size_t bigLen) +{ + unsigned littleLen = strlen(little); + if (littleLen > bigLen) + return 0; + + unsigned n; + for (n = bigLen - littleLen + 1; n-- > 0; ++big) { + if (memcmp(big, little, littleLen) == 0) + return (char*)big; + } + + return 0; +} + +NSData *digestPfbForSfnt(NSString *pfbPath, typ1Header *t1h) +{ + static char *target1 = "currentfile eexec"; + static char *target2 = "0000000000000000000000000000000000000000000000000000000000000000"; + static char *target3 = "mark currentfile closefile"; + /* despite what the "Type 1 sfnt" document says, these don't appear to be necessary */ + static char *replacement1 = "\nsystemdict begin\n"; + static char *replacement2 = "\nend\n"; + + + NSData *pfbData = [NSData dataWithContentsOfFile:pfbPath]; + if (!pfbData) + [NSException raise:T1WrapExceptionName format:@"Cannot read file:%@",pfbPath]; + + NSMutableData *outData = [NSMutableData dataWithCapacity:[pfbData length]]; + if (!outData) + [NSException raise:T1WrapExceptionName format:@"Cannot allocate workspace"]; + + const char *pfbBytes = [pfbData bytes]; + unsigned long chunkSize; + unsigned long asciiSize = 0, binSize = 0; + while (1) { + if ((unsigned char)pfbBytes[0] != 0x80 ) + [NSException raise:T1WrapExceptionName format:@"Wrong PFB format"]; + + if (pfbBytes[1] == 0x01) + { + // read the ASCII chunk (before and after binary chunks) + chunkSize = getPfbLong(pfbBytes+2); + + const char * p0 = pfbBytes+6; + char * p1, *p2; + p1 = strnstr(p0,target1,chunkSize); + if (p1) { + if (p1 != p0+chunkSize-strlen(target1)-1) + [NSException raise:T1WrapExceptionName format:@"I'm confused..."]; + [outData appendBytes:p0 length:p1-p0]; + [outData appendBytes:replacement1 length:strlen(replacement1)]; + asciiSize = p1-p0+strlen(replacement1); + } else { + p2 = strnstr(p0,target2,chunkSize); + if (p2) { +#if 0 + /* the following test if false with: '\r00000...' */ + if (p2 != p0) + [NSException raise:T1WrapExceptionName format:@"I'm confused..."]; +#endif + ; + //[outData appendBytes:p0 length:chunkSize]; + } + else + [NSException raise:T1WrapExceptionName format:@"Cannot find begin/end of encrypted portion"]; + } + } + else if (pfbBytes[1] == 0x02) + { + // read the binary chunk + chunkSize = getPfbLong(pfbBytes+2); + NSData *decryptedData = decrypt(pfbBytes+6,chunkSize); + const char *p0 = [decryptedData bytes]; + const char *p1 = p0+chunkSize-(int)strlen(target3)-1; + if (strncmp(target3,p1,strlen(target3))!=0) + [NSException raise:T1WrapExceptionName format:@"Cannot find internal end of encrypted portion"]; + + [outData appendBytes:p0+4 length:p1-p0-4]; /* +4 is to skip YNDY */ + [outData appendBytes:replacement2 length:strlen(replacement2)]; + binSize = p1-p0-4+strlen(replacement2); + } + else if (pfbBytes[1] == 0x03) + break; + else + [NSException raise:T1WrapExceptionName format:@"Wrong PFB format"]; + pfbBytes += chunkSize+6; + } // while (1) + + // fill the table header + + t1h->version = SWAP32(0x00010000); + t1h->flags = SWAP16(0); + t1h->glyphCount = SWAP16(130); /* number of elements of CharStrings array/dict */ + t1h->totalLength = SWAP32(asciiSize+binSize); + t1h->asciiLength = SWAP32(asciiSize); + t1h->binaryLength = SWAP32(binSize); + t1h->subrMaxLength = SWAP32(-1); + + // pad the data to long boundary + { + unsigned x = [outData length]%4; + unsigned long y = 0; + if (x) [outData appendBytes:&y length:4-x]; + } + + return outData; +} + + + +void fillTag(FourCharCode *tag, char *str) +{ + char * p = (char*)tag; + p[0] = str[0]; + p[1] = str[1]; + p[2] = str[2]; + p[3] = str[3]; +} + +unsigned long calcTableChecksum(register unsigned long *table, unsigned long length) +{ + register unsigned long sum = 0L; + register unsigned long *endptr = table+((length+3) & ~3) / sizeof(long); + while (table < endptr) + sum += SWAP32(*table++); + return sum; +} + +unsigned four_align(unsigned a) { return ((a+3)/4)*4; } + + +NSData *wrapPfb(NSString *fontPath, BOOL omitType1Data) +{ + + unsigned totalSize = 0; + + // needed tables: HFMX, TYP1, cmap, fdsc, name + // we add also a post table (suggested by Jonathan Kew) + + + // TYP1 table + + typ1Header *t1h = calloc(1,sizeof(typ1Header)); + NSData *type1Data = digestPfbForSfnt(fontPath,t1h); + + totalSize += sizeof(typ1Header) + [type1Data length]; + + // parse pfb + + NSDictionary *fontDir = nil; + + { + SimplePSInterpreter *psi = [[SimplePSInterpreter alloc] init]; +// [psi doString:[NSString stringWithCString:[type1Data bytes] length:[type1Data length]]]; + [psi doString:[[NSString alloc] initWithData:type1Data encoding:NSMacOSRomanStringEncoding]]; + fontDir = [[[psi fontDir] retain] autorelease]; + [psi release]; + } + + if ([fontDir count]!=1) + [NSException raise:T1WrapExceptionName format:@"expecting only one font definition in pfb (found many or none)"]; + + NSDictionary *fontDict = (NSDictionary*)[[fontDir allValues] objectAtIndex:0]; + NSDictionary *fontInfo = [fontDict objectForKey:@"/FontInfo"]; + NSDictionary *charStrings = [fontDict objectForKey:@"/CharStrings"]; + + int glyphCount = [charStrings count]-1; // subtract 1 for the [KEY ORDER] key added by the pseudo-interpreter + + t1h->glyphCount = SWAP16(glyphCount); + + NSMutableData *type1TableData = [NSMutableData dataWithCapacity:sizeof(typ1Header)+[type1Data length]]; + [type1TableData appendBytes:t1h length:sizeof(typ1Header)]; + [type1TableData appendData:type1Data]; + + // create glyphNames array + + NSMutableArray *glyphNames = [NSMutableArray arrayWithCapacity:glyphCount]; + + { + NSEnumerator *en = [[charStrings objectForKey:@"[KEY ORDER]"] objectEnumerator]; + NSString *name; + [glyphNames addObject:@"/.notdef"]; + while ((name = [en nextObject])) + { + if (![name isEqualToString:@"/.notdef"]) [glyphNames addObject:name]; + } + } + + // HFMX table + + unsigned HFMXTableSize = sizeof(HFMXHeader); + HFMXHeader *hh = calloc(1,HFMXTableSize); + + hh->Version = SWAP32(0x00010000); + hh->Ascent = SWAP16([(NSNumber*)[(NSArray*)[(NSArray*)[fontDict objectForKey:@"/FontBBox"] objectAtIndex:1] objectAtIndex:3] intValue]); + hh->Descent = SWAP16(-[(NSNumber*)[(NSArray*)[(NSArray*)[fontDict objectForKey:@"/FontBBox"] objectAtIndex:1] objectAtIndex:1] intValue]); + hh->LineGap = SWAP16(0); + hh->CaretSlopeRise = SWAP16(1); + hh->CaretSlopeRun = SWAP16(0); + hh->CaretOffset = SWAP16(0); + + totalSize += HFMXTableSize; + + // name table + + NSMutableArray *nameIdArray = [NSMutableArray arrayWithCapacity:10]; + NSMutableArray *stringsArray = [NSMutableArray arrayWithCapacity:10]; + NSString *string; + + [nameIdArray addObject:[NSNumber numberWithInt:kFontPostscriptName]]; + string = [fontDict objectForKey:@"/FontName"]; + if ([string characterAtIndex:0] == '/') string = [string substringFromIndex:1]; + [stringsArray addObject:string]; + + string = [fontInfo objectForKey:@"/FullName"]; + if (string) { + [nameIdArray addObject:[NSNumber numberWithInt:kFontFullName]]; + [stringsArray addObject:string]; + } + + string = [fontInfo objectForKey:@"/FamilyName"]; + if (string) { + [nameIdArray addObject:[NSNumber numberWithInt:kFontFamilyName]]; + [stringsArray addObject:string]; + } + + string = [fontInfo objectForKey:@"/Copyright"]; + if (string) { + [nameIdArray addObject:[NSNumber numberWithInt:kFontCopyrightName]]; + [stringsArray addObject:string]; + } + + string = [fontInfo objectForKey:@"/Notice"]; + if (string) { + [nameIdArray addObject:[NSNumber numberWithInt:([fontDict objectForKey:@"/Copyright"] ? kFontCopyrightName : kFontDescriptionName)]]; + [stringsArray addObject:string]; + } + + string = [fontInfo objectForKey:@"/version"]; + if (string) { + [nameIdArray addObject:[NSNumber numberWithInt:kFontVersionName]]; + [stringsArray addObject:string]; + } + + + + NSMutableData *nameRecs = [NSMutableData dataWithCapacity:100]; + NSMutableData *nameStrings = [NSMutableData dataWithCapacity:100]; + + sfntNameRecord rec; + int nameRecords = 0; + rec.platformID = SWAP16(kFontMacintoshPlatform); + rec.scriptID = SWAP16(kFontRomanScript); + rec.languageID = SWAP16(kFontEnglishLanguage); + + NSEnumerator *nameIdEn = [nameIdArray objectEnumerator]; + NSEnumerator *stringsEn = [stringsArray objectEnumerator]; + NSNumber *nameIdObj; + while ((nameIdObj = [nameIdEn nextObject]) && (string = [stringsEn nextObject])) + { + rec.nameID = SWAP16([nameIdObj intValue]); + rec.length = SWAP16([string length]); + rec.offset = SWAP16([nameStrings length]); + [nameStrings appendBytes:[string cString] length:[string cStringLength]]; + [nameRecs appendBytes:&rec length:sizeof(sfntNameRecord)]; + nameRecords++; + } + + unsigned nameTableSize = four_align( sizeof_sfntNameHeader+ + [nameRecs length]+ + [nameStrings length]); + + + sfntNameHeader nameh; + nameh.format = SWAP16(0); + nameh.count = SWAP16(nameRecords); + nameh.stringOffset = SWAP16(sizeof_sfntNameHeader + [nameRecs length]); + + NSMutableData *nameTable = [NSMutableData dataWithCapacity:nameTableSize]; + [nameTable appendBytes:&nameh length:sizeof_sfntNameHeader]; + [nameTable appendData:nameRecs]; + [nameTable appendData:nameStrings]; + [nameTable increaseLengthBy:nameTableSize-[nameTable length]]; // pad with zeros + + totalSize += nameTableSize; + + // fdsc table + + unsigned fdscTableSize = four_align(sizeof_sfntDescriptorHeader+sizeof(sfntFontDescriptor)*2); + sfntDescriptorHeader *dh = calloc(1,fdscTableSize); + dh->version = SWAP32(0x00010000); + dh->descriptorCount = SWAP32(2); + /* FIXME: could try to infer better values from known font names like "bold", "condensed", etc */ + dh->descriptor[0].name = SWAP32(0x77647468); /* wdth */ + dh->descriptor[0].value = SWAP32(0x00010000); /* +1.0 */ + dh->descriptor[1].name = SWAP32(0x77676874); /* wght */ + dh->descriptor[1].value = SWAP32(0x00010000); /* +1.0 */ + + totalSize += fdscTableSize; + + // cmap table + NSArray *encoding = [(NSArray*)[fontDict objectForKey:@"/Encoding"] objectAtIndex:1]; + unsigned encsize = [encoding count]; + + unsigned cmapTableSize; + sfntCMapHeader *cmaph; + + if (glyphCount > 256) { + // more than 256 glyphs: use format 6 cmap + cmapTableSize = four_align(sizeof_sfntCMapHeader+sizeof_sfntCMapEncoding+sizeof_sfntCMapSubHeader6+256*2); + cmaph = calloc(1,cmapTableSize); + sfntCMapSubHeader6 *cmapsh = (sfntCMapSubHeader6*)(((char*)cmaph)+12); + UInt16 *glyphIndexArray = (UInt16*)(((char*)cmaph)+12+sizeof_sfntCMapSubHeader6); + cmaph->version = 0; + cmaph->numTables = SWAP16(1); + cmaph->encoding[0].platformID = SWAP16(kFontMacintoshPlatform); + cmaph->encoding[0].scriptID = SWAP16(kFontRomanScript); + cmaph->encoding[0].offset = SWAP32(12); + cmapsh->format = SWAP16(6); + cmapsh->length = SWAP16(10+256*2); + cmapsh->languageID = SWAP16(0); + cmapsh->firstCode = SWAP16(0); + cmapsh->entryCount = SWAP16(256); + { + int i; + NSString *name; + for (i=0; i<256; i++) { + if (i < encsize) { + name = [encoding objectAtIndex:i]; + if ([name isEqualToString:@" "]) name = @"/.notdef"; + } else name = @"/.notdef"; + glyphIndexArray[i] = SWAP16([glyphNames indexOfObject:name]); + } + } + } else { + // less than 256 glyphs: use format 0 cmap + cmapTableSize = four_align(sizeof_sfntCMapHeader+sizeof_sfntCMapEncoding+sizeof_sfntCMapSubHeader+256); + cmaph = calloc(1,cmapTableSize); + sfntCMapSubHeader *cmapsh = (sfntCMapSubHeader*)(((char*)cmaph)+12); + UInt8 *glyphIndexArray = (UInt8*)(((char*)cmaph)+12+sizeof_sfntCMapSubHeader); + cmaph->version = 0; + cmaph->numTables = SWAP16(1); + cmaph->encoding[0].platformID = SWAP16(kFontMacintoshPlatform); + cmaph->encoding[0].scriptID = SWAP16(kFontRomanScript); + cmaph->encoding[0].offset = SWAP32(12); + cmapsh->format = SWAP16(0); + cmapsh->length = SWAP16(6+256); + cmapsh->languageID = SWAP16(0); + { + int i; + NSString *name; + for (i=0; i<256; i++) { + if (i < encsize) { + name = [encoding objectAtIndex:i]; + if ([name isEqualToString:@" "]) name = @"/.notdef"; + } else name = @"/.notdef"; + glyphIndexArray[i] = [glyphNames indexOfObject:name]; + } + } + } + + totalSize += cmapTableSize; + + // post table + + NSArray *appleGlyphNames = [NSArray arrayWithObjects: + @".notdef",@".null",@"nonmarkingreturn",@"space",@"exclam",@"quotedbl",@"numbersign",@"dollar", + @"percent",@"ampersand",@"quotesingle",@"parenleft",@"parenright",@"asterisk",@"plus",@"comma", + @"hyphen",@"period",@"slash",@"zero",@"one",@"two",@"three",@"four", + @"five",@"six",@"seven",@"eight",@"nine",@"colon",@"semicolon",@"less", + @"equal",@"greater",@"question",@"at",@"A",@"B",@"C",@"D", + @"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L", + @"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T", + @"U",@"V",@"W",@"X",@"Y",@"Z",@"bracketleft",@"backslash", + @"bracketright",@"asciicircum",@"underscore",@"grave",@"a",@"b",@"c",@"d", + @"e",@"f",@"g",@"h",@"i",@"j",@"k",@"l", + @"m",@"n",@"o",@"p",@"q",@"r",@"s",@"t", + @"u",@"v",@"w",@"x",@"y",@"z",@"braceleft",@"bar", + @"braceright",@"asciitilde",@"Adieresis",@"Aring",@"Ccedilla",@"Eacute",@"Ntilde",@"Odieresis", + @"Udieresis",@"aacute",@"agrave",@"acircumflex",@"adieresis",@"atilde",@"aring",@"ccedilla", + @"eacute",@"egrave",@"ecircumflex",@"edieresis",@"iacute",@"igrave",@"icircumflex",@"idieresis", + @"ntilde",@"oacute",@"ograve",@"ocircumflex",@"odieresis",@"otilde",@"uacute",@"ugrave", + @"ucircumflex",@"udieresis",@"dagger",@"degree",@"cent",@"sterling",@"section",@"bullet", + @"paragraph",@"germandbls",@"registered",@"copyright",@"trademark",@"acute",@"dieresis",@"notequal", + @"AE",@"Oslash",@"infinity",@"plusminus",@"lessequal",@"greaterequal",@"yen",@"mu", + @"partialdiff",@"summation",@"product",@"pi",@"integral",@"ordfeminine",@"ordmasculine",@"Omega", + @"ae",@"oslash",@"questiondown",@"exclamdown",@"logicalnot",@"radical",@"florin",@"approxequal", + @"Delta",@"guillemotleft",@"guillemotright",@"ellipsis",@"nonbreakingspace",@"Agrave",@"Atilde",@"Otilde", + @"OE",@"oe",@"endash",@"emdash",@"quotedblleft",@"quotedblright",@"quoteleft",@"quoteright", + @"divide",@"lozenge",@"ydieresis",@"Ydieresis",@"fraction",@"currency",@"guilsinglleft",@"guilsinglright", + @"fi",@"fl",@"daggerdbl",@"periodcentered",@"quotesinglbase",@"quotedblbase",@"perthousand",@"Acircumflex", + @"Ecircumflex",@"Aacute",@"Edieresis",@"Egrave",@"Iacute",@"Icircumflex",@"Idieresis",@"Igrave", + @"Oacute",@"Ocircumflex",@"apple",@"Ograve",@"Uacute",@"Ucircumflex",@"Ugrave",@"dotlessi", + @"circumflex",@"tilde",@"macron",@"breve",@"dotaccent",@"ring",@"cedilla",@"hungarumlaut", + @"ogonek",@"caron",@"Lslash",@"lslash",@"Scaron",@"scaron",@"Zcaron",@"zcaron", + @"brokenbar",@"Eth",@"eth",@"Yacute",@"yacute",@"Thorn",@"thorn",@"minus", + @"multiply",@"onesuperior",@"twosuperior",@"threesuperior",@"onehalf",@"onequarter",@"threequarters",@"franc", + @"Gbreve",@"gbreve",@"Idotaccent",@"Scedilla",@"scedilla",@"Cacute",@"cacute",@"Ccaron", + @"ccaron",@"dcroat", + nil]; + + + NSMutableData *postTableStrings = [NSMutableData dataWithCapacity:100]; + UInt16 *postTableGlyphArray = calloc([glyphNames count],sizeof(UInt16)); + UInt16 nGlyphs = 0; + { + NSEnumerator *gnEn = [glyphNames objectEnumerator]; + int nStrings = 0; + NSString *string; + while ((string = [gnEn nextObject])) { + if ([string characterAtIndex:0]=='/') string = [string substringFromIndex:1]; + unsigned index = [appleGlyphNames indexOfObject:string]; + if (index != NSNotFound) { + postTableGlyphArray[nGlyphs] = SWAP16(index); + } else { + postTableGlyphArray[nGlyphs] = SWAP16(258+(nStrings++)); + char strLength = [string cStringLength]; + [postTableStrings appendBytes:&strLength length:1]; + [postTableStrings appendBytes:[string cString] length:strLength]; + } + nGlyphs++; + } + } + + + sfntPostHeader ph; + ph.version = SWAP32(0x00020000); + ph.italicAngle = SWAP32(0); + ph.underlinePosition = SWAP16([(NSNumber*)[fontInfo objectForKey:@"/UnderlinePosition"] intValue]); + ph.underlineThickness = SWAP16([(NSNumber*)[fontInfo objectForKey:@"/UnderlineThickness"] intValue]); + ph.isFixedPitch = SWAP16(([(NSNumber*)[fontInfo objectForKey:@"/isFixedPitch"] intValue] ? 1 : 0)); + ph.reserved = 0; + ph.minMemType42 = 0; + ph.maxMemType42 = 0; + ph.minMemType1 = 0; + ph.maxMemType1 = 0; +// ph.glyphCount = nGlyphs; + + NSMutableData *postTable = [NSMutableData dataWithCapacity:100]; + [postTable appendBytes:&ph length:sizeof_sfntPostHeader]; + nGlyphs = SWAP16(nGlyphs); + [postTable appendBytes:&nGlyphs length:sizeof(UInt16)]; + nGlyphs = SWAP16(nGlyphs); + [postTable appendBytes:postTableGlyphArray length:sizeof(UInt16)*nGlyphs]; + [postTable appendData:postTableStrings]; + [postTable increaseLengthBy:(4-([postTable length] % 4)) % 4]; // pad with zeros + free(postTableGlyphArray); + + + // sfnt directory + + unsigned sfntDirectorySize = sizeof_sfntDirectory+sizeof(sfntDirectoryEntry)*6; + sfntDirectory *dir = calloc(1,sfntDirectorySize); + fillTag(&(dir->format),"typ1"); + dir->numOffsets = SWAP16(6); /* number of tables */ + dir->searchRange = SWAP16(4*16); /* (max pow 2 <= numOffsets)*16 */ + dir->entrySelector = SWAP16(2);/* log2(max pow 2 <= numOffsets) */ + dir->rangeShift = SWAP16(32); /* numOffsets*16-searchRange*/ + + unsigned totalOffset = sfntDirectorySize; + + /* table directory entries must be sorted in ascending order by tag, + but we want to put the TYP1 table last because we optionally omit the data + (but still include the table header) */ + + dir->table[0].tableTag = SWAP32(HFMXTableTag); + dir->table[0].checkSum = SWAP32(calcTableChecksum((void*)hh,HFMXTableSize)); + dir->table[0].offset = SWAP32(totalOffset); + dir->table[0].length = SWAP32(HFMXTableSize); + totalOffset += SWAP32(dir->table[0].length); + + dir->table[2].tableTag = SWAP32(cmapFontTableTag); + dir->table[2].checkSum = SWAP32(calcTableChecksum((void*)cmaph,cmapTableSize)); + dir->table[2].offset = SWAP32(totalOffset); + dir->table[2].length = SWAP32(cmapTableSize); + totalOffset += SWAP32(dir->table[2].length); + + dir->table[3].tableTag = SWAP32(descriptorFontTableTag); + dir->table[3].checkSum = SWAP32(calcTableChecksum((void*)dh,fdscTableSize)); + dir->table[3].offset = SWAP32(totalOffset); + dir->table[3].length = SWAP32(fdscTableSize); + totalOffset += SWAP32(dir->table[3].length); + + dir->table[4].tableTag = SWAP32(nameFontTableTag); + dir->table[4].checkSum = SWAP32(calcTableChecksum((void*)[nameTable bytes], [nameTable length])); + dir->table[4].offset = SWAP32(totalOffset); + dir->table[4].length = SWAP32([nameTable length]); + totalOffset += SWAP32(dir->table[4].length); + + dir->table[5].tableTag = SWAP32(postTableTag); + dir->table[5].checkSum = SWAP32(calcTableChecksum((void*)[postTable bytes],[postTable length])); + dir->table[5].offset = SWAP32(totalOffset); + dir->table[5].length = SWAP32([postTable length]); + totalOffset += SWAP32(dir->table[5].length); + + dir->table[1].tableTag = SWAP32(typ1TableTag); + dir->table[1].checkSum = SWAP32(calcTableChecksum((void*)[type1TableData bytes],[type1TableData length])); + dir->table[1].offset = SWAP32(totalOffset); + dir->table[1].length = SWAP32([type1TableData length]); +// totalOffset += dir->table[0].length; + + NSMutableData *sfntData = [NSMutableData dataWithCapacity:totalSize]; + [sfntData appendBytes:dir length:sfntDirectorySize]; + + /* append all the tables, matching the order of directory entry creation so that the offsets will be right */ + [sfntData appendBytes:hh length:HFMXTableSize]; + [sfntData appendBytes:cmaph length:cmapTableSize]; + [sfntData appendBytes:dh length:fdscTableSize]; + [sfntData appendData:nameTable]; + [sfntData appendData:postTable]; + if (omitType1Data) + [sfntData appendBytes:t1h length:sizeof(typ1Header)]; + else + [sfntData appendData:type1TableData]; + free(t1h); + + free(dir); + + free(cmaph); free(dh); free(hh); + + return sfntData; +} + + +void usage(const char* progName) +{ + fprintf(stderr, "# usage: %s [-t | -T] pfbFile\n\ +# writes sfnt-wrapped Type 1 font to stdout\n\ +# options:\n\ +# -t omit TYP1 table from sfnt\n\ +# -T only generate TYP1 data\n", progName); + exit(1); +} + +int main (int argc, char * const *argv) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + +#if 1 + const char* progName = argv[0]; + int ch; + BOOL omitTyp1 = NO; + BOOL onlyTyp1 = NO; + while ((ch = getopt(argc, argv, "tT")) != -1) + switch (ch) { + case 't': + omitTyp1 = YES; + break; + case 'T': + onlyTyp1 = YES; + break; + case '?': + default: + usage(progName); + } + argc -= optind; + argv += optind; + if (argc != 1 || (omitTyp1 && onlyTyp1)) + usage(progName); + NSString *pfbFilename = [NSString stringWithCString:argv[0]]; + NS_DURING + if (onlyTyp1) { + typ1Header *t1h = calloc(1,sizeof(typ1Header)); + NSData *type1Data = digestPfbForSfnt(pfbFilename, t1h); + fwrite([type1Data bytes], 1, [type1Data length], stdout); + } + else { + NSData *sfntData = wrapPfb(pfbFilename, omitTyp1); + fwrite([sfntData bytes], 1, [sfntData length], stdout); + } + NS_HANDLER + fprintf(stderr,"%s",[[NSString stringWithFormat:@"exception: %@ reason: %@\n",[localException name],[localException reason]] cString]); + NS_ENDHANDLER +// [sfntData writeToFile:@"/Users/mgubi/Desktop/cmr10.sfnt" atomically:NO]; + +#else + NSString *basePath = @"/usr/local/teTeX/share/texmf.tetex/fonts/type1"; + NSDirectoryEnumerator *direnum = [[NSFileManager defaultManager] + enumeratorAtPath:basePath]; + NSString *pname; + NSString *fullname; + BOOL fOk = YES; + + + while ((pname = [direnum nextObject])) { + if ([[pname pathExtension] isEqualToString:@"pfb"]) { + fullname = [basePath stringByAppendingPathComponent:pname]; + fprintf(stdout,"testing %s\n",[fullname fileSystemRepresentation]); + NS_DURING + NSData *sfntData = wrapPfb(fullname); + NS_HANDLER + + fOk = NO; + fprintf(stderr,"%s",[[NSString stringWithFormat:@"exception: %@ reason: %@",[localException name],[localException reason]] cString]); + + NS_ENDHANDLER + } + } + + + + +#endif + + + + [pool release]; + return 0; +} + diff --git a/Build/source/texk/xdv2pdf/acconfig.h b/Build/source/texk/xdv2pdf/acconfig.h new file mode 100644 index 00000000000..ee49123b348 --- /dev/null +++ b/Build/source/texk/xdv2pdf/acconfig.h @@ -0,0 +1,37 @@ +#define VERSION 0 + +#define PACKAGE "package" + +/* define if you have kpathsea */ +#undef HAVE_KPATHSEA + +/* define if your zlib has the compress2 function */ +#undef HAVE_ZLIB_COMPRESS2 + +/* define if you have zlib and its headers */ +#undef HAVE_ZLIB + +/* define if you have xbasename() in your libkpathsea instead of basename() */ +#undef HAVE_XBASENAME + +/* define if kpathsea understands TrueType (TTF) formats */ +#undef HAVE_TTF_FORMATS + +/* define if struct tm has tm_gmtoff as a member */ +#undef HAVE_TM_GMTOFF + +/* define if has timezone as an external variable */ +#undef HAVE_TIMEZONE + +/* define if kpathsea supports type1 and vf formats */ +#undef HAVE_KPSE_FORMATS + +/* define if you have libpng */ +#undef HAVE_LIBPNG + +/* Define if kpathsea understands Omega (OFM/OVF) formats */ +#undef HAVE_OMEGA_FORMATS + + + + diff --git a/Build/source/texk/xdv2pdf/acconfig.h.in b/Build/source/texk/xdv2pdf/acconfig.h.in new file mode 100644 index 00000000000..e81beaf36c9 --- /dev/null +++ b/Build/source/texk/xdv2pdf/acconfig.h.in @@ -0,0 +1,45 @@ + +/* Local variables defined by MAW */ +#ifndef _CONFIG_H + +#define VERSION 0 + +#define PACKAGE "package" + +/* HAVE_TIMEZONE - Define if has timezone as an external variable */ +#undef HAVE_TIMEZONE + +/* HAVE_TM_GMTOFF - Define if struct tm has tm_gmtoff as a member */ +#undef HAVE_TM_GMTOFF + +/* HAVE_KPATHSEA - Define if you have kpathsea */ +#define HAVE_KPATHSEA + +/* HAVE_XBASENAME - Define if you have xbasename() in your libkpathsea instead of basename() */ +#undef HAVE_XBASENAME + +/* HAVE_ZLIB - Define if you have zlib and its headers */ +#undef HAVE_ZLIB +/* HAVE_ZLIB_COMPRESS2 - Define if your zlib has the compress2 function */ +#undef HAVE_ZLIB_COMPRESS2 + +/* HAVE_KPSE_FORMATS - Define if you have a + version of kpathsea with type1 and vf formats */ +#define HAVE_KPSE_FORMATS + +/* HAVE_OMEGA_FORMATS - Define if you have a + version of kpathsea that understands Omega (OFM/OVF) formats */ +#define HAVE_OMEGA_FORMATS + +/* HAVE_TTF_FORMATS - Define if you have a + version of kpathsea that understands TrueType (TTF) formats */ +#define HAVE_TTF_FORMATS + +/* HAVE_LIBPNG - Define if you have libpng */ +#undef HAVE_LIBPNG + +/* HAVE_SYSTEM - Define if you have the system() command */ +#undef HAVE_SYSTEM + + +#endif /* _CONFIG_H */ diff --git a/Build/source/texk/xdv2pdf/appleGlyphNames.c b/Build/source/texk/xdv2pdf/appleGlyphNames.c new file mode 100644 index 00000000000..cec18fac1ef --- /dev/null +++ b/Build/source/texk/xdv2pdf/appleGlyphNames.c @@ -0,0 +1,272 @@ +/****************************************************************************\ + Part of the XeTeX typesetting system + copyright (c) 1994-2005 by SIL International + written by Jonathan Kew + + This software is distributed under the terms of the Common Public License, + version 1.0. + For details, see or the file + cpl1.0.txt included with the software. +\****************************************************************************/ + +char* appleGlyphNames[] = { + ".notdef", + ".null", + "nonmarkingreturn", + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quotesingle", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "grave", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + "Adieresis", + "Aring", + "Ccedilla", + "Eacute", + "Ntilde", + "Odieresis", + "Udieresis", + "aacute", + "agrave", + "acircumflex", + "adieresis", + "atilde", + "aring", + "ccedilla", + "eacute", + "egrave", + "ecircumflex", + "edieresis", + "iacute", + "igrave", + "icircumflex", + "idieresis", + "ntilde", + "oacute", + "ograve", + "ocircumflex", + "odieresis", + "otilde", + "uacute", + "ugrave", + "ucircumflex", + "udieresis", + "dagger", + "degree", + "cent", + "sterling", + "section", + "bullet", + "paragraph", + "germandbls", + "registered", + "copyright", + "trademark", + "acute", + "dieresis", + "notequal", + "AE", + "Oslash", + "infinity", + "plusminus", + "lessequal", + "greaterequal", + "yen", + "mu", + "partialdiff", + "summation", + "product", + "pi", + "integral", + "ordfeminine", + "ordmasculine", + "Omega", + "ae", + "oslash", + "questiondown", + "exclamdown", + "logicalnot", + "radical", + "florin", + "approxequal", + "Delta", + "guillemotleft", + "guillemotright", + "ellipsis", + "nonbreakingspace", + "Agrave", + "Atilde", + "Otilde", + "OE", + "oe", + "endash", + "emdash", + "quotedblleft", + "quotedblright", + "quoteleft", + "quoteright", + "divide", + "lozenge", + "ydieresis", + "Ydieresis", + "fraction", + "currency", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "daggerdbl", + "periodcentered", + "quotesinglbase", + "quotedblbase", + "perthousand", + "Acircumflex", + "Ecircumflex", + "Aacute", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Oacute", + "Ocircumflex", + "apple", + "Ograve", + "Uacute", + "Ucircumflex", + "Ugrave", + "dotlessi", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron", + "Lslash", + "lslash", + "Scaron", + "scaron", + "Zcaron", + "zcaron", + "brokenbar", + "Eth", + "eth", + "Yacute", + "yacute", + "Thorn", + "thorn", + "minus", + "multiply", + "onesuperior", + "twosuperior", + "threesuperior", + "onehalf", + "onequarter", + "threequarters", + "franc", + "Gbreve", + "gbreve", + "Idotaccent", + "Scedilla", + "scedilla", + "Cacute", + "cacute", + "Ccaron", + "ccaron", + "dcroat", + 0 +}; diff --git a/Build/source/texk/xdv2pdf/c-auto.in b/Build/source/texk/xdv2pdf/c-auto.in new file mode 100644 index 00000000000..9c30520187e --- /dev/null +++ b/Build/source/texk/xdv2pdf/c-auto.in @@ -0,0 +1,4 @@ +/* c-auto.in. Generated automatically from configure.in by autoheader. */ + +/* The number of bytes in a int. */ +#undef SIZEOF_INT diff --git a/Build/source/texk/xdv2pdf/config.h.in b/Build/source/texk/xdv2pdf/config.h.in new file mode 100644 index 00000000000..43e2c999be4 --- /dev/null +++ b/Build/source/texk/xdv2pdf/config.h.in @@ -0,0 +1,68 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if your declares struct tm. */ +#undef TM_IN_SYS_TIME + +#define VERSION 0 + +#define PACKAGE "package" + +/* define if you have kpathsea */ +#undef HAVE_KPATHSEA + +/* define if your zlib has the compress2 function */ +#undef HAVE_ZLIB_COMPRESS2 + +/* define if you have zlib and its headers */ +#undef HAVE_ZLIB + +/* define if you have xbasename() in your libkpathsea instead of basename() */ +#undef HAVE_XBASENAME + +/* define if kpathsea understands TrueType (TTF) formats */ +#undef HAVE_TTF_FORMATS + +/* define if struct tm has tm_gmtoff as a member */ +#undef HAVE_TM_GMTOFF + +/* define if has timezone as an external variable */ +#undef HAVE_TIMEZONE + +/* define if kpathsea supports type1 and vf formats */ +#undef HAVE_KPSE_FORMATS + +/* define if you have libpng */ +#undef HAVE_LIBPNG + +/* Define if kpathsea understands Omega (OFM/OVF) formats */ +#undef HAVE_OMEGA_FORMATS + +/* Define if you have the strspn function. */ +#undef HAVE_STRSPN + +/* Define if you have the system function. */ +#undef HAVE_SYSTEM + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the header file. */ +#undef HAVE_ZLIB_H + +/* Define if you have the m library (-lm). */ +#undef HAVE_LIBM + +/* Define if you have the z library (-lz). */ +#undef HAVE_LIBZ + +/* Define if the target architecture is big-endian */ +#undef WORDS_BIGENDIAN diff --git a/Build/source/texk/xdv2pdf/configure b/Build/source/texk/xdv2pdf/configure new file mode 100755 index 00000000000..899b963ed1d --- /dev/null +++ b/Build/source/texk/xdv2pdf/configure @@ -0,0 +1,2298 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-maint enable autoconf portions of Makefile" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +ac_config_files= +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_envvar| sed 's/[_a-zA-Z0-9]//g'`"; then + { echo "configure: error: invalid variable name: $ac_envvar" 1>&2; exit 1; } + fi + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=xdv2pdf.cpp + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + + +VERSION="0.991" + +cat >> confdefs.h <<\EOF +#define VERSION "0.991" +EOF + +cat >> confdefs.h <<\EOF +#define PACKAGE "xdv2pdf" +EOF + + + + +# Check whether --enable-maint or --disable-maint was given. +if test "${enable_maint+set}" = set; then + enableval="$enable_maint" + MAINT='' +else + MAINT='#' +fi + + + + +# Extra configure tests to support XeTeX + + + + + + + +# +# Check for Carbon framework on Mac OS X +# + _cppflags=$CPPFLAGS _ldflags=$LDFLAGS + echo $ac_n "checking for Apple Carbon framework""... $ac_c" 1>&6 +echo "configure:578: checking for Apple Carbon framework" >&5 + cat > conftest.$ac_ext < + +int main() { + +ATSUStyle style; + +; return 0; } +EOF +if { (eval echo configure:591: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_CARBON 1 +EOF + + LDCARBON="-framework Carbon" + has_carbon=yes + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + LDCARBON= + has_carbon=no + + +fi +rm -f conftest* + +if test "x$has_carbon" = xno; then + with_xdv2pdf=no + exit +fi + + +# +# Check for QuickTime framework on Mac OS X +# + _cppflags=$CPPFLAGS _ldflags=$LDFLAGS + echo $ac_n "checking for Apple QuickTime framework""... $ac_c" 1>&6 +echo "configure:624: checking for Apple QuickTime framework" >&5 + cat > conftest.$ac_ext < + +int main() { + +ImageDescriptionHandle h; + +; return 0; } +EOF +if { (eval echo configure:637: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_QUICKTIME 1 +EOF + + LDQUICKTIME="-framework QuickTime" + has_quicktime=yes + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + LDQUICKTIME= + has_quicktime=no + + +fi +rm -f conftest* + +if test "x$has_quicktime" = xno; then + with_xdv2pdf=no + exit +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:667: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + if test -z "$COMSPEC"; then ac_x=-f; else ac_x=-x; fi + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test $ac_x $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:698: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + if test -z "$COMSPEC"; then ac_x=-f; else ac_x=-x; fi + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test $ac_x $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:750: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + if test -z "$COMSPEC"; then ac_x=-f; else ac_x=-x; fi + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test $ac_x $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:783: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 794 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:799: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:825: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:830: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:858: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:894: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + if test -z "$COMSPEC"; then ac_x=-f; else ac_x=-x; fi + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test $ac_x $ac_dir/$ac_word; then + ac_cv_prog_CXX="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CXX="$ac_cv_prog_CXX" +if test -n "$CXX"; then + echo "$ac_t""$CXX" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$CXX" && break +done +test -n "$CXX" || CXX="gcc" + + +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:927: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 + +ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + +cat > conftest.$ac_ext << EOF + +#line 938 "configure" +#include "confdefs.h" + +int main(){return(0);} +EOF +if { (eval echo configure:943: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cxx_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cxx_cross=no + else + ac_cv_prog_cxx_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cxx_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 +if test $ac_cv_prog_cxx_works = no; then + { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:969: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 +cross_compiling=$ac_cv_prog_cxx_cross + +echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 +echo "configure:974: checking whether we are using GNU C++" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.C <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gxx=yes +else + ac_cv_prog_gxx=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gxx" 1>&6 + +if test $ac_cv_prog_gxx = yes; then + GXX=yes +else + GXX= +fi + +ac_test_CXXFLAGS="${CXXFLAGS+set}" +ac_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS= +echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 +echo "configure:1002: checking whether ${CXX-g++} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.cc +if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then + ac_cv_prog_cxx_g=yes +else + ac_cv_prog_cxx_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS="$ac_save_CXXFLAGS" +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:1034: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1055: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1072: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1089: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + case $ac_dir in + /*|[A-z]:/*) ac_aux_dir=$ac_dir;; + *) ac_aux_dir=`pwd`/$ac_dir;; + esac + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + case $ac_dir in + /*|[A-z]:/*) ac_aux_dir=$ac_dir;; + *) ac_aux_dir=`pwd`/$ac_dir;; + esac + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1150: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + # Hack for MSDOS and descendants. + if test -z "$COMSPEC"; then ac_x=-f; else ac_x=-x; fi + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test $ac_x $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:1205: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +# MS-DOS is a special case, because it sort of pretends that ln -s +# works for executables. +if test -z "$COMSPEC" && ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:1228: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +cat >> confdefs.h <<\EOF +#define KPATHSEA 1 +EOF + +cat >> confdefs.h <<\EOF +#define HAVE_KPATHSEA 1 +EOF + +cat >> confdefs.h <<\EOF +#define HAVE_KPSE_FORMATS 1 +EOF + + +TTF_OPT='' + + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:1272: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1285: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:1352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +for ac_hdr in unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1379: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1389: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:1417: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:1471: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:1492: checking for size_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#if STDC_HEADERS +#include +#include +#endif +#if HAVE_STDINT_H +#include +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_size_t=yes +else + rm -rf conftest* + ac_cv_type_size_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_size_t" 1>&6 +if test $ac_cv_type_size_t = no; then + cat >> confdefs.h <<\EOF +#define size_t unsigned +EOF + +fi + +echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 +echo "configure:1528: checking whether struct tm is in sys/time.h or time.h" >&5 +if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +int main() { +struct tm *tp; tp->tm_sec; +; return 0; } +EOF +if { (eval echo configure:1541: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_tm=time.h +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_struct_tm=sys/time.h +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_struct_tm" 1>&6 +if test $ac_cv_struct_tm = sys/time.h; then + cat >> confdefs.h <<\EOF +#define TM_IN_SYS_TIME 1 +EOF + +fi + + +echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 +echo "configure:1563: checking whether byte ordering is bigendian" >&5 +if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_bigendian=unknown +# See if sys/param.h defines the BYTE_ORDER macro. +cat > conftest.$ac_ext < +#include +int main() { + +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif +; return 0; } +EOF +if { (eval echo configure:1581: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + # It does; now see whether it defined to BIG_ENDIAN or not. +cat > conftest.$ac_ext < +#include +int main() { + +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif +; return 0; } +EOF +if { (eval echo configure:1596: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_bigendian=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_bigendian=no +fi +rm -f conftest* +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +if test $ac_cv_c_bigendian = unknown; then +if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_c_bigendian=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_c_bigendian=yes +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_c_bigendian" 1>&6 +if test $ac_cv_c_bigendian = yes; then + cat >> confdefs.h <<\EOF +#define WORDS_BIGENDIAN 1 +EOF + +fi + + +echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 +echo "configure:1654: checking for 8-bit clean memcmp" >&5 +if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_memcmp_clean=no +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_memcmp_clean=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_memcmp_clean=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6 +test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}" + +for ac_func in strspn system +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1692: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1720: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +echo $ac_n "checking for main in -lm""... $ac_c" 1>&6 +echo "configure:1745: checking for main in -lm" >&5 +ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + +ac_config_files="$ac_config_files Makefile" + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + + +trap 'rm -fr `echo "$ac_config_files config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@VERSION@%$VERSION%g +s%@MAINT@%$MAINT%g +s%@CC@%$CC%g +s%@CXX@%$CXX%g +s%@CPP@%$CPP%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@LN_S@%$LN_S%g +s%@SET_MAKE@%$SET_MAKE%g +s%@TTF_OPT@%$TTF_OPT%g +s%@LIBOBJS@%$LIBOBJS%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*|[A-z]:/*) # Absolute path. + srcdir="$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + "") ;; + [/$]*|[A-z]:/*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + rm -f conftest.in + ac_file_inputs=`echo $ac_file_in|sed -e "s%:% $ac_given_srcdir/%g" -e "s%^%$ac_given_srcdir/%"` + cat $ac_file_inputs > conftest.in + # + # Replace lines of the form ac_include foo with the contents of foo: + # first, from the ac_include lines construct a list of file names. + # From that list, we construct a second list of those files that exist. + # Then we construct lists of sed commands for including those files, + # and a sed command that removes the ac_include lines. We don't attempt + # to read non-existent files because some (buggy) versions of sed choke + # on this. Have to use sed because old (Ultrix, SunOS) awk does not support + # getline or system. (Anyway, configure scripts aren't supposed to use awk.) + # Can't use only one -e and commands {dr foo} because foo has to be last. + # Be careful, because the filename may contain /. Be careful with + # whitespace; we need to use echo. + # + file_substs=`sed -n '/^ac_include/s%ac_include[ ]*\(.*\)%\1%p' conftest.in` + # Create the sed command line ... + if test -n "$file_substs"; then + echo "configure: warning: ac_include is obsolete; instead use kpse_include" 1>&2 + file_subst_cmd="sed -e 's/^ac_include/kpse_include/'" + else + file_subst_cmd='sed' + fi + kpse_substs=`sed -n '/^kpse_include/s%kpse_include[ ]*\(.*\)%\1%p' conftest.in` + for ac_inc in $file_substs $kpse_substs; do + if test -f "$ac_given_srcdir/$ac_inc"; then + ac_mung=`echo $ac_inc | sed 's,/,%,g'` + file_subst_cmd="$file_subst_cmd -e '/^kpse_include $ac_mung$/r $ac_given_srcdir/$ac_inc'" + fi + done + file_subst_cmd="$file_subst_cmd -e '/^kpse_include/d'" + # ... and fix the whitespace and escaped slashes. + file_subst_cmd=`echo "$file_subst_cmd" | sed -e 's,%,\\\/,g' \ +-e 's/kpse_include /kpse_include[ ]*/g'` + # I can't find any way to do variable substitution in the sed commands + # (so the user could have, e.g., $top_srcdir in their ac_include line). + (eval $file_subst_cmd conftest.in) \ + | sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* conftest.in + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ].*$%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%:% $ac_given_srcdir/%g" -e "s%^%$ac_given_srcdir/%"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + + + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + +if test "$no_recursion" != yes; then + + # Remove --cache-file and --srcdir arguments so they do not pile up. + ac_sub_configure_args= + ac_prev= + for ac_arg in $ac_configure_args; do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case "$ac_arg" in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;; + esac + done + + for ac_config_dir in : $subdirs; do + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + if test ! -d $srcdir/$ac_config_dir; then + continue + fi + + echo configuring in $ac_config_dir + + case "$srcdir" in + .) ;; + *) + if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :; + else + { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; } + fi + ;; + esac + + ac_popdir=`pwd` + cd $ac_config_dir + + # A "../" for each directory in /$ac_config_dir. + ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'` + + case "$srcdir" in + .) # No --srcdir option. We are building in place. + ac_sub_srcdir=$srcdir ;; + /*|[A-z]:/*) # Absolute path. + ac_sub_srcdir=$srcdir/$ac_config_dir ;; + *) # Relative path. + ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;; + esac + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f ./configure; then + ac_sub_configure=./configure + elif test -f $ac_sub_srcdir/configure; then + ac_sub_configure=$ac_sub_srcdir/configure + elif test -f $ac_sub_srcdir/configure.in; then + ac_sub_configure=$ac_configure + else + echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2 + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + + # Make the cache file name correct relative to the subdirectory. + case "$cache_file" in + /*|[A-z]:/*) ac_sub_cache_file=$cache_file ;; + *) # Relative path. + ac_sub_cache_file="$ac_dots$cache_file" ;; + esac + case "$ac_given_INSTALL" in + "") ;; + [/$]*|[A-z]:/*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir" + # The eval makes quoting arguments work. + if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir + then : + else + { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; } + fi + fi + + cd $ac_popdir + done +fi + diff --git a/Build/source/texk/xdv2pdf/configure.in b/Build/source/texk/xdv2pdf/configure.in new file mode 100644 index 00000000000..776a5b255a2 --- /dev/null +++ b/Build/source/texk/xdv2pdf/configure.in @@ -0,0 +1,66 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(xdv2pdf.cpp) + +define([_version_],"0.991") + +VERSION=_version_ +AC_SUBST(VERSION) +AC_DEFINE(VERSION,_version_) +AC_DEFINE(PACKAGE,"xdv2pdf") + +AC_CONFIG_HEADERS([config.h]) + +AC_ARG_ENABLE(maint, [ --enable-maint enable autoconf portions of Makefile], + [MAINT=''], [MAINT='#']) +AC_SUBST(MAINT) + +dnl First, check if we're configuring on Mac OS X -- can't build elsewhere + +sinclude(../web2c/xetexdir/tests.ac) + +AC_HAS_CARBON +if test "x$has_carbon" = xno; then + with_xdv2pdf=no + exit +fi + +AC_HAS_QUICKTIME +if test "x$has_quicktime" = xno; then + with_xdv2pdf=no + exit +fi + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_CXX +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET + +AC_DEFINE(KPATHSEA) +AC_DEFINE(HAVE_KPATHSEA) +AC_DEFINE(HAVE_KPSE_FORMATS) + +TTF_OPT='' +AC_SUBST(TTF_OPT) + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(unistd.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_SIZE_T +AC_STRUCT_TM + +AC_C_BIGENDIAN + +dnl Checks for library functions. +AC_FUNC_MEMCMP +AC_CHECK_FUNCS(strspn system) +AC_CHECK_LIB(m, main) + +KPSE_CONFIG_FILES([Makefile]) + +AC_OUTPUT diff --git a/Build/source/texk/xdv2pdf/xdv2pdf.cpp b/Build/source/texk/xdv2pdf/xdv2pdf.cpp new file mode 100755 index 00000000000..49f2ef3906f --- /dev/null +++ b/Build/source/texk/xdv2pdf/xdv2pdf.cpp @@ -0,0 +1,2348 @@ +/****************************************************************************\ + Part of the XeTeX typesetting system + copyright (c) 1994-2005 by SIL International + written by Jonathan Kew + + This software is distributed under the terms of the Common Public License, + version 1.0. + For details, see or the file + cpl1.0.txt included with the software. +\****************************************************************************/ + +/* + xdv2pdf + Convert xdv file from XeTeX to PDF format for viewing/printing + + usage: xdv2pdf [-d debug] [-m mag] [-p papersize] [-v] xdvfile [-o pdffile] + + -m override magnification from xdv file + -v show progress messages (page counters) + -d set kpathsea_debug values + -p papersize [default: from Mac OS X printing system] + + known papersize values: + a0-a10 + b0-b10 + c0-c10 + jb0-jb10 + letter + legal + ledger + tabloid + can append ":landscape" + or use "x,y" where x and y are dimensions in "big points" or with units + + output file defaults to .pdf + + also permissible to omit xdvfile but specify pdffile; then input is from stdin +*/ + +#ifdef __POWERPC__ +#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_2 +#else +#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_4 +#endif + +#include "config.h" + +#include +#include + +#include +#include +#include +#include + +#include + +#include "DVIops.h" + +#define XDV_ID 5 // current id_byte value for .xdv files from xetex + +#define XDV_FLAG_FONTTYPE_ATSUI 0x0001 +#define XDV_FLAG_FONTTYPE_ICU 0x0002 + +#define XDV_FLAG_VERTICAL 0x0100 +#define XDV_FLAG_COLORED 0x0200 +#define XDV_FLAG_FEATURES 0x0400 +#define XDV_FLAG_VARIATIONS 0x0800 + +#define pdfbox_crop 1 +#define pdfbox_media 2 +#define pdfbox_bleed 3 +#define pdfbox_trim 4 +#define pdfbox_art 5 + + +#define DEFINE_GLOBALS 1 +#include "xdv2pdf_globals.h" + +paperSizeRec gPaperSizes[] = +{ + { "a0", 2383.937008, 3370.393701 }, + { "a1", 1683.779528, 2383.937008 }, + { "a2", 1190.551181, 1683.779528 }, + { "a3", 841.8897638, 1190.551181 }, + { "a4", 595.2755906, 841.8897638 }, + { "a5", 419.5275591, 595.2755906 }, + { "a6", 297.6377953, 419.5275591 }, + { "a7", 209.7637795, 297.6377953 }, + { "a8", 147.4015748, 209.7637795 }, + { "a9", 104.8818898, 147.4015748 }, + { "a10", 73.7007874, 104.8818898 }, + + { "b0", 2834.645669, 4008.188976 }, + { "b1", 2004.094488, 2834.645669 }, + { "b2", 1417.322835, 2004.094488 }, + { "b3", 1000.629921, 1417.322835 }, + { "b4", 708.6614173, 1000.629921 }, + { "b5", 498.8976378, 708.6614173 }, + { "b6", 354.3307087, 498.8976378 }, + { "b7", 249.4488189, 354.3307087 }, + { "b8", 175.7480315, 249.4488189 }, + { "b9", 124.7244094, 175.7480315 }, + { "b10", 87.87401575, 124.7244094 }, + + { "c0", 2599.370079, 3676.535433 }, + { "c1", 1836.850394, 2599.370079 }, + { "c2", 1298.267717, 1836.850394 }, + { "c3", 918.4251969, 1298.267717 }, + { "c4", 649.1338583, 918.4251969 }, + { "c5", 459.2125984, 649.1338583 }, + { "c6", 323.1496063, 459.2125984 }, + { "c7", 229.6062992, 323.1496063 }, + { "c8", 161.5748031, 229.6062992 }, + { "c9", 113.3858268, 161.5748031 }, + { "c10", 79.37007874, 113.3858268 }, + + { "jb0", 2919.685039, 4127.244094 }, + { "jb1", 2063.622047, 2919.685039 }, + { "jb2", 1459.84252, 2063.622047 }, + { "jb3", 1031.811024, 1459.84252 }, + { "jb4", 728.503937, 1031.811024 }, + { "jb5", 515.9055118, 728.503937 }, + { "jb6", 362.8346457, 515.9055118 }, + { "jb7", 257.9527559, 362.8346457 }, + { "jb8", 181.4173228, 257.9527559 }, + { "jb9", 127.5590551, 181.4173228 }, + { "jb10", 90.70866142, 127.5590551 }, + + { "letter", 612.0, 792.0 }, + { "legal", 612.0, 1008.0 }, + { "tabloid", 792.0, 1224.0 }, + { "ledger", 1224.0, 792.0 }, + + { 0, 0, 0 } +}; + +static CGAffineTransform horizontalMatrix = { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }; +static CGAffineTransform verticalMatrix = { 0.0, 1.0, -1.0, 0.0, 0.0, 0.0 }; + +struct nativeFont { + nativeFont() + : cgFont(0) + , atsFont(0) + , atsuStyleH(0) + , atsuStyleV(0) + , size(Long2Fix(10)) + , isColored(false) + , isVertical(false) + { + } + CGFontRef cgFont; + ATSFontRef atsFont; + ATSUStyle atsuStyleH; // only present if isVertical is true + ATSUStyle atsuStyleV; + Fixed size; + CGColorRef color; + bool isColored; + bool isVertical; +}; + +static std::map sNativeFonts; + +static UInt32 sMag = 0; + +static bool sVerbose = false; + +static std::map sCGFonts; + +static CGFontRef +getCGFontForATSFont(ATSFontRef fontRef) +{ + std::map::const_iterator i = sCGFonts.find(fontRef); + if (i != sCGFonts.end()) { + return i->second; + } + CGFontRef newFont; + if (fontRef == 0) { + ATSFontRef tmpRef = ATSFontFindFromPostScriptName(CFSTR("Helvetica"), kATSOptionFlagsDefault); + newFont = CGFontCreateWithPlatformFont(&tmpRef); + } + else + newFont = CGFontCreateWithPlatformFont(&fontRef); + sCGFonts[fontRef] = newFont; + return newFont; +} + +inline UInt32 +SWAP(UInt32 v) +{ +#ifdef WORDS_BIGENDIAN + return v; +#else + return (v << 24) + + ((v << 8) & 0x00FF0000) + + ((v >> 8) & 0x0000FF00) + + (v >> 24); +#endif +} + +inline SInt32 +SWAP(SInt32 v) +{ +#ifdef WORDS_BIGENDIAN + return v; +#else + return (v << 24) + + ((v << 8) & 0x00FF0000) + + ((v >> 8) & 0x0000FF00) + + ((v >> 24) & 0x000000FF); +#endif +} + +inline UInt16 +SWAP(UInt16 v) +{ +#ifdef WORDS_BIGENDIAN + return v; +#else + return (v << 8) + (v >> 8); +#endif +} + +inline SInt16 +SWAP(SInt16 v) +{ +#ifdef WORDS_BIGENDIAN + return v; +#else + return (v << 8) + ((v >> 8) & 0xFF); +#endif +} + +/* precaution, just in case we apply these to byte-sized values! */ +inline UInt8 +SWAP(UInt8 v) +{ + return v; +} + +inline SInt8 +SWAP(SInt8 v) +{ + return v; +} + +void +initAnnotBox() +{ + gAnnotBox.llx = gPageWd; + gAnnotBox.lly = 0; + gAnnotBox.urx = 0; + gAnnotBox.ury = gPageHt; +} + +void +flushAnnotBox() +{ + char buf[200]; + sprintf(buf, "ABOX [%f %f %f %f]", + kDvi2Scr * gAnnotBox.llx + 72.0, + kDvi2Scr * (gPageHt - gAnnotBox.lly) - 72.0, + kDvi2Scr * gAnnotBox.urx + 72.0, + kDvi2Scr * (gPageHt - gAnnotBox.ury) - 72.0); + doPDFspecial(buf); + initAnnotBox(); +} + +static void +mergeBox(const box& b) +{ + if (b.llx < gAnnotBox.llx) + gAnnotBox.llx = b.llx; + if (b.lly > gAnnotBox.lly) + gAnnotBox.lly = b.lly; // NB positive is downwards! + if (b.urx > gAnnotBox.urx) + gAnnotBox.urx = b.urx; + if (b.ury < gAnnotBox.ury) + gAnnotBox.ury = b.ury; +} + +long +readSigned(FILE* f, int k) +{ + long s = (long)(signed char)getc(f); + while (--k > 0) { + s <<= 8; + s += (getc(f) & 0xff); + } + return s; +} + +unsigned long +readUnsigned(FILE* f, int k) +{ + unsigned long u = getc(f); + while (--k > 0) { + u <<= 8; + u += (getc(f) & 0xff); + } + return u; +} + + +void +setColor(CGColorRef color, bool force = false) +{ + if (force || !gCurrentColor || !CGColorEqualToColor(color, gCurrentColor)) + CGContextSetFillColorWithColor(gCtx, color); + gCurrentColor = color; +} + +inline double +radians(double degrees) +{ + return degrees / 180.0 * M_PI; +} + +void +ensurePageStarted() +{ + if (gPageStarted) + return; + + CGContextSaveGState(gCtx); + CGContextBeginPage(gCtx, &gMediaBox); + + static CGAffineTransform sInitTextMatrix; + if (gPageIndex == 1) { + sInitTextMatrix = CGContextGetTextMatrix(gCtx); + } + else + CGContextSetTextMatrix(gCtx, sInitTextMatrix); + + gCurrentColor = NULL; /* ensure color will get set by first drawing op */ + + CGContextTranslateCTM(gCtx, 72.0, -72.0); + + gPageWd = kScr2Dvi * gMediaBox.size.width; + gPageHt = kScr2Dvi * gMediaBox.size.height; + + cur_cgFont = kUndefinedFont; + + gPageStarted = true; + + paintBackground(); +} + +void +paintBackground() +{ + if (gBackground != NULL) { + if (!gPageStarted) + ensurePageStarted(); /* this will call paintBackground() again */ + else { + CGContextSaveGState(gCtx); + CGContextSetFillColorWithColor(gCtx, gBackground); + CGContextTranslateCTM(gCtx, -72.0, 72.0); + CGContextFillRect(gCtx, gMediaBox); + CGContextRestoreGState(gCtx); + } + } +} + +#define MAX_BUFFERED_GLYPHS 1024 +int gGlyphCount = 0; +CGGlyph gGlyphs[MAX_BUFFERED_GLYPHS]; +CGSize gAdvances[MAX_BUFFERED_GLYPHS+1]; +CGPoint gStartLoc; +CGPoint gPrevLoc; + +static void +myShowGlyphsWithAdvances(CGContextRef c, const CGGlyph* glyphs, const CGSize* advances, int count) +{ + CGPoint loc = CGContextGetTextPosition(c); + while (count > 0) { + CGContextShowGlyphsAtPoint(c, loc.x, loc.y, glyphs, 1); + loc.x += advances->width; + loc.y += advances->height; + ++advances; + ++glyphs; + --count; + } +} + +void +flushGlyphs() +{ + if (gGlyphCount > 0) { + CGContextSetTextPosition(gCtx, gStartLoc.x, gStartLoc.y); + gAdvances[gGlyphCount].width = 0; + gAdvances[gGlyphCount].height = 0; + + if (sNativeFonts[cur_cgFont].isColored) + setColor(sNativeFonts[cur_cgFont].color); + else + setColor(gTextColor); + if (&CGContextShowGlyphsWithAdvances != NULL) + CGContextShowGlyphsWithAdvances(gCtx, gGlyphs, gAdvances, gGlyphCount); + else + myShowGlyphsWithAdvances(gCtx, gGlyphs, gAdvances, gGlyphCount); + + gGlyphCount = 0; + } +} + +void +bufferGlyph(CGGlyph g) +{ + ensurePageStarted(); + + CGPoint curLoc; + curLoc.x = kDvi2Scr * dvi.h; + curLoc.y = kDvi2Scr * (gPageHt - dvi.v); + if (gGlyphCount == 0) + gStartLoc = curLoc; + else { + gAdvances[gGlyphCount-1].width = curLoc.x - gPrevLoc.x; + gAdvances[gGlyphCount-1].height = curLoc.y - gPrevLoc.y; + } + gPrevLoc = curLoc; + gGlyphs[gGlyphCount] = g; + if (++gGlyphCount == MAX_BUFFERED_GLYPHS) + flushGlyphs(); +} + +void +setChar(UInt32 c, bool adv) +{ + OSStatus status; + + ensurePageStarted(); + + if (f != cur_cgFont) { + flushGlyphs(); + CGContextSetFont(gCtx, gTeXFonts[f].cgFont); + CGContextSetFontSize(gCtx, Fix2X(gTeXFonts[f].size) * gMagScale); + CGContextSetTextMatrix(gCtx, horizontalMatrix); + cur_cgFont = f; + } + + CGGlyph g; + if (gTeXFonts[f].charMap != NULL) { + if (c < gTeXFonts[f].charMap->size()) + g = (*gTeXFonts[f].charMap)[c]; + else + g = c; + } + else + // default: glyph ID = char + 1, works for the majority of the CM PS fonts + g = c + 1; + + bufferGlyph(g); + + if (gTrackingBoxes) { + if (gTeXFonts[f].hasMetrics) { + box b = { + dvi.h, + dvi.v + gTeXFonts[f].depths[c], + dvi.h + gTeXFonts[f].widths[c], + dvi.v - gTeXFonts[f].heights[c] }; + mergeBox(b); + } + } + + if (adv && gTeXFonts[f].hasMetrics) + dvi.h += gTeXFonts[f].widths[c]; +} + + +static FixedPoint +getGlyphVOrg(const nativeFont& f, UInt16 gid) +{ + FixedPoint vorg; + ATSGlyphIdealMetrics metrics; + OSStatus status = ATSUGlyphGetIdealMetrics(f.atsuStyleV, 1, &gid, 0, &metrics); +/* + fprintf(stderr, "\nmetrics(V) for glyph %d: adv = (%.3f, %.3f) sb = (%.3f, %.3f) os = (%.3f, %.3f)\n", gid, + metrics.advance.x, metrics.advance.y, metrics.sideBearing.x, metrics.sideBearing.y, + metrics.otherSideBearing.x, metrics.otherSideBearing.y); +*/ + vorg.y = X2Fix(-metrics.advance.y/* - metrics.otherSideBearing.y*/); + status = ATSUGlyphGetIdealMetrics(f.atsuStyleH, 1, &gid, 0, &metrics); +/* + fprintf(stderr, "metrics(H) for glyph %d: adv = (%.3f, %.3f) sb = (%.3f, %.3f) os = (%.3f, %.3f)\n", gid, + metrics.advance.x, metrics.advance.y, metrics.sideBearing.x, metrics.sideBearing.y, + metrics.otherSideBearing.x, metrics.otherSideBearing.y); +*/ + vorg.x = X2Fix(metrics.advance.x / 2); + return vorg; +} + +static void +doGlyphArray(FILE* xdv, bool yLocs) +{ + static int maxGlyphs = 0; + static FixedPoint* locations = 0; + static CGSize* advances = 0; + static UInt16* glyphs = 0; + + flushGlyphs(); + + Fixed wid = readUnsigned(xdv, 4); + int glyphCount = readUnsigned(xdv, 2); + + if (glyphCount >= maxGlyphs) { + maxGlyphs = glyphCount + 100; + if (glyphs != 0) + delete[] glyphs; + glyphs = new UInt16[maxGlyphs]; + if (locations != 0) + delete[] locations; + locations = new FixedPoint[maxGlyphs]; + if (advances != 0) + delete[] advances; + advances = new CGSize[maxGlyphs]; + } + + for (int i = 0; i < glyphCount; ++i) { + locations[i].x = readSigned(xdv, 4); + locations[i].y = yLocs ? readSigned(xdv, 4) : 0; + } + for (int i = 0; i < glyphCount; ++i) + glyphs[i] = readUnsigned(xdv, 2); + + if (f != cur_cgFont) { + CGContextSetFont(gCtx, sNativeFonts[f].cgFont); + CGContextSetFontSize(gCtx, Fix2X(sNativeFonts[f].size)); + CGContextSetTextMatrix(gCtx, sNativeFonts[f].isVertical + ? verticalMatrix : horizontalMatrix); + cur_cgFont = f; + } + + if (sNativeFonts[f].isColored) + setColor(sNativeFonts[f].color); + else + setColor(gTextColor); + + if (sNativeFonts[f].isVertical) { + for (int i = 0; i < glyphCount; ++i) { + // need to adjust position to right by VOrg.y and down by VOrg.x + FixedPoint vorg = getGlyphVOrg(sNativeFonts[f], glyphs[i]); + locations[i].x += vorg.y; + locations[i].y += vorg.x; + } + } + + CGContextSetTextPosition(gCtx, kDvi2Scr * dvi.h + Fix2X(locations[0].x) * 72 / 72.27, + kDvi2Scr * (gPageHt - dvi.v) - Fix2X(locations[0].y) * 72 / 72.27); + + for (int i = 0; i < glyphCount - 1; ++i) { + advances[i].width = gMagScale * Fix2X(locations[i+1].x - locations[i].x) * 72 / 72.27; + advances[i].height = gMagScale * Fix2X(locations[i].y - locations[i+1].y) * 72 / 72.27; + } + advances[glyphCount-1].width = 0.0; + advances[glyphCount-1].height = 0.0; + + if (&CGContextShowGlyphsWithAdvances != NULL) + CGContextShowGlyphsWithAdvances(gCtx, glyphs, advances, glyphCount); + else + myShowGlyphsWithAdvances(gCtx, glyphs, advances, glyphCount); + + if (gTrackingBoxes) { + box b = { + dvi.h, + dvi.v + (sNativeFonts[f].size / 3), + dvi.h + wid, + dvi.v - (2 * sNativeFonts[f].size / 3) }; + mergeBox(b); + } + + dvi.h += wid; +} + +/* code lifted almost verbatim from Apple sample "QTtoCG" */ +typedef struct { + size_t width; + size_t height; + size_t bitsPerComponent; + size_t bitsPerPixel; + size_t bytesPerRow; + size_t size; + CGImageAlphaInfo ai; + CGColorSpaceRef cs; + unsigned char *data; + CMProfileRef prof; +} BitmapInfo; + +void readBitmapInfo(GraphicsImportComponent gi, BitmapInfo *bi) +{ + ComponentResult result; + ImageDescriptionHandle imageDescH = NULL; + ImageDescription *desc; + Handle profile = NULL; + + result = GraphicsImportGetImageDescription(gi, &imageDescH); + if( noErr != result || imageDescH == NULL ) { + fprintf(stderr, "Error while retrieving image description"); + exit(1); + } + + desc = *imageDescH; + + bi->width = desc->width; + bi->height = desc->height; + bi->bitsPerComponent = 8; + bi->bitsPerPixel = 32; + bi->bytesPerRow = (bi->bitsPerPixel * bi->width + 7)/8; + bi->ai = (desc->depth == 32) ? kCGImageAlphaFirst : kCGImageAlphaNoneSkipFirst; + bi->size = bi->bytesPerRow * bi->height; + bi->data = (unsigned char*)malloc(bi->size); + + bi->cs = NULL; + bi->prof = NULL; + GraphicsImportGetColorSyncProfile(gi, &profile); + if( NULL != profile ) { + CMError err; + CMProfileLocation profLoc; + Boolean bValid, bPreferredCMMNotFound; + + profLoc.locType = cmHandleBasedProfile; + profLoc.u.handleLoc.h = profile; + + err = CMOpenProfile(&bi->prof, &profLoc); + if( err != noErr ) { + fprintf(stderr, "Cannot open profile"); + exit(1); + } + + /* Not necessary to validate profile, but good for debugging */ + err = CMValidateProfile(bi->prof, &bValid, &bPreferredCMMNotFound); + if( err != noErr ) { + fprintf(stderr, "Cannot validate profile : Valid: %d, Preferred CMM not found : %d", bValid, + bPreferredCMMNotFound); + exit(1); + } + + bi->cs = CGColorSpaceCreateWithPlatformColorSpace( bi->prof ); + + if( bi->cs == NULL ) { + fprintf(stderr, "Error creating cg colorspace from csync profile"); + exit(1); + } + DisposeHandle(profile); + } + + if( imageDescH != NULL) + DisposeHandle((Handle)imageDescH); +} + +void getBitmapData(GraphicsImportComponent gi, BitmapInfo *bi) +{ + GWorldPtr gWorld; + QDErr err = noErr; + Rect boundsRect = { 0, 0, bi->height, bi->width }; + ComponentResult result; + + if( bi->data == NULL ) { + fprintf(stderr, "no bitmap buffer available"); + exit(1); + } + + err = NewGWorldFromPtr( &gWorld, k32ARGBPixelFormat, &boundsRect, NULL, NULL, 0, + (char*)bi->data, bi->bytesPerRow ); + if (noErr != err) { + fprintf(stderr, "error creating new gworld - %d", err); + exit(1); + } + + if( (result = GraphicsImportSetGWorld(gi, gWorld, NULL)) != noErr ) { + fprintf(stderr, "error while setting gworld"); + exit(1); + } + + if( (result = GraphicsImportDraw(gi)) != noErr ) { + fprintf(stderr, "error while drawing image through qt"); + exit(1); + } + + DisposeGWorld(gWorld); +} +/* end of code from "QTtoCG" */ + +struct imageRec { + CGImageRef ref; + CGRect bounds; +}; +std::map sCGImages; +std::map sPdfDocs; + +static void +doPicFile(FILE* xdv, int pdfBoxType) // t[4][6] p[2] l[2] a[l] +{ + CGAffineTransform t; + t.a = Fix2X(readSigned(xdv, 4)); + t.b = Fix2X(readSigned(xdv, 4)); + t.c = Fix2X(readSigned(xdv, 4)); + t.d = Fix2X(readSigned(xdv, 4)); + t.tx = Fix2X(readSigned(xdv, 4)); + t.ty = Fix2X(readSigned(xdv, 4)); + if (sMag != 1000) + t = CGAffineTransformConcat(t, CGAffineTransformMakeScale(gMagScale, gMagScale)); + + int p = readSigned(xdv, 2); + int l = readUnsigned(xdv, 2); + unsigned char* pathname = new unsigned char[l + 1]; + for (int i = 0; i < l; ++i) + pathname[i] = readUnsigned(xdv, 1); + pathname[l] = 0; + + CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, pathname, l, false); + if (url != NULL) { + std::string pathString((char*)pathname, l); // key for our map<>s of already-used images + + // is it a \pdffile instance? + CGPDFDocumentRef document = NULL; + CGImageRef image = NULL; + CGRect bounds; + CGPDFBox cgPdfBoxType; + if (pdfBoxType > 0) { + std::map::const_iterator i = sPdfDocs.find(pathString); + if (i != sPdfDocs.end()) + document = i->second; + else { + document = CGPDFDocumentCreateWithURL(url); + sPdfDocs[pathString] = document; + } + if (document != NULL) { + int nPages = CGPDFDocumentGetNumberOfPages(document); + if (p < 0) p = nPages + 1 + p; + if (p > nPages) p = nPages; + if (p < 1) p = 1; +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 + if (&CGPDFDocumentGetPage == NULL) { + switch (pdfBoxType) { + case pdfbox_crop: + default: + bounds = CGPDFDocumentGetCropBox(document, p); + break; + case pdfbox_media: + bounds = CGPDFDocumentGetMediaBox(document, p); + break; + case pdfbox_bleed: + bounds = CGPDFDocumentGetBleedBox(document, p); + break; + case pdfbox_trim: + bounds = CGPDFDocumentGetTrimBox(document, p); + break; + case pdfbox_art: + bounds = CGPDFDocumentGetArtBox(document, p); + break; + } + } + else +#endif + { + CGPDFPageRef pageRef = CGPDFDocumentGetPage(document, p); + switch (pdfBoxType) { + case pdfbox_crop: + default: + cgPdfBoxType = kCGPDFCropBox; + break; + case pdfbox_media: + cgPdfBoxType = kCGPDFMediaBox; + break; + case pdfbox_bleed: + cgPdfBoxType = kCGPDFBleedBox; + break; + case pdfbox_trim: + cgPdfBoxType = kCGPDFTrimBox; + break; + case pdfbox_art: + cgPdfBoxType = kCGPDFArtBox; + break; + } + bounds = CGPDFPageGetBoxRect(pageRef, cgPdfBoxType); + } + } + } + + // otherwise use GraphicsImport + else { + std::map::const_iterator i = sCGImages.find(pathString); + if (i != sCGImages.end()) { + image = i->second.ref; + bounds = i->second.bounds; + } + else { + FSRef ref; + if (CFURLGetFSRef(url, &ref)) { + FSSpec spec; + if (FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, &spec, NULL) == noErr) { + ComponentInstance gi; + OSErr result = GetGraphicsImporterForFile(&spec, &gi); + if (result == noErr) { + BitmapInfo bi; + readBitmapInfo(gi, &bi); + getBitmapData(gi, &bi); + + if (bi.cs == NULL) + bi.cs = CGColorSpaceCreateDeviceRGB(); + CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bi.data, bi.size, NULL); + image = CGImageCreate(bi.width, bi.height, bi.bitsPerComponent, bi.bitsPerPixel, + bi.bytesPerRow, bi.cs, bi.ai, provider, NULL, 0, kCGRenderingIntentDefault); + CGColorSpaceRelease(bi.cs); + + ImageDescriptionHandle desc = NULL; + result = GraphicsImportGetImageDescription(gi, &desc); + bounds.origin.x = 0; + bounds.origin.y = 0; + bounds.size.width = (*desc)->width * 72.0 / Fix2X((*desc)->hRes); + bounds.size.height = (*desc)->height * 72.0 / Fix2X((*desc)->vRes); + DisposeHandle((Handle)desc); + result = CloseComponent(gi); + } + imageRec ir = { image, bounds }; + sCGImages[pathString] = ir; + } + } + } + } + + CGContextSaveGState(gCtx); + + CGContextTranslateCTM(gCtx, kDvi2Scr * dvi.h, kDvi2Scr * (gPageHt - dvi.v)); + CGContextConcatCTM(gCtx, t); + + if (document != NULL) { +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 + if (&CGPDFDocumentGetPage == NULL) { + CGRect mediaBox = CGPDFDocumentGetMediaBox(document, p); + CGRect cropBox = CGPDFDocumentGetCropBox(document, p); + CGContextClipToRect(gCtx, cropBox); + CGContextDrawPDFDocument(gCtx, mediaBox, document, p); + } + else +#endif + { + CGPDFPageRef pageRef = CGPDFDocumentGetPage(document, p); + CGAffineTransform xf = CGPDFPageGetDrawingTransform(pageRef, cgPdfBoxType, bounds, 0, true); + CGContextConcatCTM(gCtx, xf); + CGRect cropBox = CGPDFPageGetBoxRect(pageRef, kCGPDFCropBox); + CGContextClipToRect(gCtx, cropBox); + CGContextDrawPDFPage(gCtx, pageRef); + } + } + else if (image != NULL) + CGContextDrawImage(gCtx, bounds, image); + + if (gTrackingBoxes) { + // figure out the corners of the transformed and positioned image, + // and remember the lower left and upper right of the result + CGPoint p[4]; + p[0].x = bounds.origin.x; + p[0].y = bounds.origin.y; + p[1].x = bounds.origin.x; + p[1].y = bounds.origin.y + bounds.size.height; + p[2].x = bounds.origin.x + bounds.size.width; + p[2].y = bounds.origin.y + bounds.size.height; + p[3].x = bounds.origin.x + bounds.size.width; + p[3].y = bounds.origin.y; + + CGPoint ll = { MAXFLOAT, MAXFLOAT }; + CGPoint ur = { -MAXFLOAT, -MAXFLOAT }; + + t = CGContextGetCTM(gCtx); + // now t is the CTM, including positioning as well as transformations of the image + + for (int i = 0; i < 4; ++i) { + p[i] = CGPointApplyAffineTransform(p[i], t); + if (p[i].x < ll.x) + ll.x = p[i].x; + if (p[i].y < ll.y) + ll.y = p[i].y; + if (p[i].x > ur.x) + ur.x = p[i].x; + if (p[i].y > ur.y) + ur.y = p[i].y; + } + + // convert back to dvi space and add to the annotation area + box b = { + (ll.x - 72.0) * kScr2Dvi, + gPageHt - (ur.y + 72.0) * kScr2Dvi, + (ur.x - 72.0) * kScr2Dvi, + gPageHt - (ll.y + 72.0) * kScr2Dvi + }; + mergeBox(b); + } + + CGContextRestoreGState(gCtx); + + CFRelease(url); + } + +} + +/* declarations of KPATHSEARCH functions we use for finding TFMs and OTFs */ +extern "C" { + UInt8* kpse_find_file(const UInt8* name, int type, int must_exist); + UInt8* uppercasify(const UInt8* s); +}; +extern unsigned kpathsea_debug; + +#include "xdv_kpse_formats.h" + +static void +loadMetrics(struct texFont& font, UInt8* name, Fixed d, Fixed s) +{ + UInt8* pathname = kpse_find_file(name, xdv_kpse_tfm_format, true); + if (pathname) { + FILE* tfmFile = fopen((char*)pathname, "rb"); + if (tfmFile != 0) { + enum { lf = 0, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np }; + SInt16 directory[12]; + for (int i = 0; i < 12; ++i) + directory[i] = readSigned(tfmFile, 2); + fseek(tfmFile, directory[lh] * 4, SEEK_CUR); + int nChars = directory[ec] - directory[bc] + 1; + double_t factor = Fix2X(d) / 16.0; + if (s != d) + factor = factor * Fix2X(s) / Fix2X(d); + if (nChars > 0) { + struct s_charinfo { + UInt8 widthIndex; + UInt8 heightDepth; + UInt8 italicIndex; + UInt8 remainder; + }; + s_charinfo* charInfo = new s_charinfo[nChars]; + for (int i = 0; i < nChars; ++i) { + charInfo[i].widthIndex = readUnsigned(tfmFile, 1); + charInfo[i].heightDepth = readUnsigned(tfmFile, 1); + charInfo[i].italicIndex = readUnsigned(tfmFile, 1); + charInfo[i].remainder = readUnsigned(tfmFile, 1); + } + Fixed* widths = new Fixed[directory[nw]]; + for (int i = 0; i < directory[nw]; ++i) + widths[i] = readSigned(tfmFile, 4); + Fixed* heights = new Fixed[directory[nh]]; + for (int i = 0; i < directory[nh]; ++i) + heights[i] = readSigned(tfmFile, 4); + Fixed* depths = new Fixed[directory[nd]]; + for (int i = 0; i < directory[nd]; ++i) + depths[i] = readSigned(tfmFile, 4); + + font.widths.reserve(directory[ec] + 1); + font.heights.reserve(directory[ec] + 1); + font.depths.reserve(directory[ec] + 1); + font.charMap = new std::vector; + font.charMap->reserve(directory[ec] + 1); + for (int i = 0; i < directory[bc]; ++i) { + font.widths.push_back(0); + font.heights.push_back(0); + font.depths.push_back(0); + font.charMap->push_back(0); + } + int g = 0; + for (int i = 0; i < nChars; ++i) { + if (charInfo[i].widthIndex == 0) { + font.widths.push_back(0); + font.heights.push_back(0); + font.depths.push_back(0); + font.charMap->push_back(0); + } + else { + double_t wid = Fix2X(widths[charInfo[i].widthIndex]) * factor; + font.widths.push_back(X2Fix(wid)); + + int heightIndex = (charInfo[i].heightDepth >> 4); + double_t ht = Fix2X(heights[heightIndex]) * factor; + font.heights.push_back(X2Fix(ht)); + + int depthIndex = (charInfo[i].heightDepth & 0x0f); + double_t dp = Fix2X(depths[depthIndex]) * factor; + font.depths.push_back(X2Fix(dp)); + + font.charMap->push_back(++g); + } + } + + delete[] widths; + delete[] heights; + delete[] depths; + delete[] charInfo; + } + + font.hasMetrics = true; + fclose(tfmFile); + } + free(pathname); + } +} + +typedef std::vector encoding; +std::map sEncodings; + +class fontMapRec { +public: + fontMapRec() + : cgFont(0) + , cmap(NULL) + , loaded(false) + { } + + std::string psName; + std::string encName; + std::string pfbName; + + CGFontRef cgFont; + std::vector* cmap; + + bool loaded; +}; + +std::map psFontsMap; + +static void +clearFontMap() +{ + std::map::iterator i; + for (i = psFontsMap.begin(); i != psFontsMap.end(); ++i) { + if (i->second.cmap != NULL) + delete i->second.cmap; + } + psFontsMap.clear(); +} + +void +doPdfMapLine(const char* line, char mode) +{ + if (*line == '%') + return; + while (*line == ' ' || *line == '\t') + ++line; + if (*line < ' ') + return; + + if (mode == 0) { + switch (*line) { + case '+': + case '-': + case '=': + mode = *line; + ++line; + while (*line == ' ' || *line == '\t') + ++line; + if (*line < ' ') + return; + break; + default: + clearFontMap(); + mode = '+'; + break; + } + } + + const char* b = line; + const char* e = b; + while (*e > ' ') + ++e; + std::string tfmName(b, e - b); + + if (mode == '-') { + psFontsMap.erase(tfmName); + return; + // erase existing entry + } + + if ((mode == '+') && (psFontsMap.find(tfmName) != psFontsMap.end())) + return; + // don't add if entry already exists + + while (*e && *e <= ' ') + ++e; + b = e; + while (*e > ' ') + ++e; + if (e > b) { + fontMapRec fr; + fr.psName.assign(b, e - b); + while (*e && *e <= ' ') + ++e; + if (*e == '"') { // skip quoted string; we don't do oblique, stretch, etc. (yet) + ++e; + while (*e && *e != '"') + ++e; + if (*e == '"') + ++e; + while (*e && *e <= ' ') + ++e; + } + while (*e == '<') { + ++e; + b = e; + while (*e > ' ') + ++e; + if (strncmp(e - 4, ".enc", 4) == 0) { + fr.encName.assign(b, e - b); + } + else if (strncmp(e - 4, ".pfb", 4) == 0) { + fr.pfbName.assign(b, e - b); + } +/* + else if (strncmp(e - 4, ".pfa", 4) == 0) { + fr.otfName.assign(b, e - b - 4); + } +*/ + while (*e && *e <= ' ') + ++e; + } + psFontsMap[tfmName] = fr; + } +} + +static bool sMapFileLoaded = false; + +void +doPdfMapFile(const char* fileName) +{ + char mode = 0; + + while (*fileName == ' ' || *fileName == '\t') + ++fileName; + if (*fileName < ' ') + return; + + switch (*fileName) { + case '+': + case '-': + case '=': + mode = *fileName; + ++fileName; + break; + default: + clearFontMap(); + mode = '+'; + break; + } + while (*fileName == ' ' || *fileName == '\t') + ++fileName; + if (*fileName < ' ') + return; + + bool loaded = false; + UInt8* pathname = kpse_find_file((UInt8*)fileName, xdv_kpse_font_map_format, true); + if (pathname) { + FILE* f = fopen((char*)pathname, "r"); + if (f != NULL) { + char line[1000]; + while (!feof(f)) { + if (fgets(line, 999, f) == 0) + break; + doPdfMapLine(line, mode); + + } + loaded = true; + fclose(f); + if (sVerbose) + fprintf(stderr, "\n{fontmap: %s} ", pathname); + } + free(pathname); + } + if (!loaded) + fprintf(stderr, "\n*** fontmap %s not found; texmf.cnf may be broken\n", fileName); + else + sMapFileLoaded = true; +} + +// return a pointer to the encoding vector with the given name, loading it if necessary +// we don't really "parse" the .enc file +static const encoding* +getEncoding(const std::string& name) +{ + std::map::iterator i = sEncodings.find(name); + if (i == sEncodings.end()) { + encoding enc; + UInt8* pathname = kpse_find_file((UInt8*)(name.c_str()), xdv_kpse_enc_format, true); + if (pathname != NULL) { + FILE* f = fopen((char*)pathname, "r"); + if (f != NULL) { + int c; + bool inVector = false; + std::string str; + while ((c = getc(f)) != EOF) { + got_ch: + if (c == '%') { // comment: skip rest of line + while ((c = getc(f)) != EOF && c != '\r' && c != '\n') + ; + goto got_ch; + } + if (c == '[') { + inVector = true; + } + else if (c == '/' || c <= ' ' || c == ']' || c == EOF) { + if (inVector && str.length() > 0) + enc.push_back(str); + str.clear(); + } + else if (inVector && c != EOF) + str.append(1, (char)c); + } + if (sVerbose) + fprintf(stderr, "\n{encoding: %s} ", pathname); + fclose(f); + } + free(pathname); + } + sEncodings[name] = enc; + return &(sEncodings[name]); + } + + return &(i->second); +} + +static ATSFontRef +activateFromPath(const char* pathName) +{ + if (sVerbose) + fprintf(stderr, "\n{activate %s", pathName); + ItemCount count = 0; + FSRef fontFileRef; + bzero(&fontFileRef, sizeof(fontFileRef)); + OSStatus status = FSPathMakeRef((UInt8*)pathName, &fontFileRef, 0); + if (status == noErr) { + ++count; + FSSpec fontFileSpec; + bzero(&fontFileSpec, sizeof(fontFileSpec)); + status = FSGetCatalogInfo(&fontFileRef, 0, 0, 0, &fontFileSpec, 0); + if (status == noErr) { + ++count; + ATSFontContainerRef containerRef = 0; + status = ATSFontActivateFromFileSpecification(&fontFileSpec, kATSFontContextLocal, + kATSFontFormatUnspecified, 0, kATSOptionFlagsDefault, &containerRef); + if (status == noErr) { + ++count; + ATSFontRef fontRef; + status = ATSFontFindFromContainer(containerRef, 0, 1, &fontRef, &count); + if (status == noErr && count == 1) { + if (sVerbose) + fprintf(stderr, "}"); + return fontRef; + } + // failed, or container contained multiple fonts(!) -- confused + ATSFontDeactivate(containerRef, 0, kATSOptionFlagsDefault); + } + } + } + if (sVerbose) + fprintf(stderr, "... failed: status=%d, count=%d}", status, count); + return 0; +} + +struct postTable { + Fixed format; + Fixed italicAngle; + SInt16 underlinePosition; + SInt16 underlineThickness; + UInt16 isFixedPitch; + UInt16 reserved; + UInt32 minMemType42; + UInt32 maxMemType42; + UInt32 minMemType1; + UInt32 maxMemType1; +}; + +#include "appleGlyphNames.c" + +#define sfntCacheDir "/Library/Caches/Type1-sfnt-fonts/" +#define sfntWrapCommand "T1Wrap" +#define sfntWrapSuffix "-sfnt.otf" + +static ATSFontRef +activatePFB(const char* pfbName) +{ + static std::map sActivatedFonts; + + std::map::iterator i = sActivatedFonts.find(pfbName); + if (i != sActivatedFonts.end()) + return i->second; + + ATSFontRef fontRef = 0; + OSStatus status = noErr; + + static int firstTime = 1; + if (firstTime) { + firstTime = 0; + status = mkdir(sfntCacheDir, S_IRWXU | S_IRWXG | S_IRWXO); + if (status != 0) { + if (errno == EEXIST) { + // clean up possible residue from past failed conversions + system("/usr/bin/find " sfntCacheDir " -maxdepth 1 -empty -type f -delete"); + status = 0; + } + else + fprintf(stderr, "*** failed to create sfnt cache directory %s (errno = %d), cannot activate .pfb fonts\n", + sfntCacheDir, errno); + } + } + + char* sfntName = new char[strlen(sfntCacheDir) + strlen(pfbName) + strlen(sfntWrapSuffix) + 1]; + strcpy(sfntName, sfntCacheDir); + strcat(sfntName, pfbName); + strcat(sfntName, sfntWrapSuffix); + + FSRef ref; + status = FSPathMakeRef((const UInt8*)sfntName, &ref, NULL); + if (status == fnfErr) { + char* pathName = (char*)kpse_find_file((UInt8*)pfbName, xdv_kpse_pfb_format, true); + if (pathName != NULL) { + char* cmd = new char[strlen(sfntWrapCommand) + strlen(pathName) + strlen(sfntName) + 6]; + strcpy(cmd, sfntWrapCommand " "); + strcat(cmd, pathName); + strcat(cmd, " > "); + strcat(cmd, sfntName); + status = system(cmd); + delete[] cmd; + free(pathName); + } + } + + if (status == noErr) + fontRef = activateFromPath(sfntName); + + delete[] sfntName; + + if (fontRef == 0) { + // try removing extension (.pfb) and looking for an .otf font... + char* baseName = new char[strlen(pfbName) + 1]; + strcpy(baseName, pfbName); + char* dot = strrchr(baseName, '.'); + if (dot != NULL) + *dot = 0; + char* pathName = (char*)kpse_find_file((UInt8*)baseName, xdv_kpse_otf_format, true); + delete[] baseName; + if (pathName != NULL) { + fontRef = activateFromPath(pathName); + free(pathName); + } + } + + if (fontRef == 0) + fprintf(stderr, "\n*** font activation failed (status=%d): %s\n", status, pfbName); + + sActivatedFonts[pfbName] = fontRef; + return fontRef; +} + +static std::vector* +readMacRomanCmap(ATSFontRef fontRef) +{ + std::vector* cmap = NULL; + ByteCount size; + OSStatus status = ATSFontGetTable(fontRef, 'cmap', 0, 0, 0, &size); + if (status == noErr) { + UInt8* buffer = new UInt8[size]; + ATSFontGetTable(fontRef, 'cmap', 0, size, buffer, &size); + + struct cmapHeader { + UInt16 version; + UInt16 numSubtables; + }; + struct subtableHeader { + UInt16 platform; + UInt16 encoding; + UInt32 offset; + }; + struct format0 { + UInt16 format; + UInt16 length; + UInt16 language; + UInt8 glyphIndex[256]; + }; + struct format6 { + UInt16 format; + UInt16 length; + UInt16 language; + UInt16 firstCode; + UInt16 entryCount; + UInt16 glyphIndex[1]; + }; + + struct cmapHeader* h = (struct cmapHeader*)buffer; + struct subtableHeader* sh = (struct subtableHeader*)(buffer + sizeof(struct cmapHeader)); + int subtable = 0; + cmap = new std::vector; + cmap->reserve(256); + while (subtable < SWAP(h->numSubtables)) { + if ((SWAP(sh->platform) == 1) && (SWAP(sh->encoding) == 0)) { + struct format0* f0 = (struct format0*)(buffer + SWAP(sh->offset)); + if (SWAP(f0->format) == 0) { + for (int ch = 0; ch < 256; ++ch) { + cmap->push_back(SWAP(f0->glyphIndex[ch])); + } + } + else if (SWAP(f0->format) == 6) { + struct format6* f6 = (struct format6*)f0; + for (int ch = 0; ch < 256; ++ch) { + if ((ch < SWAP(f6->firstCode)) || (ch >= SWAP(f6->firstCode) + SWAP(f6->entryCount))) + cmap->push_back(0); + else + cmap->push_back(SWAP(f6->glyphIndex[ch - SWAP(f6->firstCode)])); + } + } + else { + // unsupported cmap subtable format + fprintf(stderr, "\n*** unsupported 'cmap' subtable format (%d)\n", SWAP(f0->format)); + } + break; + } + ++subtable; + ++sh; + } + + delete[] buffer; + } + + return cmap; +} + +static const fontMapRec* +getFontRec(const std::string& name) +{ + if (!sMapFileLoaded) + doPdfMapFile("psfonts.map"); + + std::map::iterator i = psFontsMap.find(name); + if (i == psFontsMap.end()) + return NULL; + + fontMapRec& fr = i->second; + if (fr.loaded) + return &fr; + + ATSFontRef fontRef = 0; + // if a filename is known, try to find and activate it + + if (fr.pfbName.length() > 0) + fontRef = activatePFB(fr.pfbName.c_str()); + + // if no downloadable file, see if it's installed in the OS + if (fontRef == 0) + fontRef = ATSFontFindFromPostScriptName(CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, fr.psName.c_str(), + CFStringGetSystemEncoding(), kCFAllocatorNull), kATSOptionFlagsDefault); + + if (fontRef == 0) + fprintf(stderr, "\n*** font %s (%s: file '%s') not found\n", name.c_str(), fr.psName.c_str(), fr.pfbName.c_str()); + + if (fontRef != 0) { + // if re-encoding was called for, load the encoding vector and build a new cmap + if (fr.encName.length() > 0) { + const encoding* enc = getEncoding(fr.encName); + if (enc != 0) { + ByteCount size; + OSStatus status = ATSFontGetTable(fontRef, 'post', 0, 0, 0, &size); + if (status == noErr) { + UInt8* buffer = new UInt8[size]; + ATSFontGetTable(fontRef, 'post', 0, size, buffer, &size); + postTable* p = (postTable*)&buffer[0]; + std::map name2gid; + UInt16 g = 0; + switch (SWAP(p->format)) { + case 0x00010000: + { + char* cp; + while ((cp = appleGlyphNames[g]) != 0) { + name2gid[cp] = g; + ++g; + } + } + break; + + case 0x00020000: + { + UInt16* n = (UInt16*)(p + 1); + UInt16 numGlyphs = SWAP(*n++); + UInt8* ps = (UInt8*)(n + numGlyphs); + std::vector newNames; + while (ps < buffer + size) { + newNames.push_back(std::string((char*)ps + 1, *ps)); + ps += *ps + 1; + } + for (g = 0; g < numGlyphs; ++g) { + if (SWAP(*n) < 258) + name2gid[appleGlyphNames[SWAP(*n)]] = g; + else + name2gid[newNames[SWAP(*n) - 258]] = g; + ++n; + } + } + break; + + case 0x00028000: + fprintf(stderr, "\n*** format 2.5 'post' table not supported\n"); + break; + + case 0x00030000: + // TODO: see if it's a CFF OpenType font, and if so, get the glyph names from the CFF data + fprintf(stderr, "\n*** format 3 'post' table; cannot reencode font %s\n", name.c_str()); + break; + + case 0x00040000: + fprintf(stderr, "\n*** format 4 'post' table not supported\n"); + break; + + default: + fprintf(stderr, "\n*** unknown 'post' table format %08x\n"); + break; + } + if (fr.cmap != NULL) + delete fr.cmap; + fr.cmap = new std::vector; + for (encoding::const_iterator i = enc->begin(); i != enc->end(); ++i) { + std::map::const_iterator g = name2gid.find(*i); + if (g == name2gid.end()) + fr.cmap->push_back(0); + else + fr.cmap->push_back(g->second); + } + } + else { + fprintf(stderr, "\n*** no 'post' table found, unable to re-encode font %s\n", name.c_str()); + } + } + } + else { + // read the MacOS/Roman cmap, if available + std::vector* cmap = readMacRomanCmap(fontRef); + if (fr.cmap != NULL) + delete fr.cmap; + fr.cmap = cmap; + } + } + + if (fontRef == 0) { + fprintf(stderr, "\n*** font %s (%s) not found, will substitute Helvetica glyphs\n", name.c_str(), fr.pfbName.c_str()); + fontRef = ATSFontFindFromPostScriptName(CFSTR("Helvetica"), kATSOptionFlagsDefault); + if (fr.cmap != NULL) + delete fr.cmap; + fr.cmap = readMacRomanCmap(fontRef); + } + + fr.cgFont = getCGFontForATSFont(fontRef); + fr.loaded = true; + + return &fr; +} + +static void +doFontDef(FILE* xdv, int k) +{ + OSStatus status; + + UInt32 f = readUnsigned(xdv, k); // font number we're defining + UInt32 c = readUnsigned(xdv, 4); // TFM checksum + Fixed s = readUnsigned(xdv, 4); // at size + Fixed d = readUnsigned(xdv, 4); // design size + + UInt16 alen = readUnsigned(xdv, 1); // area length + UInt16 nlen = readUnsigned(xdv, 1); // name length + + UInt8* name = new UInt8[alen + nlen + 2]; + if (alen > 0) { + fread(name, 1, alen, xdv); + name[alen] = '/'; + fread(name + alen + 1, 1, nlen, xdv); + nlen += alen + 1; + } + else + fread(name, 1, nlen, xdv); + name[nlen] = 0; + + texFont font; + loadMetrics(font, name, d, s); + + if (alen > 0) + name = name + alen + 1; // point past the area to get the name by itself for the remaining operations + + ATSFontRef fontRef; + + // look for a map entry for this font name + std::string nameStr((char*)name); + const fontMapRec* fr = getFontRec(nameStr); + if (fr != NULL) { + font.cgFont = fr->cgFont; + if (fr->cmap->size() > 0) { + if (font.charMap != NULL) + delete font.charMap; + font.charMap = fr->cmap; // replacing map that was synthesized from the tfm coverage + } + } + else { + /* try to find the font without the benefit of psfonts.map... + first try the name as a pfb or otf filename + and then as the PS name of an installed font + */ + + // ****** FIXME ****** this needs re-working to read the 'cmap' properly + + fontRef = ATSFontFindFromPostScriptName(CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, (char*)name, + CFStringGetSystemEncoding(), kCFAllocatorNull), kATSOptionFlagsDefault); + UInt8* ucname = 0; + if (fontRef == 0) { + ucname = uppercasify(name); + fontRef = ATSFontFindFromPostScriptName(CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, (char*)ucname, + CFStringGetSystemEncoding(), kCFAllocatorNull), kATSOptionFlagsDefault); + } + + if (ucname != 0) + free(ucname); + + if (fontRef == 0) { + fprintf(stderr, "\n*** font %s not found in psfonts.map or host system; will substitute Helvetica glyphs\n", (char*)name); + fontRef = ATSFontFindFromPostScriptName(CFSTR("Helvetica"), kATSOptionFlagsDefault); + if (font.charMap != NULL) + delete font.charMap; + font.charMap = readMacRomanCmap(fontRef); + } + + font.cgFont = getCGFontForATSFont(fontRef); + + delete[] name; + } + + font.size = s; + gTeXFonts.insert(std::pair(f, font)); +} + +static void +variationWarning() +{ + static bool alreadyWarned = false; + if (alreadyWarned) + return; + fprintf(stderr, "\n" + "## xdv2pdf: AAT variation axes/multiple master fonts not supported on this system\n" + "## (at least Mac OS X 10.4 is required)\n"); + alreadyWarned = true; +} + +static void +doNativeFontDef(FILE* xdv) +{ + UInt32 f = readUnsigned(xdv, 4); // font ID + Fixed s = X2Fix(Fix2X(readUnsigned(xdv, 4)) * 72 / 72.27); // size, converted to "big" points + if (sMag != 1000) + s = X2Fix(gMagScale * Fix2X(s)); + UInt16 flags = readUnsigned(xdv, 2); + + int psLen = readUnsigned(xdv, 1); // PSName length + int skipLen = readUnsigned(xdv, 1); // family name length + skipLen += readUnsigned(xdv, 1); // style name length + + char* name = new char[psLen+1]; + fread(name, 1, psLen, xdv); + name[psLen] = 0; + + // don't use fseek, doesn't work when reading from a pipe! + while (skipLen-- > 0) + (void)readUnsigned(xdv, 1); + + UInt32 rgba = 0x000000FF; + if (flags & XDV_FLAG_COLORED) + rgba = readUnsigned(xdv, 4); + + ATSFontRef fontRef = 0; + ATSUFontID fontID = kATSUInvalidFontID; + + if (name[0] == '[') { // uninstalled font specified by filename: not supported + fprintf(stderr, "\n" + "## xdv2pdf: use of uninstalled fonts (specified by filename) such as\n" + "## %s\n" + "## is not supported; try using the xdvipdfmx driver instead.\n", name); + } + else { + CFStringRef psNameStr = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingMacRoman); + fontRef = ATSFontFindFromPostScriptName(psNameStr, kATSOptionFlagsDefault); + CFRelease(psNameStr); + + fontID = FMGetFontFromATSFontRef(fontRef); + } + + if (fontID == kATSUInvalidFontID) + rgba = 0xFF0000FF; + + CGFontRef cgFont = getCGFontForATSFont(fontRef); + + OSStatus status = noErr; + + if (flags & XDV_FLAG_VARIATIONS) { + int n = readUnsigned(xdv, 2); // number of variations + if (n > 0) { + bool applyVars = true; + CFStringRef* axes = new CFStringRef[n]; + for (int i = 0; i < n; ++i) { + UInt32 axis = readUnsigned(xdv, 4); + FontNameCode nameCode; + status = ATSUGetFontVariationNameCode(fontID, axis, &nameCode); + ByteCount len; + status = ATSUFindFontName(fontID, nameCode, kFontMacintoshPlatform, kFontRomanScript, + (FontLanguageCode)kFontNoLanguage, 0, NULL, &len, NULL); + if (status == noErr) { + char* buf = new char[len + 1]; + status = ATSUFindFontName(fontID, nameCode, kFontMacintoshPlatform, kFontRomanScript, + (FontLanguageCode)kFontNoLanguage, len, buf, &len, NULL); + buf[len] = 0; + axes[i] = CFStringCreateWithCString(kCFAllocatorDefault, buf, kCFStringEncodingMacRoman); + delete[] buf; + } + else + applyVars = false; + } + + CFNumberRef* values = new CFNumberRef[n]; + for (int i = 0; i < n; ++i) { + SInt32 v = readSigned(xdv, 4); + Float32 f = Fix2X(v); + values[i] = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat32Type, &f); + } + + if (&CGFontCreateCopyWithVariations != NULL) { + CFDictionaryRef variations = CFDictionaryCreate(kCFAllocatorDefault, + (const void**)axes, (const void**)values, n, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + cgFont = CGFontCreateCopyWithVariations(cgFont, variations); + CFRelease(variations); + } + else + variationWarning(); + + for (int i = 0; i < n; ++i) { + CFRelease(axes[i]); + CFRelease(values[i]); + } + delete[] values; + delete[] axes; + } + } + + nativeFont fontRec; + fontRec.cgFont = cgFont; + fontRec.atsFont = fontRef; + fontRec.size = s; + fontRec.isColored = (flags & XDV_FLAG_COLORED) != 0 || fontID == kATSUInvalidFontID; + fontRec.isVertical = (flags & XDV_FLAG_VERTICAL) != 0; + if (fontRec.isColored) { + float values[4]; + values[0] = (rgba >> 24) / 255.0; + values[1] = ((rgba >> 16) & 0xFF) / 255.0; + values[2] = ((rgba >> 8) & 0xFF) / 255.0; + values[3] = ( rgba & 0xFF) / 255.0; + fontRec.color = CGColorCreate(gRGBColorSpace, values); + } + else + fontRec.color = NULL; + + if (fontRec.isVertical) { + ATSUStyle style; + status = ATSUCreateStyle(&style); + ATSUVerticalCharacterType vert = kATSUStronglyHorizontal; + ATSUAttributeTag tags[] = { kATSUFontTag, kATSUSizeTag, kATSUVerticalCharacterTag }; + ByteCount sizes[] = { sizeof(fontID), sizeof(s), sizeof(vert) }; + ATSUAttributeValuePtr values[] = { &fontID, &s, &vert }; + ItemCount numTags = sizeof(tags) / sizeof(ATSUAttributeTag); + status = ATSUSetAttributes(style, numTags, tags, sizes, values); + fontRec.atsuStyleH = style; + + status = ATSUCreateStyle(&style); + vert = kATSUStronglyVertical; + status = ATSUSetAttributes(style, numTags, tags, sizes, values); + fontRec.atsuStyleV = style; + } + + sNativeFonts.insert(std::pair(f, fontRec)); +} + +static void +processPage(FILE* xdv) +{ + /* enter here having just read BOP from xdv file */ + ++gPageIndex; + + OSStatus status; + int i; + + std::list stack; + gDviLevel = 0; + + int j = 0; + for (i = 0; i < 10; ++i) { // read counts + gCounts[i] = readSigned(xdv, 4); + if (gCounts[i] != 0) + j = i; + } + if (sVerbose) { + fprintf(stderr, "["); + for (i = 0; i < j; ++i) + fprintf(stderr, "%d.", gCounts[i]); + fprintf(stderr, "%d", gCounts[j]); + } + + (void)readUnsigned(xdv, 4); // skip prev-BOP pointer + + cur_cgFont = kUndefinedFont; + dvi.h = dvi.v = 0; + dvi.w = dvi.x = dvi.y = dvi.z = 0; + f = 0; + + unsigned int cmd = DVI_BOP; + while (cmd != DVI_EOP) { + UInt32 u; + SInt32 s; + SInt32 ht, wd; + int k = 1; + + cmd = readUnsigned(xdv, 1); + switch (cmd) { + default: + if (cmd < DVI_SET1) + setChar(cmd, true); + else if (cmd >= DVI_FNTNUM0 && cmd <= DVI_FNTNUM0 + 63) + f = cmd - DVI_FNTNUM0; + else + goto ABORT_PAGE; + break; + + case DVI_EOP: + flushGlyphs(); + break; + + case DVI_NOP: + break; + + case DVI_FNT4: + ++k; + case DVI_FNT3: + ++k; + case DVI_FNT2: + ++k; + case DVI_FNT1: + f = readUnsigned(xdv, k); // that's it: just set |f| + break; + + case DVI_XXX4: + ++k; + case DVI_XXX3: + ++k; + case DVI_XXX2: + ++k; + case DVI_XXX1: + flushGlyphs(); + u = readUnsigned(xdv, k); + if (u > 0) { + char* special = new char[u+1]; + fread(special, 1, u, xdv); + special[u] = '\0'; + + doSpecial(special); + + delete[] special; + } + break; + + case DVI_SETRULE: + case DVI_PUTRULE: + ensurePageStarted(); + ht = readSigned(xdv, 4); + wd = readSigned(xdv, 4); + if (ht > 0 && wd > 0) { + CGRect r = CGRectMake(kDvi2Scr * dvi.h, kDvi2Scr * (gPageHt - dvi.v), kDvi2Scr * wd, kDvi2Scr * ht); + setColor(gRuleColor); + CGContextFillRect(gCtx, r); + if (gTrackingBoxes) { + box b = { + dvi.h, + dvi.v, + dvi.h + wd, + dvi.v - ht }; + mergeBox(b); + } + } + if (cmd == DVI_SETRULE) + dvi.h += wd; + break; + + case DVI_SET4: + ++k; + case DVI_SET3: + ++k; + case DVI_SET2: + ++k; + case DVI_SET1: + u = readUnsigned(xdv, k); + setChar(u, true); + break; + + case DVI_PUT4: + ++k; + case DVI_PUT3: + ++k; + case DVI_PUT2: + ++k; + case DVI_PUT1: + u = readUnsigned(xdv, k); + setChar(u, false); + break; + + case DVI_PUSH: + stack.push_back(dvi); + ++gDviLevel; + break; + + case DVI_POP: + if (gDviLevel == gTagLevel) + flushAnnotBox(); + --gDviLevel; + dvi = stack.back(); + stack.pop_back(); + break; + + case DVI_RIGHT4: + ++k; + case DVI_RIGHT3: + ++k; + case DVI_RIGHT2: + ++k; + case DVI_RIGHT1: + s = readSigned(xdv, k); + dvi.h += s; + break; + + case DVI_DOWN4: + ++k; + case DVI_DOWN3: + ++k; + case DVI_DOWN2: + ++k; + case DVI_DOWN1: + s = readSigned(xdv, k); + dvi.v += s; + break; + + case DVI_W4: + ++k; + case DVI_W3: + ++k; + case DVI_W2: + ++k; + case DVI_W1: + s = readSigned(xdv, k); + dvi.w = s; + case DVI_W0: + dvi.h += dvi.w; + break; + + case DVI_X4: + ++k; + case DVI_X3: + ++k; + case DVI_X2: + ++k; + case DVI_X1: + s = readSigned(xdv, k); + dvi.x = s; + case DVI_X0: + dvi.h += dvi.x; + break; + + case DVI_Y4: + ++k; + case DVI_Y3: + ++k; + case DVI_Y2: + ++k; + case DVI_Y1: + s = readSigned(xdv, k); + dvi.y = s; + case DVI_Y0: + dvi.v += dvi.y; + break; + + case DVI_Z4: + ++k; + case DVI_Z3: + ++k; + case DVI_Z2: + ++k; + case DVI_Z1: + s = readSigned(xdv, k); + dvi.z = s; + case DVI_Z0: + dvi.v += dvi.z; + break; + + case XDV_GLYPH_ARRAY: + ensurePageStarted(); + doGlyphArray(xdv, true); + break; + + case XDV_GLYPH_STRING: + ensurePageStarted(); + doGlyphArray(xdv, false); + break; + + case XDV_PIC_FILE: + ensurePageStarted(); + k = readUnsigned(xdv, 1); /* 0 for QT picfile, or PDF box code (1..5) */ + doPicFile(xdv, k); + break; + + case DVI_FNTDEF4: + ++k; + case DVI_FNTDEF3: + ++k; + case DVI_FNTDEF2: + ++k; + case DVI_FNTDEF1: + doFontDef(xdv, k); + break; + + case XDV_NATIVE_FONT_DEF: + doNativeFontDef(xdv); + break; + } + } + + ensurePageStarted(); // needed for completely blank pages! + + if (sVerbose) { + fprintf(stderr, "]%s", (gPageIndex % 10) == 0 ? "\n" : ""); + } + +ABORT_PAGE: + + if (gPageStarted) { + CGContextEndPage(gCtx); + CGContextRestoreGState(gCtx); + } + + gPageStarted = false; +} + +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4 +/* From Apple Technical Q&A 1396, Listing 2 */ +static CGColorSpaceRef +CreateICCColorSpaceFromPathToProfile(const char* iccProfilePath) +{ + CMProfileRef iccProfile = (CMProfileRef)0; + CGColorSpaceRef iccColorSpace = NULL; + CMProfileLocation loc; + + // Specify that the location of the profile will be a POSIX path to the profile. + loc.locType = cmPathBasedProfile; + + // Make sure the path is not larger then the buffer + if (strlen(iccProfilePath) > sizeof(loc.u.pathLoc.path)) + return NULL; + + // Copy the path the profile into the CMProfileLocation structure + strcpy(loc.u.pathLoc.path, iccProfilePath); + + // Open the profile + if (CMOpenProfile(&iccProfile, &loc) != noErr) { + iccProfile = (CMProfileRef)0; + return NULL; + } + + // Create the ColorSpace with the open profile. + iccColorSpace = CGColorSpaceCreateWithPlatformColorSpace(iccProfile); + + // Close the profile now that we have what we need from it. + CMCloseProfile(iccProfile); + + return iccColorSpace; +} + +static CGColorSpaceRef +CreateColorSpaceFromSystemICCProfileName(CFStringRef profileName) +{ + FSRef pathToProfilesFolder; + FSRef pathToProfile; + + // Find the Systems Color Sync Profiles folder + if (FSFindFolder(kOnSystemDisk, kColorSyncProfilesFolderType, + kDontCreateFolder, &pathToProfilesFolder) == noErr) { + + // Make a UniChar string of the profile name + UniChar uniBuffer[sizeof(CMPathLocation)]; + CFStringGetCharacters(profileName, CFRangeMake(0, CFStringGetLength(profileName)), uniBuffer); + + // Create a FSRef to the profile in the Systems Color Sync Profile folder + if (FSMakeFSRefUnicode(&pathToProfilesFolder, CFStringGetLength(profileName), uniBuffer, + kUnicodeUTF8Format, &pathToProfile) == noErr) { + char path[sizeof(CMPathLocation)]; + + // Write the posix path to the profile into our path buffer from the FSRef + if (FSRefMakePath(&pathToProfile, (UInt8*)path, sizeof(CMPathLocation)) == noErr) + return CreateICCColorSpaceFromPathToProfile(path); + } + } + + return NULL; +} +/* end of Apple Q&A code */ +#endif + +static void +processAllPages(FILE* xdv) +{ + // initialize some global variables that we use as CG "constants" +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4 + if (&kCGColorSpaceGenericRGB == NULL) { + gRGBColorSpace = CreateColorSpaceFromSystemICCProfileName(CFSTR("Generic RGB Profile.icc")); + gCMYKColorSpace = CreateColorSpaceFromSystemICCProfileName(CFSTR("Generic CMYK Profile.icc")); + gGrayColorSpace = CreateColorSpaceFromSystemICCProfileName(CFSTR("Generic Gray Profile.icc")); + } + else +#endif + { + gRGBColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + gCMYKColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericCMYK); + gGrayColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); + } + + if (gRGBColorSpace == NULL || gCMYKColorSpace == NULL || gGrayColorSpace == NULL) { + fprintf(stderr, "\n*** unable to initialize color spaces.... something's badly broken\n"); + exit(1); + } + + const float black[2] = { 0.0, 1.0 }; + kBlackColor = CGColorCreate(gGrayColorSpace, black); + + gPageIndex = 0; + unsigned int cmd; + while ((cmd = readUnsigned(xdv, 1)) != DVI_POST) { + switch (cmd) { + case DVI_BOP: + processPage(xdv); + break; + + case DVI_NOP: + break; + + default: + fprintf(stderr, "\n*** unexpected DVI command: %d\n", cmd); + exit(1); + } + } + if (sVerbose && (gPageIndex % 10) != 0) + fprintf(stderr, "\n"); +} + +const char* progName; +static void +usage() +{ + fprintf(stderr, "usage: %s [-m mag] [-p papersize[:landscape]] [-v] [-o pdfFile] xdvFile\n", progName); + fprintf(stderr, " papersize values: "); + paperSizeRec* ps = &gPaperSizes[0]; + while (ps->name != 0) { + fprintf(stderr, "%s/", ps->name); + ++ps; + } + fprintf(stderr, "wd,ht [in 'big' points or with explicit units]\n"); +} + +int +xdv2pdf(int argc, char** argv) +{ + OSStatus status; + + progName = argv[0]; + + gMagScale = 1.0; + gRuleColor = kBlackColor; + gTextColor = gRuleColor; + + gTagLevel = -1; + + double_t paperWd = 0.0; + double_t paperHt = 0.0; + + int ch; + while ((ch = getopt(argc, argv, "o:p:m:d:hv" /*r:*/)) != -1) { + switch (ch) { + case 'o': + { + CFStringRef outFileName = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8); + gSaveURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, outFileName, kCFURLPOSIXPathStyle, false); + CFRelease(outFileName); + } + break; + + case 'p': + if (!getPaperSize(optarg, paperWd, paperHt)) { + fprintf(stderr, "*** unknown paper name: %s\n", optarg); + exit(1); + } + break; + + case 'm': + sMag = atoi(optarg); + break; + + case 'd': + kpathsea_debug |= atoi(optarg); + break; + + case 'v': + sVerbose = true; + break; + + case 'h': + usage(); + exit(0); + } + } + + if ((paperWd == 0.0) || (paperHt == 0.0)) { + // get default paper size from printing system + PMRect paperRect = { 0, 0, 792, 612 }; + PMPrintSession printSession; + PMPrintSettings printSettings; + PMPageFormat pageFormat; + status = PMCreateSession(&printSession); + if (status == noErr) { + status = PMCreatePrintSettings(&printSettings); + if (status == noErr) { + status = PMSessionDefaultPrintSettings(printSession, printSettings); + status = PMCreatePageFormat(&pageFormat); + if (status == noErr) { + status = PMSessionDefaultPageFormat(printSession, pageFormat); + PMGetUnadjustedPaperRect(pageFormat, &paperRect); + status = PMRelease(pageFormat); + } + status = PMRelease(printSettings); + } + status = PMRelease(printSession); + } + paperWd = paperRect.right - paperRect.left; + paperHt = paperRect.bottom - paperRect.top; + } + + // set the media box for PDF generation + gMediaBox = CGRectMake(0, 0, paperWd, paperHt); + + argc -= optind; + argv += optind; + if (argc == 1 && gSaveURL == 0) { + CFStringRef inFileName = CFStringCreateWithCString(kCFAllocatorDefault, argv[0], CFStringGetSystemEncoding()); + CFURLRef inURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, inFileName, kCFURLPOSIXPathStyle, false); + CFRelease(inFileName); + CFURLRef tmpURL = CFURLCreateCopyDeletingPathExtension(kCFAllocatorDefault, inURL); + CFRelease(inURL); + gSaveURL = CFURLCreateCopyAppendingPathExtension(kCFAllocatorDefault, tmpURL, CFSTR("pdf")); + CFRelease(tmpURL); + } + + if (argc > 1 || gSaveURL == 0) { + usage(); + exit(1); + } + + FILE* xdv; + if (argc == 1) + xdv = fopen(argv[0], "r"); + else + xdv = stdin; + + if (xdv != NULL) { + // read the preamble + unsigned b = readUnsigned(xdv, 1); + if (b != DVI_PRE) { fprintf(stderr, "*** bad XDV file: DVI_PRE not found, b=%d\n", b); exit(1); } + b = readUnsigned(xdv, 1); + if (b != XDV_ID) { fprintf(stderr, "*** bad XDV file: version=%d, expected %d\n", b, XDV_ID); exit(1); } + (void)readUnsigned(xdv, 4); // num + (void)readUnsigned(xdv, 4); // den + if (sMag == 0) + sMag = readUnsigned(xdv, 4); // sMag + else + (void)readUnsigned(xdv, 4); + + unsigned numBytes = readUnsigned(xdv, 1); // length of output comment + UInt8* bytes = new UInt8[numBytes]; + fread(bytes, 1, numBytes, xdv); + + CFStringRef keys[2] = { CFSTR("Creator") , CFSTR("Title") /*, CFSTR("Author")*/ }; + CFStringRef values[2] = { CFSTR("xdv2pdf") , 0 /*, 0*/ }; + values[1] = CFStringCreateWithBytes(kCFAllocatorDefault, bytes, numBytes, CFStringGetSystemEncoding(), false); + delete[] bytes; +// values[2] = CFStringCreateWithCString(kCFAllocatorDefault, getlogin(), CFStringGetSystemEncoding()); + CFDictionaryRef auxInfo = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)values, sizeof(keys) / sizeof(keys[0]), + &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFRelease(values[1]); +// CFRelease(values[2]); + + // create PDF graphics context + gCtx = CGPDFContextCreateWithURL(gSaveURL, &gMediaBox, auxInfo); + + // handle magnification + if (sMag != 1000) { + gMagScale = sMag / 1000.0; + kScr2Dvi /= gMagScale; + kDvi2Scr *= gMagScale; + CGContextScaleCTM(gCtx, gMagScale, gMagScale); + } + + // draw all the pages + processAllPages(xdv); + + CGContextRelease(gCtx); + + while (getc(xdv) != EOF) + ; + fclose(xdv); + } + + if (gPdfMarkFile != NULL) { + fclose(gPdfMarkFile); + char pdfPath[_POSIX_PATH_MAX+1]; + Boolean gotPath = CFURLGetFileSystemRepresentation(gSaveURL, true, (UInt8*)pdfPath, _POSIX_PATH_MAX); + CFRelease(gSaveURL); +#if 0 + if (gotPath) { + char* mergeMarks = "xdv2pdf_mergemarks"; + execlp(mergeMarks, mergeMarks, pdfPath, gPdfMarkPath, 0); // should not return! + status = errno; + } + fprintf(stderr, "*** failed to run xdv2pdf_mergemarks: status = %d\n", status); +#else + if (gotPath) { + char* mergeMarks = "xdv2pdf_mergemarks"; + char cmd[_POSIX_PATH_MAX*2 + 100]; + sprintf(cmd, "%s \"%s\" \"%s\"", mergeMarks, pdfPath, gPdfMarkPath); + status = system(cmd); + } + else + status = fnfErr; + if (status != 0) + fprintf(stderr, "*** failed to run xdv2pdf_mergemarks: status = %d\n", status); +#endif + } + else + CFRelease(gSaveURL); + + return status; +} diff --git a/Build/source/texk/xdv2pdf/xdv2pdf_globals.h b/Build/source/texk/xdv2pdf/xdv2pdf_globals.h new file mode 100644 index 00000000000..63baa0b7e30 --- /dev/null +++ b/Build/source/texk/xdv2pdf/xdv2pdf_globals.h @@ -0,0 +1,142 @@ +/****************************************************************************\ + Part of the XeTeX typesetting system + copyright (c) 1994-2005 by SIL International + written by Jonathan Kew + + This software is distributed under the terms of the Common Public License, + version 1.0. + For details, see or the file + cpl1.0.txt included with the software. +\****************************************************************************/ + + +#ifndef XDV2PDF_GLOBALS +#define XDV2PDF_GLOBALS + +#include +#include +#include + +#ifdef DEFINE_GLOBALS +#define GLOBAL +#else +#define GLOBAL extern +#endif + +#define kUndefinedFont 0x80000000UL + +GLOBAL CGContextRef gCtx; + +GLOBAL CGColorSpaceRef gRGBColorSpace; +GLOBAL CGColorSpaceRef gCMYKColorSpace; +GLOBAL CGColorSpaceRef gGrayColorSpace; + +GLOBAL bool gPageStarted; +GLOBAL CGRect gMediaBox; + +struct dviVars { + SInt32 h; + SInt32 v; + SInt32 w; + SInt32 x; + SInt32 y; + SInt32 z; +}; +GLOBAL dviVars dvi; +GLOBAL UInt32 f, cur_cgFont; + +GLOBAL double_t kScr2Dvi // not quite const, actually - mag changes them +#ifdef DEFINE_GLOBALS + = (72.27 * 65536.0) / 72.0 +#endif + ; +GLOBAL double_t kDvi2Scr +#ifdef DEFINE_GLOBALS + = 1.0 / kScr2Dvi +#endif + ; + +GLOBAL CGColorRef kBlackColor; + +GLOBAL std::list gTextColorStack; +GLOBAL std::list gRuleColorStack; + +GLOBAL CGColorRef gTextColor; +GLOBAL CGColorRef gRuleColor; +GLOBAL CGColorRef gBackground; + +GLOBAL CGColorRef gCurrentColor; + +struct texFont { + texFont() + : cgFont(0) + , size(Long2Fix(10)) + , charMap(NULL) + , hasMetrics(false) + { + } + CGFontRef cgFont; + Fixed size; + std::vector widths; + std::vector heights; + std::vector depths; + std::vector*charMap; + bool hasMetrics; + bool hasMap; +}; + +GLOBAL std::map gTeXFonts; + +GLOBAL long gPageIndex; +GLOBAL int gCounts[10]; + +struct box { + float llx; + float lly; + float urx; + float ury; +}; +GLOBAL box gAnnotBox; + +GLOBAL int gTagLevel; +GLOBAL int gDviLevel; +GLOBAL bool gTrackingBoxes; + +GLOBAL double_t gMagScale; + +GLOBAL double_t gPageHt; +GLOBAL double_t gPageWd; + +struct paperSizeRec { + const char* name; + double_t width; + double_t height; // dimensions in BP ("big" or PostScript/CG points) +}; + +#ifndef DEFINE_GLOBALS +GLOBAL paperSizeRec gPaperSizes[]; +#endif + +GLOBAL CFURLRef gSaveURL; +GLOBAL char gPdfMarkPath[_POSIX_PATH_MAX+1]; +GLOBAL FILE* gPdfMarkFile; + + +void flushAnnotBox(); +void initAnnotBox(); +bool getPaperSize(const char* arg, double_t& paperWd, double_t& paperHt); +void doPDFspecial(const char* special); +void doSpecial(const char* special); + + +void ensurePageStarted(); +void paintBackground(); +void setColor(CGColorRef color, bool force); +void doPdfMapLine(const char* line, char mode); +void doPdfMapFile(const char* fileName); + +extern "C" { + int xdv2pdf(int argc, char** argv); +}; + +#endif /* XDV2PDF_GLOBALS */ diff --git a/Build/source/texk/xdv2pdf/xdv2pdf_main.c b/Build/source/texk/xdv2pdf/xdv2pdf_main.c new file mode 100755 index 00000000000..94977588718 --- /dev/null +++ b/Build/source/texk/xdv2pdf/xdv2pdf_main.c @@ -0,0 +1,227 @@ +/****************************************************************************\ + Part of the XeTeX typesetting system + copyright (c) 1994-2005 by SIL International + written by Jonathan Kew + + This software is distributed under the terms of the Common Public License, + version 1.0. + For details, see or the file + cpl1.0.txt included with the software. +\****************************************************************************/ + +/* + xdv2pdf_main + + Main file for xdv2pdf + Written in plain C for easier linkage to kpathsea library +*/ + +#define MAC_OS_X_VERSION_MIN_REQUIRED 1020 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xdv_kpse_formats.h" + +/* The program name, for `.PROG' construct in texmf.cnf. (-program) */ +string progname = NULL; + +extern int xdv2pdf(int argc, char** argv); + +#ifndef DEFAULT_OTFFONTS +#define DEFAULT_OTFFONTS ".:/usr/local/teTeX/share/texmf/fonts/otf//:/usr/TeX/texmf/fonts/otf//" +#endif + +#define INIT_FORMAT(text, default_path, envs) \ + FMT_INFO.type = text; \ + init_path (&FMT_INFO, default_path, envs, NULL) + +#define OTFFONTS_ENVS "OTFFONTS" + +#define TFM_ENVS "TFMFONTS", "TEXFONTS" +#define CNF_ENVS "TEXMFCNF" +#define DB_ENVS "TEXMFDBS" +#define DVIPS_CONFIG_ENVS "TEXCONFIG" +#define FONTMAP_ENVS "TEXFONTMAPS", "TEXFONTS", DVIPS_CONFIG_ENVS /* try TEXCONFIG for teTeX 2 */ +#define TEX_PS_HEADER_ENVS "TEXPSHEADERS", "PSHEADERS" +#define ENC_ENVS "ENCFONTS", "TEXFONTS", TEX_PS_HEADER_ENVS +#define TYPE1_ENVS "T1FONTS", "T1INPUTS", "TEXFONTS", TEX_PS_HEADER_ENVS + +#define FMT_INFO kpse_format_info[format] +/* Call kpse_set_add_suffixes. */ +#define SUFFIXES(args) kpse_set_suffixes(format, false, args, NULL) +#define ALT_SUFFIXES(args) kpse_set_suffixes(format, true, args, NULL) + +/* Macro subroutines for `init_path'. TRY_ENV checks if an envvar ENAME + is set and non-null, and sets var to ENAME if so. */ +#define TRY_ENV(ename) do { \ + string evar = ename; \ +} while (0) + +/* And EXPAND_DEFAULT calls kpse_expand_default on try_path and the + present info->path. */ +#define EXPAND_DEFAULT(try_path, source_string) \ + if (try_path) { \ + info->raw_path = try_path; \ + info->path = kpse_expand_default (try_path, info->path); \ + info->path_source = source_string; \ + } + +static string +remove_dbonly P1C(const_string, path) +{ + string ret = XTALLOC(strlen (path) + 1, char), q=ret; + const_string p=path; + boolean new_elt=true; + + while (*p) { + if (new_elt && *p && *p == '!' && *(p+1) == '!') + p += 2; + else { + new_elt = (*p == ENV_SEP); + *q++ = *p++; + } + } + *q = '\0'; + return(ret); +} + +/* Find the final search path to use for the format entry INFO, given + the compile-time default (DEFAULT_PATH), and the environment + variables to check (the remaining arguments, terminated with NULL). + We set the `path' and `path_source' members of INFO. The + `client_path' member must already be set upon entry. */ + +static void +init_path PVAR2C(kpse_format_info_type *, info, const_string, default_path, ap) +{ + string env_name; + string var = NULL; + + info->default_path = default_path; + + /* First envvar that's set to a nonempty value will exit the loop. If + none are set, we want the first cnf entry that matches. Find the + cnf entries simultaneously, to avoid having to go through envvar + list twice -- because of the PVAR?C macro, that would mean having + to create a str_list and then use it twice. Yuck. */ + while ((env_name = va_arg (ap, string)) != NULL) { + /* Since sh doesn't like envvar names with `.', check PATH_prog + as well as PATH.prog. */ + if (!var) { + /* Try PATH.prog. */ + string evar = concat3 (env_name, ".", kpse_program_name); + string env_value = getenv (evar); + if (env_value && *env_value) { + var = evar; + } else { + free (evar); + /* Try PATH_prog. */ + evar = concat3 (env_name, "_", kpse_program_name); + env_value = getenv (evar); + if (env_value && *env_value) { + var = evar; + } else { + free (evar); + /* Try simply PATH. */ + env_value = getenv (env_name); + if (env_value && *env_value) { + var = env_name; + } + } + } + } + + /* If we are initializing the cnf path, don't try to get any + values from the cnf files; that's infinite loop time. */ + if (!info->cnf_path && info != &kpse_format_info[kpse_cnf_format]) + info->cnf_path = kpse_cnf_get (env_name); + + if (var && info->cnf_path) + break; + } + va_end (ap); + + /* Expand any extra :'s. For each level, we replace an extra : with + the path at the next lower level. For example, an extra : in a + user-set envvar should be replaced with the path from the cnf file. + things are complicated because none of the levels above the very + bottom are guaranteed to exist. */ + + /* Assume we can reliably start with the compile-time default. */ + info->path = info->raw_path = info->default_path; + info->path_source = "compile-time paths.h"; + + EXPAND_DEFAULT (info->cnf_path, "texmf.cnf"); + EXPAND_DEFAULT (info->client_path, "program config file"); + if (var) + EXPAND_DEFAULT (getenv (var), concat (var, " environment variable")); + EXPAND_DEFAULT (info->override_path, "application override variable"); + info->path = kpse_brace_expand (info->path); +} +} /* extra closing brace to match with PVAR2C in function header */ + +int +main(int argc, char** argv) +{ + kpse_file_format_type format; + + kpse_set_program_name (argv[0], progname); + + /* It seems to be critical that I do a kpse_cnf_get to trigger the reading of texmf.cnf files + BEFORE the INIT_FORMAT stuff below. I don't really understand all the interactions + of search paths, config files, etc., but for now this is working for me. */ + kpse_cnf_get("TETEXDIR"); + + format = kpse_cnf_format; + INIT_FORMAT ("cnf", DEFAULT_TEXMFCNF, CNF_ENVS); + SUFFIXES (".cnf"); + + format = kpse_db_format; + INIT_FORMAT ("ls-R", DEFAULT_TEXMFDBS, DB_ENVS); + SUFFIXES ("ls-R"); + FMT_INFO.path = remove_dbonly (FMT_INFO.path); + + format = xdv_kpse_pfb_format; + INIT_FORMAT ("type1 fonts", DEFAULT_T1FONTS, TYPE1_ENVS); + FMT_INFO.binmode = true; + FMT_INFO.suffix_search_only = true; + SUFFIXES (".pfb"); + + format = xdv_kpse_otf_format; + INIT_FORMAT ("otf fonts", DEFAULT_OTFFONTS, OTFFONTS_ENVS); + FMT_INFO.binmode = true; + FMT_INFO.suffix_search_only = true; + SUFFIXES (".otf"); + + format = xdv_kpse_tfm_format; + INIT_FORMAT ("tfm", DEFAULT_TFMFONTS, TFM_ENVS); + FMT_INFO.binmode = true; + FMT_INFO.suffix_search_only = true; + SUFFIXES (".tfm"); + + format = xdv_kpse_font_map_format; + INIT_FORMAT ("map", DEFAULT_TEXFONTMAPS, FONTMAP_ENVS); + FMT_INFO.suffix_search_only = true; + SUFFIXES (".map"); + + format = xdv_kpse_enc_format; + INIT_FORMAT ("enc files", DEFAULT_ENCFONTS, ENC_ENVS); + FMT_INFO.suffix_search_only = true; + SUFFIXES (".enc"); + + return xdv2pdf(argc, argv); +} diff --git a/Build/source/texk/xdv2pdf/xdv2pdf_mergemarks b/Build/source/texk/xdv2pdf/xdv2pdf_mergemarks new file mode 100755 index 00000000000..ce36f1e8116 --- /dev/null +++ b/Build/source/texk/xdv2pdf/xdv2pdf_mergemarks @@ -0,0 +1,205 @@ +#!/usr/bin/perl + +# /****************************************************************************\ +# Part of the XeTeX typesetting system +# copyright (c) 1994-2005 by SIL International +# written by Jonathan Kew +# +# This software is distributed under the terms of the Common Public License, +# version 1.0. +# For details, see or the file +# cpl1.0.txt included with the software. +# \****************************************************************************/ + +BEGIN { + # try to locate our private Perl module directory + my $p = `kpsewhich -progname=xetex -format=texmfscripts Reuse.pm`; + chomp $p; + if ($p eq '') { + # try a known location + $p = '/usr/local/teTeX/share/texmf.local/scripts/xetex/perl/lib/PDF/Reuse.pm'; + die "can't find Reuse.pm!" unless -e $p; + } + $p =~ s!/PDF/Reuse.pm!!; + die "perl/lib directory $p not found!" unless -d $p; + unshift @INC, $p; +}; + +use strict; +use PDF::Reuse; + +die "usage: $0 \n" unless $#ARGV == 1; + +my $infile = $ARGV[0]; +my $markfile = $ARGV[1]; +my $outfile = "$ARGV[0].tmp"; + +my $newlink = undef; +my $seenbox = 0; +my %dest; +my @links; +my @bookmarks; + +sub toUtf16 +{ + my $txt = shift; + $txt =~ s/\\([\\\(\)])/$1/g; + $txt = pack('n*', 0xfeff, unpack('U*', $txt)); + $txt =~ s/\\/\\\\/g; + $txt =~ s/\(/\\(/g; + $txt =~ s/\)/\\)/g; + return $txt; +} + +open FH, "<:utf8", "$markfile" or die "failed to read mark-file $markfile\n"; +while () { + chomp; + my ($page, $xpos, $ypos, $txt) = split(/\t/, $_, 4); + if ($txt =~ /^\s*dest/o) { + $txt =~ /^\s*dest\s+\(([^\)]+)\)\s*(\[.+\])/o; + my $destname = $1; + $dest{$destname} = $2; + my $zp = $page - 1; + $dest{$destname} =~ s/\/View\s\[(.+)\]/$1/; + $dest{$destname} =~ s/\@thispage/$zp/; + $dest{$destname} =~ s/\@xpos/$xpos/; + $dest{$destname} =~ s/\@ypos/$ypos/; + } + + elsif ($txt =~ /^\s*bann/o) { + if ($txt =~ m!<+\s*/Type\s*/Annot\s*/Subtype\s*/Link\s*.*/A\s*<+([^>]+)>>\s*>>!o) { + $newlink = { page => $page, x => $xpos, y => $ypos, action => $1 }; + if ($txt =~ m!/Border\s*(\[[^]]+\])!o) { + $newlink->{border} = $1; + } + if ($txt =~ m!/C\s*(\[[^]]+\])!o) { + $newlink->{color} = $1; + } + } + $seenbox = 0; + } + + elsif ($txt =~ /^\s*ABOX/o) { + if (defined $newlink) { + $txt =~ m/\[\s*(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*\]/o; + my $boxlink = { page => $newlink->{page}, action => $newlink->{action} }; + $boxlink->{border} = $newlink->{border} if exists $newlink->{border}; + $boxlink->{color} = $newlink->{color} if exists $newlink->{color}; + $boxlink->{x} = $1 < $3 ? $1 : $3; + $boxlink->{y} = $2 < $4 ? $2 : $4; + $boxlink->{width} = abs($1 - $3); + $boxlink->{height} = abs($2 - $4); + push @links, $boxlink; + $seenbox = 1; + } + } + + elsif ($txt =~ /^\s*eann/o) { + if ((defined $newlink) && ($seenbox == 0)) { + $newlink->{width} = $xpos - $newlink->{x}; + if ($newlink->{width} < 0) { + $newlink->{width} = -$newlink->{width}; + $newlink->{x} = $xpos; + } + $newlink->{height} = $ypos - $newlink->{y}; + if ($newlink->{height} < 0) { + $newlink->{height} = -$newlink->{height}; + $newlink->{y} = $ypos; + } + push @links, $newlink; + undef $newlink; + } + } + + elsif ($txt =~ /^\s*ann/o) { + $txt =~ m!width\s+(\d+(?:\.\d*)?)pt\s+height\s+(\d+(?:\.\d*)?)pt\s+.*/A\s*<+([^>]+)>>!o; + if (defined $1) { + $newlink = { page => $page, x => $xpos, y => $ypos, width => $1, height => $2, action => $3 }; + if ($txt =~ m!/Border\s*(\[[^]]+\])!o) { + $newlink->{border} = $1; + } + if ($txt =~ m!/C\s*(\[[^]]+\])!o) { + $newlink->{color} = $1; + } + push @links, $newlink; + undef $newlink; + } + } + + elsif ($txt =~ /^\s*outline/o) { + $txt =~ m!outline\s+(-?\d+)\s*<+\s*/Title\s*\(((?:[^\)]|\\\))+)\)\s*/A\s*<+([^>]+)>>\s*>>!o; + my ($level, $title, $action) = ($1, $2, $3); + my $bm = { 'text' => &toUtf16($title), 'pdfact' => $action, '_lvl' => $level }; + if ((scalar @bookmarks == 0) || ($level <= $bookmarks[$#bookmarks]->{'_lvl'})) { + push @bookmarks, $bm; + } + else { + my $parent = $bookmarks[$#bookmarks]; + my $plevel = $parent->{'_lvl'}; + while ($plevel + 1 < $level) { + if (exists $parent->{'kids'}) { + $parent = $parent->{'kids'}[$#{$parent->{'kids'}}]; + $plevel = $parent->{'_lvl'}; + } + else { + last; + } + } + push @{$parent->{'kids'}}, $bm; + } + } + +} +close FH; + +fixActions(\@bookmarks); + +prFile("$outfile"); + +prBookmark(\@bookmarks); + +foreach (@links) { + my $action = $_->{action}; + if ($action =~ m!/S\s/GoTo\s/D\s\(([^\)]+)\)!o) { + my $destname = $1; + my $explicit = $dest{$destname}; + $action =~ s/\(.+\)/$explicit/; + $_->{action} = $action; + } + prLink($_); +} + +prDoc($infile); + +prEnd(); + +unlink($markfile); + +unlink($infile); +rename($outfile, $infile); + +exit(0); + +sub fixActions +{ + my $bookmarks = shift; + foreach (@$bookmarks) { + $_->{'pdfact'} = fixAct($_->{'pdfact'}); + if (exists $_->{'kids'}) { + fixActions($_->{'kids'}); + } + } +} + +sub fixAct +{ + my $action = shift; + if ($action =~ m!/S\s*/GoTo\s*/D\s*\(([^\)]+)\)!o) { + my $destname = $1; + if (exists $dest{$destname}) { + $action = "/Type /Action /S /GoTo /D $dest{$destname}"; + } + } + return $action; +} + diff --git a/Build/source/texk/xdv2pdf/xdv2pdf_specials.cpp b/Build/source/texk/xdv2pdf/xdv2pdf_specials.cpp new file mode 100644 index 00000000000..58af6f4bfab --- /dev/null +++ b/Build/source/texk/xdv2pdf/xdv2pdf_specials.cpp @@ -0,0 +1,770 @@ +/****************************************************************************\ + Part of the XeTeX typesetting system + copyright (c) 1994-2005 by SIL International + written by Jonathan Kew + + This software is distributed under the terms of the Common Public License, + version 1.0. + For details, see or the file + cpl1.0.txt included with the software. +\****************************************************************************/ + +// \special{} support for xdv2pdf + +#define MAC_OS_X_VERSION_MIN_REQUIRED 1020 + +#include + +#include "xdv2pdf_globals.h" + + +struct dimenRec { + const char* name; + double_t factor; // multiplier to convert to BP +}; + +static dimenRec sDimenRatios[] = +{ + { "in", 72.0 }, + { "mm", 72.0 / 25.4 }, + { "cm", 72.0 / 2.54 }, + { "bp", 1.0 }, + { "pt", 72.0 / 72.27 }, + { "pc", 12.0 * 72.0 / 72.27 }, + { "dd", 1238.0 * 72.0 / 72.27 / 1157.0 }, + { "cc", 14856.0 * 72.0 / 72.27 / 1157.0 }, + { 0, 0 } +}; + +static int +readHexDigit(const char*& cp) +{ + if (*cp >= '0' && *cp <= '9') + return *cp++ - '0'; + if (*cp >= 'A' && *cp <= 'F') + return *cp++ - 'A' + 10; + if (*cp >= 'a' && *cp <= 'f') + return *cp++ - 'a' + 10; + return 0; +} + +static CGColorRef +readColorValue(const char* s) +{ + float components[4]; + int x; + x = readHexDigit(s); + x <<= 4; + x += readHexDigit(s); + components[0] = x / 255.0; + x = readHexDigit(s); + x <<= 4; + x += readHexDigit(s); + components[1] = x / 255.0; + x = readHexDigit(s); + x <<= 4; + x += readHexDigit(s); + components[2] = x / 255.0; + components[3] = 1.0; + return CGColorCreate(gRGBColorSpace, components); +} + +static CGColorRef +readColorValueWithAlpha(const char* s) +{ + float components[4]; + int x; + x = readHexDigit(s); + x <<= 4; + x += readHexDigit(s); + components[0] = x / 255.0; + x = readHexDigit(s); + x <<= 4; + x += readHexDigit(s); + components[1] = x / 255.0; + x = readHexDigit(s); + x <<= 4; + x += readHexDigit(s); + components[2] = x / 255.0; + x = readHexDigit(s); + x <<= 4; + x += readHexDigit(s); + components[3] = x / 255.0; + return CGColorCreate(gRGBColorSpace, components); +} + +static float +readFloat(const char*& cp) +{ + float result = 0.0; + bool negate = false; + if (*cp == '-') { + negate = true; + ++cp; + } + while (*cp >= '0' && *cp <= '9') + result = result * 10 + *cp++ - '0'; + if (*cp == '.') { + ++cp; + float dec = 1.0; + while (*cp >= '0' && *cp <= '9') + result = result + (dec /= 10.0) * (*cp++ - '0'); + } + if (negate) + result = -result; + return result; +} + +void +doPDFspecial(const char* special) +{ + ensurePageStarted(); + + if (gPdfMarkFile == NULL) { + static bool firstTime = true; + if (firstTime) { + firstTime = false; + CFURLRef markURL = CFURLCreateCopyAppendingPathExtension(kCFAllocatorDefault, gSaveURL, CFSTR("marks")); + Boolean gotPath = CFURLGetFileSystemRepresentation(markURL, true, (UInt8*)gPdfMarkPath, _POSIX_PATH_MAX); + if (gotPath) { + gPdfMarkFile = fopen(gPdfMarkPath, "w"); + if (gPdfMarkFile == NULL) + fprintf(stderr, "*** unable to write to PDFmark file \"%s\"\n", gPdfMarkPath); + } + else + fprintf(stderr, "*** unable to get pathname for PDFmark file\n"); + } + } + if (gPdfMarkFile != NULL) { + if (strncmp(special, "bann", 4) == 0) { + gTagLevel = gDviLevel; + initAnnotBox(); + gTrackingBoxes = true; + } + else if (strncmp(special, "eann", 4) == 0) { + flushAnnotBox(); + gTrackingBoxes = false; + gTagLevel = -1; + } + fprintf(gPdfMarkFile, "%d\t%f\t%f\t%s\n", + gPageIndex, kDvi2Scr * dvi.h + 72.0, kDvi2Scr * (gPageHt - dvi.v) - 72.0, special); + } +} + +static void +pushTextColor() +{ + gTextColorStack.push_back(gTextColor); +} + +static void +popTextColor() +{ + if (gTextColorStack.size() == 0) { + fprintf(stderr, "\n*** text color stack underflow\n"); + } + else { + gTextColor = gTextColorStack.back(); + gTextColorStack.pop_back(); + } +} + +static void +pushRuleColor() +{ + gRuleColorStack.push_back(gRuleColor); +} + +static void +popRuleColor() +{ + if (gRuleColorStack.size() == 0) { + fprintf(stderr, "\n*** rule color stack underflow\n"); + } + else { + gRuleColor = gRuleColorStack.back(); + gRuleColorStack.pop_back(); + } +} + +static void +setRuleColor(CGColorRef color) +{ + gRuleColor = color; +} + +static void +resetRuleColor() +{ + gRuleColor = kBlackColor; +} + +static void +setTextColor(CGColorRef color) +{ + gTextColor = color; +} + +static void +resetTextColor() +{ + gTextColor = kBlackColor; +} + +static void +setBackground(CGColorRef bg) +{ + gBackground = bg; + paintBackground(); +} + +static bool +readColorValues(const char*& s, int n, float* v) +{ + while (n-- > 0) { + while (*s == ' ') + ++s; + if ( !( ( (*s >= '0') && (*s <= '9') ) // unless we have a digit + || (*s == '.') || (*s == ',') ) ) // or decimal sign, break + return false; + float val = 0.0; + while ((*s >= '0') && (*s <= '9')) { + val = val * 10.0 + *s - '0'; + ++s; + } + if ((*s == '.') || (*s == ',')) { + ++s; + float dec = 10.0; + while ((*s >= '0') && (*s <= '9')) { + val += (*s - '0') / dec; + dec *= 10; + ++s; + } + } + *v++ = val; + } + return true; +} + +struct namedColor { + char *name; + float cmyk[4]; +} colorsByName[] = { + {"GreenYellow", {0.15, 0, 0.69, 0}}, + {"Yellow", {0, 0, 1, 0}}, + {"Goldenrod", {0, 0.10, 0.84, 0}}, + {"Dandelion", {0, 0.29, 0.84, 0}}, + {"Apricot", {0, 0.32, 0.52, 0}}, + {"Peach", {0, 0.50, 0.70, 0}}, + {"Melon", {0, 0.46, 0.50, 0}}, + {"YellowOrange", {0, 0.42, 1, 0}}, + {"Orange", {0, 0.61, 0.87, 0}}, + {"BurntOrange", {0, 0.51, 1, 0}}, + {"Bittersweet", {0, 0.75, 1, 0.24}}, + {"RedOrange", {0, 0.77, 0.87, 0}}, + {"Mahogany", {0, 0.85, 0.87, 0.35}}, + {"Maroon", {0, 0.87, 0.68, 0.32}}, + {"BrickRed", {0, 0.89, 0.94, 0.28}}, + {"Red", {0, 1, 1, 0}}, + {"OrangeRed", {0, 1, 0.50, 0}}, + {"RubineRed", {0, 1, 0.13, 0}}, + {"WildStrawberry", {0, 0.96, 0.39, 0}}, + {"Salmon", {0, 0.53, 0.38, 0}}, + {"CarnationPink", {0, 0.63, 0, 0}}, + {"Magenta", {0, 1, 0, 0}}, + {"VioletRed", {0, 0.81, 0, 0}}, + {"Rhodamine", {0, 0.82, 0, 0}}, + {"Mulberry", {0.34, 0.90, 0, 0.02}}, + {"RedViolet", {0.07, 0.90, 0, 0.34}}, + {"Fuchsia", {0.47, 0.91, 0, 0.08}}, + {"Lavender", {0, 0.48, 0, 0}}, + {"Thistle", {0.12, 0.59, 0, 0}}, + {"Orchid", {0.32, 0.64, 0, 0}}, + {"DarkOrchid", {0.40, 0.80, 0.20, 0}}, + {"Purple", {0.45, 0.86, 0, 0}}, + {"Plum", {0.50, 1, 0, 0}}, + {"Violet", {0.79, 0.88, 0, 0}}, + {"RoyalPurple", {0.75, 0.90, 0, 0}}, + {"BlueViolet", {0.86, 0.91, 0, 0.04}}, + {"Periwinkle", {0.57, 0.55, 0, 0}}, + {"CadetBlue", {0.62, 0.57, 0.23, 0}}, + {"CornflowerBlue", {0.65, 0.13, 0, 0}}, + {"MidnightBlue", {0.98, 0.13, 0, 0.43}}, + {"NavyBlue", {0.94, 0.54, 0, 0}}, + {"RoyalBlue", {1, 0.50, 0, 0}}, + {"Blue", {1, 1, 0, 0}}, + {"Cerulean", {0.94, 0.11, 0, 0}}, + {"Cyan", {1, 0, 0, 0}}, + {"ProcessBlue", {0.96, 0, 0, 0}}, + {"SkyBlue", {0.62, 0, 0.12, 0}}, + {"Turquoise", {0.85, 0, 0.20, 0}}, + {"TealBlue", {0.86, 0, 0.34, 0.02}}, + {"Aquamarine", {0.82, 0, 0.30, 0}}, + {"BlueGreen", {0.85, 0, 0.33, 0}}, + {"Emerald", {1, 0, 0.50, 0}}, + {"JungleGreen", {0.99, 0, 0.52, 0}}, + {"SeaGreen", {0.69, 0, 0.50, 0}}, + {"Green", {1, 0, 1, 0}}, + {"ForestGreen", {0.91, 0, 0.88, 0.12}}, + {"PineGreen", {0.92, 0, 0.59, 0.25}}, + {"LimeGreen", {0.50, 0, 1, 0}}, + {"YellowGreen", {0.44, 0, 0.74, 0}}, + {"SpringGreen", {0.26, 0, 0.76, 0}}, + {"OliveGreen", {0.64, 0, 0.95, 0.40}}, + {"RawSienna", {0, 0.72, 1, 0.45}}, + {"Sepia", {0, 0.83, 1, 0.70}}, + {"Brown", {0, 0.81, 1, 0.60}}, + {"Tan", {0.14, 0.42, 0.56, 0}}, + {"Gray", {0, 0, 0, 0.50}}, + {"Black", {0, 0, 0, 1}}, + {"White", {0, 0, 0, 0}} +}; + +inline bool +kwmatch(const char*& s, const char* k) +{ + while (*s == ' ') + ++s; + int kwlen = strlen(k); + if ( (s[kwlen] == 0) || (s[kwlen] == ' ') ) { + if (strncmp(s, k, kwlen) == 0) { + s += kwlen; + return true; + } + } + return false; +} + +static float +readAlphaIfPresent(const char*& s) +{ + if (kwmatch(s, "alpha")) { + float alpha; + if (readColorValues(s, 1, &alpha)) + return alpha; + } + return 1.0; +} + +static void +doColorSpecial(const char* s, bool background) +{ + while (*s != 0) { + if (!background) { + if (kwmatch(s, "push")) { + pushRuleColor(); + pushTextColor(); + continue; + } + + if (kwmatch(s, "pop")) { + popRuleColor(); + popTextColor(); + continue; + } + } + + if (kwmatch(s, "rgb")) { + float rgba[4]; + if (readColorValues(s, 3, rgba)) { + rgba[3] = readAlphaIfPresent(s); + CGColorRef c = CGColorCreate(gRGBColorSpace, rgba); + if (background) + setBackground(c); + else { + setRuleColor(c); + setTextColor(c); + } + } + break; + } + + if (kwmatch(s, "cmyk")) { + float cmyka[5]; + if (readColorValues(s, 4, cmyka)) { + cmyka[4] = readAlphaIfPresent(s); + CGColorRef c = CGColorCreate(gCMYKColorSpace, cmyka); + if (background) + setBackground(c); + else { + setRuleColor(c); + setTextColor(c); + } + } + break; + } + + if (kwmatch(s, "hsb") || kwmatch(s, "hsv")) { + float hsb[3]; + if (readColorValues(s, 3, hsb)) { + CMColor cm; + cm.hsv.hue = (UInt16)(hsb[0] * 65535); + cm.hsv.saturation = (UInt16)(hsb[1] * 65535); + cm.hsv.value = (UInt16)(hsb[2] * 65535); + CMConvertHSVToRGB(&cm, &cm, 1); + float rgba[4]; + rgba[0] = cm.rgb.red / 65535.0; + rgba[1] = cm.rgb.green / 65535.0; + rgba[2] = cm.rgb.blue / 65535.0; + rgba[3] = readAlphaIfPresent(s); + CGColorRef c = CGColorCreate(gRGBColorSpace, rgba); + if (background) + setBackground(c); + else { + setRuleColor(c); + setTextColor(c); + } + } + break; + } + + if (kwmatch(s, "hls")) { + float hls[3]; + if (readColorValues(s, 3, hls)) { + CMColor cm; + cm.hls.hue = (UInt16)(hls[0] * 65535); + cm.hls.lightness = (UInt16)(hls[1] * 65535); + cm.hls.saturation = (UInt16)(hls[2] * 65535); + CMConvertHLSToRGB(&cm, &cm, 1); + float rgba[4]; + rgba[0] = cm.rgb.red / 65535.0; + rgba[1] = cm.rgb.green / 65535.0; + rgba[2] = cm.rgb.blue / 65535.0; + rgba[3] = readAlphaIfPresent(s); + CGColorRef c = CGColorCreate(gRGBColorSpace, rgba); + if (background) + setBackground(c); + else { + setRuleColor(c); + setTextColor(c); + } + } + break; + } + + if (kwmatch(s, "gray")) { + float gray[2]; + if (readColorValues(s, 1, gray)) { + gray[1] = readAlphaIfPresent(s); + CGColorRef c = CGColorCreate(gGrayColorSpace, gray); + if (background) + setBackground(c); + else { + setRuleColor(c); + setTextColor(c); + } + } + break; + } + + const namedColor* nc = colorsByName + sizeof(colorsByName) / sizeof(namedColor); + while (nc-- > colorsByName) { + if (kwmatch(s, nc->name)) { + float cmyka[5]; + cmyka[0] = nc->cmyk[0]; + cmyka[1] = nc->cmyk[1]; + cmyka[2] = nc->cmyk[2]; + cmyka[3] = nc->cmyk[3]; + cmyka[4] = readAlphaIfPresent(s); + CGColorRef c = CGColorCreate(gCMYKColorSpace, cmyka); + if (background) + setBackground(c); + else { + setRuleColor(c); + setTextColor(c); + } + break; + } + } + break; + } +} + +static double_t +readDimen(const char* arg) // currently reads unsigned dimens only; no negative paper sizes! +{ + double_t rval = 0.0; + while ((*arg >= '0') && (*arg <= '9')) { + rval *= 10.0; + rval += *arg - '0'; + ++arg; + } + if (*arg == '.') { + ++arg; + double_t frac = 10.0; + while ((*arg >= '0') && (*arg <= '9')) { + rval += (*arg - '0') / frac; + frac *= 10.0; + ++arg; + } + } + const dimenRec* dim = &sDimenRatios[0]; + while (dim->name != 0) { + if (strcasecmp(arg, dim->name) == 0) { + rval *= dim->factor; + break; + } + ++dim; + } + return rval; +} + +bool +getPaperSize(const char* arg, double_t& paperWd, double_t& paperHt) +{ + paperHt = paperWd = 0.0; + + char* s1 = strdup(arg); + char* s2 = strchr(s1, ':'); + if (s2 != NULL) + *s2++ = 0; + + const paperSizeRec* ps = &gPaperSizes[0]; + while (ps->name != 0) { + if (strcasecmp(s1, ps->name) == 0) { + paperWd = ps->width; + paperHt = ps->height; + break; + } + ++ps; + } + if (ps->name == 0) { + char* s3 = strchr(s1, ','); + if (s3 != NULL) { + *s3++ = 0; + paperWd = readDimen(s1); + paperHt = readDimen(s3); + } + } + if (s2 != NULL && strcasecmp(s2, "landscape") == 0) { + double_t t = paperHt; + paperHt = paperWd; + paperWd = t; + } + + free(s1); + + return (paperHt > 0.0) && (paperWd > 0.0); +} + +static bool +prefixMatch(const char* str, const char* prefix, const char*& remainder) +{ + int len = strlen(prefix); + if (strncmp(str, prefix, len) == 0) { + remainder = str + len; + return true; + } + return false; +} + +inline bool +strMatch(const char* s, const char* t) +{ + return (strcmp(s, t) == 0); +} + +static void +shadowWarning() +{ + static bool alreadyWarned = false; + if (alreadyWarned) + return; + fprintf(stderr, "\n" + "## xdv2pdf: CoreGraphics shadow effects not supported on this system\n" + "## (at least Mac OS X 10.3 is required)\n"); + alreadyWarned = true; +} + +void +doSpecial(const char* special) +{ + int u = strlen(special); + const char* specialArg; + + if (prefixMatch(special, "pdf:", specialArg)) + doPDFspecial(specialArg); + + else if (prefixMatch(special, "color ", specialArg)) + doColorSpecial(specialArg, false); + + else if (prefixMatch(special, "background ", specialArg)) + doColorSpecial(specialArg, true); + + else if (prefixMatch(special, "x:fontmapfile", specialArg)) + doPdfMapFile(specialArg); + else if (prefixMatch(special, "x:fontmapline", specialArg)) + doPdfMapLine(specialArg, 0); + + else if (strMatch(special, "x:textcolorpush")) + pushTextColor(); + else if (strMatch(special, "x:textcolorpop")) + popTextColor(); + else if (strMatch(special, "x:rulecolorpush")) + pushRuleColor(); + else if (strMatch(special, "x:rulecolorpop")) + popRuleColor(); + + else if (prefixMatch(special, "x:rulecolor", specialArg)) { + // set rule color + if (*specialArg != '=' || u < 18) + // not long enough for a proper color spec, so set it to black + resetRuleColor(); + else { + ++specialArg; + CGColorRef color; + if (u < 20) + color = readColorValue(specialArg); + else + color = readColorValueWithAlpha(specialArg); + setRuleColor(color); + } + } + + else if (prefixMatch(special, "x:textcolor", specialArg)) { + // set text color (overriding color of the font style) + if (*specialArg != '=' || u < 18) + resetTextColor(); + else { + ++specialArg; + CGColorRef color; + if (u < 20) + color = readColorValue(specialArg); + else + color = readColorValueWithAlpha(specialArg); + setTextColor(color); + } + } + + else if (strMatch(special, "x:gsave")) { + ensurePageStarted(); + CGContextSaveGState(gCtx); + } + else if (strMatch(special, "x:grestore")) { + ensurePageStarted(); + CGContextRestoreGState(gCtx); + setColor(gCurrentColor, true); + cur_cgFont = kUndefinedFont; + } + else if (prefixMatch(special, "x:scale", specialArg)) { + ensurePageStarted(); + while (*specialArg && (*specialArg <= ' ')) + ++specialArg; + float xscale = atof(specialArg); + while (*specialArg && (((*specialArg >= '0') && (*specialArg <= '9')) || *specialArg == '.' || *specialArg == '-')) + ++specialArg; + while (*specialArg && (*specialArg <= ' ')) + ++specialArg; + float yscale = atof(specialArg); + if ((xscale != 0.0) && (yscale != 0.0)) { + CGContextTranslateCTM(gCtx, kDvi2Scr * dvi.h, kDvi2Scr * (gPageHt - dvi.v)); + CGContextScaleCTM(gCtx, xscale, yscale); + CGContextTranslateCTM(gCtx, -kDvi2Scr * dvi.h, -kDvi2Scr * (gPageHt - dvi.v)); + } + } + else if (prefixMatch(special, "x:rotate", specialArg)) { + ensurePageStarted(); + while (*specialArg && (*specialArg <= ' ')) + ++specialArg; + float rotation = atof(specialArg); + CGContextTranslateCTM(gCtx, kDvi2Scr * dvi.h, kDvi2Scr * (gPageHt - dvi.v)); + CGContextRotateCTM(gCtx, rotation * M_PI / 180.0); + CGContextTranslateCTM(gCtx, -kDvi2Scr * dvi.h, -kDvi2Scr * (gPageHt - dvi.v)); + } + else if (prefixMatch(special, "x:backgroundcolor", specialArg)) { + ensurePageStarted(); + if ((*specialArg != '=') || (u < 24)) { + // ignore incorrect special + } + else { + ++specialArg; + CGColorRef bg; + if (u < 26) + bg = readColorValue(specialArg); + else + bg = readColorValueWithAlpha(specialArg); + setBackground(bg); + } + } + else if (prefixMatch(special, "x:shadow", specialArg)) { + // syntax: \special{x:shadow(x,y),b} + do { + CGSize offset; + float blur; + + if (*specialArg++ != '(') break; + offset.width = readFloat(specialArg); + + if (*specialArg++ != ',') break; + offset.height = readFloat(specialArg); + + if (*specialArg++ != ')') break; + if (*specialArg++ != ',') break; + blur = readFloat(specialArg); + + // NB: API only available on 10.3 and later + if (&CGContextSetShadow != NULL) + CGContextSetShadow(gCtx, offset, blur); + else + shadowWarning(); + } while (false); + } + else if (prefixMatch(special, "x:colorshadow", specialArg)) { + // syntax: \special{x:colorshadow(x,y),b,c} + do { + CGSize offset; + float blur; + CGColorRef color; + + if (*specialArg++ != '(') break; + offset.width = readFloat(specialArg); + + if (*specialArg++ != ',') break; + offset.height = readFloat(specialArg); + + if (*specialArg++ != ')') break; + if (*specialArg++ != ',') break; + blur = readFloat(specialArg); + + if (*specialArg++ != ',') break; + if (special + u < specialArg + 6) break; + if (special + u < specialArg + 8) + color = readColorValue(specialArg); + else + color = readColorValueWithAlpha(specialArg); + + // NB: APIs only available on 10.3 and later + if (&CGContextSetShadowWithColor != NULL) { + CGContextSetShadowWithColor(gCtx, offset, blur, color); + } + else + shadowWarning(); + CGColorRelease(color); + } while (false); + } + else if (prefixMatch(special, "x:papersize", specialArg) || prefixMatch(special, "papersize", specialArg)) { + // syntax: \special{x:papersize=a4:landscape} etc + while (*specialArg && (*specialArg <= ' ')) + ++specialArg; + if (*specialArg == '=') { + ++specialArg; + while (*specialArg && (*specialArg <= ' ')) + ++specialArg; + } + double_t paperWd, paperHt; + if (getPaperSize(specialArg, paperWd, paperHt)) { + gMediaBox = CGRectMake(0, 0, paperWd, paperHt); + if (gPageStarted) { + fprintf(stderr, "\n### warning on page ["); + int i, j; + for (j = 9; j > 1; --j) + if (gCounts[j] != 0) + break; + for (i = 0; i < j; ++i) + fprintf(stderr, "%d.", gCounts[i]); + fprintf(stderr, "%d", gCounts[j]); + fprintf(stderr, "]: paper size \"%s\" will take effect from NEXT page ", specialArg); + } + } + } +} \ No newline at end of file diff --git a/Build/source/texk/xdv2pdf/xdv_kpse_formats.h b/Build/source/texk/xdv2pdf/xdv_kpse_formats.h new file mode 100644 index 00000000000..6fc8ae851d5 --- /dev/null +++ b/Build/source/texk/xdv2pdf/xdv_kpse_formats.h @@ -0,0 +1,16 @@ +/****************************************************************************\ + Part of the XeTeX typesetting system + copyright (c) 1994-2005 by SIL International + written by Jonathan Kew + + This software is distributed under the terms of the Common Public License, + version 1.0. + For details, see or the file + cpl1.0.txt included with the software. +\****************************************************************************/ + +#define xdv_kpse_otf_format 0 +#define xdv_kpse_pfb_format 1 +#define xdv_kpse_tfm_format 2 +#define xdv_kpse_font_map_format 3 +#define xdv_kpse_enc_format 4 -- cgit v1.2.3