New multi-byte support

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@17322 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Adam Fedor 2003-07-24 03:24:13 +00:00
parent b0eff28727
commit a20f5d62ed
6 changed files with 657 additions and 12 deletions

View file

@ -1,3 +1,11 @@
2003-07-22 Kazunobu Kuriyama <kazunobu.kuriyama@nifty.com>
* Headers/xlib/XGFontSetFontInfo.h: New file.
* Source/xlib/XGFontSetFontInfo.m: New file.
* Source/xlib/XGContext.m:
([XGContext +initializeBackend]): Modified to use XGFontSetFontInfo.
* Source/xlib/GNUmakefile: Modified to include XGFontSetFontInfo.m.
2003-07-22 Adam Fedor <fedor@gnu.org>
* Headers/x11/XGOpenGL.h (GSglxMinorVersion): New

View file

@ -0,0 +1,65 @@
/*
XGFontSetFontInfo.h
NSFont helper for GNUstep X/GPS Backend
Author: Kazunobu Kuriyama <kazunobu.kuriyama@nifty.com>
Date: July 2003
*/
#ifndef __XGFontSetFontInfo_h
#define __XGFontSetFontInfo_h
#include <X11/Xlib.h>
#include <AppKit/GSFontInfo.h>
#ifdef X_HAVE_UTF8_STRING
#if 0 // Commented out till the implementation completes.
// ----------------------------------------------------------------------------
// XGFontSetEnumerator
// ----------------------------------------------------------------------------
@interface XGFontSetEnumerator : GSFontEnumerator
{
}
- (void) enumerateFontsAndFamilies;
@end // XGFontSetEnumerator : GSFontEnumerator
#endif // #if 0
// ----------------------------------------------------------------------------
// XGFontSetFontInfo
// ----------------------------------------------------------------------------
@interface XGFontSetFontInfo : GSFontInfo
{
XFontSet _font_set;
XFontStruct **_fonts;
int _num_fonts;
}
- (id) initWithFontName: (NSString *)name
matrix: (const float *)matrix
screenFont: (BOOL)screenFont;
- (void) dealloc;
- (NSSize) advancementForGlyph: (NSGlyph)glyph;
- (NSRect) boundingRectForGlyph: (NSGlyph)glyph;
- (BOOL) glyphIsEncoded: (NSGlyph)glyph;
- (NSGlyph) glyphWithName: (NSString *)glyphName;
- (void) drawGlyphs: (const NSGlyph *)glyphs
lenght: (int)len
onDisplay: (Display *)dpy
drawable: (Drawable)win
with: (GC)gc
at: (XPoint)xp;
- (float) widthOfGlyphs: (const NSGlyph *)glyphs
lenght: (int)len;
- (void) setActiveFor: (Display *)dpy
gc: (GC)gc;
@end // XGFontSetFontInfo : GSFontInfo
#endif // X_HAVE_UTF8_STRING defined
#endif // __XGFontSetFontInfo_h

View file

@ -64,6 +64,7 @@
- (id)initWithAttributes:(NSOpenGLPixelFormatAttribute *)attribs
{
int v1, v2;
int AccumSize;
NSOpenGLPixelFormatAttribute *ptr = attribs;
NSMutableData *data = [NSMutableData data];
MAKE_DISPLAY(dpy);
@ -79,7 +80,12 @@
{
switch(*ptr)
{
// case NSOpenGLPFAAllRenderers:
// it means all the same on GLX - there is no diffrent here
case NSOpenGLPFASingleRenderer:
case NSOpenGLPFAAllRenderers:
case NSOpenGLPFAAccelerated:
append(GLX_USE_GL,YES);
break;
case NSOpenGLPFADoubleBuffer:
append(GLX_DOUBLEBUFFER, YES);
break;
@ -110,16 +116,44 @@
break;
case NSOpenGLPFAAccumSize:
ptr++;
//has to been tested - I did it in that way....
//FIXME? I don't understand...
append(GLX_ACCUM_RED_SIZE, *ptr/3);
append(GLX_ACCUM_GREEN_SIZE, *ptr/3);
append(GLX_ACCUM_BLUE_SIZE, *ptr/3);
break;
//append(GLX_ACCUM_RED_SIZE, *ptr/3);
//append(GLX_ACCUM_GREEN_SIZE, *ptr/3);
//append(GLX_ACCUM_BLUE_SIZE, *ptr/3);
AccumSize=*ptr;
switch (AccumSize){
case 8:
append(GLX_ACCUM_RED_SIZE, 3);
append(GLX_ACCUM_GREEN_SIZE, 3);
append(GLX_ACCUM_BLUE_SIZE, 2);
append(GLX_ACCUM_ALPHA_SIZE, 0);
break;
case 16:
append(GLX_ACCUM_RED_SIZE, 5);
append(GLX_ACCUM_GREEN_SIZE, 5);
append(GLX_ACCUM_BLUE_SIZE, 6);
append(GLX_ACCUM_ALPHA_SIZE, 0);
break;
case 24:
append(GLX_ACCUM_RED_SIZE, 8);
append(GLX_ACCUM_GREEN_SIZE, 8);
append(GLX_ACCUM_BLUE_SIZE, 8);
append(GLX_ACCUM_ALPHA_SIZE, 0);
break;
case 32:
append(GLX_ACCUM_RED_SIZE, 8);
append(GLX_ACCUM_GREEN_SIZE, 8);
append(GLX_ACCUM_BLUE_SIZE, 8);
append(GLX_ACCUM_ALPHA_SIZE, 8);
break;
};
break;
//can not be handle by X11
case NSOpenGLPFAMinimumPolicy:
//FIXME
break;
// can not be handle by X11
case NSOpenGLPFAMaximumPolicy:
//FIXME
break;
//FIXME all of this stuff...
@ -129,9 +163,7 @@
case NSOpenGLPFASamples:
case NSOpenGLPFAAuxDepthStencil:
case NSOpenGLPFARendererID:
case NSOpenGLPFASingleRenderer:
case NSOpenGLPFANoRecovery:
case NSOpenGLPFAAccelerated:
case NSOpenGLPFAClosestPolicy:
case NSOpenGLPFARobust:
case NSOpenGLPFABackingStore:
@ -143,7 +175,6 @@
case NSOpenGLPFAVirtualScreenCount:
break;
}
ptr ++;
}

View file

@ -43,6 +43,7 @@ XGFontManager.m \
XGContext.m \
XGGState.m \
XGGeometry.m \
XGFontSetFontInfo.m \
linking.m
ifeq ($(WITH_XFT),yes)

View file

@ -47,6 +47,8 @@
#include "xlib/GSXftFontInfo.h"
#endif
#include "xlib/XGFontSetFontInfo.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
@ -70,6 +72,7 @@
{
Class fontClass = Nil;
Class fontEnumerator = Nil;
BOOL enableFontSet;
NSDebugLog(@"Initializing GNUstep xlib backend.\n");
@ -84,14 +87,43 @@
#endif
}
#endif
enableFontSet = [[NSUserDefaults standardUserDefaults] boolForKey:
@"GSXEnableFontSet"];
if (fontClass == Nil)
{
fontClass = [XGFontInfo class];
if (enableFontSet == NO)
{
fontClass = [XGFontInfo class];
}
else
{
#ifdef X_HAVE_UTF8_STRING
fontClass = [XGFontSetFontInfo class];
#else
NSLog("Can't use GSXEnableFontSet: You need XFree86 >= 4.0.2");
fontClass = [XGFontInfo class];
#endif
}
}
[GSFontInfo setDefaultClass: fontClass];
if (fontEnumerator == Nil)
{
fontEnumerator = [XGFontEnumerator class];
if (enableFontSet == NO)
{
fontEnumerator = [XGFontEnumerator class];
}
else
{
#ifdef X_HAVE_UTF8_STRING
// Commented out till the implementation of XGFontSetEnumerator
// completes.
//fontEnumerator = [XGFontSetEnumerator class];
fontEnumerator = [XGFontEnumerator class];
#else
fontEnumerator = [XGFontEnumerator class];
#endif
}
}
[GSFontEnumerator setDefaultClass: fontEnumerator];
}

View file

@ -0,0 +1,508 @@
/*
XGFontSetFontInfo.m
NSFont helper for GNUstep X/GPS Backend
Author: Kazunobu Kuriyama <kazunobu.kuriyama@nifty.com>
Date: July 2003
*/
#include "x11/XGServer.h"
#include "xlib/XGPrivate.h"
#include "xlib/XGFontSetFontInfo.h"
#ifdef X_HAVE_UTF8_STRING
#define XSERVER [XGServer currentXDisplay]
typedef struct _UTF8Str {
char *data;
int size;
} UTF8Str;
#define UTF8StrData(x) ((x)->data)
#define UTF8StrSize(x) ((x)->size)
#define UTF8StrFree(x) \
do { \
if ((x)->data) \
{ \
free((x)->data); \
(x)->data = NULL; \
(x)->size = 0; \
} \
} while (0)
#define UTF8StrAlloc(x, length) \
do { (x)->data = malloc(6 * (length)); } while (0)
#define UTF8StrUsable(x) ((x)->data != NULL)
// Forward declarations
static BOOL load_font_set(Display *dpy, const char *given_font_name,
XFontSet *font_set,
XFontStruct ***fonts, int *num_fonts);
static BOOL glyphs2utf8(const NSGlyph* glyphs, int length, UTF8Str* ustr);
static BOOL char_struct_for_glyph(NSGlyph glyph, XFontSet font_set,
XFontStruct **fonts, int num_fonts,
XCharStruct *cs);
#if 0 // Commented out till the implementation completes.
// ----------------------------------------------------------------------------
// XGFontSetEnumerator
// ----------------------------------------------------------------------------
@implementation XGFontSetEnumerator : GSFontEnumerator
- (void) enumerateFontsAndFamilies
{ }
@end // XGFontSetEnumerator : GSFontEnumerator
#endif // #if 0
// ----------------------------------------------------------------------------
// XGFontSetFontInfo
// ----------------------------------------------------------------------------
@implementation XGFontSetFontInfo : GSFontInfo
- (id) initWithFontName: (NSString *)name
matrix: (const float *)fmatrix
screenFont: (BOOL)screenFont
{
Display *dpy;
XFontSet font_set;
XFontStruct **fonts;
XFontStruct *base;
int num_fonts;
if (screenFont)
{
RELEASE(self);
return nil;
}
if (!name || [name length] == 0 || (dpy = XSERVER) == NULL)
{
RELEASE(self);
return nil;
}
if (!load_font_set(dpy, [XGXFontName(name, fmatrix[0]) cString],
&font_set, &fonts, &num_fonts))
{
RELEASE(self);
return nil;
}
base = fonts[0];
// GSFontInfo part
[super init];
ASSIGN(fontName, name);
ASSIGN(familyName, XGFontFamily(dpy, base));
memcpy(matrix, fmatrix, sizeof(matrix));
italicAngle = 0;
underlinePosition = 0;
underlineThickness = 0;
capHeight = 0;
xHeight = 0;
descender = -base->descent;
ascender = base->ascent;
maximumAdvancement =
NSMakeSize(base->max_bounds.width,
base->max_bounds.ascent + base->max_bounds.descent);
minimumAdvancement = NSMakeSize(0, 0);
ASSIGN(encodingScheme, @"");
mostCompatibleStringEncoding = NSASCIIStringEncoding;
fontBBox =
NSMakeRect(base->min_bounds.lbearing,
-base->max_bounds.ascent,
base->max_bounds.rbearing - base->max_bounds.lbearing,
base->max_bounds.ascent + base->max_bounds.descent);
isFixedPitch = XGFontIsFixedPitch(dpy, base);
isBaseFont = NO;
weight = XGWeightOfFont(dpy, base);
traits = XGTraitsOfFont(dpy, base);
// XGFontSetFontInfo part
_font_set = font_set;
_fonts = fonts;
_num_fonts = num_fonts;
return self;
}
- (void) dealloc
{
if (_font_set)
{
XFreeFontSet(XSERVER, _font_set);
_font_set = NULL;
}
}
- (NSSize) advancementForGlyph: (NSGlyph)glyph
{
XCharStruct cs;
if (!char_struct_for_glyph(glyph, _font_set, _fonts, _num_fonts, &cs))
{
cs.width = _fonts[0]->max_bounds.width;
}
return NSMakeSize((float)cs.width, 0);
}
- (NSRect) boundingRectForGlyph: (NSGlyph)glyph
{
XCharStruct cs;
if (!char_struct_for_glyph(glyph, _font_set, _fonts, _num_fonts, &cs))
{
return fontBBox;
}
return NSMakeRect((float)cs.lbearing, (float)-cs.descent,
(float)(cs.rbearing - cs.lbearing),
(float)(cs.ascent + cs.descent));
}
- (BOOL) glyphIsEncoded: (NSGlyph)glyph
{
XCharStruct cs;
return char_struct_for_glyph(glyph, _font_set, _fonts, _num_fonts, &cs);
}
- (NSGlyph) glyphWithName: (NSString *)glyphName
{
KeySym k;
k = XStringToKeysym([glyphName cString]);
if (k == NoSymbol)
return 0;
else
return (NSGlyph)k;
}
- (void) drawGlyphs: (const NSGlyph *)glyphs
lenght: (int)len
onDisplay: (Display *)dpy
drawable: (Drawable)win
with: (GC)gc
at: (XPoint)xp
{
UTF8Str ustr;
if (glyphs2utf8(glyphs, len, &ustr))
{
Xutf8DrawString(dpy, win, _font_set, gc, xp.x, xp.y,
UTF8StrData(&ustr), UTF8StrSize(&ustr));
UTF8StrFree(&ustr);
}
}
- (float) widthOfGlyphs: (const NSGlyph *)glyphs
lenght: (int)len
{
UTF8Str ustr;
float val;
if (glyphs2utf8(glyphs, len, &ustr))
{
XRectangle logical;
Xutf8TextExtents(_font_set, UTF8StrData(&ustr), UTF8StrSize(&ustr),
NULL, &logical);
UTF8StrFree(&ustr);
val = logical.width;
}
else
{
val = 0.0;
}
return val;
}
- (void) setActiveFor: (Display *)dpy
gc: (GC)gc
{
// Do nothing.
}
@end // XGFontSetFontInfo : GSFontInfo
// ----------------------------------------------------------------------------
// Static Functions
// ----------------------------------------------------------------------------
static BOOL
load_font_set(Display *dpy, const char *given_font_name,
XFontSet *font_set, XFontStruct ***fonts, int *num_fonts)
{
int i;
char xlfd[256];
#ifndef STATIC_BUFFER_IS_RELIABLE
char *p;
#endif
int xlfd_num_elms;
BOOL has_add_style;
char *xlfd_elms[14];
char base_font_name[256];
char **missing_charsets;
int num_missing_charsets;
char *def_string;
char **font_names;
int num_font_names;
XFontStruct **font_structs;
if (!dpy || !given_font_name)
{
return NO;
}
strcpy(xlfd, given_font_name);
xlfd_num_elms = 14;
has_add_style = YES;
// Both of the following compilation branches, based on the switch
// 'STATIC_BUFFER_IS_RELIABLE', basically do the same thing. Because some
// people worry about making use of strtok(), the latter branch is used
// primarily unless the switch is explicitly defined somewhere. The former
// branch should document what the latter one does.
#ifdef STATIC_BUFFER_IS_RELIABLE
if (strstr(xlfd, "--"))
{
--xlfd_num_elms;
has_add_style = NO;
}
i = 0;
xlfd_elms[i++] = strtok(xlfd, "-");
while (i < xlfd_num_elms)
{
xlfd_elms[i++] = strtok(NULL, "-");
}
#else // 'STATIC_BUFFER_IS_RELIABLE' not defined
i = 0;
p = xlfd;
do
{
while (*p != '-')
++p;
*p = '\0';
if (*++p == '-') // The token is in the form of '--'.
{
*p++ = '\0';
--xlfd_num_elms;
has_add_style = NO;
}
xlfd_elms[i] = p;
}
while (++i < xlfd_num_elms && *p != '\0');
#endif // 'STATIC_BUFFER_IS_RELIABLE' not defined
// To let the X server determine a font set automatically, some elements
// of the XLFD should be replaced with the wild card.
//
// N.B. Rigorously speaking, to make use of proportional fonts, we need to
// define a mapping from NSGlyph to the XFontStruct's field 'per_char'.
// The property 'spacing' is set to "*" until such a mapping is given.
// (see also char_struct_for_glyph()).
if (has_add_style)
{
sprintf(base_font_name,
"-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
xlfd_elms[0], // foundry
"*", // family
xlfd_elms[2], // weight
xlfd_elms[3], // slant
xlfd_elms[4], // set width
xlfd_elms[5], // add style
xlfd_elms[6], // pixel size
xlfd_elms[7], // point size
xlfd_elms[8], // resolutionX
xlfd_elms[9], // resolutionY
"*", // spacing
xlfd_elms[11], // avg width
"*", // registry
"*" // encoding
);
}
else
{
sprintf(base_font_name,
"-%s-%s-%s-%s-%s--%s-%s-%s-%s-%s-%s-%s-%s",
xlfd_elms[0], // foundry
"*", // family
xlfd_elms[2], // weight
xlfd_elms[3], // slant
xlfd_elms[4], // set width
xlfd_elms[5], // pixel size
xlfd_elms[6], // point size
xlfd_elms[7], // resolutionX
xlfd_elms[8], // resolutionY
"*", // spacing
xlfd_elms[10], // avg width
"*", // registry
"*" // encoding
);
}
// N.B. def_string is owned by the X server: Don't release it.
missing_charsets = NULL;
num_missing_charsets = 0;
def_string = NULL;
*font_set = NULL;
*font_set = XCreateFontSet(dpy, base_font_name,
&missing_charsets,
&num_missing_charsets,
&def_string);
if (!*font_set)
{
NSLog(@"XGFontSetFontInfo: Can't create a font set\n");
return NO;
}
if (num_missing_charsets > 0)
{
for (i = 0; i < num_missing_charsets; ++i)
{
NSLog(@"XGFontSetFontInfo: Charset %s is not available\n",
missing_charsets[i]);
}
XFreeStringList(missing_charsets);
missing_charsets = NULL;
num_missing_charsets = 0;
}
// N.B. font_structs and font_names are owned by the X server: Don't
// release them.
num_font_names = 0;
font_structs = NULL;
font_names = NULL;
num_font_names = XFontsOfFontSet(*font_set, &font_structs, &font_names);
if (!num_font_names)
{
NSLog(@"XGFontSetFontInfo: "
@"Can't get any information from the font set\n");
return NO;
}
*fonts = font_structs;
*num_fonts = num_font_names;
return YES;
}
// N.B. Use UTF8StrFree() to release the space pointed to by 'ustr'.
static BOOL
glyphs2utf8(const NSGlyph* glyphs, int length, UTF8Str* ustr)
{
int i;
NSGlyph *g;
NSGlyph *end;
char *p;
if (!glyphs || !length)
{
return NO;
}
UTF8StrAlloc(ustr, length);
if (!UTF8StrUsable(ustr))
{
return NO;
}
p = UTF8StrData(ustr);
i = 0;
for (g = (NSGlyph *)glyphs, end = (NSGlyph *)glyphs + length; g < end; ++g)
{
if (*g < 0x00000080)
{
p[i++] = *g;
}
else if (*g < 0x00000800)
{
p[i++] = 0xc0 | ((*g >> 6) & 0x1f);
p[i++] = 0x80 | ( *g & 0x3f);
}
else if (*g < 0x00010000)
{
p[i++] = 0xe0 | ((*g >> 12) & 0x0f);
p[i++] = 0x80 | ((*g >> 6) & 0x3f);
p[i++] = 0x80 | ( *g & 0x3f);
}
else if (*g < 0x00200000)
{
p[i++] = 0xf0 | ((*g >> 18) & 0x07);
p[i++] = 0x80 | ((*g >> 12) & 0x3f);
p[i++] = 0x80 | ((*g >> 6) & 0x3f);
p[i++] = 0x80 | ( *g & 0x3f);
}
else if (*g < 0x04000000)
{
p[i++] = 0xf8 | ((*g >> 24) & 0x03);
p[i++] = 0x80 | ((*g >> 18) & 0x3f);
p[i++] = 0x80 | ((*g >> 12) & 0x3f);
p[i++] = 0x80 | ((*g >> 6) & 0x3f);
p[i++] = 0x80 | ( *g & 0x3f);
}
else if (*g < 0x80000000)
{
p[i++] = 0xfc | ((*g >> 30) & 0x01);
p[i++] = 0x80 | ((*g >> 24) & 0x3f);
p[i++] = 0x80 | ((*g >> 18) & 0x3f);
p[i++] = 0x80 | ((*g >> 12) & 0x3f);
p[i++] = 0x80 | ((*g >> 6) & 0x3f);
p[i++] = 0x80 | ( *g & 0x3f);
}
else
{
// Out of range
UTF8StrFree(ustr);
return NO;
}
}
UTF8StrSize(ustr) = i;
return YES;
}
static BOOL
char_struct_for_glyph(NSGlyph glyph, XFontSet font_set,
XFontStruct **fonts, int num_fonts,
XCharStruct *cs)
{
UTF8Str utf8char;
if (glyphs2utf8(&glyph, 1, &utf8char))
{
XRectangle ink, logical;
int num_chars;
Xutf8TextPerCharExtents(font_set,
UTF8StrData(&utf8char), UTF8StrSize(&utf8char),
&ink, &logical, 1, &num_chars, NULL, NULL);
UTF8StrFree(&utf8char);
if (num_chars != 1)
{
return NO;
}
// When the font in use is proportional, the following variables should
// be tuned finer based on the the XFontStruct's field 'per_char'.
cs->lbearing = 0;
cs->rbearing = 0;
cs->width = logical.width;
cs->ascent = fonts[0]->max_bounds.ascent;
cs->descent = fonts[0]->max_bounds.descent;
cs->attributes = 0;
return YES;
}
else
{
return NO;
}
}
#endif // X_HAVE_UTF8_STRING defined