mirror of
https://github.com/gnustep/libs-back.git
synced 2025-05-29 16:31:29 +00:00
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
This commit is contained in:
parent
6efb80b30b
commit
c43e467784
39 changed files with 2030 additions and 1500 deletions
|
@ -56,5 +56,6 @@ endif
|
|||
-include GNUmakefile.preamble
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/aggregate.make
|
||||
include $(GNUSTEP_MAKEFILES)/Master/deb.make
|
||||
|
||||
-include 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::
|
||||
|
|
|
@ -31,44 +31,17 @@
|
|||
#ifndef CAIROFACEINFO_H
|
||||
#define CAIROFACEINFO_H
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include "fontconfig/FCFaceInfo.h"
|
||||
#define id cairo_id
|
||||
#include <cairo-ft.h>
|
||||
#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
|
||||
|
|
|
@ -28,41 +28,16 @@
|
|||
#ifndef CairoFontEnumerator_h
|
||||
#define CairoFontEnumerator_h
|
||||
|
||||
#include <GNUstepGUI/GSFontInfo.h>
|
||||
#include "fontconfig/FCFontEnumerator.h"
|
||||
#include <cairo.h>
|
||||
#define id fontconfig_id
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#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
|
||||
|
|
|
@ -28,24 +28,16 @@
|
|||
#ifndef CairoFontInfo_h
|
||||
#define CairoFontInfo_h
|
||||
|
||||
#include <GNUstepGUI/GSFontInfo.h>
|
||||
#include "fontconfig/FCFontInfo.h"
|
||||
#include "cairo/CairoFaceInfo.h"
|
||||
#include <cairo.h>
|
||||
|
||||
@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;
|
||||
|
|
72
Headers/fontconfig/FCFaceInfo.h
Normal file
72
Headers/fontconfig/FCFaceInfo.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
FCFaceInfo.h
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
August 31, 2003
|
||||
Written by Banlu Kemiyatorn <object at gmail dot com>
|
||||
Base on code by Alexander Malmberg <alexander@malmberg.org>
|
||||
Rewrite: Fred Kiefer <fredkiefer@gmx.de>
|
||||
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 <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef FCFACEINFO_H
|
||||
#define FCFACEINFO_H
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
||||
@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
|
70
Headers/fontconfig/FCFontEnumerator.h
Normal file
70
Headers/fontconfig/FCFontEnumerator.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
FCFontEnumerator.h
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
August 31, 2003
|
||||
Written by Banlu Kemiyatorn <object at gmail dot com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FCFontEnumerator_h
|
||||
#define FCFontEnumerator_h
|
||||
|
||||
#include <GNUstepGUI/GSFontInfo.h>
|
||||
#define id fontconfig_id
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#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
|
50
Headers/fontconfig/FCFontInfo.h
Normal file
50
Headers/fontconfig/FCFontInfo.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
FCFontInfo.h
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
August 31, 2003
|
||||
Written by Banlu Kemiyatorn <object at gmail dot com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef FCFontInfo_h
|
||||
#define FCFontInfo_h
|
||||
|
||||
#include <GNUstepGUI/GSFontInfo.h>
|
||||
#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
|
|
@ -33,12 +33,6 @@
|
|||
@interface OpalContext : GSContext
|
||||
{
|
||||
}
|
||||
+ (void) initializeBackend;
|
||||
+ (Class) GStateClass;
|
||||
- (void) GSSetDevice: (void *)device
|
||||
: (int)x
|
||||
: (int)y;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
|
@ -28,14 +28,15 @@
|
|||
#ifndef OpalFontEnumerator_h_defined
|
||||
#define OpalFontEnumerator_h_defined
|
||||
|
||||
#import <GNUstepGUI/GSFontInfo.h>
|
||||
#import "fontconfig/FCFontEnumerator.h"
|
||||
|
||||
@interface OpalFontEnumerator : GSFontEnumerator
|
||||
@class OpalFaceInfo;
|
||||
|
||||
@interface OpalFontEnumerator : FCFontEnumerator
|
||||
{
|
||||
}
|
||||
|
||||
- (void) enumerateFontsAndFamilies;
|
||||
|
||||
+ (Class) faceInfoClass;
|
||||
+ (OpalFaceInfo *) fontWithName: (NSString *)name;
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
|
@ -28,16 +28,28 @@
|
|||
#ifndef OpalFontInfo_h_defined
|
||||
#define OpalFontInfo_h_defined
|
||||
|
||||
#import <GNUstepGUI/GSFontInfo.h>
|
||||
|
||||
@interface OpalFontInfo : GSFontInfo
|
||||
#include "fontconfig/FCFontInfo.h"
|
||||
#include "opal/OpalFaceInfo.h"
|
||||
#if 0
|
||||
#include <cairo.h>
|
||||
#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
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
#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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
@interface XGGLPixelFormat : NSOpenGLPixelFormat
|
||||
{
|
||||
Display * display;
|
||||
long int glxminorversion;
|
||||
int glxminorversion;
|
||||
|
||||
GLXFBConfig *fbconfig;
|
||||
int pickedFBConfig;
|
||||
|
|
|
@ -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--;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -29,84 +29,31 @@
|
|||
*/
|
||||
|
||||
#include "cairo/CairoFaceInfo.h"
|
||||
#include "cairo/CairoFontEnumerator.h"
|
||||
#include <cairo-ft.h>
|
||||
#include <AppKit/NSFontManager.h>
|
||||
|
||||
@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
|
||||
|
|
|
@ -28,850 +28,20 @@
|
|||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <Foundation/NSObject.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSSet.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
#include <Foundation/NSPathUtilities.h>
|
||||
#include <Foundation/NSFileManager.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSBundle.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <GNUstepGUI/GSFontInfo.h>
|
||||
#include <AppKit/NSAffineTransform.h>
|
||||
#include <AppKit/NSBezierPath.h>
|
||||
#include <AppKit/NSFontDescriptor.h>
|
||||
|
||||
#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; i<fontSet->nfont; 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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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...
|
||||
|
|
141
Source/fontconfig/FCFaceInfo.m
Normal file
141
Source/fontconfig/FCFaceInfo.m
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
FCFaceInfo.m
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
August 31, 2003
|
||||
Written by Banlu Kemiyatorn <object at gmail dot com>
|
||||
Base on original code of Alex Malmberg
|
||||
Rewrite: Fred Kiefer <fredkiefer@gmx.de>
|
||||
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 <http://www.gnu.org/licenses/> 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 <AppKit/NSFontManager.h>
|
||||
|
||||
@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
|
884
Source/fontconfig/FCFontEnumerator.m
Normal file
884
Source/fontconfig/FCFontEnumerator.m
Normal file
|
@ -0,0 +1,884 @@
|
|||
/*
|
||||
FCFontEnumerator.m
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
August 31, 2003
|
||||
Written by Banlu Kemiyatorn <object at gmail dot com>
|
||||
Base on original code of Alex Malmberg
|
||||
Rewrite: Fred Kiefer <fredkiefer@gmx.de>
|
||||
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 <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <Foundation/NSObject.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSSet.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
#include <Foundation/NSPathUtilities.h>
|
||||
#include <Foundation/NSFileManager.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSBundle.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <GNUstepGUI/GSFontInfo.h>
|
||||
#include <AppKit/NSAffineTransform.h>
|
||||
#include <AppKit/NSBezierPath.h>
|
||||
#include <AppKit/NSFontDescriptor.h>
|
||||
|
||||
#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; i<fontSet->nfont; 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
|
||||
|
174
Source/fontconfig/FCFontInfo.m
Normal file
174
Source/fontconfig/FCFontInfo.m
Normal file
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
FCFontInfo.m
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
August 31, 2003
|
||||
Written by Banlu Kemiyatorn <object at gmail dot com>
|
||||
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 <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "GNUstepBase/Unicode.h"
|
||||
#include <AppKit/NSAffineTransform.h>
|
||||
#include <AppKit/NSBezierPath.h>
|
||||
#include "fontconfig/FCFontInfo.h"
|
||||
#include "fontconfig/FCFontEnumerator.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "x11/XGInputServer.h"
|
||||
#include <X11/Xlocale.h>
|
||||
|
||||
#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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
415
configure
vendored
415
configure
vendored
|
@ -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
|
||||
|
|
65
configure.ac
65
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 <fedor@gnu.org>
|
||||
#
|
||||
|
@ -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
|
||||
|
|
|
@ -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 <bug-gnustep@gnu.org>
|
||||
Vendor: The GNUstep Project
|
||||
URL: http://www.gnustep.org/
|
||||
|
||||
%description
|
||||
This is a backend for the GNUstep gui Library which allows you to use
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue