mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 15:31:14 +00:00
Moved ligature handling code from art to gui. Small improvements for
other font classes. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@26431 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
cdae5f32e9
commit
5a01087f39
5 changed files with 202 additions and 537 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2008-04-04 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/winlib/WIN32FontInfo.m
|
||||
(-appendBezierPathWithGlyphs:count:toBezierPath:): New method.
|
||||
Patch by Christopher Armstrong <carmstrong@fastmail.com.au>.
|
||||
* Source/art/ftfont.m,
|
||||
* Source/art/ftfont-old.m: Moved ligature handling code from here
|
||||
to gui.
|
||||
* Source/cairo/CairoFontInfo.m (-glyphIsEncoded:): Report all
|
||||
ligatures as not supported, as we have no way to determine if they
|
||||
exist in the font.
|
||||
|
||||
2008-04-03 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/cairo/CairoFontInfo.m (-appendBezierPathWithGlyphs:...):
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSBundle.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <GNUstepBase/Unicode.h>
|
||||
|
||||
#include <GNUstepGUI/GSFontInfo.h>
|
||||
#include <AppKit/NSAffineTransform.h>
|
||||
#include <AppKit/NSBezierPath.h>
|
||||
|
@ -105,11 +107,6 @@ static int subpixel_text;
|
|||
unsigned int cachedGlyph[CACHE_SIZE];
|
||||
NSSize cachedSize[CACHE_SIZE];
|
||||
|
||||
|
||||
/* Glyph generation */
|
||||
NSGlyph ligature_ff,ligature_fi,ligature_fl,ligature_ffl,ligature_ffi;
|
||||
|
||||
|
||||
float lineHeight;
|
||||
}
|
||||
@end
|
||||
|
@ -258,24 +255,6 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, FT_Pointer data, FT_
|
|||
fontBBox.origin.x, fontBBox.origin.y,
|
||||
fontBBox.size.width, fontBBox.size.height);*/
|
||||
|
||||
{
|
||||
FTC_CMapDescRec cmap;
|
||||
cmap.face_id = imgd.font.face_id;
|
||||
cmap.u.encoding = ft_encoding_unicode;
|
||||
cmap.type = FTC_CMAP_BY_ENCODING;
|
||||
ligature_ff = FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, 0xfb00);
|
||||
ligature_fi = FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, 0xfb01);
|
||||
ligature_fl = FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, 0xfb02);
|
||||
ligature_ffi = FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, 0xfb03);
|
||||
ligature_ffl = FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, 0xfb04);
|
||||
/* printf("ligatures %04x %04x %04x %04x %04x | %02x %02x %02x for |%@|\n",
|
||||
ligature_ff,ligature_fi,ligature_fl,ligature_ffi,ligature_ffl,
|
||||
FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, 'f'),
|
||||
FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, 'l'),
|
||||
FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, 'i'),
|
||||
fontName);*/
|
||||
}
|
||||
|
||||
{
|
||||
float xx, yy;
|
||||
#ifdef FT212_STUFF
|
||||
|
@ -362,8 +341,6 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, FT_Pointer data, FT_
|
|||
}
|
||||
|
||||
|
||||
#include <GNUstepBase/Unicode.h>
|
||||
|
||||
/* TODO: the current point probably needs updating after drawing is done */
|
||||
|
||||
/* draw string at point, clipped, w/given color and alpha, and possible deltas:
|
||||
|
@ -2364,6 +2341,22 @@ static int filters[3][7]=
|
|||
}
|
||||
}
|
||||
|
||||
-(NSGlyph) glyphForCharacter: (unichar)ch
|
||||
{
|
||||
NSGlyph g;
|
||||
|
||||
FTC_CMapDescRec cmap;
|
||||
|
||||
cmap.face_id = imgd.font.face_id;
|
||||
cmap.u.encoding = ft_encoding_unicode;
|
||||
cmap.type = FTC_CMAP_BY_ENCODING;
|
||||
|
||||
g = FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, ch);
|
||||
if (g)
|
||||
return g + 1;
|
||||
else
|
||||
return NSNullGlyph;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
@ -2748,242 +2741,6 @@ static int filters[3][7]=
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@interface NSFont (backend)
|
||||
-(NSGlyph) glyphForCharacter: (unichar)ch;
|
||||
-(NSString *) nameOfGlyph: (NSGlyph)glyph;
|
||||
@end
|
||||
|
||||
@implementation NSFont (backend)
|
||||
-(NSGlyph) glyphForCharacter: (unichar)ch
|
||||
{
|
||||
FTFontInfo *fi=fontInfo;
|
||||
NSGlyph g;
|
||||
|
||||
FTC_CMapDescRec cmap;
|
||||
|
||||
cmap.face_id = fi->imgd.font.face_id;
|
||||
cmap.u.encoding = ft_encoding_unicode;
|
||||
cmap.type = FTC_CMAP_BY_ENCODING;
|
||||
|
||||
g = FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, ch);
|
||||
if (g)
|
||||
return g + 1;
|
||||
else
|
||||
return NSNullGlyph;
|
||||
}
|
||||
|
||||
-(NSString *) nameOfGlyph: (NSGlyph)glyph
|
||||
{
|
||||
FTFontInfo *fi=fontInfo;
|
||||
FT_Face face;
|
||||
|
||||
char buf[256];
|
||||
|
||||
glyph--;
|
||||
|
||||
if (FTC_Manager_Lookup_Size(ftc_manager, &fi->imgd.font, &face, 0))
|
||||
return nil;
|
||||
|
||||
if (FT_Get_Glyph_Name(face,glyph,buf,sizeof(buf)))
|
||||
return nil;
|
||||
|
||||
return [NSString stringWithCString: buf]; /* TODO: really cstring? */
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
/*
|
||||
GSLayoutManager glyph generation code.
|
||||
|
||||
TODO: clean this up
|
||||
*/
|
||||
#include <Foundation/NSCharacterSet.h>
|
||||
#include <GNUstepGUI/GSLayoutManager_internal.h>
|
||||
#include <AppKit/NSTextStorage.h>
|
||||
#include <AppKit/NSTextAttachment.h>
|
||||
|
||||
@implementation GSLayoutManager (backend)
|
||||
|
||||
/*
|
||||
This is a fairly simple implementation. It will use "ff", "fl", "fi",
|
||||
"ffl", and "ffi" ligatures if available. If a glyph for a character isn't
|
||||
available, it will try to decompose it before giving up.
|
||||
|
||||
TODO: how should words like "pfffffffffff" be handled?
|
||||
|
||||
0066 'f'
|
||||
0069 'i'
|
||||
006c 'l'
|
||||
fb00 'ff'
|
||||
fb01 'fi'
|
||||
fb02 'fl'
|
||||
fb03 'ffi'
|
||||
fb04 'ffl'
|
||||
*/
|
||||
|
||||
-(unsigned int) _findSafeBreakMovingBackwardFrom: (unsigned int)ch
|
||||
{
|
||||
NSString *str=[_textStorage string];
|
||||
while (ch>0 && [str characterAtIndex: ch-1]=='f')
|
||||
ch--;
|
||||
return ch;
|
||||
}
|
||||
|
||||
-(unsigned int) _findSafeBreakMovingForwardFrom: (unsigned int)ch
|
||||
{
|
||||
unsigned int l=[_textStorage length];
|
||||
NSString *str=[_textStorage string];
|
||||
while (ch<l && [str characterAtIndex: ch]=='f')
|
||||
ch++;
|
||||
if (ch<l && ch>0 && [str characterAtIndex: ch-1]=='f')
|
||||
ch++;
|
||||
return ch;
|
||||
}
|
||||
|
||||
-(void) _generateGlyphsForRun: (glyph_run_t *)run at: (unsigned int)pos
|
||||
{
|
||||
glyph_t *g;
|
||||
unsigned int glyph_size;
|
||||
unsigned int i,j;
|
||||
unsigned int ch,ch2,ch3;
|
||||
|
||||
FTFontInfo *fi=[run->font fontInfo];
|
||||
FTC_CMapDescRec cmap;
|
||||
|
||||
NSCharacterSet *cs=[NSCharacterSet controlCharacterSet];
|
||||
IMP characterIsMember=[cs methodForSelector: @selector(characterIsMember:)];
|
||||
|
||||
unsigned int c=run->head.char_length;
|
||||
unichar buf[c];
|
||||
|
||||
|
||||
[[_textStorage string] getCharacters: buf
|
||||
range: NSMakeRange(pos,c)];
|
||||
|
||||
cmap.face_id = fi->imgd.font.face_id;
|
||||
cmap.u.encoding = ft_encoding_unicode;
|
||||
cmap.type = FTC_CMAP_BY_ENCODING;
|
||||
|
||||
/* first guess */
|
||||
glyph_size=c;
|
||||
g=run->glyphs=malloc(sizeof(glyph_t)*glyph_size);
|
||||
memset(g,0,sizeof(glyph_t)*glyph_size);
|
||||
|
||||
for (i=j=0;i<c;i++,g++,j++)
|
||||
{
|
||||
ch=buf[i];
|
||||
ch2=ch3=0;
|
||||
if (i+1<c)
|
||||
{
|
||||
ch2=buf[i+1];
|
||||
if (i+2<c)
|
||||
ch3=buf[i+2];
|
||||
}
|
||||
|
||||
g->char_offset=i;
|
||||
if (characterIsMember(cs,@selector(characterIsMember:),ch))
|
||||
{
|
||||
g->g=NSControlGlyph;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == NSAttachmentCharacter)
|
||||
{
|
||||
g->g=GSAttachmentGlyph;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (run->ligature>=1)
|
||||
{
|
||||
if (ch=='f' && ch2=='f' && ch3=='l' && fi->ligature_ffl)
|
||||
{
|
||||
g->g=fi->ligature_ffl + 1;
|
||||
i+=2;
|
||||
continue;
|
||||
}
|
||||
if (ch=='f' && ch2=='f' && ch3=='i' && fi->ligature_ffi)
|
||||
{
|
||||
g->g=fi->ligature_ffi + 1;
|
||||
i+=2;
|
||||
continue;
|
||||
}
|
||||
if (ch=='f' && ch2=='f' && fi->ligature_ff)
|
||||
{
|
||||
g->g=fi->ligature_ff + 1;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (ch=='f' && ch2=='i' && fi->ligature_fi)
|
||||
{
|
||||
g->g=fi->ligature_fi + 1;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (ch=='f' && ch2=='l' && fi->ligature_fl)
|
||||
{
|
||||
g->g=fi->ligature_fl + 1;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch>=0xd800 && ch<=0xdfff)
|
||||
{
|
||||
if (ch >= 0xd800 && ch < 0xdc00 && ch2 >= 0xdc00 && ch2 <= 0xdfff)
|
||||
{
|
||||
ch = ((ch & 0x3ff) << 10) + (ch2 & 0x3ff) + 0x10000;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
ch = 0xfffd;
|
||||
}
|
||||
|
||||
g->g=FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, ch) + 1;
|
||||
|
||||
if (g->g == 1 && ch<0x10000)
|
||||
{
|
||||
unichar *decomp;
|
||||
decomp=uni_is_decomp(ch);
|
||||
if (decomp)
|
||||
{
|
||||
int c=0;
|
||||
for (;*decomp;decomp++)
|
||||
{
|
||||
glyph_size++;
|
||||
run->glyphs=realloc(run->glyphs,sizeof(glyph_t)*glyph_size);
|
||||
g=run->glyphs+j;
|
||||
memset(&run->glyphs[glyph_size-1],0,sizeof(glyph_t));
|
||||
|
||||
g->g=FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, *decomp) + 1;
|
||||
if (g->g == 1)
|
||||
break;
|
||||
c++;
|
||||
g++;
|
||||
j++;
|
||||
g->char_offset=i;
|
||||
}
|
||||
if (*decomp)
|
||||
{
|
||||
g-=c;
|
||||
j-=c;
|
||||
g->g=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
g--;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: shrink allocated array if possible */
|
||||
run->head.glyph_length=j;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@interface FTFontInfo (experimental_glyph_printing_extension)
|
||||
-(const char *) nameOfGlyph: (NSGlyph)g;
|
||||
@end
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSBundle.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <GNUstepBase/Unicode.h>
|
||||
|
||||
#include <GNUstepGUI/GSFontInfo.h>
|
||||
#include <AppKit/NSAffineTransform.h>
|
||||
#include <AppKit/NSBezierPath.h>
|
||||
|
@ -111,11 +113,6 @@ static int subpixel_text;
|
|||
unsigned int cachedGlyph[CACHE_SIZE];
|
||||
NSSize cachedSize[CACHE_SIZE];
|
||||
|
||||
|
||||
/* Glyph generation */
|
||||
NSGlyph ligature_ff,ligature_fi,ligature_fl,ligature_ffl,ligature_ffi;
|
||||
|
||||
|
||||
float lineHeight;
|
||||
}
|
||||
@end
|
||||
|
@ -162,9 +159,10 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, FT_Pointer data, FT_
|
|||
|
||||
|
||||
@implementation FTFontInfo
|
||||
|
||||
- (id) initWithFontName: (NSString *)name
|
||||
matrix: (const float *)fmatrix
|
||||
screenFont: (BOOL)p_screenFont
|
||||
matrix: (const float *)fmatrix
|
||||
screenFont: (BOOL)p_screenFont
|
||||
{
|
||||
NSArray *rfi;
|
||||
FTFaceInfo *font_entry;
|
||||
|
@ -251,7 +249,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, FT_Pointer data, FT_
|
|||
if ((error = FTC_Manager_LookupSize(ftc_manager, &scaler, &ft_size)))
|
||||
{
|
||||
NSLog(@"FTC_Manager_LookupSize() failed for '%@', error %08x!",
|
||||
name, error);
|
||||
name, error);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -291,24 +289,6 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, FT_Pointer data, FT_
|
|||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
ligature_ff
|
||||
= FTC_CMapCache_Lookup(ftc_cmapcache, faceId, unicodeCmap, 0xfb00);
|
||||
ligature_fi
|
||||
= FTC_CMapCache_Lookup(ftc_cmapcache, faceId, unicodeCmap, 0xfb01);
|
||||
ligature_fl
|
||||
= FTC_CMapCache_Lookup(ftc_cmapcache, faceId, unicodeCmap, 0xfb02);
|
||||
ligature_ffi
|
||||
= FTC_CMapCache_Lookup(ftc_cmapcache, faceId, unicodeCmap, 0xfb03);
|
||||
ligature_ffl
|
||||
= FTC_CMapCache_Lookup(ftc_cmapcache, faceId, unicodeCmap, 0xfb04);
|
||||
/* printf("ligatures %04x %04x %04x %04x %04x | %02x %02x %02x for |%@|\n",
|
||||
ligature_ff,ligature_fi,ligature_fl,ligature_ffi,ligature_ffl,
|
||||
FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, 'f'),
|
||||
FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, 'l'),
|
||||
FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, 'i'),
|
||||
fontName);*/
|
||||
}
|
||||
|
||||
if (screenFont)
|
||||
{
|
||||
|
@ -429,8 +409,6 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, FT_Pointer data, FT_
|
|||
return numberOfGlyphs;
|
||||
}
|
||||
|
||||
#include <GNUstepBase/Unicode.h>
|
||||
|
||||
/* TODO: the current point probably needs updating after drawing is done */
|
||||
|
||||
/* draw string at point, clipped, w/given color and alpha, and possible deltas:
|
||||
|
@ -2253,6 +2231,16 @@ static int filters[3][7]=
|
|||
}
|
||||
}
|
||||
|
||||
- (NSGlyph) glyphForCharacter: (unichar)ch
|
||||
{
|
||||
NSGlyph g;
|
||||
|
||||
g = FTC_CMapCache_Lookup(ftc_cmapcache, faceId, unicodeCmap, ch);
|
||||
if (g)
|
||||
return g + 1;
|
||||
else
|
||||
return NSNullGlyph;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
@ -2623,233 +2611,6 @@ static int filters[3][7]=
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@interface NSFont (backend)
|
||||
- (NSGlyph) glyphForCharacter: (unichar)ch;
|
||||
- (NSString *) nameOfGlyph: (NSGlyph)glyph;
|
||||
@end
|
||||
|
||||
@implementation NSFont (backend)
|
||||
- (NSGlyph) glyphForCharacter: (unichar)ch
|
||||
{
|
||||
FTFontInfo *fi=fontInfo;
|
||||
NSGlyph g;
|
||||
|
||||
g = FTC_CMapCache_Lookup(ftc_cmapcache, fi->faceId, fi->unicodeCmap, ch);
|
||||
if (g)
|
||||
return g + 1;
|
||||
else
|
||||
return NSNullGlyph;
|
||||
}
|
||||
|
||||
- (NSString *) nameOfGlyph: (NSGlyph)glyph
|
||||
{
|
||||
FTFontInfo *fi=fontInfo;
|
||||
FT_Face face;
|
||||
FT_Size size;
|
||||
|
||||
char buf[256];
|
||||
|
||||
glyph--;
|
||||
|
||||
if (FTC_Manager_LookupSize(ftc_manager, &fi->scaler, &size))
|
||||
return nil;
|
||||
face = size->face;
|
||||
|
||||
if (FT_Get_Glyph_Name(face,glyph,buf,sizeof(buf)))
|
||||
return nil;
|
||||
|
||||
return [NSString stringWithCString: buf]; /* TODO: really cstring? */
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
/*
|
||||
GSLayoutManager glyph generation code.
|
||||
|
||||
TODO: clean this up
|
||||
*/
|
||||
#include <Foundation/NSCharacterSet.h>
|
||||
#include <GNUstepGUI/GSLayoutManager_internal.h>
|
||||
#include <AppKit/NSTextStorage.h>
|
||||
#include <AppKit/NSTextAttachment.h>
|
||||
|
||||
@implementation GSLayoutManager (backend)
|
||||
|
||||
/*
|
||||
This is a fairly simple implementation. It will use "ff", "fl", "fi",
|
||||
"ffl", and "ffi" ligatures if available. If a glyph for a character isn't
|
||||
available, it will try to decompose it before giving up.
|
||||
|
||||
TODO: how should words like "pfffffffffff" be handled?
|
||||
|
||||
0066 'f'
|
||||
0069 'i'
|
||||
006c 'l'
|
||||
fb00 'ff'
|
||||
fb01 'fi'
|
||||
fb02 'fl'
|
||||
fb03 'ffi'
|
||||
fb04 'ffl'
|
||||
*/
|
||||
|
||||
- (unsigned int) _findSafeBreakMovingBackwardFrom: (unsigned int)ch
|
||||
{
|
||||
NSString *str=[_textStorage string];
|
||||
while (ch>0 && [str characterAtIndex: ch-1]=='f')
|
||||
ch--;
|
||||
return ch;
|
||||
}
|
||||
|
||||
- (unsigned int) _findSafeBreakMovingForwardFrom: (unsigned int)ch
|
||||
{
|
||||
unsigned int l=[_textStorage length];
|
||||
NSString *str=[_textStorage string];
|
||||
while (ch<l && [str characterAtIndex: ch]=='f')
|
||||
ch++;
|
||||
if (ch<l && ch>0 && [str characterAtIndex: ch-1]=='f')
|
||||
ch++;
|
||||
return ch;
|
||||
}
|
||||
|
||||
- (void) _generateGlyphsForRun: (glyph_run_t *)run at: (unsigned int)pos
|
||||
{
|
||||
glyph_t *g;
|
||||
unsigned int glyph_size;
|
||||
unsigned int i,j;
|
||||
unsigned int ch,ch2,ch3;
|
||||
|
||||
FTFontInfo *fi = (FTFontInfo *)[run->font fontInfo];
|
||||
|
||||
NSCharacterSet *cs = [NSCharacterSet controlCharacterSet];
|
||||
IMP characterIsMember = [cs methodForSelector: @selector(characterIsMember:)];
|
||||
|
||||
unsigned int c=run->head.char_length;
|
||||
unichar buf[c];
|
||||
|
||||
|
||||
[[_textStorage string] getCharacters: buf
|
||||
range: NSMakeRange(pos,c)];
|
||||
|
||||
/* first guess */
|
||||
glyph_size=c;
|
||||
g=run->glyphs=malloc(sizeof(glyph_t)*glyph_size);
|
||||
memset(g,0,sizeof(glyph_t)*glyph_size);
|
||||
|
||||
for (i=j=0;i<c;i++,g++,j++)
|
||||
{
|
||||
ch=buf[i];
|
||||
ch2=ch3=0;
|
||||
if (i+1<c)
|
||||
{
|
||||
ch2=buf[i+1];
|
||||
if (i+2<c)
|
||||
ch3=buf[i+2];
|
||||
}
|
||||
|
||||
g->char_offset=i;
|
||||
if (characterIsMember(cs,@selector(characterIsMember:),ch))
|
||||
{
|
||||
g->g=NSControlGlyph;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == NSAttachmentCharacter)
|
||||
{
|
||||
g->g=GSAttachmentGlyph;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (run->ligature>=1)
|
||||
{
|
||||
if (ch=='f' && ch2=='f' && ch3=='l' && fi->ligature_ffl)
|
||||
{
|
||||
g->g=fi->ligature_ffl + 1;
|
||||
i+=2;
|
||||
continue;
|
||||
}
|
||||
if (ch=='f' && ch2=='f' && ch3=='i' && fi->ligature_ffi)
|
||||
{
|
||||
g->g=fi->ligature_ffi + 1;
|
||||
i+=2;
|
||||
continue;
|
||||
}
|
||||
if (ch=='f' && ch2=='f' && fi->ligature_ff)
|
||||
{
|
||||
g->g=fi->ligature_ff + 1;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (ch=='f' && ch2=='i' && fi->ligature_fi)
|
||||
{
|
||||
g->g=fi->ligature_fi + 1;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (ch=='f' && ch2=='l' && fi->ligature_fl)
|
||||
{
|
||||
g->g=fi->ligature_fl + 1;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch>=0xd800 && ch<=0xdfff)
|
||||
{
|
||||
if (ch >= 0xd800 && ch < 0xdc00 && ch2 >= 0xdc00 && ch2 <= 0xdfff)
|
||||
{
|
||||
ch = ((ch & 0x3ff) << 10) + (ch2 & 0x3ff) + 0x10000;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
ch = 0xfffd;
|
||||
}
|
||||
|
||||
g->g=FTC_CMapCache_Lookup(ftc_cmapcache, fi->faceId, fi->unicodeCmap, ch) + 1;
|
||||
|
||||
if (g->g == 1 && ch<0x10000)
|
||||
{
|
||||
unichar *decomp;
|
||||
decomp = uni_is_decomp(ch);
|
||||
if (decomp)
|
||||
{
|
||||
int c=0;
|
||||
for (;*decomp;decomp++)
|
||||
{
|
||||
glyph_size++;
|
||||
run->glyphs=realloc(run->glyphs,sizeof(glyph_t)*glyph_size);
|
||||
g=run->glyphs+j;
|
||||
memset(&run->glyphs[glyph_size-1],0,sizeof(glyph_t));
|
||||
|
||||
g->g = FTC_CMapCache_Lookup(ftc_cmapcache, fi->faceId, fi->unicodeCmap, *decomp) + 1;
|
||||
if (g->g == 1)
|
||||
break;
|
||||
c++;
|
||||
g++;
|
||||
j++;
|
||||
g->char_offset=i;
|
||||
}
|
||||
if (*decomp)
|
||||
{
|
||||
g-=c;
|
||||
j-=c;
|
||||
g->g=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
g--;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: shrink allocated array if possible */
|
||||
run->head.glyph_length=j;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@interface FTFontInfo (experimental_glyph_printing_extension)
|
||||
- (const char *) nameOfGlyph: (NSGlyph)g;
|
||||
@end
|
||||
|
|
|
@ -175,8 +175,15 @@
|
|||
|
||||
- (BOOL) glyphIsEncoded: (NSGlyph)glyph
|
||||
{
|
||||
/* subclass should override */
|
||||
return YES;
|
||||
/* FIXME: There is no proper way to determine with the toy font API,
|
||||
whether a glyph is supported or not. We will just ignore ligatures
|
||||
and report all other glyph as existing.
|
||||
return !NSEqualSizes([self advancementForGlyph: glyph], NSZeroSize);
|
||||
*/
|
||||
if ((glyph >= 0xFB00) && (glyph <= 0xFB05))
|
||||
return NO;
|
||||
else
|
||||
return YES;
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -459,5 +466,5 @@ BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph,
|
|||
cairo_status_to_string(cairo_status(ct)), str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
#include <AppKit/NSBezierPath.h>
|
||||
|
||||
#include "winlib/WIN32FontInfo.h"
|
||||
|
||||
|
@ -80,14 +81,14 @@ NSString *win32_font_family(NSString *fontName);
|
|||
HDC hdc;
|
||||
HFONT old;
|
||||
|
||||
hdc = GetDC(NULL);
|
||||
hdc = CreateCompatibleDC(NULL);
|
||||
old = SelectObject(hdc, hFont);
|
||||
GetTextExtentPoint32W(hdc,
|
||||
(const unichar*)[string cStringUsingEncoding: NSUnicodeStringEncoding],
|
||||
[string length],
|
||||
&size);
|
||||
SelectObject(hdc, old);
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteDC(hdc);
|
||||
|
||||
return size.cx;
|
||||
}
|
||||
|
@ -105,12 +106,12 @@ NSString *win32_font_family(NSString *fontName);
|
|||
ABCFLOAT abc;
|
||||
HFONT old;
|
||||
|
||||
hdc = GetDC(NULL);
|
||||
hdc = CreateCompatibleDC(NULL);
|
||||
old = SelectObject(hdc, hFont);
|
||||
// FIXME ... currently a gnustep glyph is a unichar ... what if that changes.
|
||||
GetCharABCWidthsFloatW(hdc, u, u, &abc);
|
||||
SelectObject(hdc, old);
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteDC(hdc);
|
||||
|
||||
//NSLog(@"Width for %d is %f or %f", glyph, w, (abc.abcfA + abc.abcfB + abc.abcfC));
|
||||
w = abc.abcfA + abc.abcfB + abc.abcfC;
|
||||
|
@ -126,13 +127,13 @@ NSString *win32_font_family(NSString *fontName);
|
|||
GLYPHMETRICS gm;
|
||||
NSRect rect;
|
||||
|
||||
hdc = GetDC(NULL);
|
||||
hdc = CreateCompatibleDC(NULL);
|
||||
old = SelectObject(hdc, hFont);
|
||||
// Convert from GNUstep glyph (unichar) to windows glyph.
|
||||
if (GetGlyphIndicesW(hdc, &c, 1, &windowsGlyph, 0) == GDI_ERROR)
|
||||
{
|
||||
SelectObject(hdc, old);
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteDC(hdc);
|
||||
NSLog(@"No glyph for U%d", c);
|
||||
return NSMakeRect(0, 0, 0, 0); // No such glyph
|
||||
}
|
||||
|
@ -150,14 +151,30 @@ NSLog(@"No glyph for U%d", c);
|
|||
}
|
||||
|
||||
SelectObject(hdc, old);
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteDC(hdc);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (BOOL) glyphIsEncoded: (NSGlyph)glyph
|
||||
{
|
||||
return YES;
|
||||
WORD c = (WORD)glyph;
|
||||
WORD windowsGlyph;
|
||||
HDC hdc;
|
||||
HFONT old;
|
||||
BOOL result = YES;
|
||||
|
||||
hdc = CreateCompatibleDC(NULL);
|
||||
old = SelectObject(hdc, hFont);
|
||||
// Convert from GNUstep glyph (unichar) to windows glyph.
|
||||
if ((GetGlyphIndicesW(hdc, &c, 1, &windowsGlyph, 0) == GDI_ERROR)
|
||||
|| (windowsGlyph == 0xFFFF))
|
||||
{
|
||||
result = NO;
|
||||
}
|
||||
SelectObject(hdc, old);
|
||||
DeleteDC(hdc);
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSGlyph) glyphWithName: (NSString*)glyphName
|
||||
|
@ -183,7 +200,7 @@ NSLog(@"No glyph for U%d", c);
|
|||
HFONT old;
|
||||
|
||||
ms = [NSMutableCharacterSet new];
|
||||
hdc = GetDC(NULL);
|
||||
hdc = CreateCompatibleDC(NULL);
|
||||
old = SelectObject(hdc, hFont);
|
||||
count = (unsigned)GetFontUnicodeRanges(hdc, 0);
|
||||
if (count > 0)
|
||||
|
@ -218,7 +235,7 @@ NSLog(@"No glyph for U%d", c);
|
|||
objc_free(gs);
|
||||
}
|
||||
SelectObject(hdc, old);
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteDC(hdc);
|
||||
coveredCharacterSet = [ms copy];
|
||||
RELEASE(ms);
|
||||
}
|
||||
|
@ -227,8 +244,8 @@ NSLog(@"No glyph for U%d", c);
|
|||
}
|
||||
|
||||
- (void) drawString: (NSString*)string
|
||||
onDC: (HDC)hdc
|
||||
at: (POINT)p
|
||||
onDC: (HDC)hdc
|
||||
at: (POINT)p
|
||||
{
|
||||
HFONT old;
|
||||
|
||||
|
@ -252,9 +269,9 @@ NSLog(@"No glyph for U%d", c);
|
|||
}
|
||||
|
||||
- (void) drawGlyphs: (const NSGlyph*)s
|
||||
length: (int)len
|
||||
onDC: (HDC)hdc
|
||||
at: (POINT)p
|
||||
length: (int)len
|
||||
onDC: (HDC)hdc
|
||||
at: (POINT)p
|
||||
{
|
||||
WORD buf[len];
|
||||
HFONT old;
|
||||
|
@ -282,6 +299,117 @@ NSLog(@"No glyph for U%d", c);
|
|||
return numberOfGlyphs;
|
||||
}
|
||||
|
||||
- (void) appendBezierPathWithGlyphs: (NSGlyph *)glyphs
|
||||
count: (int)length
|
||||
toBezierPath: (NSBezierPath *)path
|
||||
{
|
||||
WORD buf[length];
|
||||
int i;
|
||||
SIZE sBoundBox;
|
||||
int h;
|
||||
int iPoints;
|
||||
POINT *ptPoints;
|
||||
BYTE *bTypes;
|
||||
NSPoint startPoint;
|
||||
HDC hDC = CreateCompatibleDC(NULL);
|
||||
|
||||
if (!hDC)
|
||||
{
|
||||
NSDebugLLog(@"WIN32FontInfo",
|
||||
@"Problem creating HDC for appendBezierPathWithGlyphs:");
|
||||
return;
|
||||
}
|
||||
|
||||
SetGraphicsMode(hDC, GM_ADVANCED);
|
||||
SetMapMode(hDC, MM_ANISOTROPIC);
|
||||
SetWindowExtEx(hDC, 1, 1, NULL);
|
||||
SetViewportExtEx(hDC, 1, -1, NULL);
|
||||
SetViewportOrgEx(hDC, 0, 0, NULL);
|
||||
|
||||
/*
|
||||
* For now, assume that a glyph is a unicode character and can be
|
||||
* stored in a windows WORD
|
||||
*/
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
buf[i] = glyphs[i];
|
||||
}
|
||||
|
||||
SelectObject(hDC, hFont);
|
||||
GetTextExtentPoint32W(hDC, buf, length, &sBoundBox);
|
||||
h = sBoundBox.cy;
|
||||
|
||||
if ([path elementCount] > 0)
|
||||
{
|
||||
startPoint = [path currentPoint];
|
||||
}
|
||||
else
|
||||
{
|
||||
startPoint = NSZeroPoint;
|
||||
}
|
||||
|
||||
SetBkMode(hDC, TRANSPARENT);
|
||||
BeginPath(hDC);
|
||||
SetTextAlign(hDC, TA_LEFT | TA_TOP);
|
||||
TextOutW(hDC, startPoint.x, -startPoint.y, buf, length);
|
||||
EndPath(hDC);
|
||||
|
||||
iPoints = GetPath(hDC, NULL, NULL, 0);
|
||||
if (iPoints == 0)
|
||||
{
|
||||
DeleteDC(hDC);
|
||||
return;
|
||||
}
|
||||
|
||||
ptPoints = objc_malloc(sizeof(POINT) * iPoints);
|
||||
if (!ptPoints)
|
||||
{
|
||||
DeleteDC(hDC);
|
||||
return;
|
||||
}
|
||||
bTypes = objc_malloc(sizeof(BYTE) * iPoints);
|
||||
if (!bTypes)
|
||||
{
|
||||
objc_free(ptPoints);
|
||||
DeleteDC(hDC);
|
||||
return;
|
||||
}
|
||||
GetPath(hDC, ptPoints, bTypes, iPoints);
|
||||
|
||||
// Now append the glyphs to the path
|
||||
i = 0;
|
||||
while (i < iPoints)
|
||||
{
|
||||
if (bTypes[i] == PT_MOVETO)
|
||||
{
|
||||
[path moveToPoint: NSMakePoint(ptPoints[i].x, h - ptPoints[i].y)];
|
||||
i++;
|
||||
}
|
||||
else if (bTypes[i] & PT_LINETO)
|
||||
{
|
||||
[path lineToPoint: NSMakePoint(ptPoints[i].x, h - ptPoints[i].y)];
|
||||
if (bTypes[i] & PT_CLOSEFIGURE)
|
||||
[path closePath];
|
||||
i++;
|
||||
}
|
||||
else if (bTypes[i] & PT_BEZIERTO)
|
||||
{
|
||||
// FIXME: We assume windows isn't lying here about the bezier points
|
||||
[path curveToPoint: NSMakePoint(ptPoints[i+2].x, h - ptPoints[i+2].y)
|
||||
controlPoint1: NSMakePoint(ptPoints[i].x, h - ptPoints[i].y)
|
||||
controlPoint2: NSMakePoint(ptPoints[i+1].x, h - ptPoints[i+1].y)];
|
||||
if ((bTypes[i] & PT_CLOSEFIGURE) || (bTypes[i+1] & PT_CLOSEFIGURE)
|
||||
|| (bTypes[i+2] & PT_CLOSEFIGURE))
|
||||
[path closePath];
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
|
||||
objc_free(bTypes);
|
||||
objc_free(ptPoints);
|
||||
DeleteDC(hDC);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation WIN32FontInfo (Private)
|
||||
|
@ -297,7 +425,7 @@ NSLog(@"No glyph for U%d", c);
|
|||
//NSLog(@"Creating Font %@ of size %f", fontName, matrix[0]);
|
||||
ASSIGN(familyName, win32_font_family(fontName));
|
||||
memset(&logfont, 0, sizeof(LOGFONT));
|
||||
hdc = GetDC(NULL);
|
||||
hdc = CreateCompatibleDC(NULL);
|
||||
// FIXME This hack gets the font size about right, but what is the real solution?
|
||||
logfont.lfHeight = (int)(matrix[0] * 4 / 3);
|
||||
//logfont.lfHeight = -MulDiv(matrix[0], GetDeviceCaps(hdc, LOGPIXELSY), 72);
|
||||
|
@ -318,14 +446,14 @@ NSLog(@"No glyph for U%d", c);
|
|||
if (!hFont)
|
||||
{
|
||||
NSLog(@"Could not create font %@", fontName);
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteDC(hdc);
|
||||
return NO;
|
||||
}
|
||||
|
||||
old = SelectObject(hdc, hFont);
|
||||
GetTextMetricsW(hdc, &metric);
|
||||
SelectObject(hdc, old);
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteDC(hdc);
|
||||
|
||||
// Fill the ivars
|
||||
isFixedPitch = TMPF_FIXED_PITCH & metric.tmPitchAndFamily;
|
||||
|
|
Loading…
Reference in a new issue