mirror of
https://github.com/gnustep/libs-back.git
synced 2025-02-23 20:01:22 +00:00
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:
parent
b0eff28727
commit
a20f5d62ed
6 changed files with 657 additions and 12 deletions
|
@ -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
|
||||
|
|
65
Headers/xlib/XGFontSetFontInfo.h
Normal file
65
Headers/xlib/XGFontSetFontInfo.h
Normal 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
|
|
@ -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);
|
||||
//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 ++;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ XGFontManager.m \
|
|||
XGContext.m \
|
||||
XGGState.m \
|
||||
XGGeometry.m \
|
||||
XGFontSetFontInfo.m \
|
||||
linking.m
|
||||
|
||||
ifeq ($(WITH_XFT),yes)
|
||||
|
|
|
@ -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,15 +87,44 @@
|
|||
#endif
|
||||
}
|
||||
#endif
|
||||
enableFontSet = [[NSUserDefaults standardUserDefaults] boolForKey:
|
||||
@"GSXEnableFontSet"];
|
||||
if (fontClass == Nil)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
|
|
508
Source/xlib/XGFontSetFontInfo.m
Normal file
508
Source/xlib/XGFontSetFontInfo.m
Normal 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
|
Loading…
Reference in a new issue