From c43e4677848a4965d825835e0c39377983f4124f Mon Sep 17 00:00:00 2001 From: Marcian Lytwyn Date: Tue, 14 Jul 2015 22:36:43 +0000 Subject: [PATCH] Merge GNUstep back with main trunk revision 38789 git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/branches/gnustep_testplant_branch@38797 72102866-910b-0410-8b05-ffd578937521 --- GNUmakefile | 1 + GNUmakefile.postamble | 14 +- Headers/cairo/CairoFaceInfo.h | 33 +- Headers/cairo/CairoFontEnumerator.h | 39 +- Headers/cairo/CairoFontInfo.h | 12 +- Headers/fontconfig/FCFaceInfo.h | 72 +++ Headers/fontconfig/FCFontEnumerator.h | 70 ++ Headers/fontconfig/FCFontInfo.h | 50 ++ Headers/opal/OpalContext.h | 6 - Headers/opal/OpalFontEnumerator.h | 11 +- Headers/opal/OpalFontInfo.h | 22 +- Headers/opal/OpalGState.h | 62 +- Headers/opal/OpalSurface.h | 17 +- Headers/x11/XGGeneric.h | 2 +- Headers/x11/XGOpenGL.h | 2 +- Source/art/blit.m | 2 +- Source/art/image.m | 6 +- Source/cairo/CairoContext.m | 64 +- Source/cairo/CairoFaceInfo.m | 95 +-- Source/cairo/CairoFontEnumerator.m | 840 +----------------------- Source/cairo/CairoFontInfo.m | 95 +-- Source/cairo/CairoGState.m | 39 +- Source/cairo/GNUmakefile | 4 + Source/cairo/Win32CairoSurface.m | 4 +- Source/fontconfig/FCFaceInfo.m | 141 ++++ Source/fontconfig/FCFontEnumerator.m | 884 ++++++++++++++++++++++++++ Source/fontconfig/FCFontInfo.m | 174 +++++ Source/gsc/GSGState.m | 33 +- Source/x11/XGDragView.m | 18 +- Source/x11/XGGLContext.m | 29 +- Source/x11/XGGLFormat.m | 44 +- Source/x11/XGServerWindow.m | 81 ++- Source/x11/XIMInputServer.m | 62 +- Source/xlib/GSXftFontInfo.m | 12 - Source/xlib/XGBitmap.m | 2 - Source/xlib/XGFontManager.m | 5 + configure | 415 ++++++------ configure.ac | 65 +- gnustep-back.spec.in | 3 + 39 files changed, 2030 insertions(+), 1500 deletions(-) create mode 100644 Headers/fontconfig/FCFaceInfo.h create mode 100644 Headers/fontconfig/FCFontEnumerator.h create mode 100644 Headers/fontconfig/FCFontInfo.h create mode 100644 Source/fontconfig/FCFaceInfo.m create mode 100644 Source/fontconfig/FCFontEnumerator.m create mode 100644 Source/fontconfig/FCFontInfo.m diff --git a/GNUmakefile b/GNUmakefile index b34f75b..03ad17f 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -56,5 +56,6 @@ endif -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/aggregate.make +include $(GNUSTEP_MAKEFILES)/Master/deb.make -include GNUmakefile.postamble diff --git a/GNUmakefile.postamble b/GNUmakefile.postamble index 228dab4..b34b3d3 100644 --- a/GNUmakefile.postamble +++ b/GNUmakefile.postamble @@ -62,10 +62,18 @@ after-distclean:: rm -f config.status config.log config.cache TAGS config.h config.make back.make back.make: back.make.in Version configure - ./configure + if [ -x config.status ]; then \ + ./config.status --recheck && ./config.status; \ + else \ + ./configure; \ + fi -config.mak: config.mak.in configure - ./configure +config.make: config.make.in configure + if [ -x config.status ]; then \ + ./config.status --recheck && ./config.status; \ + else \ + ./configure; \ + fi # Things to do before checking # before-check:: diff --git a/Headers/cairo/CairoFaceInfo.h b/Headers/cairo/CairoFaceInfo.h index 4894c28..9fa12fc 100644 --- a/Headers/cairo/CairoFaceInfo.h +++ b/Headers/cairo/CairoFaceInfo.h @@ -31,44 +31,17 @@ #ifndef CAIROFACEINFO_H #define CAIROFACEINFO_H -#include -#include -#include FT_FREETYPE_H +#include "fontconfig/FCFaceInfo.h" #define id cairo_id #include #undef id -@interface CairoFaceInfo : NSObject +@interface CairoFaceInfo : FCFaceInfo { - int _weight; - unsigned int _traits; - cairo_font_face_t *_fontFace; - FcPattern *_pattern; - - NSString *_familyName; - NSCharacterSet *_characterSet; - BOOL _hasNoCharacterSet; } -- (id) initWithfamilyName: (NSString *)familyName - weight: (int)weight - traits: (unsigned int)traits - pattern: (FcPattern *)pattern; - -- (unsigned int) cacheSize; - -- (int) weight; -- (void) setWeight: (int)weight; -- (unsigned int) traits; -- (void) setTraits: (unsigned int)traits; - -- (NSString *) familyName; -- (void) setFamilyName: (NSString *)name; - -- (cairo_font_face_t *)fontFace; - -- (NSCharacterSet*)characterSet; +- (void *)fontFace; @end #endif diff --git a/Headers/cairo/CairoFontEnumerator.h b/Headers/cairo/CairoFontEnumerator.h index c75b258..ea1fa1c 100644 --- a/Headers/cairo/CairoFontEnumerator.h +++ b/Headers/cairo/CairoFontEnumerator.h @@ -28,41 +28,16 @@ #ifndef CairoFontEnumerator_h #define CairoFontEnumerator_h -#include +#include "fontconfig/FCFontEnumerator.h" #include -#define id fontconfig_id -#include -#undef id -#include "cairo/CairoFaceInfo.h" -@interface CairoFontEnumerator : GSFontEnumerator +@class CairoFaceInfo; + +@interface CairoFontEnumerator : FCFontEnumerator +{ +} ++ (Class) faceInfoClass; + (CairoFaceInfo *) fontWithName: (NSString *)name; @end -@interface FontconfigPatternGenerator : NSObject -{ - NSDictionary *_attributes; - FcPattern *_pat; -} -- (FcPattern *)createPatternWithAttributes: (NSDictionary *)attributes; -@end - -@interface FontconfigPatternParser : NSObject -{ - NSMutableDictionary *_attributes; - FcPattern *_pat; -} -- (NSDictionary*)attributesFromPattern: (FcPattern *)pat; -@end - -@interface FontconfigCharacterSet : NSCharacterSet -{ - FcCharSet *_charset; -} - -- (id)initWithFontconfigCharSet: (FcCharSet*)charset; -- (FcCharSet*)fontconfigCharSet; - -@end - #endif diff --git a/Headers/cairo/CairoFontInfo.h b/Headers/cairo/CairoFontInfo.h index 9f84240..990ed82 100644 --- a/Headers/cairo/CairoFontInfo.h +++ b/Headers/cairo/CairoFontInfo.h @@ -28,24 +28,16 @@ #ifndef CairoFontInfo_h #define CairoFontInfo_h -#include +#include "fontconfig/FCFontInfo.h" #include "cairo/CairoFaceInfo.h" #include -@interface CairoFontInfo : GSFontInfo +@interface CairoFontInfo : FCFontInfo { @public cairo_scaled_font_t *_scaled; - CairoFaceInfo *_faceInfo; - BOOL _screenFont; - CGFloat lineHeight; - - unsigned int _cacheSize; - unsigned int *_cachedGlyphs; - NSSize *_cachedSizes; } -- (void) setCacheSize:(unsigned int)size; - (void) drawGlyphs: (const NSGlyph*)glyphs length: (int)length on: (cairo_t*)ct; diff --git a/Headers/fontconfig/FCFaceInfo.h b/Headers/fontconfig/FCFaceInfo.h new file mode 100644 index 0000000..d6ce142 --- /dev/null +++ b/Headers/fontconfig/FCFaceInfo.h @@ -0,0 +1,72 @@ +/* + FCFaceInfo.h + + Copyright (C) 2003 Free Software Foundation, Inc. + + August 31, 2003 + Written by Banlu Kemiyatorn + Base on code by Alexander Malmberg + Rewrite: Fred Kiefer + Date: Jan 2006 + + This file is part of GNUstep. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; see the file COPYING.LIB. + If not, see or write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef FCFACEINFO_H +#define FCFACEINFO_H + +#include +#include +#include FT_FREETYPE_H +#include + +@interface FCFaceInfo : NSObject +{ + int _weight; + unsigned int _traits; + + FcPattern *_pattern; + + NSString *_familyName; + NSCharacterSet *_characterSet; + BOOL _hasNoCharacterSet; +} + +- (id) initWithfamilyName: (NSString *)familyName + weight: (int)weight + traits: (unsigned int)traits + pattern: (FcPattern *)pattern; + +- (unsigned int) cacheSize; + +- (int) weight; +- (void) setWeight: (int)weight; +- (unsigned int) traits; +- (void) setTraits: (unsigned int)traits; + +- (NSString *) familyName; +- (void) setFamilyName: (NSString *)name; + +- (void *) fontFace; +- (FcPattern *) matchedPattern; + +- (NSCharacterSet*)characterSet; + +@end +#endif diff --git a/Headers/fontconfig/FCFontEnumerator.h b/Headers/fontconfig/FCFontEnumerator.h new file mode 100644 index 0000000..8dcb703 --- /dev/null +++ b/Headers/fontconfig/FCFontEnumerator.h @@ -0,0 +1,70 @@ +/* + FCFontEnumerator.h + + Copyright (C) 2003 Free Software Foundation, Inc. + August 31, 2003 + Written by Banlu Kemiyatorn + + This file is part of GNUstep. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; see the file COPYING.LIB. + If not, see or write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#ifndef FCFontEnumerator_h +#define FCFontEnumerator_h + +#include +#define id fontconfig_id +#include +#undef id +#include "fontconfig/FCFaceInfo.h" + +@interface FCFontEnumerator : GSFontEnumerator +{ +} ++ (Class) faceInfoClass; ++ (FCFaceInfo *) fontWithName: (NSString *)name; +@end + +@interface FontconfigPatternGenerator : NSObject +{ + NSDictionary *_attributes; + FcPattern *_pat; +} +- (FcPattern *)createPatternWithAttributes: (NSDictionary *)attributes; +@end + +@interface FontconfigPatternParser : NSObject +{ + NSMutableDictionary *_attributes; + FcPattern *_pat; +} +- (NSDictionary*)attributesFromPattern: (FcPattern *)pat; +@end + +@interface FontconfigCharacterSet : NSCharacterSet +{ + FcCharSet *_charset; +} + +- (id)initWithFontconfigCharSet: (FcCharSet*)charset; +- (FcCharSet*)fontconfigCharSet; + +@end + +#endif diff --git a/Headers/fontconfig/FCFontInfo.h b/Headers/fontconfig/FCFontInfo.h new file mode 100644 index 0000000..401de34 --- /dev/null +++ b/Headers/fontconfig/FCFontInfo.h @@ -0,0 +1,50 @@ +/* + FCFontInfo.h + + Copyright (C) 2003 Free Software Foundation, Inc. + + August 31, 2003 + Written by Banlu Kemiyatorn + + This file is part of GNUstep. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; see the file COPYING.LIB. + If not, see or write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef FCFontInfo_h +#define FCFontInfo_h + +#include +#include "fontconfig/FCFaceInfo.h" + +@interface FCFontInfo : GSFontInfo +{ +@public + FCFaceInfo *_faceInfo; + BOOL _screenFont; + CGFloat lineHeight; + + unsigned int _cacheSize; + unsigned int *_cachedGlyphs; + NSSize *_cachedSizes; +} + +- (void) setCacheSize:(unsigned int)size; +- (BOOL) setupAttributes; +@end + +#endif diff --git a/Headers/opal/OpalContext.h b/Headers/opal/OpalContext.h index afaf673..dde0665 100644 --- a/Headers/opal/OpalContext.h +++ b/Headers/opal/OpalContext.h @@ -33,12 +33,6 @@ @interface OpalContext : GSContext { } -+ (void) initializeBackend; -+ (Class) GStateClass; -- (void) GSSetDevice: (void *)device - : (int)x - : (int)y; - @end #endif diff --git a/Headers/opal/OpalFontEnumerator.h b/Headers/opal/OpalFontEnumerator.h index 1c1a709..7a02067 100644 --- a/Headers/opal/OpalFontEnumerator.h +++ b/Headers/opal/OpalFontEnumerator.h @@ -28,14 +28,15 @@ #ifndef OpalFontEnumerator_h_defined #define OpalFontEnumerator_h_defined -#import +#import "fontconfig/FCFontEnumerator.h" -@interface OpalFontEnumerator : GSFontEnumerator +@class OpalFaceInfo; + +@interface OpalFontEnumerator : FCFontEnumerator { } - -- (void) enumerateFontsAndFamilies; - ++ (Class) faceInfoClass; ++ (OpalFaceInfo *) fontWithName: (NSString *)name; @end #endif diff --git a/Headers/opal/OpalFontInfo.h b/Headers/opal/OpalFontInfo.h index e0788ef..3cd941e 100644 --- a/Headers/opal/OpalFontInfo.h +++ b/Headers/opal/OpalFontInfo.h @@ -28,16 +28,28 @@ #ifndef OpalFontInfo_h_defined #define OpalFontInfo_h_defined -#import - -@interface OpalFontInfo : GSFontInfo +#include "fontconfig/FCFontInfo.h" +#include "opal/OpalFaceInfo.h" +#if 0 +#include +#endif +@interface OpalFontInfo : FCFontInfo { +@public +#if 0 + cairo_scaled_font_t *_scaled; +#endif } - +/* - (id) initWithFontName: (NSString *)name matrix: (const CGFloat *)fmatrix screenFont: (BOOL)p_screenFont; - +*/ +#if 0 +- (void) drawGlyphs: (const NSGlyph*)glyphs + length: (int)length + on: (cairo_t*)ct; +#endif @end #endif diff --git a/Headers/opal/OpalGState.h b/Headers/opal/OpalGState.h index 9864c16..a56a866 100644 --- a/Headers/opal/OpalGState.h +++ b/Headers/opal/OpalGState.h @@ -25,6 +25,7 @@ Boston, MA 02110-1301, USA. */ +#import #import "gsc/GSGState.h" @class OpalSurface; @@ -32,35 +33,50 @@ @interface OpalGState : GSGState { OpalSurface * _opalSurface; -} -- (void) DPSinitclip; + /** When a surface's gstate is being switched away from, + we store the current gstate in _opGState. + + When a surface's gstate is being switched back to, + if _opGState is not nil, we apply the stored gstate. + + To facilitate OpalGState class instance copying, we + also store a copy of the gstate inside _opGState when + gstate's -copyWithZone: is being run. This is because + the same _opalSurface should be used in both new and + old OpalGState. + + The same is done in Cairo backend, with one key + difference: since all graphics state operations in + Cairo are done directly on cairo_t and are unrelated + to the surface, Opal mixes the concepts of a gstate + and a surface into a context. Hence, when gstate is + switched, it's OpalContext's duty to apply the stored + copy of a gstate from _opGState. No such trickery + is needed with Cairo, as Cairo backend can simply + have a different cairo_t with the same surface. + **/ + OPGStateRef _opGState; +} +@end + +@interface OpalGState (InitializationMethods) - (void) DPSinitgraphics; -- (void) DPSclip; -- (void) DPSfill; -- (void) DPSimage: (NSAffineTransform *)matrix - : (NSInteger)pixelsWide - : (NSInteger)pixelsHigh - : (NSInteger)bitsPerSample - : (NSInteger)samplesPerPixel - : (NSInteger)bitsPerPixel - : (NSInteger)bytesPerRow - : (BOOL)isPlanar - : (BOOL)hasAlpha - : (NSString *)colorSpaceName - : (const unsigned char *const[5])data; -- (void) compositeGState: (OpalGState *)source - fromRect: (NSRect)srcRect - toPoint: (NSPoint)destPoint - op: (NSCompositingOperation)op - fraction: (CGFloat)delta; -- (void) compositerect: (NSRect)aRect - op: (NSCompositingOperation)op; - (void) GSSetSurface: (OpalSurface *)opalSurface : (int)x : (int)y; +- (void) GSCurrentSurface: (OpalSurface **)surface + : (int *)x + : (int *)y; @end @interface OpalGState (Accessors) -- (CGContextRef) cgContext; +- (CGContextRef) CGContext; +- (OPGStateRef) OPGState; +- (void) setOPGState: (OPGStateRef) opGState; +@end + +@interface OpalGState (NonrequiredMethods) +- (void) DPSgsave; +- (void) DPSgrestore; @end diff --git a/Headers/opal/OpalSurface.h b/Headers/opal/OpalSurface.h index 54b83d0..1e6e104 100644 --- a/Headers/opal/OpalSurface.h +++ b/Headers/opal/OpalSurface.h @@ -36,13 +36,12 @@ } - (id) initWithDevice: (void *)device; -- (struct _gswindow_device_t *) device; -- (CGContextRef) cgContext; -- (void) createCGContexts; -@end - -@interface OpalSurface (DebugExtensions) - -- (void) dummyDraw; - +- (void *)device; +- (CGContextRef) CGContext; +- (NSSize) size; + +- (CGContextRef) backingCGContext; +- (CGContextRef) x11CGContext; +- (void) handleExposeRect: (NSRect)rect; +- (BOOL) isDrawingToScreen; @end diff --git a/Headers/x11/XGGeneric.h b/Headers/x11/XGGeneric.h index 17ecd81..21b668f 100644 --- a/Headers/x11/XGGeneric.h +++ b/Headers/x11/XGGeneric.h @@ -60,7 +60,7 @@ typedef struct { typedef struct { Atom net_wm_state_atom; - Atom new_wm_state_modal_atom; + Atom net_wm_state_modal_atom; Atom net_wm_state_sticky_atom; Atom net_wm_state_maximized_vert_atom; Atom net_wm_state_maximized_horz_atom; diff --git a/Headers/x11/XGOpenGL.h b/Headers/x11/XGOpenGL.h index f966088..3ec933e 100644 --- a/Headers/x11/XGOpenGL.h +++ b/Headers/x11/XGOpenGL.h @@ -57,7 +57,7 @@ @interface XGGLPixelFormat : NSOpenGLPixelFormat { Display * display; - long int glxminorversion; + int glxminorversion; GLXFBConfig *fbconfig; int pickedFBConfig; diff --git a/Source/art/blit.m b/Source/art/blit.m index d9b045a..3592d0d 100644 --- a/Source/art/blit.m +++ b/Source/art/blit.m @@ -318,7 +318,7 @@ static void MPRE(run_opaque) (render_run_t *ri, int num) COPY_ASSEMBLE_PIXEL(v, ri->r, ri->g, ri->b) v = v + (v << 16); - if (((int)dst&2) && num) + if (((NSUInteger)dst&2) && num) { *dst++ = v; num--; diff --git a/Source/art/image.m b/Source/art/image.m index d6a5b9c..e041138 100644 --- a/Source/art/image.m +++ b/Source/art/image.m @@ -606,9 +606,9 @@ seem to cause edges to be off by a pixel - (void)DPSimage: (NSAffineTransform *) matrix - : (int) pixelsWide : (int) pixelsHigh - : (int) bitsPerSample : (int) samplesPerPixel - : (int) bitsPerPixel : (int) bytesPerRow : (BOOL) isPlanar + : (NSInteger) pixelsWide : (NSInteger) pixelsHigh + : (NSInteger) bitsPerSample : (NSInteger) samplesPerPixel + : (NSInteger) bitsPerPixel : (NSInteger) bytesPerRow : (BOOL) isPlanar : (BOOL) hasAlpha : (NSString *) colorSpaceName : (const unsigned char *const [5]) data { diff --git a/Source/cairo/CairoContext.m b/Source/cairo/CairoContext.m index 134acbf..5ac138a 100644 --- a/Source/cairo/CairoContext.m +++ b/Source/cairo/CairoContext.m @@ -74,17 +74,6 @@ # error Invalid server for Cairo backend : non implemented #endif /* BUILD_SERVER */ -@interface NSBitmapImageRep (GSPrivate) -- (NSBitmapImageRep *) _convertToFormatBitsPerSample: (int)bps - samplesPerPixel: (int)spp - hasAlpha: (BOOL)alpha - isPlanar: (BOOL)isPlanar - colorSpaceName: (NSString*)colorSpaceName - bitmapFormat: (NSBitmapFormat)bitmapFormat - bytesPerRow: (int)rowBytes - bitsPerPixel: (int)pixelBits; -@end - @implementation CairoContext + (void) initializeBackend @@ -124,8 +113,8 @@ // further debugging cairo/MSwindows non-retained backing store type: // This is called from NSWindow/flushWindow for the non-retained backing // store case. This code originally seems to have been added due to the - // non-retained backing store type NOT showing up on XWindows/Cairo combination - // and added this XFlush call to handle this case. + // non-retained backing store type NOT showing up on XWindows/Cairo + // combination and added this XFlush call to handle this case. // For MSWindows a similar problem seems to occur. However, the only // equivalent to XFlush on MSWindows is GdiFlush, which doesn't cause @@ -137,9 +126,10 @@ #if BUILD_SERVER == SERVER_x11 XFlush([(XGServer *)server xDisplay]); #elif BUILD_SERVER == SERVER_win32 - Win32CairoSurface *surface; + CairoSurface *surface = nil; + [CGSTATE GSCurrentSurface: &surface : NULL : NULL]; - if (surface) + if ((surface != nil) && ([surface surface] != NULL)) { // Non-retained backing store types currently unsupported on MSWindows... // Currently handling such windows as buffered and invoking the handle @@ -225,50 +215,6 @@ } } -- (void) GSDrawImage: (NSRect)rect: (void *)imageref -{ - NSBitmapImageRep *bitmap; - const unsigned char *data[5]; - NSString *colorSpaceName; - - bitmap = (NSBitmapImageRep*)imageref; - colorSpaceName = [bitmap colorSpaceName]; - if ([bitmap isPlanar] || ([bitmap bitmapFormat] != 0) - || ([bitmap bitsPerSample] != 8) || - (![colorSpaceName isEqualToString: NSDeviceRGBColorSpace] && - ![colorSpaceName isEqualToString: NSCalibratedRGBColorSpace])) - { - int bitsPerSample = 8; - BOOL isPlanar = NO; - int samplesPerPixel = [bitmap hasAlpha] ? 4 : 3; - NSString *colorSpaceName = NSCalibratedRGBColorSpace; - NSBitmapImageRep *new; - - new = [bitmap _convertToFormatBitsPerSample: bitsPerSample - samplesPerPixel: samplesPerPixel - hasAlpha: [bitmap hasAlpha] - isPlanar: isPlanar - colorSpaceName: colorSpaceName - bitmapFormat: 0 - bytesPerRow: 0 - bitsPerPixel: 0]; - - if (new == nil) - { - NSLog(@"Could not convert bitmap data"); - return; - } - bitmap = new; - } - - [bitmap getBitmapDataPlanes: (unsigned char **)&data]; - [self NSDrawBitmap: rect : [bitmap pixelsWide] : [bitmap pixelsHigh] - : [bitmap bitsPerSample] : [bitmap samplesPerPixel] - : [bitmap bitsPerPixel] : [bitmap bytesPerRow] : [bitmap isPlanar] - : [bitmap hasAlpha] : [bitmap colorSpaceName] - : data]; - } - - (void) GSCurrentDevice: (void **)device : (int *)x : (int *)y { CairoSurface *surface; diff --git a/Source/cairo/CairoFaceInfo.m b/Source/cairo/CairoFaceInfo.m index 122d2ca..b384f3d 100644 --- a/Source/cairo/CairoFaceInfo.m +++ b/Source/cairo/CairoFaceInfo.m @@ -29,84 +29,31 @@ */ #include "cairo/CairoFaceInfo.h" -#include "cairo/CairoFontEnumerator.h" #include -#include @implementation CairoFaceInfo -- (id) initWithfamilyName: (NSString *)familyName - weight: (int)weight - traits: (unsigned int)traits - pattern: (FcPattern *)pattern -{ - _pattern = pattern; - FcPatternReference(_pattern); - - [self setFamilyName: familyName]; - [self setWeight: weight]; - [self setTraits: traits]; - - return self; -} - - (void) dealloc { if (_fontFace) { cairo_font_face_destroy(_fontFace); } - FcPatternDestroy(_pattern); - RELEASE(_familyName); - RELEASE(_characterSet); [super dealloc]; } -- (void) setFamilyName: (NSString *)name -{ - ASSIGN(_familyName, name); -} - -- (NSString *)familyName -{ - return _familyName; -} - -- (int) weight -{ - return _weight; -} - -- (void) setWeight: (int)weight -{ - _weight = weight; -} - -- (unsigned int) traits -{ - return _traits; -} - -- (void) setTraits: (unsigned int)traits -{ - _traits = traits; -} - -- (unsigned int) cacheSize -{ - return 257; -} - -- (cairo_font_face_t *)fontFace +- (void *)fontFace { if (!_fontFace) { - FcResult result; FcPattern *resolved; + FcBool scalable; - FcConfigSubstitute(NULL, _pattern, FcMatchPattern); - FcDefaultSubstitute(_pattern); - resolved = FcFontMatch(NULL, _pattern, &result); + resolved = [self matchedPattern]; + FcPatternGetBool(resolved, FC_SCALABLE, 0, &scalable); + if (scalable != FcTrue) { + NSLog(@"Selected non-scalable font."); + } _fontFace = cairo_ft_font_face_create_for_pattern(resolved); FcPatternDestroy(resolved); @@ -123,32 +70,4 @@ return _fontFace; } -- (NSCharacterSet*)characterSet -{ - if (_characterSet == nil && !_hasNoCharacterSet) - { - FcResult result; - FcPattern *resolved; - FcCharSet *charset; - - FcConfigSubstitute(NULL, _pattern, FcMatchPattern); - FcDefaultSubstitute(_pattern); - resolved = FcFontMatch(NULL, _pattern, &result); - - if (FcResultMatch == FcPatternGetCharSet(resolved, FC_CHARSET, 0, &charset)) - { - _characterSet = [[FontconfigCharacterSet alloc] initWithFontconfigCharSet: charset]; - } - - /* Only try to get the character set once because FcFontMatch is expensive */ - if (_characterSet == nil) - { - _hasNoCharacterSet = YES; - } - - FcPatternDestroy(resolved); - } - return _characterSet; -} - @end diff --git a/Source/cairo/CairoFontEnumerator.m b/Source/cairo/CairoFontEnumerator.m index eeeb160..19639d1 100644 --- a/Source/cairo/CairoFontEnumerator.m +++ b/Source/cairo/CairoFontEnumerator.m @@ -28,850 +28,20 @@ Boston, MA 02110-1301, USA. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gsc/GSGState.h" #include "cairo/CairoFontEnumerator.h" #include "cairo/CairoFontInfo.h" -// Old versions of fontconfig don't have FC_WEIGHT_ULTRABLACK defined. -// Use the maximal value instead. -#ifndef FC_WEIGHT_ULTRABLACK -#define FC_WEIGHT_ULTRABLACK FC_WEIGHT_BLACK -#endif - @implementation CairoFontEnumerator -NSMutableDictionary * __allFonts; ++ (Class) faceInfoClass +{ + return [CairoFaceInfo class]; + } + (CairoFaceInfo *) fontWithName: (NSString *) name { - CairoFaceInfo *face; - - face = [__allFonts objectForKey: name]; - if (!face) - { - NSDebugLLog(@"NSFont", @"Font not found %@", name); + return (CairoFaceInfo *) [super fontWithName: name]; } - return face; -} - -// Make a GNUstep style font descriptor from a FcPattern -static NSArray *faFromFc(FcPattern *pat) -{ - int weight, slant, spacing, nsweight; - unsigned int nstraits = 0; - char *family; - NSMutableString *name, *style; - - if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &weight) != FcResultMatch - || FcPatternGetInteger(pat, FC_SLANT, 0, &slant) != FcResultMatch - || FcPatternGetString(pat, FC_FAMILY, 0, (FcChar8 **)&family) - != FcResultMatch) - return nil; - - if (FcPatternGetInteger(pat, FC_SPACING, 0, &spacing) == FcResultMatch) - if (spacing==FC_MONO || spacing==FC_CHARCELL) - nstraits |= NSFixedPitchFontMask; - - name = [NSMutableString stringWithCapacity: 100]; - style = [NSMutableString stringWithCapacity: 100]; - [name appendString: [NSString stringWithUTF8String: family]]; - - switch (weight) - { - case FC_WEIGHT_LIGHT: - [style appendString: @"Light"]; - nsweight = 3; - break; - case FC_WEIGHT_MEDIUM: - nsweight = 6; - break; - case FC_WEIGHT_DEMIBOLD: - [style appendString: @"Demibold"]; - nsweight = 7; - break; - case FC_WEIGHT_BOLD: - [style appendString: @"Bold"]; - nsweight = 9; - nstraits |= NSBoldFontMask; - break; - case FC_WEIGHT_BLACK: - [style appendString: @"Black"]; - nsweight = 12; - nstraits |= NSBoldFontMask; - break; - default: - nsweight = 6; - } - - switch (slant) - { - case FC_SLANT_ROMAN: - break; - case FC_SLANT_ITALIC: - [style appendString: @"Italic"]; - nstraits |= NSItalicFontMask; - break; - case FC_SLANT_OBLIQUE: - [style appendString: @"Oblique"]; - nstraits |= NSItalicFontMask; - break; - } - - if ([style length] > 0) - { - [name appendString: @"-"]; - [name appendString: style]; - } - else - { - [style appendString: @"Roman"]; - } - - return [NSArray arrayWithObjects: name, - style, - [NSNumber numberWithInt: nsweight], - [NSNumber numberWithUnsignedInt: nstraits], - nil]; -} - -- (void) enumerateFontsAndFamilies -{ - int i; - NSMutableDictionary *fcxft_allFontFamilies = [NSMutableDictionary new]; - NSMutableDictionary *fcxft_allFonts = [NSMutableDictionary new]; - NSMutableArray *fcxft_allFontNames = [NSMutableArray new]; - - FcPattern *pat = FcPatternCreate(); - FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_SLANT, FC_WEIGHT, - FC_SPACING, NULL); - FcFontSet *fs = FcFontList(NULL, pat, os); - - FcPatternDestroy(pat); - FcObjectSetDestroy(os); - - for (i = 0; i < fs->nfont; i++) - { - char *family; - - if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **)&family) - == FcResultMatch) - { - NSArray *fontArray; - - if ((fontArray = faFromFc(fs->fonts[i]))) - { - NSString *familyString; - NSMutableArray *familyArray; - CairoFaceInfo *aFont; - NSString *name = [fontArray objectAtIndex: 0]; - - familyString = [NSString stringWithUTF8String: family]; - familyArray = [fcxft_allFontFamilies objectForKey: familyString]; - if (familyArray == nil) - { - NSDebugLLog(@"NSFont", @"Found font family %@", familyString); - familyArray = [[NSMutableArray alloc] init]; - [fcxft_allFontFamilies setObject: familyArray - forKey: familyString]; - RELEASE(familyArray); - } - NSDebugLLog(@"NSFont", @"fc enumerator: adding font: %@", name); - [familyArray addObject: fontArray]; - [fcxft_allFontNames addObject: name]; - aFont = [[CairoFaceInfo alloc] initWithfamilyName: familyString - weight: [[fontArray objectAtIndex: 2] intValue] - traits: [[fontArray objectAtIndex: 3] unsignedIntValue] - pattern: fs->fonts[i]]; - [fcxft_allFonts setObject: aFont forKey: name]; - RELEASE(aFont); - } - } - } - FcFontSetDestroy (fs); - - allFontNames = fcxft_allFontNames; - allFontFamilies = fcxft_allFontFamilies; - __allFonts = fcxft_allFonts; -} - -- (NSString *) defaultSystemFontName -{ - if ([allFontNames containsObject: @"Bitstream Vera Sans"]) - { - return @"Bitstream Vera Sans"; - } - if ([allFontNames containsObject: @"FreeSans"]) - { - return @"FreeSans"; - } - if ([allFontNames containsObject: @"DejaVu Sans"]) - { - return @"DejaVu Sans"; - } - if ([allFontNames containsObject: @"Tahoma"]) - { - return @"Tahoma"; - } - if ([allFontNames containsObject: @"Arial"]) - { - return @"Arial"; - } - return @"Helvetica"; -} - -- (NSString *) defaultBoldSystemFontName -{ - if ([allFontNames containsObject: @"Bitstream Vera Sans-Bold"]) - { - return @"Bitstream Vera Sans-Bold"; - } - if ([allFontNames containsObject: @"FreeSans-Bold"]) - { - return @"FreeSans-Bold"; - } - if ([allFontNames containsObject: @"DejaVu Sans-Bold"]) - { - return @"DejaVu Sans-Bold"; - } - if ([allFontNames containsObject: @"Tahoma-Bold"]) - { - return @"Tahoma-Bold"; - } - if ([allFontNames containsObject: @"Arial-Bold"]) - { - return @"Arial-Bold"; - } - return @"Helvetica-Bold"; -} - -- (NSString *) defaultFixedPitchFontName -{ - if ([allFontNames containsObject: @"Bitstream Vera Sans Mono"]) - { - return @"Bitstream Vera Sans Mono"; - } - if ([allFontNames containsObject: @"FreeMono"]) - { - return @"FreeMono"; - } - if ([allFontNames containsObject: @"DejaVu Sans Mono"]) - { - return @"DejaVu Sans Mono"; - } - if ([allFontNames containsObject: @"Courier New"]) - { - return @"Courier New"; - } - return @"Courier"; -} - -/** - * Overrides the implementation in GSFontInfo, and delegates the - * matching to Fontconfig. - */ -- (NSArray *) matchingFontDescriptorsFor: (NSDictionary *)attributes -{ - NSMutableArray *descriptors; - FcResult result; - FcPattern *matchedpat, *pat; - FontconfigPatternGenerator *generator; - - descriptors = [NSMutableArray array]; - - generator = [[FontconfigPatternGenerator alloc] init]; - pat = [generator createPatternWithAttributes: attributes]; - DESTROY(generator); - - FcConfigSubstitute(NULL, pat, FcMatchPattern); - FcDefaultSubstitute(pat); - result = FcResultMatch; - matchedpat = FcFontMatch(NULL, pat, &result); - if (result != FcResultMatch) - { - NSLog(@"Warning, FcFontMatch failed with code: %d", result); - } - else - { - FcFontSet *fontSet; - result = FcResultMatch; - fontSet = FcFontSort(NULL, matchedpat, FcFalse, NULL, &result); - if (result == FcResultMatch) - { - int i; - for (i=0; infont; i++) - { - FontconfigPatternParser *parser = [[FontconfigPatternParser alloc] init]; - // FIXME: do we need to match this pattern? - FcPattern *matchingpat = fontSet->fonts[i]; - NSDictionary *attribs = [parser attributesFromPattern: matchingpat]; - [parser release]; - - [descriptors addObject: [NSFontDescriptor fontDescriptorWithFontAttributes: attribs]]; - } - } - else - { - NSLog(@"ERROR! FcFontSort failed"); - } - - FcFontSetDestroy(fontSet); - FcPatternDestroy(matchedpat); - } - - FcPatternDestroy(pat); - return descriptors; -} - -@end - - - -@implementation FontconfigPatternGenerator - -- (void)addName: (NSString*)name -{ - // FIXME: Fontconfig ignores PostScript names of fonts; we need - // https://bugs.freedesktop.org/show_bug.cgi?id=18095 fixed. - - // This is a heuristic to try to 'parse' a PostScript font name, - // however, since they are just unique identifiers for fonts and - // don't need to follow any naming convention, this may fail - - NSRange dash = [name rangeOfString: @"-"]; - if (dash.location == NSNotFound) - { - FcPatternAddString(_pat, FC_FAMILY, (const FcChar8 *)[name UTF8String]); - } - else - { - NSString *weightAndSlant = [name substringFromIndex: dash.location + 1]; - NSString *family = [name substringToIndex: dash.location]; - - FcPatternAddString(_pat, FC_FAMILY, (const FcChar8 *)[family UTF8String]); - - if (NSNotFound != [weightAndSlant rangeOfString: @"Light"].location) - { - FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_LIGHT); - } - else if (NSNotFound != [weightAndSlant rangeOfString: @"Medium"].location) - { - FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_MEDIUM); - } - else if (NSNotFound != [weightAndSlant rangeOfString: @"Demibold"].location) - { - FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_DEMIBOLD); - } - else if (NSNotFound != [weightAndSlant rangeOfString: @"Bold"].location) - { - FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_BOLD); - } - else if (NSNotFound != [weightAndSlant rangeOfString: @"Black"].location) - { - FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_BLACK); - } - - if (NSNotFound != [weightAndSlant rangeOfString: @"Italic"].location) - { - FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_ITALIC); - } - else if (NSNotFound != [weightAndSlant rangeOfString: @"Oblique"].location) - { - FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_OBLIQUE); - } - - if (NSNotFound != [weightAndSlant rangeOfString: @"Condensed"].location) - { - FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_CONDENSED); - } - else if (NSNotFound != [weightAndSlant rangeOfString: @"Expanded"].location) - { - FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_EXPANDED); - } - } -} - -- (void)addVisibleName: (NSString*)name -{ - FcPatternAddString(_pat, FC_FULLNAME, (const FcChar8 *)[name UTF8String]); -} - -- (void)addFamilyName: (NSString*)name -{ - FcPatternAddString(_pat, FC_FAMILY, (const FcChar8 *)[name UTF8String]); -} - -- (void)addStyleName: (NSString*)style -{ - FcPatternAddString(_pat, FC_STYLE, (const FcChar8 *)[style UTF8String]); -} - -- (void)addTraits: (NSDictionary*)traits -{ - if ([traits objectForKey: NSFontSymbolicTrait]) - { - NSFontSymbolicTraits symTraits = [[traits objectForKey: NSFontSymbolicTrait] intValue]; - - if (symTraits & NSFontItalicTrait) - { - // NOTE: May be overridden by NSFontSlantTrait - FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_ITALIC); - } - if (symTraits & NSFontBoldTrait) - { - // NOTE: May be overridden by NSFontWeightTrait - FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_BOLD); - } - if (symTraits & NSFontExpandedTrait) - { - // NOTE: May be overridden by NSFontWidthTrait - FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_EXPANDED); - } - if (symTraits & NSFontCondensedTrait) - { - // NOTE: May be overridden by NSFontWidthTrait - FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_CONDENSED); - } - if (symTraits & NSFontMonoSpaceTrait) - { - FcValue value; - // If you run "fc-match :spacing=100", you get "DejaVu Sans" even though you would - // expect to get "DejaVu Sans Mono". So, we also add "monospace" as a weak family - // name to fix the problem. - FcPatternAddInteger(_pat, FC_SPACING, FC_MONO); - - value.type = FcTypeString; - value.u.s = (FcChar8*)"monospace"; - FcPatternAddWeak(_pat, FC_FAMILY, value, FcTrue); - } - if (symTraits & NSFontVerticalTrait) - { - // FIXME: What is this supposed to mean? - } - if (symTraits & NSFontUIOptimizedTrait) - { - // NOTE: Fontconfig can't express this - } - - { - NSFontFamilyClass class = symTraits & NSFontFamilyClassMask; - char *addWeakFamilyName = NULL; - switch (class) - { - default: - case NSFontUnknownClass: - case NSFontOrnamentalsClass: - case NSFontScriptsClass: - case NSFontSymbolicClass: - // FIXME: Is there some way to convey these to Fontconfig? - break; - case NSFontOldStyleSerifsClass: - case NSFontTransitionalSerifsClass: - case NSFontModernSerifsClass: - case NSFontClarendonSerifsClass: - case NSFontSlabSerifsClass: - case NSFontFreeformSerifsClass: - addWeakFamilyName = "serif"; - break; - case NSFontSansSerifClass: - addWeakFamilyName = "sans"; - break; - } - if (addWeakFamilyName) - { - FcValue value; - value.type = FcTypeString; - value.u.s = (const FcChar8 *)addWeakFamilyName; - FcPatternAddWeak(_pat, FC_FAMILY, value, FcTrue); - } - } - } - - if ([traits objectForKey: NSFontWeightTrait]) - { - /** - * Scale: -1 is thinnest, 0 is normal, 1 is heaviest - */ - double weight = [[traits objectForKey: NSFontWeightTrait] doubleValue]; - int fcWeight; - - weight = MAX(-1, MIN(1, weight)); - if (weight <= 0) - { - fcWeight = FC_WEIGHT_THIN + ((weight + 1.0) * (FC_WEIGHT_NORMAL - FC_WEIGHT_THIN)); - } - else - { - fcWeight = FC_WEIGHT_NORMAL + (weight * (FC_WEIGHT_ULTRABLACK - FC_WEIGHT_NORMAL)); - } - FcPatternAddInteger(_pat, FC_WEIGHT, fcWeight); - } - - if ([traits objectForKey: NSFontWidthTrait]) - { - /** - * Scale: -1 is most condensed, 0 is normal, 1 is most spread apart - */ - double width = [[traits objectForKey: NSFontWidthTrait] doubleValue]; - int fcWidth; - - width = MAX(-1, MIN(1, width)); - if (width <= 0) - { - fcWidth = FC_WIDTH_ULTRACONDENSED + ((width + 1.0) * (FC_WIDTH_NORMAL - FC_WIDTH_ULTRACONDENSED)); - } - else - { - fcWidth = FC_WIDTH_NORMAL + (width * (FC_WIDTH_ULTRAEXPANDED - FC_WIDTH_NORMAL)); - } - FcPatternAddInteger(_pat, FC_WIDTH, fcWidth); - } - - if ([traits objectForKey: NSFontSlantTrait]) - { - /** - * Scale: -1 is 30 degree counterclockwise slant, 0 is no slant, 1 - * is 30 degree clockwise slant - */ - double slant = [[traits objectForKey: NSFontSlantTrait] doubleValue]; - - // NOTE: Fontconfig can't express this as a scale - if (slant > 0) - { - FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_ITALIC); - } - else - { - FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_ROMAN); - } - } -} - -- (void)addSize: (NSNumber*)size -{ - FcPatternAddDouble(_pat, FC_SIZE, [size doubleValue]); -} - -- (void)addCharacterSet: (NSCharacterSet*)characterSet -{ - if ([characterSet isKindOfClass: [FontconfigCharacterSet class]]) - { - // Fast case - FcPatternAddCharSet(_pat, FC_CHARSET, [(FontconfigCharacterSet*)characterSet fontconfigCharSet]); - } - else - { - // Slow case - FcCharSet *fcSet = FcCharSetCreate(); - uint32_t plane; - for (plane=0; plane<=16; plane++) - { - if ([characterSet hasMemberInPlane: plane]) - { - uint32_t codePoint; - for (codePoint = plane<<16; codePoint <= 0xffff + (plane<<16); codePoint++) - { - if ([characterSet longCharacterIsMember: codePoint]) - { - FcCharSetAddChar(fcSet, codePoint); - } - } - } - } - - FcPatternAddCharSet(_pat, FC_CHARSET, fcSet); - FcCharSetDestroy(fcSet); - } -} - -#define ADD_TO_PATTERN(key, handlerMethod, valueClass) \ - do { \ - id value = [_attributes objectForKey: key]; \ - if (value) \ - { \ - if ([value isKindOfClass: valueClass]) \ - { \ - [self handlerMethod value]; \ - } \ - else \ - { \ - NSLog(@"NSFontDescriptor: Ignoring invalid value %@ for attribute %@", value, key); \ - } \ - } \ - } while (0); - -- (void)addAttributes -{ - ADD_TO_PATTERN(NSFontNameAttribute, addName:, [NSString class]); - ADD_TO_PATTERN(NSFontVisibleNameAttribute, addVisibleName:, [NSString class]); - ADD_TO_PATTERN(NSFontFamilyAttribute, addFamilyName:, [NSString class]); - ADD_TO_PATTERN(NSFontFaceAttribute, addStyleName:, [NSString class]); - ADD_TO_PATTERN(NSFontTraitsAttribute, addTraits:, [NSDictionary class]); - ADD_TO_PATTERN(NSFontSizeAttribute, addSize:, [NSNumber class]); - ADD_TO_PATTERN(NSFontCharacterSetAttribute, addCharacterSet:, [NSCharacterSet class]); -} - -- (FcPattern *)createPatternWithAttributes: (NSDictionary *)attributes -{ - _attributes = attributes; - _pat = FcPatternCreate(); - [self addAttributes]; - - return _pat; -} - -@end - - -@implementation FontconfigPatternParser - -- (NSString*)readFontconfigString: (const char *)key fromPattern: (FcPattern*)pat -{ - unsigned char *string = NULL; - if (FcResultMatch == FcPatternGetString(pat, key, 0, &string)) - { - if (string) - { - return [NSString stringWithUTF8String: (const char *)string]; - } - } - return nil; -} - -- (NSNumber*)readFontconfigInteger: (const char *)key fromPattern: (FcPattern*)pat -{ - int value; - if (FcResultMatch == FcPatternGetInteger(pat, key, 0, &value)) - { - return [NSNumber numberWithInt: value]; - } - return nil; -} - -- (NSNumber*)readFontconfigDouble: (const char *)key fromPattern: (FcPattern*)pat -{ - double value; - if (FcResultMatch == FcPatternGetDouble(pat, key, 0, &value)) - { - return [NSNumber numberWithDouble: value]; - } - return nil; -} - - - -- (NSString*)readNameFromPattern: (FcPattern*)pat -{ - // FIXME: Hack which generates a PostScript-style name from the - // family name and style - - NSString *family = [self readFontconfigString: FC_FAMILY fromPattern: pat]; - NSString *style = [self readFontconfigString: FC_STYLE fromPattern: pat]; - if (style) - { - return [NSString stringWithFormat: @"%@-%@", family, style]; - } - else - { - return family; - } -} -- (NSString*)readVisibleNameFromPattern: (FcPattern*)pat -{ - // FIXME: try to get the localized one - return [self readFontconfigString: FC_FULLNAME fromPattern: pat]; -} -- (NSString*)readFamilyNameFromPattern: (FcPattern*)pat -{ - // FIXME: try to get the localized one - return [self readFontconfigString: FC_FAMILY fromPattern: pat]; -} -- (NSString*)readStyleNameFromPattern: (FcPattern*)pat -{ - // FIXME: try to get the localized one - return [self readFontconfigString: FC_STYLE fromPattern: pat]; -} -- (NSDictionary*)readTraitsFromPattern: (FcPattern*)pat -{ - NSMutableDictionary *traits = [NSMutableDictionary dictionary]; - - NSFontSymbolicTraits symTraits = 0; - - int value; - if (FcResultMatch == FcPatternGetInteger(pat, FC_SLANT, 0, &value)) - { - if (value == FC_SLANT_ITALIC) - { - symTraits |= NSFontItalicTrait; - } - } - if (FcResultMatch == FcPatternGetInteger(pat, FC_WEIGHT, 0, &value)) - { - double weight; - - if (value >= FC_WEIGHT_BOLD) - { - symTraits |= NSFontBoldTrait; - } - - if (value <= FC_WEIGHT_NORMAL) - { - weight = ((value - FC_WEIGHT_THIN) / (double)(FC_WEIGHT_NORMAL - FC_WEIGHT_THIN)) - 1.0; - } - else - { - weight = (value - FC_WEIGHT_NORMAL) / (double)(FC_WEIGHT_ULTRABLACK - FC_WEIGHT_NORMAL); - } - - [traits setObject: [NSNumber numberWithDouble: weight] - forKey: NSFontWeightTrait]; - } - if (FcResultMatch == FcPatternGetInteger(pat, FC_WIDTH, 0, &value)) - { - double width; - - if (value >= FC_WIDTH_EXPANDED) - { - symTraits |= NSFontExpandedTrait; - } - if (value <= FC_WIDTH_CONDENSED) - { - symTraits |= NSFontCondensedTrait; - } - - if (value <= FC_WIDTH_NORMAL) - { - width = ((value - FC_WIDTH_ULTRACONDENSED) / (double)(FC_WIDTH_NORMAL - FC_WIDTH_ULTRACONDENSED)) - 1.0; - } - else - { - width = (value - FC_WIDTH_NORMAL) / (double)(FC_WIDTH_ULTRAEXPANDED - FC_WIDTH_NORMAL); - } - - [traits setObject: [NSNumber numberWithDouble: width] - forKey: NSFontWidthTrait]; - } - if (FcResultMatch == FcPatternGetInteger(pat, FC_SPACING, 0, &value)) - { - if (value == FC_MONO || value == FC_CHARCELL) - { - symTraits |= NSFontMonoSpaceTrait; - } - } - - if (symTraits != 0) - { - [traits setObject: [NSNumber numberWithUnsignedInt: symTraits] - forKey: NSFontSymbolicTrait]; - } - - return traits; -} - -- (NSNumber*)readSizeFromPattern: (FcPattern*)pat -{ - return [self readFontconfigDouble: FC_SIZE fromPattern: pat]; -} - -- (NSCharacterSet*)readCharacterSetFromPattern: (FcPattern*)pat -{ - FcCharSet *value; - if (FcResultMatch == FcPatternGetCharSet(pat, FC_CHARSET, 0, &value)) - { - return [[[FontconfigCharacterSet alloc] initWithFontconfigCharSet: value] autorelease]; - } - return nil; -} - -#define READ_FROM_PATTERN(key, readMethod) \ - do { \ - id result = [self readMethod _pat]; \ - if (result != nil) \ - { \ - [_attributes setObject: result \ - forKey: key]; \ - } \ - } while (0); - -- (void)parseAttributes -{ - READ_FROM_PATTERN(NSFontNameAttribute, readNameFromPattern:); - READ_FROM_PATTERN(NSFontVisibleNameAttribute, readVisibleNameFromPattern:); - READ_FROM_PATTERN(NSFontFamilyAttribute, readFamilyNameFromPattern:); - READ_FROM_PATTERN(NSFontFaceAttribute, readStyleNameFromPattern:); - READ_FROM_PATTERN(NSFontTraitsAttribute, readTraitsFromPattern:); - READ_FROM_PATTERN(NSFontSizeAttribute, readSizeFromPattern:); - READ_FROM_PATTERN(NSFontCharacterSetAttribute, readCharacterSetFromPattern:); -} - -- (NSDictionary*)attributesFromPattern: (FcPattern *)pat -{ - _attributes = [NSMutableDictionary dictionary]; - _pat = pat; - [self parseAttributes]; - return _attributes; -} - -@end - - - -@implementation FontconfigCharacterSet - -- (id)initWithFontconfigCharSet: (FcCharSet*)charset -{ - if ((self = [super init])) - { - _charset = FcCharSetCopy(charset); - } - return self; -} - -- (id)mutableCopyWithZone: (NSZone*)aZone -{ - return [[NSMutableCharacterSet characterSetWithBitmapRepresentation: - [self bitmapRepresentation]] retain]; -} - -- (void)dealloc -{ - FcCharSetDestroy(_charset); - [super dealloc]; -} - -- (FcCharSet*)fontconfigCharSet -{ - return _charset; -} - -- (BOOL)characterIsMember: (unichar)c -{ - return FcCharSetHasChar(_charset, c); -} - -- (BOOL)longCharacterIsMember: (UTF32Char)c -{ - return FcCharSetHasChar(_charset, c); -} - -// FIXME: Implement for better performance -//- (NSData *)bitmapRepresentation -//{ -//} @end diff --git a/Source/cairo/CairoFontInfo.m b/Source/cairo/CairoFontInfo.m index 329aca3..4ca98c5 100644 --- a/Source/cairo/CairoFontInfo.m +++ b/Source/cairo/CairoFontInfo.m @@ -37,29 +37,6 @@ @implementation CairoFontInfo -- (void) setCacheSize: (unsigned int)size -{ - _cacheSize = size; - if (_cachedSizes) - { - free(_cachedSizes); - } - if (_cachedGlyphs) - { - free(_cachedGlyphs); - } - _cachedSizes = malloc(sizeof(NSSize) * size); - if (_cachedSizes) - { - memset(_cachedSizes, 0, sizeof(NSSize) * size); - } - _cachedGlyphs = malloc(sizeof(unsigned int) * size); - if (_cachedGlyphs) - { - memset(_cachedGlyphs, 0, sizeof(unsigned int) * size); - } -} - - (BOOL) setupAttributes { cairo_font_extents_t font_extents; @@ -68,28 +45,11 @@ cairo_matrix_t ctm; cairo_font_options_t *options; - ASSIGN(_faceInfo, [CairoFontEnumerator fontWithName: fontName]); - if (!_faceInfo) + if (![super setupAttributes]) { return NO; } - // check for font specific cache size from face info - [self setCacheSize: [_faceInfo cacheSize]]; - - /* setting GSFontInfo: - * weight, traits, familyName, - * mostCompatibleStringEncoding, encodingScheme, coveredCharacterSet - */ - - weight = [_faceInfo weight]; - traits = [_faceInfo traits]; - familyName = [[_faceInfo familyName] copy]; - mostCompatibleStringEncoding = NSUTF8StringEncoding; - encodingScheme = @"iso10646-1"; - coveredCharacterSet = [[_faceInfo characterSet] retain]; - - /* setting GSFontInfo: * xHeight, pix_width, pix_height */ @@ -190,23 +150,13 @@ - (void) dealloc { - RELEASE(_faceInfo); if (_scaled) { cairo_scaled_font_destroy(_scaled); } - if (_cachedSizes) - free(_cachedSizes); - if (_cachedGlyphs) - free(_cachedGlyphs); [super dealloc]; } -- (CGFloat) defaultLineHeightForFont -{ - return lineHeight; -} - - (BOOL) glyphIsEncoded: (NSGlyph)glyph { /* FIXME: There is no proper way to determine with the toy font API, @@ -309,15 +259,6 @@ BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph, return 0.0; } -- (NSGlyph) glyphWithName: (NSString *) glyphName -{ - /* subclass should override */ - /* terrible! FIXME */ - NSGlyph g = [glyphName cString][0]; - - return g; -} - - (void) appendBezierPathWithGlyphs: (NSGlyph *)glyphs count: (int)length toBezierPath: (NSBezierPath *)path @@ -407,7 +348,8 @@ BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph, // Set font options from the scaled font // FIXME: Instead of setting the matrix, setting the face, and setting - // the options, we should be using cairo_set_scaled_font + // the options, we should be using cairo_set_scaled_font(). + // But we have to deal with the flipped matrix here. { cairo_font_options_t *options = cairo_font_options_create(); cairo_scaled_font_get_font_options(_scaled, options); @@ -472,7 +414,6 @@ BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph, length: (int)length on: (cairo_t*)ct { - cairo_matrix_t font_matrix; unichar ustr[length+1]; char str[3*length+1]; unsigned char *b; @@ -494,36 +435,10 @@ BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph, return; } - cairo_matrix_init(&font_matrix, matrix[0], matrix[1], -matrix[2], - matrix[3], matrix[4], matrix[5]); - cairo_set_font_matrix(ct, &font_matrix); + cairo_set_scaled_font(ct, _scaled); if (cairo_status(ct) != CAIRO_STATUS_SUCCESS) { - NSLog(@"Error while setting font matrix: %s", - cairo_status_to_string(cairo_status(ct))); - return; - } - - cairo_set_font_face(ct, [_faceInfo fontFace]); - if (cairo_status(ct) != CAIRO_STATUS_SUCCESS) - { - NSLog(@"Error while setting font face: %s", - cairo_status_to_string(cairo_status(ct))); - return; - } - - // Set font options from the scaled font - // FIXME: Instead of setting the matrix, setting the face, and setting - // the options, we should be using cairo_set_scaled_font - { - cairo_font_options_t *options = cairo_font_options_create(); - cairo_scaled_font_get_font_options(_scaled, options); - cairo_set_font_options(ct, options); - cairo_font_options_destroy(options); - } - if (cairo_status(ct) != CAIRO_STATUS_SUCCESS) - { - NSLog(@"Error while setting font options: %s", + NSLog(@"Error while setting scaled font: %s", cairo_status_to_string(cairo_status(ct))); return; } diff --git a/Source/cairo/CairoGState.m b/Source/cairo/CairoGState.m index 3447877..ddecd3e 100644 --- a/Source/cairo/CairoGState.m +++ b/Source/cairo/CairoGState.m @@ -101,6 +101,16 @@ static inline CGFloat floatToUserSpace(NSAffineTransform *ctm, double d) return (CGFloat)d; } +static inline cairo_filter_t cairoFilterFromNSImageInterpolation(NSImageInterpolation interpolation) +{ + switch (interpolation) + { + case NSImageInterpolationNone: return CAIRO_FILTER_NEAREST; + case NSImageInterpolationLow: return CAIRO_FILTER_FAST; + case NSImageInterpolationHigh: return CAIRO_FILTER_BEST; + default: return CAIRO_FILTER_GOOD; + } +} @implementation CairoGState @@ -401,18 +411,11 @@ static inline CGFloat floatToUserSpace(NSAffineTransform *ctm, double d) - (void) GSSetFont: (GSFontInfo *)fontref { - cairo_matrix_t font_matrix; - const CGFloat *matrix; - [super GSSetFont: fontref]; if (_ct) { - matrix = [font matrix]; - cairo_set_font_face(_ct, [((CairoFontInfo *)font)->_faceInfo fontFace]); - cairo_matrix_init(&font_matrix, matrix[0], matrix[1], matrix[2], - matrix[3], matrix[4], matrix[5]); - cairo_set_font_matrix(_ct, &font_matrix); + cairo_set_scaled_font(_ct, ((CairoFontInfo *)font)->_scaled); } } @@ -856,8 +859,8 @@ static inline CGFloat floatToUserSpace(NSAffineTransform *ctm, double d) r = [ctm rectInMatrixSpace: r]; x = NSWidth(r); y = NSHeight(r); - ix = abs(floor(x)); - iy = abs(floor(y)); + ix = fabs(floor(x)); + iy = fabs(floor(y)); ssize = NSMakeSize(ix, iy); dict = [NSMutableDictionary dictionary]; @@ -1170,7 +1173,8 @@ _set_op(cairo_t *ct, NSCompositingOperation op) cairo_matrix_init_scale(&source_matrix, 1, -1); cairo_matrix_translate(&source_matrix, 0, -pixelsHigh); cairo_pattern_set_matrix(cpattern, &source_matrix); - cairo_pattern_set_filter(cpattern, CAIRO_FILTER_BILINEAR); + cairo_pattern_set_filter(cpattern, + cairoFilterFromNSImageInterpolation([drawcontext imageInterpolation])); if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 6, 0)) { cairo_pattern_set_extend(cpattern, CAIRO_EXTEND_PAD); @@ -1261,7 +1265,7 @@ _set_op(cairo_t *ct, NSCompositingOperation op) cairo_pattern_t *cpattern; cairo_matrix_t source_matrix; - NSDebugMLLog(@"CairoGState", @"%self: %@\n", self); + NSDebugMLLog(@"CairoGState", @"self: %@\n", self); if (!_ct || !source->_ct) { @@ -1316,9 +1320,10 @@ _set_op(cairo_t *ct, NSCompositingOperation op) ssize = [source->_surface size]; } - if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 8, 0)) + if ((cairo_version() >= CAIRO_VERSION_ENCODE(1, 8, 0)) && + (cairo_version() <= CAIRO_VERSION_ENCODE(1, 13, 0))) { - // For cairo > 1.8 we seem to need this adjustment + // For cairo > 1.8 and < 1.13 we seem to need this adjustment srcRectInBase.origin.y -= 2 * (source->offset.y - ssize.height); } @@ -1345,7 +1350,8 @@ _set_op(cairo_t *ct, NSCompositingOperation op) //cairo_matrix_translate(&source_matrix, 0, -[_surface size].height); cairo_matrix_translate(&source_matrix, minx - x + dx, miny - y + dy - ssize.height); cairo_pattern_set_matrix(cpattern, &source_matrix); - cairo_pattern_set_filter(cpattern, CAIRO_FILTER_BILINEAR); + cairo_pattern_set_filter(cpattern, + cairoFilterFromNSImageInterpolation([drawcontext imageInterpolation])); cairo_set_source(_ct, cpattern); cairo_pattern_destroy(cpattern); cairo_rectangle(_ct, x, y, width, height); @@ -1437,7 +1443,8 @@ doesn't support to use the receiver cairo target as the source. */ cairo_matrix_init_scale(&source_matrix, 1, -1); cairo_matrix_translate(&source_matrix, 0, -[source->_surface size].height); cairo_pattern_set_matrix(cpattern, &source_matrix); - cairo_pattern_set_filter(cpattern, CAIRO_FILTER_BILINEAR); + cairo_pattern_set_filter(cpattern, + cairoFilterFromNSImageInterpolation([drawcontext imageInterpolation])); if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 6, 0)) { cairo_pattern_set_extend(cpattern, CAIRO_EXTEND_PAD); diff --git a/Source/cairo/GNUmakefile b/Source/cairo/GNUmakefile index c3538f2..27e6cb5 100644 --- a/Source/cairo/GNUmakefile +++ b/Source/cairo/GNUmakefile @@ -37,6 +37,10 @@ cairo_OBJC_FILES = CairoSurface.m \ CairoFaceInfo.m \ CairoPSSurface.m \ CairoPDFSurface.m \ + ../fontconfig/FCFaceInfo.m \ + ../fontconfig/FCFontEnumerator.m \ + ../fontconfig/FCFontInfo.m \ + ifeq ($(BUILD_SERVER),x11) ifeq ($(WITH_GLITZ),yes) diff --git a/Source/cairo/Win32CairoSurface.m b/Source/cairo/Win32CairoSurface.m index 5bee536..b8e0e78 100644 --- a/Source/cairo/Win32CairoSurface.m +++ b/Source/cairo/Win32CairoSurface.m @@ -331,7 +331,6 @@ // Cleanup the cairo surfaces... cairo_surface_destroy(src); cairo_surface_destroy(dst); - [self deleteScreenHdc:hdc]; // Convert BGRA to RGBA // Original code located in XGCairSurface.m @@ -369,6 +368,9 @@ result = [[[NSImage alloc] initWithSize: NSMakeSize(width, height)] autorelease]; [result addRepresentation: bmp]; } + + // Cleanup the screen HDC... + [self deleteScreenHdc:hdc]; } // Return whatever we got... diff --git a/Source/fontconfig/FCFaceInfo.m b/Source/fontconfig/FCFaceInfo.m new file mode 100644 index 0000000..545a9e1 --- /dev/null +++ b/Source/fontconfig/FCFaceInfo.m @@ -0,0 +1,141 @@ +/* + FCFaceInfo.m + + Copyright (C) 2003 Free Software Foundation, Inc. + + August 31, 2003 + Written by Banlu Kemiyatorn + Base on original code of Alex Malmberg + Rewrite: Fred Kiefer + Date: Jan 2006 + + This file is part of GNUstep. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; see the file COPYING.LIB. + If not, see or write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "fontconfig/FCFaceInfo.h" +#include "fontconfig/FCFontEnumerator.h" +#include + +@implementation FCFaceInfo + +- (id) initWithfamilyName: (NSString *)familyName + weight: (int)weight + traits: (unsigned int)traits + pattern: (FcPattern *)pattern +{ + _pattern = pattern; + FcPatternReference(_pattern); + + [self setFamilyName: familyName]; + [self setWeight: weight]; + [self setTraits: traits]; + + return self; +} + +- (void) dealloc +{ + FcPatternDestroy(_pattern); + RELEASE(_familyName); + RELEASE(_characterSet); + [super dealloc]; +} + +- (void) setFamilyName: (NSString *)name +{ + ASSIGN(_familyName, name); +} + +- (NSString *)familyName +{ + return _familyName; +} + +- (int) weight +{ + return _weight; +} + +- (void) setWeight: (int)weight +{ + _weight = weight; +} + +- (unsigned int) traits +{ + return _traits; +} + +- (void) setTraits: (unsigned int)traits +{ + _traits = traits; +} + +- (unsigned int) cacheSize +{ + return 257; +} + +- (void *) fontFace +{ + [self subclassResponsibility: _cmd]; + return NULL; +} + +- (FcPattern *) matchedPattern +{ + FcResult result; + FcPattern *resolved; + + FcConfigSubstitute(NULL, _pattern, FcMatchPattern); + FcDefaultSubstitute(_pattern); + resolved = FcFontMatch(NULL, _pattern, &result); + + return resolved; +} + +- (NSCharacterSet*)characterSet +{ + if (_characterSet == nil && !_hasNoCharacterSet) + { + FcResult result; + FcPattern *resolved; + FcCharSet *charset; + + FcConfigSubstitute(NULL, _pattern, FcMatchPattern); + FcDefaultSubstitute(_pattern); + resolved = FcFontMatch(NULL, _pattern, &result); + + if (FcResultMatch == FcPatternGetCharSet(resolved, FC_CHARSET, 0, &charset)) + { + _characterSet = [[FontconfigCharacterSet alloc] initWithFontconfigCharSet: charset]; + } + + /* Only try to get the character set once because FcFontMatch is expensive */ + if (_characterSet == nil) + { + _hasNoCharacterSet = YES; + } + + FcPatternDestroy(resolved); + } + return _characterSet; +} + +@end diff --git a/Source/fontconfig/FCFontEnumerator.m b/Source/fontconfig/FCFontEnumerator.m new file mode 100644 index 0000000..fcdd706 --- /dev/null +++ b/Source/fontconfig/FCFontEnumerator.m @@ -0,0 +1,884 @@ +/* + FCFontEnumerator.m + + Copyright (C) 2003 Free Software Foundation, Inc. + + August 31, 2003 + Written by Banlu Kemiyatorn + Base on original code of Alex Malmberg + Rewrite: Fred Kiefer + Date: Jan 2006 + + This file is part of GNUstep. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; see the file COPYING.LIB. + If not, see or write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gsc/GSGState.h" +#include "fontconfig/FCFontEnumerator.h" +#include "fontconfig/FCFontInfo.h" + +// Old versions of fontconfig don't have FC_WEIGHT_ULTRABLACK defined. +// Use the maximal value instead. +#ifndef FC_WEIGHT_ULTRABLACK +#define FC_WEIGHT_ULTRABLACK FC_WEIGHT_BLACK +#endif + +@implementation FCFontEnumerator + +NSMutableDictionary * __allFonts; + ++ (FCFaceInfo *) fontWithName: (NSString *) name +{ + FCFaceInfo *face; + + face = [__allFonts objectForKey: name]; + if (!face) + { + NSDebugLLog(@"NSFont", @"Font not found %@", name); + } + return face; +} + ++ (Class) faceInfoClass +{ + [self subclassResponsibility: _cmd]; + return nil; +} + +// Make a GNUstep style font descriptor from a FcPattern +static NSArray *faFromFc(FcPattern *pat) +{ + int weight, slant, spacing, nsweight; + unsigned int nstraits = 0; + char *family; + NSMutableString *name, *style; + + if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &weight) != FcResultMatch + || FcPatternGetInteger(pat, FC_SLANT, 0, &slant) != FcResultMatch + || FcPatternGetString(pat, FC_FAMILY, 0, (FcChar8 **)&family) + != FcResultMatch) + return nil; + + if (FcPatternGetInteger(pat, FC_SPACING, 0, &spacing) == FcResultMatch) + if (spacing==FC_MONO || spacing==FC_CHARCELL) + nstraits |= NSFixedPitchFontMask; + + name = [NSMutableString stringWithCapacity: 100]; + style = [NSMutableString stringWithCapacity: 100]; + [name appendString: [NSString stringWithUTF8String: family]]; + + switch (weight) + { + case FC_WEIGHT_LIGHT: + [style appendString: @"Light"]; + nsweight = 3; + break; + case FC_WEIGHT_MEDIUM: + nsweight = 6; + break; + case FC_WEIGHT_DEMIBOLD: + [style appendString: @"Demibold"]; + nsweight = 7; + break; + case FC_WEIGHT_BOLD: + [style appendString: @"Bold"]; + nsweight = 9; + nstraits |= NSBoldFontMask; + break; + case FC_WEIGHT_BLACK: + [style appendString: @"Black"]; + nsweight = 12; + nstraits |= NSBoldFontMask; + break; + default: + nsweight = 6; + } + + switch (slant) + { + case FC_SLANT_ROMAN: + break; + case FC_SLANT_ITALIC: + [style appendString: @"Italic"]; + nstraits |= NSItalicFontMask; + break; + case FC_SLANT_OBLIQUE: + [style appendString: @"Oblique"]; + nstraits |= NSItalicFontMask; + break; + } + + if ([style length] > 0) + { + [name appendString: @"-"]; + [name appendString: style]; + } + else + { + [style appendString: @"Roman"]; + } + + return [NSArray arrayWithObjects: name, + style, + [NSNumber numberWithInt: nsweight], + [NSNumber numberWithUnsignedInt: nstraits], + nil]; +} + +- (void) enumerateFontsAndFamilies +{ + int i; + NSMutableDictionary *fcxft_allFontFamilies = [NSMutableDictionary new]; + NSMutableDictionary *fcxft_allFonts = [NSMutableDictionary new]; + NSMutableArray *fcxft_allFontNames = [NSMutableArray new]; + Class faceInfoClass = [[self class] faceInfoClass]; + + FcPattern *pat = FcPatternCreate(); + FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_SLANT, FC_WEIGHT, + FC_SPACING, NULL); + FcFontSet *fs = FcFontList(NULL, pat, os); + + FcPatternDestroy(pat); + FcObjectSetDestroy(os); + + for (i = 0; i < fs->nfont; i++) + { + char *family; + + if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **)&family) + == FcResultMatch) + { + NSArray *fontArray; + + if ((fontArray = faFromFc(fs->fonts[i]))) + { + NSString *familyString; + NSMutableArray *familyArray; + FCFaceInfo *aFont; + NSString *name = [fontArray objectAtIndex: 0]; + + familyString = [NSString stringWithUTF8String: family]; + familyArray = [fcxft_allFontFamilies objectForKey: familyString]; + if (familyArray == nil) + { + NSDebugLLog(@"NSFont", @"Found font family %@", familyString); + familyArray = [[NSMutableArray alloc] init]; + [fcxft_allFontFamilies setObject: familyArray + forKey: familyString]; + RELEASE(familyArray); + } + NSDebugLLog(@"NSFont", @"fc enumerator: adding font: %@", name); + [familyArray addObject: fontArray]; + [fcxft_allFontNames addObject: name]; + aFont = [[faceInfoClass alloc] initWithfamilyName: familyString + weight: [[fontArray objectAtIndex: 2] intValue] + traits: [[fontArray objectAtIndex: 3] unsignedIntValue] + pattern: fs->fonts[i]]; + [fcxft_allFonts setObject: aFont forKey: name]; + RELEASE(aFont); + } + } + } + FcFontSetDestroy (fs); + + allFontNames = fcxft_allFontNames; + allFontFamilies = fcxft_allFontFamilies; + __allFonts = fcxft_allFonts; +} + +- (NSString *) defaultSystemFontName +{ + if ([allFontNames containsObject: @"Bitstream Vera Sans"]) + { + return @"Bitstream Vera Sans"; + } + if ([allFontNames containsObject: @"FreeSans"]) + { + return @"FreeSans"; + } + if ([allFontNames containsObject: @"DejaVu Sans"]) + { + return @"DejaVu Sans"; + } + if ([allFontNames containsObject: @"Tahoma"]) + { + return @"Tahoma"; + } + if ([allFontNames containsObject: @"Arial"]) + { + return @"Arial"; + } + return @"Helvetica"; +} + +- (NSString *) defaultBoldSystemFontName +{ + if ([allFontNames containsObject: @"Bitstream Vera Sans-Bold"]) + { + return @"Bitstream Vera Sans-Bold"; + } + if ([allFontNames containsObject: @"FreeSans-Bold"]) + { + return @"FreeSans-Bold"; + } + if ([allFontNames containsObject: @"DejaVu Sans-Bold"]) + { + return @"DejaVu Sans-Bold"; + } + if ([allFontNames containsObject: @"Tahoma-Bold"]) + { + return @"Tahoma-Bold"; + } + if ([allFontNames containsObject: @"Arial-Bold"]) + { + return @"Arial-Bold"; + } + return @"Helvetica-Bold"; +} + +- (NSString *) defaultFixedPitchFontName +{ + if ([allFontNames containsObject: @"Bitstream Vera Sans Mono"]) + { + return @"Bitstream Vera Sans Mono"; + } + if ([allFontNames containsObject: @"FreeMono"]) + { + return @"FreeMono"; + } + if ([allFontNames containsObject: @"DejaVu Sans Mono"]) + { + return @"DejaVu Sans Mono"; + } + if ([allFontNames containsObject: @"Courier New"]) + { + return @"Courier New"; + } + return @"Courier"; +} + +/** + * Overrides the implementation in GSFontInfo, and delegates the + * matching to Fontconfig. + */ +- (NSArray *) matchingFontDescriptorsFor: (NSDictionary *)attributes +{ + NSMutableArray *descriptors; + FcResult result; + FcPattern *matchedpat, *pat; + FontconfigPatternGenerator *generator; + + descriptors = [NSMutableArray array]; + + generator = [[FontconfigPatternGenerator alloc] init]; + pat = [generator createPatternWithAttributes: attributes]; + DESTROY(generator); + + FcConfigSubstitute(NULL, pat, FcMatchPattern); + FcDefaultSubstitute(pat); + result = FcResultMatch; + matchedpat = FcFontMatch(NULL, pat, &result); + if (result != FcResultMatch) + { + NSLog(@"Warning, FcFontMatch failed with code: %d", result); + } + else + { + FcFontSet *fontSet; + result = FcResultMatch; + fontSet = FcFontSort(NULL, matchedpat, FcFalse, NULL, &result); + if (result == FcResultMatch) + { + int i; + for (i=0; infont; i++) + { + FontconfigPatternParser *parser = [[FontconfigPatternParser alloc] init]; + // FIXME: do we need to match this pattern? + FcPattern *matchingpat = fontSet->fonts[i]; + NSDictionary *attribs = [parser attributesFromPattern: matchingpat]; + [parser release]; + + [descriptors addObject: [NSFontDescriptor fontDescriptorWithFontAttributes: attribs]]; + } + } + else + { + NSLog(@"ERROR! FcFontSort failed"); + } + + FcFontSetDestroy(fontSet); + FcPatternDestroy(matchedpat); + } + + FcPatternDestroy(pat); + return descriptors; +} + +@end + + + +@implementation FontconfigPatternGenerator + +- (void)addName: (NSString*)name +{ + // FIXME: Fontconfig ignores PostScript names of fonts; we need + // https://bugs.freedesktop.org/show_bug.cgi?id=18095 fixed. + + // This is a heuristic to try to 'parse' a PostScript font name, + // however, since they are just unique identifiers for fonts and + // don't need to follow any naming convention, this may fail + + NSRange dash = [name rangeOfString: @"-"]; + if (dash.location == NSNotFound) + { + FcPatternAddString(_pat, FC_FAMILY, (const FcChar8 *)[name UTF8String]); + } + else + { + NSString *weightAndSlant = [name substringFromIndex: dash.location + 1]; + NSString *family = [name substringToIndex: dash.location]; + + FcPatternAddString(_pat, FC_FAMILY, (const FcChar8 *)[family UTF8String]); + + if (NSNotFound != [weightAndSlant rangeOfString: @"Light"].location) + { + FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_LIGHT); + } + else if (NSNotFound != [weightAndSlant rangeOfString: @"Medium"].location) + { + FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_MEDIUM); + } + else if (NSNotFound != [weightAndSlant rangeOfString: @"Demibold"].location) + { + FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_DEMIBOLD); + } + else if (NSNotFound != [weightAndSlant rangeOfString: @"Bold"].location) + { + FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_BOLD); + } + else if (NSNotFound != [weightAndSlant rangeOfString: @"Black"].location) + { + FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_BLACK); + } + + if (NSNotFound != [weightAndSlant rangeOfString: @"Italic"].location) + { + FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_ITALIC); + } + else if (NSNotFound != [weightAndSlant rangeOfString: @"Oblique"].location) + { + FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_OBLIQUE); + } + + if (NSNotFound != [weightAndSlant rangeOfString: @"Condensed"].location) + { + FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_CONDENSED); + } + else if (NSNotFound != [weightAndSlant rangeOfString: @"Expanded"].location) + { + FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_EXPANDED); + } + } +} + +- (void)addVisibleName: (NSString*)name +{ + FcPatternAddString(_pat, FC_FULLNAME, (const FcChar8 *)[name UTF8String]); +} + +- (void)addFamilyName: (NSString*)name +{ + FcPatternAddString(_pat, FC_FAMILY, (const FcChar8 *)[name UTF8String]); +} + +- (void)addStyleName: (NSString*)style +{ + FcPatternAddString(_pat, FC_STYLE, (const FcChar8 *)[style UTF8String]); +} + +- (void)addTraits: (NSDictionary*)traits +{ + if ([traits objectForKey: NSFontSymbolicTrait]) + { + NSFontSymbolicTraits symTraits = [[traits objectForKey: NSFontSymbolicTrait] intValue]; + + if (symTraits & NSFontItalicTrait) + { + // NOTE: May be overridden by NSFontSlantTrait + FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_ITALIC); + } + if (symTraits & NSFontBoldTrait) + { + // NOTE: May be overridden by NSFontWeightTrait + FcPatternAddInteger(_pat, FC_WEIGHT, FC_WEIGHT_BOLD); + } + if (symTraits & NSFontExpandedTrait) + { + // NOTE: May be overridden by NSFontWidthTrait + FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_EXPANDED); + } + if (symTraits & NSFontCondensedTrait) + { + // NOTE: May be overridden by NSFontWidthTrait + FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_CONDENSED); + } + if (symTraits & NSFontMonoSpaceTrait) + { + FcValue value; + // If you run "fc-match :spacing=100", you get "DejaVu Sans" even though you would + // expect to get "DejaVu Sans Mono". So, we also add "monospace" as a weak family + // name to fix the problem. + FcPatternAddInteger(_pat, FC_SPACING, FC_MONO); + + value.type = FcTypeString; + value.u.s = (FcChar8*)"monospace"; + FcPatternAddWeak(_pat, FC_FAMILY, value, FcTrue); + } + if (symTraits & NSFontVerticalTrait) + { + // FIXME: What is this supposed to mean? + } + if (symTraits & NSFontUIOptimizedTrait) + { + // NOTE: Fontconfig can't express this + } + + { + NSFontFamilyClass class = symTraits & NSFontFamilyClassMask; + char *addWeakFamilyName = NULL; + switch (class) + { + default: + case NSFontUnknownClass: + case NSFontOrnamentalsClass: + case NSFontScriptsClass: + case NSFontSymbolicClass: + // FIXME: Is there some way to convey these to Fontconfig? + break; + case NSFontOldStyleSerifsClass: + case NSFontTransitionalSerifsClass: + case NSFontModernSerifsClass: + case NSFontClarendonSerifsClass: + case NSFontSlabSerifsClass: + case NSFontFreeformSerifsClass: + addWeakFamilyName = "serif"; + break; + case NSFontSansSerifClass: + addWeakFamilyName = "sans"; + break; + } + if (addWeakFamilyName) + { + FcValue value; + value.type = FcTypeString; + value.u.s = (const FcChar8 *)addWeakFamilyName; + FcPatternAddWeak(_pat, FC_FAMILY, value, FcTrue); + } + } + } + + if ([traits objectForKey: NSFontWeightTrait]) + { + /** + * Scale: -1 is thinnest, 0 is normal, 1 is heaviest + */ + double weight = [[traits objectForKey: NSFontWeightTrait] doubleValue]; + int fcWeight; + + weight = MAX(-1, MIN(1, weight)); + if (weight <= 0) + { + fcWeight = FC_WEIGHT_THIN + ((weight + 1.0) * (FC_WEIGHT_NORMAL - FC_WEIGHT_THIN)); + } + else + { + fcWeight = FC_WEIGHT_NORMAL + (weight * (FC_WEIGHT_ULTRABLACK - FC_WEIGHT_NORMAL)); + } + FcPatternAddInteger(_pat, FC_WEIGHT, fcWeight); + } + + if ([traits objectForKey: NSFontWidthTrait]) + { + /** + * Scale: -1 is most condensed, 0 is normal, 1 is most spread apart + */ + double width = [[traits objectForKey: NSFontWidthTrait] doubleValue]; + int fcWidth; + + width = MAX(-1, MIN(1, width)); + if (width <= 0) + { + fcWidth = FC_WIDTH_ULTRACONDENSED + ((width + 1.0) * (FC_WIDTH_NORMAL - FC_WIDTH_ULTRACONDENSED)); + } + else + { + fcWidth = FC_WIDTH_NORMAL + (width * (FC_WIDTH_ULTRAEXPANDED - FC_WIDTH_NORMAL)); + } + FcPatternAddInteger(_pat, FC_WIDTH, fcWidth); + } + + if ([traits objectForKey: NSFontSlantTrait]) + { + /** + * Scale: -1 is 30 degree counterclockwise slant, 0 is no slant, 1 + * is 30 degree clockwise slant + */ + double slant = [[traits objectForKey: NSFontSlantTrait] doubleValue]; + + // NOTE: Fontconfig can't express this as a scale + if (slant > 0) + { + FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_ITALIC); + } + else + { + FcPatternAddInteger(_pat, FC_SLANT, FC_SLANT_ROMAN); + } + } +} + +- (void)addSize: (NSNumber*)size +{ + FcPatternAddDouble(_pat, FC_SIZE, [size doubleValue]); +} + +- (void)addCharacterSet: (NSCharacterSet*)characterSet +{ + if ([characterSet isKindOfClass: [FontconfigCharacterSet class]]) + { + // Fast case + FcPatternAddCharSet(_pat, FC_CHARSET, [(FontconfigCharacterSet*)characterSet fontconfigCharSet]); + } + else + { + // Slow case + FcCharSet *fcSet = FcCharSetCreate(); + uint32_t plane; + for (plane=0; plane<=16; plane++) + { + if ([characterSet hasMemberInPlane: plane]) + { + uint32_t codePoint; + for (codePoint = plane<<16; codePoint <= 0xffff + (plane<<16); codePoint++) + { + if ([characterSet longCharacterIsMember: codePoint]) + { + FcCharSetAddChar(fcSet, codePoint); + } + } + } + } + + FcPatternAddCharSet(_pat, FC_CHARSET, fcSet); + FcCharSetDestroy(fcSet); + } +} + +#define ADD_TO_PATTERN(key, handlerMethod, valueClass) \ + do { \ + id value = [_attributes objectForKey: key]; \ + if (value) \ + { \ + if ([value isKindOfClass: valueClass]) \ + { \ + [self handlerMethod value]; \ + } \ + else \ + { \ + NSLog(@"NSFontDescriptor: Ignoring invalid value %@ for attribute %@", value, key); \ + } \ + } \ + } while (0); + +- (void)addAttributes +{ + ADD_TO_PATTERN(NSFontNameAttribute, addName:, [NSString class]); + ADD_TO_PATTERN(NSFontVisibleNameAttribute, addVisibleName:, [NSString class]); + ADD_TO_PATTERN(NSFontFamilyAttribute, addFamilyName:, [NSString class]); + ADD_TO_PATTERN(NSFontFaceAttribute, addStyleName:, [NSString class]); + ADD_TO_PATTERN(NSFontTraitsAttribute, addTraits:, [NSDictionary class]); + ADD_TO_PATTERN(NSFontSizeAttribute, addSize:, [NSNumber class]); + ADD_TO_PATTERN(NSFontCharacterSetAttribute, addCharacterSet:, [NSCharacterSet class]); +} + +- (FcPattern *)createPatternWithAttributes: (NSDictionary *)attributes +{ + _attributes = attributes; + _pat = FcPatternCreate(); + [self addAttributes]; + + return _pat; +} + +@end + + +@implementation FontconfigPatternParser + +- (NSString*)readFontconfigString: (const char *)key fromPattern: (FcPattern*)pat +{ + unsigned char *string = NULL; + if (FcResultMatch == FcPatternGetString(pat, key, 0, &string)) + { + if (string) + { + return [NSString stringWithUTF8String: (const char *)string]; + } + } + return nil; +} + +- (NSNumber*)readFontconfigInteger: (const char *)key fromPattern: (FcPattern*)pat +{ + int value; + if (FcResultMatch == FcPatternGetInteger(pat, key, 0, &value)) + { + return [NSNumber numberWithInt: value]; + } + return nil; +} + +- (NSNumber*)readFontconfigDouble: (const char *)key fromPattern: (FcPattern*)pat +{ + double value; + if (FcResultMatch == FcPatternGetDouble(pat, key, 0, &value)) + { + return [NSNumber numberWithDouble: value]; + } + return nil; +} + + + +- (NSString*)readNameFromPattern: (FcPattern*)pat +{ + // FIXME: Hack which generates a PostScript-style name from the + // family name and style + + NSString *family = [self readFontconfigString: FC_FAMILY fromPattern: pat]; + NSString *style = [self readFontconfigString: FC_STYLE fromPattern: pat]; + if (style) + { + return [NSString stringWithFormat: @"%@-%@", family, style]; + } + else + { + return family; + } +} +- (NSString*)readVisibleNameFromPattern: (FcPattern*)pat +{ + // FIXME: try to get the localized one + return [self readFontconfigString: FC_FULLNAME fromPattern: pat]; +} +- (NSString*)readFamilyNameFromPattern: (FcPattern*)pat +{ + // FIXME: try to get the localized one + return [self readFontconfigString: FC_FAMILY fromPattern: pat]; +} +- (NSString*)readStyleNameFromPattern: (FcPattern*)pat +{ + // FIXME: try to get the localized one + return [self readFontconfigString: FC_STYLE fromPattern: pat]; +} +- (NSDictionary*)readTraitsFromPattern: (FcPattern*)pat +{ + NSMutableDictionary *traits = [NSMutableDictionary dictionary]; + + NSFontSymbolicTraits symTraits = 0; + + int value; + if (FcResultMatch == FcPatternGetInteger(pat, FC_SLANT, 0, &value)) + { + if (value == FC_SLANT_ITALIC) + { + symTraits |= NSFontItalicTrait; + } + } + if (FcResultMatch == FcPatternGetInteger(pat, FC_WEIGHT, 0, &value)) + { + double weight; + + if (value >= FC_WEIGHT_BOLD) + { + symTraits |= NSFontBoldTrait; + } + + if (value <= FC_WEIGHT_NORMAL) + { + weight = ((value - FC_WEIGHT_THIN) / (double)(FC_WEIGHT_NORMAL - FC_WEIGHT_THIN)) - 1.0; + } + else + { + weight = (value - FC_WEIGHT_NORMAL) / (double)(FC_WEIGHT_ULTRABLACK - FC_WEIGHT_NORMAL); + } + + [traits setObject: [NSNumber numberWithDouble: weight] + forKey: NSFontWeightTrait]; + } + if (FcResultMatch == FcPatternGetInteger(pat, FC_WIDTH, 0, &value)) + { + double width; + + if (value >= FC_WIDTH_EXPANDED) + { + symTraits |= NSFontExpandedTrait; + } + if (value <= FC_WIDTH_CONDENSED) + { + symTraits |= NSFontCondensedTrait; + } + + if (value <= FC_WIDTH_NORMAL) + { + width = ((value - FC_WIDTH_ULTRACONDENSED) / (double)(FC_WIDTH_NORMAL - FC_WIDTH_ULTRACONDENSED)) - 1.0; + } + else + { + width = (value - FC_WIDTH_NORMAL) / (double)(FC_WIDTH_ULTRAEXPANDED - FC_WIDTH_NORMAL); + } + + [traits setObject: [NSNumber numberWithDouble: width] + forKey: NSFontWidthTrait]; + } + if (FcResultMatch == FcPatternGetInteger(pat, FC_SPACING, 0, &value)) + { + if (value == FC_MONO || value == FC_CHARCELL) + { + symTraits |= NSFontMonoSpaceTrait; + } + } + + if (symTraits != 0) + { + [traits setObject: [NSNumber numberWithUnsignedInt: symTraits] + forKey: NSFontSymbolicTrait]; + } + + return traits; +} + +- (NSNumber*)readSizeFromPattern: (FcPattern*)pat +{ + return [self readFontconfigDouble: FC_SIZE fromPattern: pat]; +} + +- (NSCharacterSet*)readCharacterSetFromPattern: (FcPattern*)pat +{ + FcCharSet *value; + if (FcResultMatch == FcPatternGetCharSet(pat, FC_CHARSET, 0, &value)) + { + return [[[FontconfigCharacterSet alloc] initWithFontconfigCharSet: value] autorelease]; + } + return nil; +} + +#define READ_FROM_PATTERN(key, readMethod) \ + do { \ + id result = [self readMethod _pat]; \ + if (result != nil) \ + { \ + [_attributes setObject: result \ + forKey: key]; \ + } \ + } while (0); + +- (void)parseAttributes +{ + READ_FROM_PATTERN(NSFontNameAttribute, readNameFromPattern:); + READ_FROM_PATTERN(NSFontVisibleNameAttribute, readVisibleNameFromPattern:); + READ_FROM_PATTERN(NSFontFamilyAttribute, readFamilyNameFromPattern:); + READ_FROM_PATTERN(NSFontFaceAttribute, readStyleNameFromPattern:); + READ_FROM_PATTERN(NSFontTraitsAttribute, readTraitsFromPattern:); + READ_FROM_PATTERN(NSFontSizeAttribute, readSizeFromPattern:); + READ_FROM_PATTERN(NSFontCharacterSetAttribute, readCharacterSetFromPattern:); +} + +- (NSDictionary*)attributesFromPattern: (FcPattern *)pat +{ + _attributes = [NSMutableDictionary dictionary]; + _pat = pat; + [self parseAttributes]; + return _attributes; +} + +@end + + + +@implementation FontconfigCharacterSet + +- (id)initWithFontconfigCharSet: (FcCharSet*)charset +{ + if ((self = [super init])) + { + _charset = FcCharSetCopy(charset); + } + return self; +} + +- (id)mutableCopyWithZone: (NSZone*)aZone +{ + return [[NSMutableCharacterSet characterSetWithBitmapRepresentation: + [self bitmapRepresentation]] retain]; +} + +- (void)dealloc +{ + FcCharSetDestroy(_charset); + [super dealloc]; +} + +- (FcCharSet*)fontconfigCharSet +{ + return _charset; +} + +- (BOOL)characterIsMember: (unichar)c +{ + return FcCharSetHasChar(_charset, c); +} + +- (BOOL)longCharacterIsMember: (UTF32Char)c +{ + return FcCharSetHasChar(_charset, c); +} + +// FIXME: Implement for better performance +//- (NSData *)bitmapRepresentation +//{ +//} + +@end + diff --git a/Source/fontconfig/FCFontInfo.m b/Source/fontconfig/FCFontInfo.m new file mode 100644 index 0000000..258a813 --- /dev/null +++ b/Source/fontconfig/FCFontInfo.m @@ -0,0 +1,174 @@ +/* + FCFontInfo.m + + Copyright (C) 2003 Free Software Foundation, Inc. + + August 31, 2003 + Written by Banlu Kemiyatorn + Base on original code of Alex Malmberg + + This file is part of GNUstep. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; see the file COPYING.LIB. + If not, see or write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "GNUstepBase/Unicode.h" +#include +#include +#include "fontconfig/FCFontInfo.h" +#include "fontconfig/FCFontEnumerator.h" + +#include + +@implementation FCFontInfo + +- (void) setCacheSize: (unsigned int)size +{ + _cacheSize = size; + if (_cachedSizes) + { + free(_cachedSizes); + } + if (_cachedGlyphs) + { + free(_cachedGlyphs); + } + _cachedSizes = malloc(sizeof(NSSize) * size); + if (_cachedSizes) + { + memset(_cachedSizes, 0, sizeof(NSSize) * size); + } + _cachedGlyphs = malloc(sizeof(unsigned int) * size); + if (_cachedGlyphs) + { + memset(_cachedGlyphs, 0, sizeof(unsigned int) * size); + } +} + +- (BOOL) setupAttributes +{ + ASSIGN(_faceInfo, [FCFontEnumerator fontWithName: fontName]); + if (!_faceInfo) + { + return NO; + } + + // check for font specific cache size from face info + [self setCacheSize: [_faceInfo cacheSize]]; + + /* setting GSFontInfo: + * weight, traits, familyName, + * mostCompatibleStringEncoding, encodingScheme, coveredCharacterSet + */ + + weight = [_faceInfo weight]; + traits = [_faceInfo traits]; + familyName = [[_faceInfo familyName] copy]; + mostCompatibleStringEncoding = NSUTF8StringEncoding; + encodingScheme = @"iso10646-1"; + coveredCharacterSet = [[_faceInfo characterSet] retain]; + + return YES; +} + +- (id) initWithFontName: (NSString *)name + matrix: (const CGFloat *)fmatrix + screenFont: (BOOL)p_screenFont +{ + self = [super init]; + if (!self) + return nil; + + _screenFont = p_screenFont; + fontName = [name copy]; + memcpy(matrix, fmatrix, sizeof(matrix)); + + if (_screenFont) + { + /* Round up; makes the text more legible. */ + matrix[0] = ceil(matrix[0]); + if (matrix[3] < 0.0) + matrix[3] = floor(matrix[3]); + else + matrix[3] = ceil(matrix[3]); + } + + if (![self setupAttributes]) + { + RELEASE(self); + return nil; + } + + return self; +} + +- (void) dealloc +{ + RELEASE(_faceInfo); + if (_cachedSizes) + free(_cachedSizes); + if (_cachedGlyphs) + free(_cachedGlyphs); + [super dealloc]; +} + +- (CGFloat) defaultLineHeightForFont +{ + return lineHeight; +} + +- (BOOL) glyphIsEncoded: (NSGlyph)glyph +{ + [self subclassResponsibility: _cmd]; + return YES; +} + +- (NSSize) advancementForGlyph: (NSGlyph)glyph +{ + [self subclassResponsibility: _cmd]; + return NSZeroSize; +} + +- (NSRect) boundingRectForGlyph: (NSGlyph)glyph +{ + [self subclassResponsibility: _cmd]; + return NSZeroRect; +} + +- (CGFloat) widthOfString: (NSString *)string +{ + [self subclassResponsibility: _cmd]; + return 0.0; +} + +- (NSGlyph) glyphWithName: (NSString *) glyphName +{ + /* subclass should override */ + /* terrible! FIXME */ + NSGlyph g = [glyphName cString][0]; + + return g; +} + +- (void) appendBezierPathWithGlyphs: (NSGlyph *)glyphs + count: (int)length + toBezierPath: (NSBezierPath *)path +{ + [self subclassResponsibility: _cmd]; +} + +@end diff --git a/Source/gsc/GSGState.m b/Source/gsc/GSGState.m index 7d2f08a..c104ed6 100644 --- a/Source/gsc/GSGState.m +++ b/Source/gsc/GSGState.m @@ -1276,31 +1276,38 @@ typedef enum { - (void) _fillRect: (NSRect)rect withPattern: (NSImage*)color_pattern { NSSize size; - CGFloat x; - CGFloat y; NSAffineTransform *ictm; + NSPoint patternPhase, startPoint, endPoint, point; // The coordinates we get here are already in device space, // but compositeToPoint needs user space coordinates ictm = [ctm copyWithZone: [self zone]]; [ictm invert]; - size = [pattern size]; - y = floor(NSMinY(rect) / size.height) * size.height; + size = [color_pattern size]; + patternPhase = [drawcontext patternPhase]; - while (y < NSMaxY(rect)) + if (!NSEqualPoints(patternPhase, NSZeroPoint)) { - x = floor(NSMinX(rect) / size.width) * size.width; - while (x < NSMaxX(rect)) + // patternPhase % pattern size + patternPhase.x -= floor(patternPhase.x / size.width) * size.width; + patternPhase.y -= floor(patternPhase.y / size.height) * size.height; + } + + startPoint = NSMakePoint(floor((NSMinX(rect) - patternPhase.x) / size.width) * size.width + + patternPhase.x, + floor((NSMinY(rect) - patternPhase.y) / size.height) * size.height + + patternPhase.y); + + endPoint = NSMakePoint(NSMaxX(rect), NSMaxY(rect)); + + for (point.y = startPoint.y; point.y < endPoint.y; point.y += size.height) { - NSPoint p = NSMakePoint(x, y); - - p = [ictm transformPoint: p]; - [color_pattern compositeToPoint: p + for (point.x = startPoint.x; point.x < endPoint.x; point.x += size.width) + { + [color_pattern compositeToPoint: [ictm transformPoint: point] operation: NSCompositeSourceOver]; - x += size.width; } - y += size.height; } RELEASE(ictm); } diff --git a/Source/x11/XGDragView.m b/Source/x11/XGDragView.m index 4854c92..ab4dcab 100644 --- a/Source/x11/XGDragView.m +++ b/Source/x11/XGDragView.m @@ -52,9 +52,9 @@ #define SLIDE_TIME_STEP .02 /* in seconds */ #define SLIDE_NR_OF_STEPS 20 -#define dragWindev [XGServer _windowWithTag: [_window windowNumber]] +#define DRAGWINDEV [XGServer _windowWithTag: [_window windowNumber]] #define XX(P) (P.x) -#define XY(P) (DisplayHeight(XDPY, dragWindev->screen) - P.y) +#define XY(P) (DisplayHeight(XDPY, DRAGWINDEV->screen) - P.y) @interface XGRawWindow : NSWindow @end @@ -268,6 +268,8 @@ static XGDragView *sharedDragView = nil; timestamp: (NSTimeInterval)time toWindow: (int)dWindowNumber { + gswindow_device_t *dragWindev = DRAGWINDEV; + switch (subtype) { case GSAppKitDraggingDrop: @@ -333,6 +335,7 @@ static XGDragView *sharedDragView = nil; None if there is no X window that accepts drag and drop. */ - (Window) _xWindowAcceptingDnDDescendentOf: (Window) parent + ignoring: (Window) ident underX: (int) x Y: (int) y { @@ -344,7 +347,7 @@ static XGDragView *sharedDragView = nil; XWindowAttributes attr; int ret_x, ret_y; - if (parent == dragWindev->ident) + if (parent == ident) return -1; XQueryTree(display, parent, &root, &ignore, &children, &nchildren); @@ -361,12 +364,17 @@ static XGDragView *sharedDragView = nil; && ret_y >= 0 && ret_y < attr.height) { result = [self _xWindowAcceptingDnDDescendentOf: child + ignoring: ident underX: x Y: y]; - if (result != (Window)-1) + // With window decoration there may be multiple windows + // at the same place. Try all of them. + if ((result != (Window)-1) && (result != (Window) None)) + { break; } } + } if (children) { @@ -389,8 +397,10 @@ static XGDragView *sharedDragView = nil; - (Window) _xWindowAcceptingDnDunderX: (int) x Y: (int) y { Window result; + gswindow_device_t *dragWindev = DRAGWINDEV; result = [self _xWindowAcceptingDnDDescendentOf: dragWindev->root + ignoring: dragWindev->ident underX: x Y: y]; if (result == (Window)-1) diff --git a/Source/x11/XGGLContext.m b/Source/x11/XGGLContext.m index 12b47b1..8c8eb64 100644 --- a/Source/x11/XGGLContext.m +++ b/Source/x11/XGGLContext.m @@ -253,8 +253,8 @@ static XGGLContext *currentGLContext; if ( !glXMakeContextCurrent(dpy, None, None, NULL) ) { NSDebugMLLog( @"GLX", - @"Can not clear current GL context - Errror %u", - glGetError() ); + @"Cannot clear current GL context - Error %s", + glGetString(glGetError())); } } else @@ -262,8 +262,8 @@ static XGGLContext *currentGLContext; if ( !glXMakeCurrent(dpy, None, NULL) ) { NSDebugMLLog( @"GLX", - @"Can not clear current GL context - Errror %u", - glGetError() ); + @"Can not clear current GL context - Error %s", + glGetString(glGetError())); } } @@ -279,8 +279,6 @@ static XGGLContext *currentGLContext; { if (xSubWindow) { - MAKE_DISPLAY(dpy); - if (currentGLContext == self) { [XGGLContext clearCurrentContext]; @@ -288,6 +286,8 @@ static XGGLContext *currentGLContext; if ( glx_drawable != xSubWindow->xwindowid ) { + MAKE_DISPLAY(dpy); + glXDestroyWindow(dpy, glx_drawable); glx_drawable = None; } @@ -316,7 +316,7 @@ static XGGLContext *currentGLContext; - (void)copyAttributesFromContext:(NSOpenGLContext *)context withMask:(unsigned long)mask { - GLint error; + GLenum error; MAKE_DISPLAY(dpy); if (context == nil || ![context isKindOfClass: [XGGLContext class]]) @@ -329,12 +329,11 @@ static XGGLContext *currentGLContext; glx_context, mask); error = glGetError(); - if ( error != GL_NO_ERROR ) { NSDebugMLLog( @"GLX", - @"Can not copy GL context %@ from context %@ - Error %u", - self, context, error ); + @"Cannot copy GL context %@ from context %@ - Error %s", + self, context, glGetString(error)); } } @@ -442,16 +441,16 @@ static XGGLContext *currentGLContext; { if ( !glXMakeContextCurrent(dpy, glx_drawable, glx_drawable, glx_context) ) { - NSDebugMLLog( @"GLX", @"Cannot make GL context %@ current - Error %u", - self, glGetError() ); + NSDebugMLLog(@"GLX", @"Cannot make GL context %@ current - Error %s", + self, glGetString(glGetError())); } } else { if ( !glXMakeCurrent(dpy, glx_drawable, glx_context) ) { - NSDebugMLLog( @"GLX", @"Cannot make GL context %@ current - Error %u", - self, glGetError() ); + NSDebugMLLog(@"GLX", @"Cannot make GL context %@ current - Error %s", + self, glGetString(glGetError())); } } @@ -507,7 +506,7 @@ static XGGLContext *currentGLContext; saved_ignores_backing = [view _ignoresBacking]; [view _setIgnoresBacking: YES]; - NSDebugMLLog(@"GLX", @"glx_window : %u", glx_drawable); + NSDebugMLLog(@"GLX", @"glx_window : %lu", (unsigned long) glx_drawable); } - (void)update diff --git a/Source/x11/XGGLFormat.m b/Source/x11/XGGLFormat.m index 3615b3e..71315ce 100644 --- a/Source/x11/XGGLFormat.m +++ b/Source/x11/XGGLFormat.m @@ -47,17 +47,21 @@ + (int) glxMinorVersion { + static int cachedVersion = -1; + + if (cachedVersion == -1) + { Display * display = [(XGServer *)GSCurrentServer() xDisplay]; NSDictionary * attributes = [GSCurrentServer() attributes]; NSString * sn = [attributes objectForKey: GSScreenNumber]; // This is due to some OpenGL drivers reporting a lower overall GLX version than they actually implement. - NSString * glxServerVersion = [NSString stringWithFormat:@"%s", glXQueryServerString(display, [sn intValue], GLX_VERSION)]; - NSString * glxClientVersion = [NSString stringWithFormat:@"%s", glXGetClientString(display, GLX_VERSION)]; - + NSString *glxServerVersion = + [NSString stringWithFormat:@"%s", glXQueryServerString(display, [sn intValue], GLX_VERSION)]; + NSString *glxClientVersion = + [NSString stringWithFormat:@"%s", glXGetClientString(display, GLX_VERSION)]; float serverversion = [glxServerVersion floatValue]; float clientversion = [glxClientVersion floatValue]; - float serverIntegerPart; float clientIntegerPart; float fracServer = modff(serverversion, &serverIntegerPart); @@ -69,11 +73,11 @@ fracClient = rintf(fracClient * 10.0f); NSDebugMLLog(@"GLX", @"server %f client %f", fracServer, fracClient ); - - return (int)MIN(fracServer, fracClient); + cachedVersion = (int)MIN(fracServer, fracClient); + } } - return -1; + return cachedVersion; } // Works for some attributes only @@ -86,7 +90,6 @@ NSAssert((fbconfig != NULL || visualinfo != NULL) && configurationCount > 0, NSInternalInconsistencyException); - if (glxminorversion >= 3) { error = glXGetFBConfigAttrib(display, fbconfig[pickedFBConfig], attrib, vals); @@ -272,11 +275,9 @@ do \ { ptr++; append(GLX_SAMPLE_BUFFERS, *ptr); - break; } - #else - break; #endif + break; } case NSOpenGLPFASamples: { @@ -285,11 +286,9 @@ do \ { ptr++; append(GLX_SAMPLES, *ptr); - break; } - #else - break; #endif + break; } case NSOpenGLPFAAuxDepthStencil: @@ -332,6 +331,10 @@ do \ NSDictionary * dsattributes; self = [super init]; + if (self == nil) + { + return nil; + } fbconfig = NULL; visualinfo = NULL; @@ -361,8 +364,7 @@ do \ if ((NULL != pictFormat && (pictFormat->type == PictTypeDirect) && (pictFormat->direct.alphaMask)) - || - !shouldRequestARGBVisual) + || !shouldRequestARGBVisual) { pickedFBConfig = i; visualinfo = vinfo; @@ -427,8 +429,8 @@ do \ if ( context == NULL ) { NSDebugMLLog(@"GLX", - @"Can not create GL context for pixel format %@ - Error %u", - self, glGetError()); + @"Cannot create GL context for pixel format %@ - Error %s", + self, glGetString(glGetError())); } return context; @@ -437,7 +439,7 @@ do \ - (GLXWindow) drawableForWindow: (Window)xwindowid { GLXWindow win; - GLint error; + GLenum error; if (glxminorversion >= 3) { @@ -452,8 +454,8 @@ do \ if ( error != GL_NO_ERROR ) { NSDebugMLLog(@"GLX", - @"Can not create GL window for pixel format %@ - Error %u", - self, error ); + @"Cannot create GL window for pixel format %@ - Error %s", + self, glGetString(error)); } return win; diff --git a/Source/x11/XGServerWindow.m b/Source/x11/XGServerWindow.m index 2b1eced..b0297b2 100644 --- a/Source/x11/XGServerWindow.m +++ b/Source/x11/XGServerWindow.m @@ -112,7 +112,7 @@ static int last_win_num = 0; bitsPerPixel: (NSInteger)pixelBits; @end -static NSBitmapImageRep *getStandardBitmapForBitmapFormat(NSImage *image, NSBitmapFormat bitmapFormat) +static NSBitmapImageRep *getStandardBitmap(NSImage *image) { NSBitmapImageRep *rep; @@ -149,16 +149,12 @@ static NSBitmapImageRep *getStandardBitmapForBitmapFormat(NSImage *image, NSBitm hasAlpha: [rep hasAlpha] isPlanar: NO colorSpaceName: NSCalibratedRGBColorSpace - bitmapFormat: bitmapFormat + bitmapFormat: 0 bytesPerRow: 0 bitsPerPixel: 0]; } } -static NSBitmapImageRep *getStandardBitmap(NSImage *image) -{ - return getStandardBitmapForBitmapFormat(image, 0); -} void __objc_xgcontextwindow_linking (void) { @@ -846,7 +842,7 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg) context->depth, CopyFromParent, context->visual, - (CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect), + (CWColormap | CWBorderPixel | CWOverrideRedirect), &window->xwn_attrs); /* @@ -1106,7 +1102,8 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg) parent = new_parent; repx = wattr.x; repy = wattr.y; - NSLog(@"QueryTree window is %lu (root %lu cwin root %lu)", + NSDebugLLog(@"Offset", + @"QueryTree window is %lu (root %lu cwin root %lu)", parent, root, window->root); if (!XQueryTree(dpy, parent, &root, &new_parent, &children, &nchildren)) @@ -1311,7 +1308,7 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg) // Window state generic.netstates.net_wm_state_atom = XInternAtom(dpy, "_NET_WM_STATE", False); - generic.netstates.new_wm_state_modal_atom = + generic.netstates.net_wm_state_modal_atom = XInternAtom(dpy, "_NET_WM_STATE_MODAL", False); generic.netstates.net_wm_state_sticky_atom = XInternAtom(dpy, "_NET_WM_STATE_STICKY", False); @@ -1830,10 +1827,6 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg) only done if the Window is buffered or retained. */ - (void) _createBuffer: (gswindow_device_t *)window { - if (window->type == NSBackingStoreNonretained - || (window->gdriverProtocol & GDriverHandlesBacking)) - return; - if (window->depth == 0) window->depth = DefaultDepth(dpy, window->screen); if (NSWidth(window->xframe) == 0 && NSHeight(window->xframe) == 0) @@ -1876,7 +1869,7 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg) long *iconPropertyData; int iconSize; - rep = getStandardBitmapForBitmapFormat(image, NSAlphaNonpremultipliedBitmapFormat); + rep = getStandardBitmap(image); if (rep == nil) { NSLog(@"Wrong image type for WM icon"); @@ -1916,14 +1909,28 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg) // blue B = d[2]; // alpha +#if 0 +/* + For unclear reasons the alpha handling does not work, so we simulate it. +*/ if (samples == 4) { - A = d[3]; + A = d[4]; } else { A = 255; } +#else + if (R || G || B) + { + A = 255; + } + else + { + A = 0; + } +#endif iconPropertyData[index++] = A << 24 | R << 16 | G << 8 | B; d += samples; @@ -2041,7 +2048,9 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg) context->depth, CopyFromParent, context->visual, - (CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect), + // Don't set the CWBackPixel, as the background of the + // window may be different. + (CWColormap | CWBorderPixel | CWOverrideRedirect), &window->xwn_attrs); /* @@ -2317,10 +2326,9 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg) NSMapRemove(windowmaps, (void*)window->ident); } - if (window->buffer && (window->gdriverProtocol & GDriverHandlesBacking) == 0) + if (window->buffer) XFreePixmap (dpy, window->buffer); - if (window->alpha_buffer - && (window->gdriverProtocol & GDriverHandlesBacking) == 0) + if (window->alpha_buffer) XFreePixmap (dpy, window->alpha_buffer); if (window->region) XDestroyRegion (window->region); @@ -2539,9 +2547,9 @@ NSLog(@"styleoffsets ... guessing offsets\n"); NSDebugLLog(@"XGTrace", @"DPSwindowbacking: %d : %d", (int)type, win); + window->type = type; if ((window->gdriverProtocol & GDriverHandlesBacking)) { - window->type = type; return; } @@ -2550,9 +2558,11 @@ NSLog(@"styleoffsets ... guessing offsets\n"); XFreePixmap (dpy, window->buffer); window->buffer = 0; } - window->type = type; + else if (window->buffer == 0) + { [self _createBuffer: window]; } +} - (void) titlewindow: (NSString *)window_title : (int) win { @@ -2752,10 +2762,26 @@ NSLog(@"styleoffsets ... guessing offsets\n"); window->buffer_width = width; window->buffer_height = height; - if (window->buffer == 0) +#if (BUILD_GRAPHICS == GRAPHICS_xlib) + /* The window->gdriverProtocol flag does not work as intended; + it doesn't get set until after _createBuffer is called, + so it's not a relaible way to tell whether we need to create + a backing pixmap here. + + This method was causing a serious leak with the default + Cairo XGCairoModernSurface because we were erroneously + creating a pixmap, and then not releasing it in -termwindow: + because the GDriverHandlesBacking flag was set in between. + + So this #if servers as a foolproof way of ensuring we + don't ever create window->buffer in the default configuration. + */ + if ((window->buffer == 0) && (window->type != NSBackingStoreNonretained) && + ((window->gdriverProtocol & GDriverHandlesBacking) == 0)) { [self _createBuffer: window]; } +#endif [self styleoffsets: &l : &r : &t : &b : window->win_attrs.window_style : window->ident]; @@ -3091,6 +3117,17 @@ static BOOL didCreatePixmaps; } } } + + if (window->win_attrs.window_level == NSModalPanelWindowLevel) + { + [self _sendRoot: window->root + type: generic.netstates.net_wm_state_atom + window: window->ident + data0: _NET_WM_STATE_ADD + data1: generic.netstates.net_wm_state_modal_atom + data2: 0 + data3: 1]; + } } XFlush(dpy); } diff --git a/Source/x11/XIMInputServer.m b/Source/x11/XIMInputServer.m index 722c38a..9e4d3de 100644 --- a/Source/x11/XIMInputServer.m +++ b/Source/x11/XIMInputServer.m @@ -39,6 +39,7 @@ #include "x11/XGInputServer.h" #include +#define NoneStyle (XIMPreeditNone | XIMStatusNone) #define RootWindowStyle (XIMPreeditNothing | XIMStatusNothing) #define OffTheSpotStyle (XIMPreeditArea | XIMStatusArea) #define OverTheSpotStyle (XIMPreeditPosition | XIMStatusArea) @@ -68,9 +69,19 @@ display: (Display *)dpy name: (NSString *)name { + char *locale; delegate = aDelegate; ASSIGN(server_name, name); + locale = setlocale(LC_CTYPE, ""); + + if (XSupportsLocale() != True) + { + NSLog(@"Xlib does not support locale setting %s", locale); + /* FIXME: Should we reset the locale or just hope that X + can deal with it? */ + } + #ifdef USE_XIM if ([self ximInit: dpy] == NO) { @@ -218,6 +229,39 @@ return YES; } +static XIMStyle +betterStyle(XIMStyle a, XIMStyle b, XIMStyle xim_requested_style) +{ + if (a == xim_requested_style) + return a; + if (b == xim_requested_style) + return b; + + // N.B. We don't support OnTheSpotStyle so it is omitted here + + if (a == OverTheSpotStyle) + return a; + if (b == OverTheSpotStyle) + return b; + + if (a == OffTheSpotStyle) + return a; + if (b == OffTheSpotStyle) + return b; + + if (a == RootWindowStyle) + return a; + if (b == RootWindowStyle) + return b; + + if (a == NoneStyle) + return a; + if (b == NoneStyle) + return b; + + return 0; +} + - (int) ximStyleInit { NSUserDefaults *uds; @@ -265,18 +309,20 @@ for (i = 0; i < styles->count_styles; i++) { - if (styles->supported_styles[i] == xim_requested_style) - { - xim_style = xim_requested_style; - XFree(styles); - return 1; + xim_style = betterStyle(xim_style, styles->supported_styles[i], + xim_requested_style); } - } - NSLog(@"XIM: '%@' is not supported", request); XFree(styles); + + if (xim_style == 0) + { + NSLog(@"XIM: no supported styles found"); return 0; } + return 1; +} + - (void) ximClose { int i; @@ -325,7 +371,7 @@ { XIC xic = NULL; - if (xim_style == RootWindowStyle) + if (xim_style == RootWindowStyle || xim_style == NoneStyle) { xic = XCreateIC(xim, XNInputStyle, xim_style, diff --git a/Source/xlib/GSXftFontInfo.m b/Source/xlib/GSXftFontInfo.m index 3dbad7c..fd5df77 100644 --- a/Source/xlib/GSXftFontInfo.m +++ b/Source/xlib/GSXftFontInfo.m @@ -730,7 +730,6 @@ static FT_Outline_Funcs bezierpath_funcs = { { Display *xdpy = [XGServer currentXDisplay]; int defaultScreen = DefaultScreen(xdpy); - NSString *weightString = nil; #ifdef HAVE_FC FcFont *realFont = [allFonts objectForKey: fontName]; @@ -775,28 +774,22 @@ static FT_Outline_Funcs bezierpath_funcs = { { case FC_WEIGHT_LIGHT: weight = 3; - weightString = @"light"; break; case FC_WEIGHT_MEDIUM: weight = 6; - weightString = @"medium"; break; case FC_WEIGHT_DEMIBOLD: weight = 7; - weightString = @"demibold"; break; case FC_WEIGHT_BOLD: weight = 9; - weightString = @"bold"; break; case FC_WEIGHT_BLACK: weight = 12; - weightString = @"black"; break; default: // Don't know weight = 6; - weightString = @"medium"; } } @@ -875,23 +868,18 @@ static FT_Outline_Funcs bezierpath_funcs = { { case 0: weight = 3; - weightString = @"light"; break; case 100: weight = 6; - weightString = @"medium"; break; case 180: weight = 7; - weightString = @"demibold"; break; case 200: weight = 9; - weightString = @"bold"; break; case 210: weight = 12; - weightString = @"black"; break; default: // Don't know diff --git a/Source/xlib/XGBitmap.m b/Source/xlib/XGBitmap.m index 3914a02..f7a389c 100644 --- a/Source/xlib/XGBitmap.m +++ b/Source/xlib/XGBitmap.m @@ -1261,7 +1261,6 @@ _pixmap_read_alpha(RContext *context, } else { - XColor c2; unsigned row; unsigned long pixels[CSIZE]; XColor colors[CSIZE]; @@ -1279,7 +1278,6 @@ _pixmap_read_alpha(RContext *context, * RGB color values - on the downside, it's very slow. */ pixel = (unsigned long)-1; // Never valid? - c2.pixel = pixel; for (row = 0; row < srect.height; row++) { diff --git a/Source/xlib/XGFontManager.m b/Source/xlib/XGFontManager.m index d571d08..4b0fee6 100644 --- a/Source/xlib/XGFontManager.m +++ b/Source/xlib/XGFontManager.m @@ -49,6 +49,11 @@ #define stringify_it(X) #X +@interface NSBundle (Private) +// Maybe we should rather use -pathForAuxiliaryExecutable:? ++ (NSString *) _absolutePathOfExecutable: (NSString *)path; +@end + static NSMutableDictionary* creationDictionary; // Fills in the size into an creation string to make it an X font name diff --git a/configure b/configure index 99acfc2..4680178 100755 --- a/configure +++ b/configure @@ -637,6 +637,13 @@ XMKMF EGREP GREP CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC target_os target_vendor target_cpu @@ -649,13 +656,6 @@ build_os build_vendor build_cpu build -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC target_alias host_alias build_alias @@ -2191,6 +2191,159 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. #-------------------------------------------------------------------- # Determine the host, build, and target systems #-------------------------------------------------------------------- +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if test "${ac_cv_build+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if test "${ac_cv_target+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +#-------------------------------------------------------------------- +# Find the compiler +#-------------------------------------------------------------------- +MAKECC=`gnustep-config --variable=CC` +MAKECPP=`gnustep-config --variable=CPP` +MAKECXX=`gnustep-config --variable=CXX` +if test "$CC" = ""; then + CC=$MAKECC +else + if test "$CC" != "$MAKECC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You are running configure with the compiler ($CC) set to a different value from that used by gnustep-make ($MAKECC). To a +void conflicts/problems, reconfigure/reinstall gnustep-make to use $CC or run the gnustep-base configure again with your CC environment var +iable set to $MAKECC" >&5 +$as_echo "$as_me: WARNING: You are running configure with the compiler ($CC) set to a different value from that used by gnustep-make ($MAKECC). To a +void conflicts/problems, reconfigure/reinstall gnustep-make to use $CC or run the gnustep-base configure again with your CC environment var +iable set to $MAKECC" >&2;} + fi +fi +if test "$CPP" = ""; then + CPP=$MAKECPP +else + if test "$CPP" != "$MAKECPP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You are running configure with the preprocessor ($CPP) set to a different value from that used by gnustep-make ($MAKECPP). + To avoid conflicts/problems, reconfigure/reinstall gnustep-make to use $CPP or run the gnustep-base configure again with your CPP environ +ment variable set to $MAKECPP" >&5 +$as_echo "$as_me: WARNING: You are running configure with the preprocessor ($CPP) set to a different value from that used by gnustep-make ($MAKECPP). + To avoid conflicts/problems, reconfigure/reinstall gnustep-make to use $CPP or run the gnustep-base configure again with your CPP environ +ment variable set to $MAKECPP" >&2;} + fi +fi +if test "$CXX" = ""; then + CXX=$MAKECXX +else + if test "$CXX" != "$MAKECXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You are running configure with the compiler ($CXX) set to a different value from that used by gnustep-make ($MAKECXX). To + avoid conflicts/problems, reconfigure/reinstall gnustep-make to use $CXX or run the gnustep-base configure again with your CXX environment + variable set to $MAKECXX" >&5 +$as_echo "$as_me: WARNING: You are running configure with the compiler ($CXX) set to a different value from that used by gnustep-make ($MAKECXX). To + avoid conflicts/problems, reconfigure/reinstall gnustep-make to use $CXX or run the gnustep-base configure again with your CXX environment + variable set to $MAKECXX" >&2;} + fi +fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -2981,171 +3134,6 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if test "${ac_cv_build+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if test "${ac_cv_host+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 -$as_echo_n "checking target system type... " >&6; } -if test "${ac_cv_target+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test "x$target_alias" = x; then - ac_cv_target=$ac_cv_host -else - ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 -$as_echo "$ac_cv_target" >&6; } -case $ac_cv_target in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;; -esac -target=$ac_cv_target -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_target -shift -target_cpu=$1 -target_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -target_os=$* -IFS=$ac_save_IFS -case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac - - -# The aliases save the names the user supplied, while $host etc. -# will get canonicalized. -test -n "$target_alias" && - test "$program_prefix$program_suffix$program_transform_name" = \ - NONENONEs,x,x, && - program_prefix=${target_alias}- - -#-------------------------------------------------------------------- -# The following is so that headers and custom libraries -# in the GNUstep root are used before the standard ones -#-------------------------------------------------------------------- -GRAPHIC_CFLAGS="$CPPFLAGS" -GRAPHIC_LFLAGS="$LDFLAGS" - -# -# It looks like we ought to source the whole GNUstep.sh here, and even -# ask it to output all variables! That way we have access to (eg) -# GNUSTEP_SYSTEM_HEADERS below. -# -GNUSTEP_SH_EXPORT_ALL_VARIABLES=yes -. "$GNUSTEP_MAKEFILES/GNUstep.sh" -unset GNUSTEP_SH_EXPORT_ALL_VARIABLES - -# For backwards compatibility, define GNUSTEP_SYSTEM_HEADERS from -# GNUSTEP_SYSTEM_ROOT if not set yet. -if test x"$GNUSTEP_SYSTEM_HEADERS" = x""; then - GNUSTEP_SYSTEM_HEADERS="$GNUSTEP_SYSTEM_ROOT/Library/Headers" -fi - -if test x"$GNUSTEP_SYSTEM_LIBRARIES" = x""; then - GNUSTEP_SYSTEM_LIBRARIES="$GNUSTEP_SYSTEM_ROOT/Library/Libraries" -fi - -if test "$GNUSTEP_IS_FLATTENED" = no; then - clean_target_os=`$GNUSTEP_MAKEFILES/clean_os.sh $target_os` - clean_target_cpu=`$GNUSTEP_MAKEFILES/clean_cpu.sh $target_cpu` - obj_dir=$clean_target_cpu/$clean_target_os - GNUSTEP_LDIR=$GNUSTEP_SYSTEM_LIBRARIES/$obj_dir - GNUSTEP_HDIR=$GNUSTEP_SYSTEM_HEADERS/$LIBRARY_COMBO -else - GNUSTEP_LDIR=$GNUSTEP_SYSTEM_LIBRARIES - GNUSTEP_HDIR=$GNUSTEP_SYSTEM_HEADERS -fi -CPPFLAGS="$CPPFLAGS -I$GNUSTEP_HDIR" -LDFLAGS="$LDFLAGS -L$GNUSTEP_LDIR/$LIBRARY_COMBO -L$GNUSTEP_LDIR" - -#-------------------------------------------------------------------- -# Add target OS directories as necessary -#-------------------------------------------------------------------- -case "$target_os" in - freebsd* | openbsd* ) - CPPFLAGS="$CPPFLAGS -I/usr/pkg/include" - LDFLAGS="$LDFLAGS -L/usr/pkg/lib";; - netbsd*) CPPFLAGS="$CPPFLAGS -I/usr/pkg/include" - LDFLAGS="$LDFLAGS -Wl,-R/usr/pkg/lib -L/usr/pkg/lib";; -esac - -#-------------------------------------------------------------------- -# These headers/functions needed by gpbs.m -#-------------------------------------------------------------------- - ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -3284,6 +3272,61 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu +#-------------------------------------------------------------------- +# The following is so that headers and custom libraries +# in the GNUstep root are used before the standard ones +#-------------------------------------------------------------------- +GRAPHIC_CFLAGS="$CPPFLAGS" +GRAPHIC_LFLAGS="$LDFLAGS" + +# +# It looks like we ought to source the whole GNUstep.sh here, and even +# ask it to output all variables! That way we have access to (eg) +# GNUSTEP_SYSTEM_HEADERS below. +# +GNUSTEP_SH_EXPORT_ALL_VARIABLES=yes +. "$GNUSTEP_MAKEFILES/GNUstep.sh" +unset GNUSTEP_SH_EXPORT_ALL_VARIABLES + +# For backwards compatibility, define GNUSTEP_SYSTEM_HEADERS from +# GNUSTEP_SYSTEM_ROOT if not set yet. +if test x"$GNUSTEP_SYSTEM_HEADERS" = x""; then + GNUSTEP_SYSTEM_HEADERS="$GNUSTEP_SYSTEM_ROOT/Library/Headers" +fi + +if test x"$GNUSTEP_SYSTEM_LIBRARIES" = x""; then + GNUSTEP_SYSTEM_LIBRARIES="$GNUSTEP_SYSTEM_ROOT/Library/Libraries" +fi + +if test "$GNUSTEP_IS_FLATTENED" = no; then + clean_target_os=`$GNUSTEP_MAKEFILES/clean_os.sh $target_os` + clean_target_cpu=`$GNUSTEP_MAKEFILES/clean_cpu.sh $target_cpu` + obj_dir=$clean_target_cpu/$clean_target_os + GNUSTEP_LDIR=$GNUSTEP_SYSTEM_LIBRARIES/$obj_dir + GNUSTEP_HDIR=$GNUSTEP_SYSTEM_HEADERS/$LIBRARY_COMBO +else + GNUSTEP_LDIR=$GNUSTEP_SYSTEM_LIBRARIES + GNUSTEP_HDIR=$GNUSTEP_SYSTEM_HEADERS +fi +CPPFLAGS="$CPPFLAGS -I$GNUSTEP_HDIR" +LDFLAGS="$LDFLAGS -L$GNUSTEP_LDIR/$LIBRARY_COMBO -L$GNUSTEP_LDIR" + +#-------------------------------------------------------------------- +# Add target OS directories as necessary +#-------------------------------------------------------------------- +case "$target_os" in + freebsd* | openbsd* ) + CPPFLAGS="$CPPFLAGS -I/usr/pkg/include" + LDFLAGS="$LDFLAGS -L/usr/pkg/lib";; + netbsd*) CPPFLAGS="$CPPFLAGS -I/usr/pkg/include" + LDFLAGS="$LDFLAGS -Wl,-R/usr/pkg/lib -L/usr/pkg/lib";; +esac + +#-------------------------------------------------------------------- +# These headers/functions needed by gpbs.m +#-------------------------------------------------------------------- + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then : @@ -4855,7 +4898,6 @@ fi $as_echo "$ac_cv_lib_Xext_XShapeCombineMask" >&6; } if test "x$ac_cv_lib_Xext_XShapeCombineMask" = x""yes; then : - LIBS="-lXext $LIBS" $as_echo "#define HAVE_XSHAPE 1" >>confdefs.h @@ -5287,11 +5329,7 @@ fi if test "$have_fc" = yes -a "$ac_cv_header_fontconfig_fontconfig_h" = yes; then - # fontconfig is likely to be included if we found xft via pkg-config, so - # don't include it twice - if test $PKG_XFT = no; then XFT_LIBS="${XFT_LIBS} -lfontconfig" - fi $as_echo "#define HAVE_FC 1" >>confdefs.h @@ -7150,7 +7188,30 @@ elif test x"$BUILD_GRAPHICS" = "xxlib"; then elif test x"$BUILD_GRAPHICS" = "xwinlib"; then : # Nothing to do elif test x"$BUILD_GRAPHICS" = "xopal"; then + CPPFLAGS="$FONTCONFIG_CFLAGS $FREETYPE_CFLAGS $CPPFLAGS" LIBS="-lopal -lgnustep-corebase $LIBS" + LIBS="$FONTCONFIG_LIBS $FREETYPE_LIBS $LIBS" + if test "$have_freetype" = no ; then # FCFaceInfo requires this + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find freetype, required for graphics=opal!" >&5 +$as_echo "$as_me: WARNING: can't find freetype, required for graphics=opal!" >&2;} + if test $BUILD_SERVER = win32; then + BUILD_GRAPHICS=winlib +else + BUILD_GRAPHICS=xlib + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: Switching to $BUILD_GRAPHICS" >&5 +$as_echo "$as_me: Switching to $BUILD_GRAPHICS" >&6;} + elif test "$have_fontconfig" = no ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find fontconfig, required for graphics=opal!" >&5 +$as_echo "$as_me: WARNING: can't find fontconfig, required for graphics=opal!" >&2;} + if test $BUILD_SERVER = win32; then + BUILD_GRAPHICS=winlib + else + BUILD_GRAPHICS=xlib + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: Switching to $BUILD_GRAPHICS" >&5 +$as_echo "$as_me: Switching to $BUILD_GRAPHICS" >&6;} + fi else as_fn_error $? "Invalid graphics backend $BUILD_GRAPHICS" "$LINENO" 5 fi diff --git a/configure.ac b/configure.ac index 5a343ba..ae54c47 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ -# configure.in for GNUstep GUI Backend +# configure.ac for GNUstep GUI Backend # Process this file with autoconf to produce a configure script. # -# Copyright (C) 1996-2002 Free Software Foundation, Inc. +# Copyright (C) 1996-2015 Free Software Foundation, Inc. # # Author: Adam Fedor # @@ -47,9 +47,44 @@ AC_CONFIG_AUX_DIR($GNUSTEP_MAKEFILES) #-------------------------------------------------------------------- # Determine the host, build, and target systems #-------------------------------------------------------------------- -AC_PROG_CC AC_CANONICAL_TARGET([]) +#-------------------------------------------------------------------- +# Find the compiler +#-------------------------------------------------------------------- +MAKECC=`gnustep-config --variable=CC` +MAKECPP=`gnustep-config --variable=CPP` +MAKECXX=`gnustep-config --variable=CXX` +if test "$CC" = ""; then + CC=$MAKECC +else + if test "$CC" != "$MAKECC"; then + AC_MSG_WARN([You are running configure with the compiler ($CC) set to a different value from that used by gnustep-make ($MAKECC). To a +void conflicts/problems, reconfigure/reinstall gnustep-make to use $CC or run the gnustep-base configure again with your CC environment var +iable set to $MAKECC]) + fi +fi +if test "$CPP" = ""; then + CPP=$MAKECPP +else + if test "$CPP" != "$MAKECPP"; then + AC_MSG_WARN([You are running configure with the preprocessor ($CPP) set to a different value from that used by gnustep-make ($MAKECPP). + To avoid conflicts/problems, reconfigure/reinstall gnustep-make to use $CPP or run the gnustep-base configure again with your CPP environ +ment variable set to $MAKECPP]) + fi +fi +if test "$CXX" = ""; then + CXX=$MAKECXX +else + if test "$CXX" != "$MAKECXX"; then + AC_MSG_WARN([You are running configure with the compiler ($CXX) set to a different value from that used by gnustep-make ($MAKECXX). To + avoid conflicts/problems, reconfigure/reinstall gnustep-make to use $CXX or run the gnustep-base configure again with your CXX environment + variable set to $MAKECXX]) + fi +fi +AC_PROG_CC +AC_PROG_CPP + #-------------------------------------------------------------------- # The following is so that headers and custom libraries # in the GNUstep root are used before the standard ones @@ -173,7 +208,6 @@ if test $set_x_paths = yes; then if test $have_xshape = yes; then AC_CHECK_LIB(Xext, XShapeCombineMask, [ - LIBS="-lXext $LIBS" AC_DEFINE(HAVE_XSHAPE, 1, [Define to enable Xshape support]) ] ,) @@ -274,11 +308,7 @@ if test $WITH_XFT = yes; then AC_CHECK_LIB(fontconfig, FcPatternCreate, have_fc=yes, have_fc=no) AC_CHECK_HEADER(fontconfig/fontconfig.h) if test "$have_fc" = yes -a "$ac_cv_header_fontconfig_fontconfig_h" = yes; then - # fontconfig is likely to be included if we found xft via pkg-config, so - # don't include it twice - if test $PKG_XFT = no; then XFT_LIBS="${XFT_LIBS} -lfontconfig" - fi AC_DEFINE(HAVE_FC,1,[Define if you have FcPatternCreate]) fi CPPFLAGS=${save_CPPFLAGS} @@ -642,7 +672,26 @@ elif test x"$BUILD_GRAPHICS" = "xxlib"; then elif test x"$BUILD_GRAPHICS" = "xwinlib"; then : # Nothing to do elif test x"$BUILD_GRAPHICS" = "xopal"; then + CPPFLAGS="$FONTCONFIG_CFLAGS $FREETYPE_CFLAGS $CPPFLAGS" LIBS="-lopal -lgnustep-corebase $LIBS" + LIBS="$FONTCONFIG_LIBS $FREETYPE_LIBS $LIBS" + if test "$have_freetype" = no ; then # FCFaceInfo requires this + AC_MSG_WARN([can't find freetype, required for graphics=opal!]) + if test $BUILD_SERVER = win32; then + BUILD_GRAPHICS=winlib +else + BUILD_GRAPHICS=xlib + fi + AC_MSG_NOTICE([Switching to $BUILD_GRAPHICS]) + elif test "$have_fontconfig" = no ; then + AC_MSG_WARN([can't find fontconfig, required for graphics=opal!]) + if test $BUILD_SERVER = win32; then + BUILD_GRAPHICS=winlib + else + BUILD_GRAPHICS=xlib + fi + AC_MSG_NOTICE([Switching to $BUILD_GRAPHICS]) + fi else AC_MSG_ERROR([Invalid graphics backend $BUILD_GRAPHICS]) fi diff --git a/gnustep-back.spec.in b/gnustep-back.spec.in index 96f3df4..c24ff8c 100644 --- a/gnustep-back.spec.in +++ b/gnustep-back.spec.in @@ -5,6 +5,9 @@ Group: Development/Libraries Source: ftp://ftp.gnustep.org/pub/gnustep/core/%{gs_name}-%{gs_version}.tar.gz Requires: gnustep-gui Obsoletes: gnustep-xgps +Packager: GNUstep Development +Vendor: The GNUstep Project +URL: http://www.gnustep.org/ %description This is a backend for the GNUstep gui Library which allows you to use