From 2657c4437c785d58e17bc3570e7ac757b969f859 Mon Sep 17 00:00:00 2001 From: Sergii Stoian Date: Fri, 17 Jan 2020 17:23:07 +0200 Subject: [PATCH 1/3] * Source/art/shfill.m:, * Source/art/path.m:, * Source/art/image.m (DPSimage:::::::::::): fixed type formatting specifiers. * Source/art/ftfont.m: removed include to ftfont-old.m. (drawString:at::to::::::::color::::transform:deltas:::widthChar:drawinfo:):, (drawGlyphs::at::to::::::color::::transform:drawinfo:):, (drawGlyphs::at::to::::::alpha::color::::transform:drawinfo:):, (bezierpath_funcs):, fixed type formatting specifiers; moved interface declaration of FTFontInfo to ftfont.h; removed GCCism. * Source/art/ftfont.h: moved interface declaration of FTFontInfo here. * Source/art/composite.m: fixed type formatting specifiers. * Source/art/FTFontEnumerator.m (load_font_configuration): fixed type formatting specifiers. --- ChangeLog | 20 +++++++++ Source/art/FTFontEnumerator.m | 2 +- Source/art/composite.m | 2 +- Source/art/ftfont.h | 37 ++++++++++++++++- Source/art/ftfont.m | 78 +++++++---------------------------- Source/art/image.m | 2 +- Source/art/path.m | 2 +- Source/art/shfill.m | 2 +- 8 files changed, 77 insertions(+), 68 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0a7f7e6..3715017 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2020-01-17 Sergii Stoian + + * Source/art/shfill.m:, + * Source/art/path.m:, + * Source/art/image.m (DPSimage:::::::::::): + fixed type formatting specifiers. + + * Source/art/ftfont.m: removed include to ftfont-old.m. + (drawString:at::to::::::::color::::transform:deltas:::widthChar:drawinfo:):, + (drawGlyphs::at::to::::::color::::transform:drawinfo:):, + (drawGlyphs::at::to::::::alpha::color::::transform:drawinfo:):, + (bezierpath_funcs):, + fixed type formatting specifiers; moved interface declaration of FTFontInfo + to ftfont.h; removed GCCism. + + * Source/art/ftfont.h: moved interface declaration of FTFontInfo here. + * Source/art/composite.m: fixed type formatting specifiers. + * Source/art/FTFontEnumerator.m (load_font_configuration): fixed type + formatting specifiers. + 2020-01-16 Sergii Stoian * Source/x11/XGServerEvent.m (_handleTakeFocusAtom:forContext:): use diff --git a/Source/art/FTFontEnumerator.m b/Source/art/FTFontEnumerator.m index 20774a0..3cc632b 100644 --- a/Source/art/FTFontEnumerator.m +++ b/Source/art/FTFontEnumerator.m @@ -444,7 +444,7 @@ static void load_font_configuration(void) [families_pending removeAllObjects]; } - NSDebugLLog(@"ftfont", @"got %i fonts in %i families", + NSDebugLLog(@"ftfont", @"got %lu fonts in %lu families", [fcfg_allFontNames count], [fcfg_allFontFamilies count]); if (![fcfg_allFontNames count]) diff --git a/Source/art/composite.m b/Source/art/composite.m index 7ec67db..7be09fb 100644 --- a/Source/art/composite.m +++ b/Source/art/composite.m @@ -1505,7 +1505,7 @@ static BOOL _rect_advance(rect_trace_t *t, int *x0, int *x1) } else { - NSLog(@"unimplemented compositerect: (%g %g)+(%g %g) op: %i", + NSLog(@"unimplemented compositerect: (%g %g)+(%g %g) op: %lu", aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height, op); diff --git a/Source/art/ftfont.h b/Source/art/ftfont.h index 7e3650a..c38874d 100644 --- a/Source/art/ftfont.h +++ b/Source/art/ftfont.h @@ -25,6 +25,8 @@ #ifndef ftfont_h #define ftfont_h +#import "blit.h" + @class NSAffineTransform; @protocol FTFontInfo @@ -66,7 +68,40 @@ +(void) initializeBackend; @end -@class FTFontInfo; +#import +#import FT_CACHE_H + +#import +#import "FTFaceInfo.h" + +#define CACHE_SIZE 257 + +@interface FTFontInfo : GSFontInfo +{ +@public + int pix_width, pix_height; + + FTC_FaceID faceId; + FTC_ImageTypeRec imageType; + FTC_ScalerRec scaler; + int unicodeCmap; + + BOOL screenFont; + + FTFaceInfo *face_info; + FT_Size ft_size; + + /* + Profiling (2003-11-14) shows that calls to -advancementForGlyph: accounted + for roughly 20% of layout time. This cache reduces it to (currently) + insignificant levels. + */ + unsigned int cachedGlyph[CACHE_SIZE]; + NSSize cachedSize[CACHE_SIZE]; + + CGFloat lineHeight; +} +@end #endif diff --git a/Source/art/ftfont.m b/Source/art/ftfont.m index b692da4..14f30cf 100644 --- a/Source/art/ftfont.m +++ b/Source/art/ftfont.m @@ -22,17 +22,6 @@ Boston, MA 02110-1301, USA. */ -#include -#include FT_FREETYPE_H - - -#if (FREETYPE_MAJOR==2) && ((FREETYPE_MINOR<1) || ((FREETYPE_MINOR==1) && (FREETYPE_PATCH<8))) - -#import "ftfont-old.m" - -#else - - #include #import @@ -56,7 +45,7 @@ #import "ftfont.h" #import "FTFontEnumerator.h" -#import "FTFaceInfo.h" +// #import "FTFaceInfo.h" #import "blit.h" @@ -66,7 +55,7 @@ /** font handling interface **/ -#include FT_CACHE_H +#include FT_FREETYPE_H #include FT_CACHE_IMAGE_H #include FT_CACHE_SMALL_BITMAPS_H @@ -86,42 +75,9 @@ from the back-art-subpixel-text defaults key */ static int subpixel_text; - - -#define CACHE_SIZE 257 - -@interface FTFontInfo : GSFontInfo -{ -@public - int pix_width, pix_height; - - FTC_FaceID faceId; - FTC_ImageTypeRec imageType; - FTC_ScalerRec scaler; - int unicodeCmap; - - BOOL screenFont; - - FTFaceInfo *face_info; - FT_Size ft_size; - - /* - Profiling (2003-11-14) shows that calls to -advancementForGlyph: accounted - for roughly 20% of layout time. This cache reduces it to (currently) - insignificant levels. - */ - unsigned int cachedGlyph[CACHE_SIZE]; - NSSize cachedSize[CACHE_SIZE]; - - CGFloat lineHeight; -} -@end - - @interface FTFontInfo_subpixel : FTFontInfo @end - static FT_Library ft_library; static FTC_Manager ftc_manager; static FTC_ImageCache ftc_imagecache; @@ -421,7 +377,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, return lineHeight; } -- (unsigned) numberOfGlyphs +- (NSUInteger) numberOfGlyphs { if (coveredCharacterSet == nil) { @@ -529,7 +485,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, real size, just a matrix. Thus, we average pix_width and pix_height; we'll get the right answer for normal cases, and we can't really do anything about the weird cases. */ - f = fabs(pix_width) + fabs(pix_height); + f = abs(pix_width) + abs(pix_height); if (f > 1) f = f / 2.0; else @@ -615,7 +571,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, { NSLog(@"FTC_SBitCache_Lookup() failed with error %08x " @"(%08x, %08x, %ix%i, %08x)", - error, glyph, imageType.face_id, imageType.width, + error, glyph, (unsigned)imageType.face_id, imageType.width, imageType.height, imageType.flags); continue; } @@ -1015,7 +971,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, float f; use_sbit = 0; - f = fabs(pix_width) + fabs(pix_height); + f = abs(pix_width) + abs(pix_height); if (f > 1) f = f / 2.0; else @@ -1045,7 +1001,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, { NSLog(@"FTC_SBitCache_Lookup() failed with error %08x " @"(%08x, %08x, %ix%i, %08x)", - error, glyph, imageType.face_id, + error, glyph, (unsigned)imageType.face_id, imageType.width, imageType.height, imageType.flags); continue; @@ -1336,7 +1292,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, float f; use_sbit = 0; - f = fabs(pix_width) + fabs(pix_height); + f = abs(pix_width) + abs(pix_height); if (f > 1) f = f / 2.0; else @@ -1365,7 +1321,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, { if (glyph != 0xffffffff) NSLog(@"FTC_SBitCache_Lookup() failed with error %08x (%08x, %08x, %ix%i, %08x)", - error, glyph, imageType.face_id, imageType.width, imageType.height, + error, glyph, (unsigned)imageType.face_id, imageType.width, imageType.height, imageType.flags ); continue; @@ -1633,7 +1589,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, if ((error = FTC_SBitCache_Lookup(ftc_sbitcache, &imageType, glyph, &sbit, NULL))) { NSLog(@"FTC_SBitCache_Lookup() failed with error %08x (%08x, %08x, %ix%i, %08x)", - error, glyph, imageType.face_id, + error, glyph, (unsigned)imageType.face_id, imageType.width, imageType.height, imageType.flags ); @@ -2025,12 +1981,12 @@ static int bezierpath_cubic_to(const FT_Vector *c1, const FT_Vector *c2, } static FT_Outline_Funcs bezierpath_funcs = { - move_to:bezierpath_move_to, - line_to:bezierpath_line_to, - conic_to:bezierpath_conic_to, - cubic_to:bezierpath_cubic_to, - shift:10, - delta:0, + .move_to = bezierpath_move_to, + .line_to = bezierpath_line_to, + .conic_to = bezierpath_conic_to, + .cubic_to = bezierpath_cubic_to, + .shift = 10, + .delta = 0, }; @@ -2659,5 +2615,3 @@ static char buf[1024]; /* !!TODO!! */ } @end -#endif /* freetype version check, >=2.1.8 */ - diff --git a/Source/art/image.m b/Source/art/image.m index e041138..3af67b1 100644 --- a/Source/art/image.m +++ b/Source/art/image.m @@ -759,7 +759,7 @@ seem to cause edges to be off by a pixel return; } - NSLog(@"unimplemented DPSimage %ix%i |%@| bips=%i spp=%i bipp=%i bypr=%i planar=%i alpha=%i\n", + NSLog(@"unimplemented DPSimage %lix%li |%@| bips=%li spp=%li bipp=%li bypr=%li planar=%i alpha=%i\n", pixelsWide, pixelsHigh, matrix, bitsPerSample, samplesPerPixel, bitsPerPixel, bytesPerRow, isPlanar, hasAlpha); diff --git a/Source/art/path.m b/Source/art/path.m index a9e34ae..4d3de87 100644 --- a/Source/art/path.m +++ b/Source/art/path.m @@ -731,7 +731,7 @@ static void clip_svp_callback(void *data, int y, int start, ci.index = malloc(sizeof(unsigned int) * (clip_sy + 1)); if (!ci.index) { - NSLog(@"Warning: out of memory calculating clipping spans (%i bytes)", + NSLog(@"Warning: out of memory calculating clipping spans (%lu bytes)", sizeof(unsigned int) * (clip_sy + 1)); return; } diff --git a/Source/art/shfill.m b/Source/art/shfill.m index 3312a7d..6c76ea9 100644 --- a/Source/art/shfill.m +++ b/Source/art/shfill.m @@ -502,7 +502,7 @@ static BOOL function_setup(NSDictionary * d, function_t *f) f->encode = NULL; free(f->decode); f->decode = NULL; - NSDebugLLog(@"GSArt -shfill", @"Need %i bytes of data, DataSource only has %i bytes.", + NSDebugLLog(@"GSArt -shfill", @"Need %i bytes of data, DataSource only has %lu bytes.", j, [data length]); return NO; } From 19a68d2d853278df84f8119c3595c8f5a1141db8 Mon Sep 17 00:00:00 2001 From: Sergii Stoian Date: Sun, 19 Jan 2020 01:31:21 +0200 Subject: [PATCH 2/3] * Source/art/ftfont.m: removed commented out #include and #include moved into ftfont.h. --- Source/art/ftfont.m | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Source/art/ftfont.m b/Source/art/ftfont.m index 14f30cf..643bfda 100644 --- a/Source/art/ftfont.m +++ b/Source/art/ftfont.m @@ -45,14 +45,9 @@ #import "ftfont.h" #import "FTFontEnumerator.h" -// #import "FTFaceInfo.h" - -#import "blit.h" - #define DI (*di) - /** font handling interface **/ #include FT_FREETYPE_H From 72284c1d37ed8ea4c9543799a683a76ec0ebea5f Mon Sep 17 00:00:00 2001 From: Sergii Stoian Date: Sun, 26 Jan 2020 22:51:22 +0200 Subject: [PATCH 3/3] * Source/art/ftont-old.m: is unused, so removed. --- Source/art/ftfont-old.m | 2771 --------------------------------------- 1 file changed, 2771 deletions(-) delete mode 100644 Source/art/ftfont-old.m diff --git a/Source/art/ftfont-old.m b/Source/art/ftfont-old.m deleted file mode 100644 index def5ecc..0000000 --- a/Source/art/ftfont-old.m +++ /dev/null @@ -1,2771 +0,0 @@ -/* - Copyright (C) 2002 Free Software Foundation, Inc. - - Author: Alexander Malmberg - - This file is part of GNUstep. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; see the file COPYING.LIB. - If not, see or write to the - Free Software Foundation, 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import -#import -#import - -#import "gsc/GSGState.h" - -#import "ftfont.h" -#import "FTFontEnumerator.h" -#import "FTFaceInfo.h" - -#import "blit.h" - - -#define DI (*di) - - -/** font handling interface **/ - -#include FT_CACHE_H - -#include FT_CACHE_IMAGE_H -#include FT_CACHE_SMALL_BITMAPS_H -#include FT_CACHE_CHARMAP_H - -#include FT_OUTLINE_H - -#if (FREETYPE_MAJOR==2) && ((FREETYPE_MINOR<1) || ((FREETYPE_MINOR==1) && (FREETYPE_PATCH<=2))) -#define FT212_STUFF -#endif - - -/* TODO: finish screen font handling */ - - -/* -from the back-art-subpixel-text defaults key -0: normal rendering -1: subpixel, rgb -2: subpixel, bgr -*/ -static int subpixel_text; - -#define CACHE_SIZE 257 - -@interface FTFontInfo : GSFontInfo -{ -@public -#ifdef FT212_STUFF - FTC_ImageDesc imgd; - - FTC_ImageDesc advancementImgd; -#else - FTC_ImageTypeRec imgd; - - FTC_ImageTypeRec advancementImgd; -#endif - - FTFaceInfo *face_info; - - BOOL screenFont; - - - /* - Profiling (2003-11-14) shows that calls to -advancementForGlyph: accounted - for roughly 20% of layout time. This cache reduces it to (currently) - insignificant levels. - */ - unsigned int cachedGlyph[CACHE_SIZE]; - NSSize cachedSize[CACHE_SIZE]; - - CGFloat lineHeight; -} -@end - - -@interface FTFontInfo_subpixel : FTFontInfo -@end - - -static FT_Library ft_library; -static FTC_Manager ftc_manager; -static FTC_ImageCache ftc_imagecache; -static FTC_SBitCache ftc_sbitcache; -static FTC_CMapCache ftc_cmapcache; - - -static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, FT_Pointer data, FT_Face *pface) -{ - FT_Error err; - NSArray *rfi = (NSArray *)fid; - int i, c = [rfi count]; - -// NSLog(@"ft_get_face: %@ '%s'", rfi, [[rfi objectAtIndex: 0] cString]); - - err = FT_New_Face(lib, [[rfi objectAtIndex: 0] cString], 0, pface); - if (err) - { - NSLog(@"Error when loading '%@' (%08x)", [rfi objectAtIndex: 0], err); - return err; - } - - for (i = 1; i < c; i++) - { -// NSLog(@" do '%s'", [[rfi objectAtIndex: i] cString]); - err = FT_Attach_File(*pface, [[rfi objectAtIndex: i] cString]); - if (err) - { - NSLog(@"Error when loading '%@' (%08x)", [rfi objectAtIndex: i], err); - /* pretend it's alright */ - } - } - return 0; -} - - -@implementation FTFontInfo -- initWithFontName: (NSString *)name - matrix: (const CGFloat *)fmatrix - screenFont: (BOOL)p_screenFont -{ - FT_Face face; - FT_Size size; - NSArray *rfi; - FTFaceInfo *font_entry; - - FT_Error error; - - - if (subpixel_text) - { - [self release]; - self = [FTFontInfo_subpixel alloc]; - } - - self = [super init]; - - screenFont = p_screenFont; - - NSDebugLLog(@"ftfont", @"[%@ -initWithFontName: %@ matrix: (%g %g %g %g %g %g)] %i\n", - self, name, - fmatrix[0], fmatrix[1], fmatrix[2], - fmatrix[3], fmatrix[4], fmatrix[5], - p_screenFont); - - font_entry = [FTFontEnumerator fontWithName: name]; - if (!font_entry) - { - [self release]; - return nil; - } - - face_info = font_entry; - - weight = font_entry->weight; - traits = font_entry->traits; - - fontName = [name copy]; - familyName = [face_info->familyName copy]; - memcpy(matrix, fmatrix, sizeof(matrix)); - - /* TODO: somehow make gnustep-gui send unicode our way. utf8? ugly, but it works */ - mostCompatibleStringEncoding = NSUTF8StringEncoding; - encodingScheme = @"iso10646-1"; - - 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]); - } - - imgd.font.pix_width = fabs(matrix[0]); - imgd.font.pix_height = fabs(matrix[3]); - - rfi = font_entry->files; - if (screenFont && font_entry->num_sizes && - imgd.font.pix_width == imgd.font.pix_height) - { - int i; - for (i = 0; i < font_entry->num_sizes; i++) - { - if (font_entry->sizes[i].pixel_size == imgd.font.pix_width) - { - rfi = font_entry->sizes[i].files; - break; - } - } - } - - imgd.font.face_id = (FTC_FaceID)rfi; - - if ((error=FTC_Manager_Lookup_Size(ftc_manager, &imgd.font, &face, &size))) - { - NSLog(@"FTC_Manager_Lookup_Size() failed for '%@', error %08x!\n", name, error); - return self; - } - -// xHeight = size->metrics.height / 64.0; -/* TODO: these are _really_ messed up when fonts are flipped */ - /* TODO: need to look acrefully at these and make sure they are correct */ - ascender = fabs(((int)size->metrics.ascender) / 64.0); - descender = fabs(((int)size->metrics.descender) / 64.0); - lineHeight = (int)size->metrics.height / 64.0; - xHeight = ascender * 0.5; /* TODO */ - maximumAdvancement = NSMakeSize((size->metrics.max_advance / 64.0), ascender + descender); - - fontBBox = NSMakeRect(0, -descender, maximumAdvancement.width, ascender + descender); - descender = -descender; - -/* printf("(%@) h=%g a=%g d=%g max=(%g %g) (%g %g)+(%g %g)\n",name, - xHeight, ascender, descender, - maximumAdvancement.width, maximumAdvancement.height, - fontBBox.origin.x, fontBBox.origin.y, - fontBBox.size.width, fontBBox.size.height);*/ - - { - float xx, yy; -#ifdef FT212_STUFF - FTC_ImageDesc cur; -#else - FTC_ImageTypeRec cur; -#endif - - cur = imgd; - - xx = matrix[0]; - yy = matrix[3]; - - if (xx == yy && xx < 16 && xx >= 8) - { - int rh = face_info->render_hints_hack; - if (rh & 0x10000) - { -#ifdef FT212_STUFF - cur.type = ftc_image_grays; -#else - cur.flags = FT_LOAD_TARGET_NORMAL; -#endif - rh = (rh >> 8) & 0xff; - } - else - { -#ifdef FT212_STUFF - cur.type = ftc_image_mono; -#else - cur.flags = FT_LOAD_TARGET_MONO; -#endif - rh = rh & 0xff; - } - if (rh & 1) -#ifdef FT212_STUFF - cur.type |= ftc_image_flag_autohinted; -#else - cur.flags |= FT_LOAD_FORCE_AUTOHINT; -#endif - if (!(rh & 2)) -#ifdef FT212_STUFF - cur.type |= ftc_image_flag_unhinted; -#else - cur.flags |= FT_LOAD_NO_HINTING; -#endif - } - else if (xx < 8) -#ifdef FT212_STUFF - cur.type = ftc_image_grays | ftc_image_flag_unhinted; -#else - cur.flags = FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING; -#endif - else -#ifdef FT212_STUFF - cur.type = ftc_image_grays; -#else - cur.flags = FT_LOAD_TARGET_NORMAL; -#endif - advancementImgd = cur; - } - - /* - Here, we simply need to make sure that we don't get any false matches - the first time a particular cache entry is used. Thus, we only need to - initialize the first entry. For all other entries, cachedGlyph[i] will - be 0, and that's a glyph that can't possibly hash to any entry except - entry #0, so it won't cause any false matches. - */ - cachedGlyph[0] = 1; - - return self; -} - --(void) set -{ - NSLog(@"ignore -set method of font '%@'\n", fontName); -} - - --(CGFloat) defaultLineHeightForFont -{ - return lineHeight; -} - - -/* TODO: the current point probably needs updating after drawing is done */ - -/* draw string at point, clipped, w/given color and alpha, and possible deltas: - flags & 0x1: data contains x offsets, use instead of glyph x advance - flags & 0x2: data contains y offsets, use instead of glyph y advance - flags & 0x4: data contains a single x and y offset, which should be added to - font's advancements for each glyph; results are undefined if - this option is combined with either x or y offsets (0x1,0x2) - flags & 0x8: data contains a single x and y offset, which should be added to - font's advancement for glyph identified by 'wch'; if combined - with 0x4 deltas contain exactly two offsets for x and y, the - first for every character, the second for 'wch'; results are - undefined if 0x8 is combined with 0x2 or 0x1 - */ --(void) drawString: (const char *)s - at: (int)x : (int)y - to: (int)x0 : (int)y0 : (int)x1 : (int)y1 - : (unsigned char *)buf : (int)bpl - : (unsigned char *)abuf : (int)abpl - color:(unsigned char)r : (unsigned char)g : (unsigned char)b : (unsigned char)alpha - transform: (NSAffineTransform *)transform - deltas: (const CGFloat *)delta_data : (int)delta_size : (int)delta_flags - widthChar: (int) wch - drawinfo: (draw_info_t *)di -{ -#if 0 - NSLog(@"ignoring drawString"); -#else - const unsigned char *c; - unsigned char ch; - unsigned int uch; - int d; - - FTC_CMapDescRec cmap; - unsigned int glyph; - NSAffineTransformStruct ts; - - int use_sbit; - - FTC_SBit sbit; -#ifdef FT212_STUFF - FTC_ImageDesc cur; -#else - FTC_ImageTypeRec cur; -#endif - - FT_Matrix ftmatrix; - FT_Vector ftdelta; - - FT_Error error; - - - if (!alpha) - return; - - /* TODO: if we had guaranteed upper bounds on glyph image size we - could do some basic clipping here */ - - x1 -= x0; - y1 -= y0; - x -= x0; - y -= y0; - - ts = [transform transformStruct]; - -/* NSLog(@"[%@ draw using matrix: (%g %g %g %g %g %g)] transform=%@\n", - self, - matrix[0], matrix[1], matrix[2], - matrix[3], matrix[4], matrix[5], - transform - );*/ - - cur = imgd; - { - float xx, xy, yx, yy; - - xx = matrix[0] * ts.m11 + matrix[1] * ts.m21; - yx = matrix[0] * ts.m12 + matrix[1] * ts.m22; - xy = matrix[2] * ts.m11 + matrix[3] * ts.m21; - yy = matrix[2] * ts.m12 + matrix[3] * ts.m22; - - /* If we're drawing 'normal' text (unscaled, unrotated, reasonable - size), we can and should use the sbit cache for screen fonts. */ - if (screenFont && - fabs(xx - ((int)xx)) < 0.01 && fabs(yy - ((int)yy)) < 0.01 && - fabs(xy) < 0.01 && fabs(yx) < 0.01 && - xx < 72 && yy < 72 && xx > 0.5 && yy > 0.5) - { - use_sbit = 1; - cur.font.pix_width = xx; - cur.font.pix_height = yy; - - if (xx == yy && xx < 16 && xx >= 8) - { - int rh = face_info->render_hints_hack; - if (rh & 0x10000) - { -#ifdef FT212_STUFF - cur.type = ftc_image_grays; -#else - cur.flags = FT_LOAD_TARGET_NORMAL; -#endif - rh = (rh >> 8) & 0xff; - } - else - { -#ifdef FT212_STUFF - cur.type = ftc_image_mono; -#else - cur.flags = FT_LOAD_TARGET_MONO; -#endif - rh = rh & 0xff; - } - if (rh & 1) -#ifdef FT212_STUFF - cur.type |= ftc_image_flag_autohinted; -#else - cur.flags |= FT_LOAD_FORCE_AUTOHINT; -#endif - if (!(rh & 2)) -#ifdef FT212_STUFF - cur.type |= ftc_image_flag_unhinted; -#else - cur.flags |= FT_LOAD_NO_HINTING; -#endif - } - else if (xx < 8) -#ifdef FT212_STUFF - cur.type = ftc_image_grays | ftc_image_flag_unhinted; -#else - cur.flags = FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING; -#endif - else -#ifdef FT212_STUFF - cur.type = ftc_image_grays; -#else - cur.flags = FT_LOAD_TARGET_NORMAL; -#endif - } - else - { - float f; - use_sbit = 0; - - f = fabs(xx * yy - xy * yx); - if (f > 1) - f = sqrt(f); - else - f = 1.0; - - f = (int)f; - - cur.font.pix_width = cur.font.pix_height = f; - ftmatrix.xx = xx / f * 65536.0; - ftmatrix.xy = xy / f * 65536.0; - ftmatrix.yx = yx / f * 65536.0; - ftmatrix.yy = yy / f * 65536.0; - ftdelta.x = ftdelta.y = 0; - } - } - - -/* NSLog(@"drawString: '%s' at: %i:%i to: %i:%i:%i:%i:%p\n", - s, x, y, x0, y0, x1, y1, buf);*/ - - cmap.face_id = imgd.font.face_id; - cmap.u.encoding = ft_encoding_unicode; - cmap.type = FTC_CMAP_BY_ENCODING; - d=0; - - for (c = s; *c; c++) - { -/* TODO: do the same thing in outlineString:... */ - ch = *c; - if (ch < 0x80) - { - uch = ch; - } - else if (ch < 0xc0) - { - uch = 0xfffd; - } - else if (ch < 0xe0) - { -#define ADD_UTF_BYTE(shift, internal) \ - ch = *++c; \ - if (ch >= 0x80 && ch < 0xc0) \ - { \ - uch |= (ch & 0x3f) << shift; \ - internal \ - } \ - else \ - { \ - uch = 0xfffd; \ - c--; \ - } - - uch = (ch & 0x1f) << 6; - ADD_UTF_BYTE(0,) - } - else if (ch < 0xf0) - { - uch = (ch & 0x0f) << 12; - ADD_UTF_BYTE(6, ADD_UTF_BYTE(0,)) - } - else if (ch < 0xf8) - { - uch = (ch & 0x07) << 18; - ADD_UTF_BYTE(12, ADD_UTF_BYTE(6, ADD_UTF_BYTE(0,))) - } - else if (ch < 0xfc) - { - uch = (ch & 0x03) << 24; - ADD_UTF_BYTE(18, ADD_UTF_BYTE(12, ADD_UTF_BYTE(6, ADD_UTF_BYTE(0,)))) - } - else if (ch < 0xfe) - { - uch = (ch & 0x01) << 30; - ADD_UTF_BYTE(24, ADD_UTF_BYTE(18, ADD_UTF_BYTE(12, ADD_UTF_BYTE(6, ADD_UTF_BYTE(0,))))) - } - else - uch = 0xfffd; -#undef ADD_UTF_BYTE - - glyph = FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, uch); - cur.font.face_id = imgd.font.face_id; - - if (use_sbit) - { - if ((error=FTC_SBitCache_Lookup(ftc_sbitcache, &cur, glyph, &sbit, NULL))) - { - NSLog(@"FTC_SBitCache_Lookup() failed with error %08x (%08x, %08x, %ix%i, %08x)\n", - error, glyph, cur.font.face_id, cur.font.pix_width, cur.font.pix_height, -#ifdef FT212_STUFF - cur.type -#else - cur.flags -#endif - ); - continue; - } - - if (!sbit->buffer) - { - if (!delta_flags) - { - x += sbit->xadvance; - } - else - { - if (delta_flags & 0x1) - x += delta_data[d++]; - if (delta_flags & 0x2) - y += (ts.m22 < 0) ? - delta_data[d++] : -delta_data[d++]; - if (delta_flags & 0x4) - { - x += sbit->xadvance + delta_data[0]; - y += /*sbit->yadvance +*/ (ts.m22 < 0) ? - delta_data[1] : -delta_data[1]; - if ((delta_flags & 0x8) && (uch == wch)) - { - x += delta_data[2]; - y += (ts.m22 < 0) ? - delta_data[3] : -delta_data[3]; - } - } - else if (delta_flags & 0x8) - { - if (uch == wch) - { - x += sbit->xadvance + delta_data[0]; - y += /*sbit->yadvance +*/ (ts.m22 < 0) ? - delta_data[1] : -delta_data[1]; - } - else - { - x += sbit->xadvance; - /*y += sbit->yadvance;*/ - } - } - } - continue; - } - - if (sbit->format == ft_pixel_mode_grays) - { - int gx = x + sbit->left, gy = y - sbit->top; - int sbpl = sbit->pitch; - int sx = sbit->width, sy = sbit->height; - const unsigned char *src = sbit->buffer; - unsigned char *dst = buf; - - if (gy < 0) - { - sy += gy; - src -= sbpl * gy; - gy = 0; - } - else if (gy > 0) - { - dst += bpl * gy; - } - - sy += gy; - if (sy > y1) - sy = y1; - - if (gx < 0) - { - sx += gx; - src -= gx; - gx = 0; - } - else if (gx > 0) - { - dst += DI.bytes_per_pixel * gx; - } - - sx += gx; - if (sx > x1) - sx = x1; - sx -= gx; - - if (sx > 0) - { - if (alpha >= 255) - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_ALPHA_OPAQUE(dst, src, r, g, b, sx); - else - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_ALPHA(dst, src, r, g, b, alpha, sx); - } - } - else if (sbit->format == ft_pixel_mode_mono) - { - int gx = x + sbit->left, gy = y - sbit->top; - int sbpl = sbit->pitch; - int sx = sbit->width, sy = sbit->height; - const unsigned char *src = sbit->buffer; - unsigned char *dst = buf; - int src_ofs = 0; - - if (gy < 0) - { - sy += gy; - src -= sbpl * gy; - gy = 0; - } - else if (gy > 0) - { - dst += bpl * gy; - } - - sy += gy; - if (sy > y1) - sy = y1; - - if (gx < 0) - { - sx += gx; - src -= gx / 8; - src_ofs = (-gx) & 7; - gx = 0; - } - else if (gx > 0) - { - dst += DI.bytes_per_pixel * gx; - } - - sx += gx; - if (sx > x1) - sx = x1; - sx -= gx; - - if (sx > 0) - { - if (alpha >= 255) - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_MONO_OPAQUE(dst, src, src_ofs, r, g, b, sx); - else - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_MONO(dst, src, src_ofs, r, g, b, alpha, sx); - } - } - else - { - NSLog(@"unhandled font bitmap format %i", sbit->format); - } - - if (!delta_flags) - { - x += sbit->xadvance; - } - else - { - if (delta_flags & 0x1) - x += delta_data[d++]; - if (delta_flags & 0x2) - y += (ts.m22 < 0) ? - delta_data[d++] : -delta_data[d++]; - if (delta_flags & 0x4) - { - x += sbit->xadvance + delta_data[0]; - y += /*sbit->yadvance +*/ (ts.m22 < 0) ? - delta_data[1] : -delta_data[1]; - if ((delta_flags & 0x8) && (uch == wch)) - { - x += delta_data[2]; - y += (ts.m22 < 0) ? - delta_data[3] : -delta_data[3]; - } - } - else if (delta_flags & 0x8) - { - if (uch == wch) - { - x += sbit->xadvance + delta_data[0]; - y += /*sbit->yadvance +*/ (ts.m22 < 0) ? - delta_data[1] : -delta_data[1]; - } - else - { - x += sbit->xadvance; - /*y += sbit->yadvance;*/ - } - } - } - } - else - { - FT_Face face; - FT_Glyph gl; - FT_BitmapGlyph gb; - - if ((error=FTC_Manager_Lookup_Size(ftc_manager, &cur.font, &face, 0))) - { - NSLog(@"FTC_Manager_Lookup_Size() failed with error %08x\n",error); - continue; - } - - /* TODO: for rotations of 90, 180, 270, and integer - scales hinting might still be a good idea. */ - if ((error=FT_Load_Glyph(face, glyph, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP))) - { - NSLog(@"FT_Load_Glyph() failed with error %08x\n",error); - continue; - } - - if ((error=FT_Get_Glyph(face->glyph, &gl))) - { - NSLog(@"FT_Get_Glyph() failed with error %08x\n",error); - continue; - } - - if ((error=FT_Glyph_Transform(gl, &ftmatrix, &ftdelta))) - { - NSLog(@"FT_Glyph_Transform() failed with error %08x\n",error); - continue; - } - if ((error=FT_Glyph_To_Bitmap(&gl, ft_render_mode_normal, 0, 1))) - { - NSLog(@"FT_Glyph_To_Bitmap() failed with error %08x\n",error); - FT_Done_Glyph(gl); - continue; - } - gb = (FT_BitmapGlyph)gl; - - - if (gb->bitmap.pixel_mode == ft_pixel_mode_grays) - { - int gx = x + gb->left, gy = y - gb->top; - int sbpl = gb->bitmap.pitch; - int sx = gb->bitmap.width, sy = gb->bitmap.rows; - const unsigned char *src = gb->bitmap.buffer; - unsigned char *dst = buf; - unsigned char *dsta = abuf; - - if (gy < 0) - { - sy += gy; - src -= sbpl * gy; - gy = 0; - } - else if (gy > 0) - { - dst += bpl * gy; - if (dsta) - dsta += abpl * gy; - } - - sy += gy; - if (sy > y1) - sy = y1; - - if (gx < 0) - { - sx += gx; - src -= gx; - gx = 0; - } - else if (gx > 0) - { - dst += DI.bytes_per_pixel * gx; - if (dsta) - dsta += gx; - } - - sx += gx; - if (sx > x1) - sx = x1; - sx -= gx; - - if (sx > 0) - { - if (dsta) - for (; gy < sy; gy++, src += sbpl, dst += bpl, dsta += abpl) - RENDER_BLIT_ALPHA_A(dst, dsta, src, r, g, b, alpha, sx); - else if (alpha >= 255) - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_ALPHA_OPAQUE(dst, src, r, g, b, sx); - else - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_ALPHA(dst, src, r, g, b, alpha, sx); - } - } -/* TODO: will this case ever appear? */ -/* else if (gb->bitmap.pixel_mode==ft_pixel_mode_mono)*/ - else - { - NSLog(@"unhandled font bitmap format %i", gb->bitmap.pixel_mode); - } - - if (!delta_flags) - { - ftdelta.x += gl->advance.x >> 10; - ftdelta.y += gl->advance.y >> 10; - } - else - { - if (delta_flags & 0x1) - ftdelta.x += delta_data[d++] * 64.0; - if (delta_flags & 0x2) - ftdelta.y += delta_data[d++] * 64.0; - if (delta_flags & 0x4) - { - ftdelta.x += (gl->advance.x >> 10) + delta_data[0] * 64.0; - ftdelta.y += (gl->advance.y >> 10) + delta_data[1] * 64.0; - if ((delta_flags & 0x8) && (uch == wch)) - { - ftdelta.x += delta_data[2] * 64.0; - ftdelta.y += delta_data[3] * 64.0; - } - } - else if (delta_flags & 0x8) - { - if (uch == wch) - { - ftdelta.x += (gl->advance.x>>10) + delta_data[0] * 64.0; - ftdelta.y += (gl->advance.y>>10) + delta_data[1] * 64.0; - } - else - { - ftdelta.x += gl->advance.x >> 10; - ftdelta.y += gl->advance.y >> 10; - } - } - } - - FT_Done_Glyph(gl); - } - } - -#endif -} - - --(void) drawGlyphs: (const NSGlyph *)glyphs : (int)length - at: (int)x : (int)y - to: (int)x0 : (int)y0 : (int)x1 : (int)y1 - : (unsigned char *)buf : (int)bpl - color: (unsigned char)r : (unsigned char)g : (unsigned char)b - : (unsigned char)alpha - transform: (NSAffineTransform *)transform - drawinfo: (struct draw_info_s *)di -{ - unsigned int glyph; - - int use_sbit; - - FTC_SBit sbit; -#ifdef FT212_STUFF - FTC_ImageDesc cur; -#else - FTC_ImageTypeRec cur; -#endif - - FT_Matrix ftmatrix; - FT_Vector ftdelta; - - FT_Error error; - NSAffineTransformStruct ts; - - - if (!alpha) - return; - - /* TODO: if we had guaranteed upper bounds on glyph image size we - could do some basic clipping here */ - - x1 -= x0; - y1 -= y0; - x -= x0; - y -= y0; - - ts = [transform transformStruct]; - -/* NSLog(@"[%@ draw using matrix: (%g %g %g %g %g %g)] transform=%@\n", - self, - matrix[0], matrix[1], matrix[2], - matrix[3], matrix[4], matrix[5], - transform - );*/ - - cur = imgd; - { - float xx, xy, yx, yy; - - xx = matrix[0] * ts.m11 + matrix[1] * ts.m21; - yx = matrix[0] * ts.m12 + matrix[1] * ts.m22; - xy = matrix[2] * ts.m11 + matrix[3] * ts.m21; - yy = matrix[2] * ts.m12 + matrix[3] * ts.m22; - - /* If we're drawing 'normal' text (unscaled, unrotated, reasonable - size), we can and should use the sbit cache for screen fonts. */ - if (screenFont && - fabs(xx - ((int)xx)) < 0.01 && fabs(yy - ((int)yy)) < 0.01 && - fabs(xy) < 0.01 && fabs(yx) < 0.01 && - xx < 72 && yy < 72 && xx > 0.5 && yy > 0.5) - { - use_sbit = 1; - cur.font.pix_width = xx; - cur.font.pix_height = yy; - - if (xx == yy && xx < 16 && xx >= 8) - { - int rh = face_info->render_hints_hack; - if (rh & 0x10000) - { -#ifdef FT212_STUFF - cur.type = ftc_image_grays; -#else - cur.flags = FT_LOAD_TARGET_NORMAL; -#endif - rh = (rh >> 8) & 0xff; - } - else - { -#ifdef FT212_STUFF - cur.type = ftc_image_mono; -#else - cur.flags = FT_LOAD_TARGET_MONO; -#endif - rh = rh & 0xff; - } - if (rh & 1) -#ifdef FT212_STUFF - cur.type |= ftc_image_flag_autohinted; -#else - cur.flags |= FT_LOAD_FORCE_AUTOHINT; -#endif - if (!(rh & 2)) -#ifdef FT212_STUFF - cur.type |= ftc_image_flag_unhinted; -#else - cur.flags |= FT_LOAD_NO_HINTING; -#endif - } - else if (xx < 8) -#ifdef FT212_STUFF - cur.type = ftc_image_grays | ftc_image_flag_unhinted; -#else - cur.flags = FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING; -#endif - else -#ifdef FT212_STUFF - cur.type = ftc_image_grays; -#else - cur.flags = FT_LOAD_TARGET_NORMAL; -#endif - } - else - { - float f; - use_sbit = 0; - - f = fabs(xx * yy - xy * yx); - if (f > 1) - f = sqrt(f); - else - f = 1.0; - - f = (int)f; - - cur.font.pix_width = cur.font.pix_height = f; - ftmatrix.xx = xx / f * 65536.0; - ftmatrix.xy = xy / f * 65536.0; - ftmatrix.yx = yx / f * 65536.0; - ftmatrix.yy = yy / f * 65536.0; - ftdelta.x = ftdelta.y = 0; - } - } - -/* NSLog(@"drawString: '%s' at: %i:%i to: %i:%i:%i:%i:%p\n", - s, x, y, x0, y0, x1, y1, buf);*/ - - for (; length; length--, glyphs++) - { - glyph = *glyphs - 1; - - if (use_sbit) - { - if ((error = FTC_SBitCache_Lookup(ftc_sbitcache, &cur, glyph, &sbit, NULL))) - { - NSLog(@"FTC_SBitCache_Lookup() failed with error %08x (%08x, %08x, %ix%i, %08x)\n", - error, glyph, cur.font.face_id, cur.font.pix_width, cur.font.pix_height, -#ifdef FT212_STUFF - cur.type -#else - cur.flags -#endif - ); - continue; - } - - if (!sbit->buffer) - { - x += sbit->xadvance; - continue; - } - - if (sbit->format == ft_pixel_mode_grays) - { - int gx = x + sbit->left, gy = y - sbit->top; - int sbpl = sbit->pitch; - int sx = sbit->width, sy = sbit->height; - const unsigned char *src = sbit->buffer; - unsigned char *dst = buf; - - if (gy < 0) - { - sy += gy; - src -= sbpl * gy; - gy = 0; - } - else if (gy > 0) - { - dst += bpl * gy; - } - - sy += gy; - if (sy > y1) - sy = y1; - - if (gx < 0) - { - sx += gx; - src -= gx; - gx = 0; - } - else if (gx > 0) - { - dst += DI.bytes_per_pixel * gx; - } - - sx += gx; - if (sx > x1) - sx = x1; - sx -= gx; - - if (sx > 0) - { - if (alpha >= 255) - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_ALPHA_OPAQUE(dst, src, r, g, b, sx); - else - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_ALPHA(dst, src, r, g, b, alpha, sx); - } - } - else if (sbit->format == ft_pixel_mode_mono) - { - int gx = x + sbit->left, gy = y - sbit->top; - int sbpl = sbit->pitch; - int sx = sbit->width, sy = sbit->height; - const unsigned char *src = sbit->buffer; - unsigned char *dst = buf; - int src_ofs = 0; - - if (gy < 0) - { - sy += gy; - src -= sbpl * gy; - gy = 0; - } - else if (gy > 0) - { - dst += bpl * gy; - } - - sy += gy; - if (sy > y1) - sy = y1; - - if (gx < 0) - { - sx += gx; - src -= gx / 8; - src_ofs = (-gx) & 7; - gx = 0; - } - else if (gx > 0) - { - dst += DI.bytes_per_pixel * gx; - } - - sx += gx; - if (sx > x1) - sx = x1; - sx -= gx; - - if (sx > 0) - { - if (alpha >= 255) - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_MONO_OPAQUE(dst, src, src_ofs, r, g, b, sx); - else - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_MONO(dst, src, src_ofs, r, g, b, alpha, sx); - } - } - else - { - NSLog(@"unhandled font bitmap format %i", sbit->format); - } - - x += sbit->xadvance; - } - else - { - FT_Face face; - FT_Glyph gl; - FT_BitmapGlyph gb; - - if ((error=FTC_Manager_Lookup_Size(ftc_manager, &cur.font, &face, 0))) - { - NSLog(@"FTC_Manager_Lookup_Size() failed with error %08x\n",error); - continue; - } - - /* TODO: for rotations of 90, 180, 270, and integer - scales hinting might still be a good idea. */ - if ((error=FT_Load_Glyph(face, glyph, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP))) - { - NSLog(@"FT_Load_Glyph() failed with error %08x\n",error); - continue; - } - - if ((error=FT_Get_Glyph(face->glyph, &gl))) - { - NSLog(@"FT_Get_Glyph() failed with error %08x\n",error); - continue; - } - - if ((error=FT_Glyph_Transform(gl, &ftmatrix, &ftdelta))) - { - NSLog(@"FT_Glyph_Transform() failed with error %08x\n",error); - continue; - } - if ((error=FT_Glyph_To_Bitmap(&gl, ft_render_mode_normal, 0, 1))) - { - NSLog(@"FT_Glyph_To_Bitmap() failed with error %08x\n",error); - FT_Done_Glyph(gl); - continue; - } - gb = (FT_BitmapGlyph)gl; - - - if (gb->bitmap.pixel_mode == ft_pixel_mode_grays) - { - int gx = x + gb->left, gy = y - gb->top; - int sbpl = gb->bitmap.pitch; - int sx = gb->bitmap.width, sy = gb->bitmap.rows; - const unsigned char *src = gb->bitmap.buffer; - unsigned char *dst = buf; - - if (gy < 0) - { - sy += gy; - src -= sbpl * gy; - gy = 0; - } - else if (gy > 0) - { - dst += bpl * gy; - } - - sy += gy; - if (sy > y1) - sy = y1; - - if (gx < 0) - { - sx += gx; - src -= gx; - gx = 0; - } - else if (gx > 0) - { - dst += DI.bytes_per_pixel * gx; - } - - sx += gx; - if (sx > x1) - sx = x1; - sx -= gx; - - if (sx > 0) - { - if (alpha >= 255) - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_ALPHA_OPAQUE(dst, src, r, g, b, sx); - else - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_ALPHA(dst, src, r, g, b, alpha, sx); - } - } -/* TODO: will this case ever appear? */ -/* else if (gb->bitmap.pixel_mode==ft_pixel_mode_mono)*/ - else - { - NSLog(@"unhandled font bitmap format %i", gb->bitmap.pixel_mode); - } - - ftdelta.x += gl->advance.x >> 10; - ftdelta.y += gl->advance.y >> 10; - - FT_Done_Glyph(gl); - } - } -} - --(void) drawGlyphs: (const NSGlyph *)glyphs : (int)length - at: (int)x : (int)y - to: (int)x0 : (int)y0 : (int)x1 : (int)y1 - : (unsigned char *)buf : (int)bpl - alpha: (unsigned char *)abuf : (int)abpl - color: (unsigned char)r : (unsigned char)g : (unsigned char)b - : (unsigned char)alpha - transform: (NSAffineTransform *)transform - drawinfo: (struct draw_info_s *)di -{ - unsigned int glyph; - - int use_sbit; - - FTC_SBit sbit; -#ifdef FT212_STUFF - FTC_ImageDesc cur; -#else - FTC_ImageTypeRec cur; -#endif - - FT_Matrix ftmatrix; - FT_Vector ftdelta; - - FT_Error error; - NSAffineTransformStruct ts; - - - if (!alpha) - return; - - /* TODO: if we had guaranteed upper bounds on glyph image size we - could do some basic clipping here */ - - x1 -= x0; - y1 -= y0; - x -= x0; - y -= y0; - - ts = [transform transformStruct]; - -/* NSLog(@"[%@ draw using matrix: (%g %g %g %g %g %g)] transform=%@\n", - self, - matrix[0], matrix[1], matrix[2], - matrix[3], matrix[4], matrix[5], - transform - );*/ - - cur = imgd; - { - float xx, xy, yx, yy; - - xx = matrix[0] * ts.m11 + matrix[1] * ts.m21; - yx = matrix[0] * ts.m12 + matrix[1] * ts.m22; - xy = matrix[2] * ts.m11 + matrix[3] * ts.m21; - yy = matrix[2] * ts.m12 + matrix[3] * ts.m22; - - /* If we're drawing 'normal' text (unscaled, unrotated, reasonable - size), we can and should use the sbit cache for screen fonts. */ - if (screenFont && - fabs(xx - ((int)xx)) < 0.01 && fabs(yy - ((int)yy)) < 0.01 && - fabs(xy) < 0.01 && fabs(yx) < 0.01 && - xx < 72 && yy < 72 && xx > 0.5 && yy > 0.5) - { - use_sbit = 1; - cur.font.pix_width = xx; - cur.font.pix_height = yy; - - if (xx == yy && xx < 16 && xx >= 8) - { - int rh = face_info->render_hints_hack; - if (rh & 0x10000) - { -#ifdef FT212_STUFF - cur.type = ftc_image_grays; -#else - cur.flags = FT_LOAD_TARGET_NORMAL; -#endif - rh = (rh >> 8) & 0xff; - } - else - { -#ifdef FT212_STUFF - cur.type = ftc_image_mono; -#else - cur.flags = FT_LOAD_TARGET_MONO; -#endif - rh = rh & 0xff; - } - if (rh & 1) -#ifdef FT212_STUFF - cur.type |= ftc_image_flag_autohinted; -#else - cur.flags |= FT_LOAD_FORCE_AUTOHINT; -#endif - if (!(rh & 2)) -#ifdef FT212_STUFF - cur.type |= ftc_image_flag_unhinted; -#else - cur.flags |= FT_LOAD_NO_HINTING; -#endif - } - else if (xx < 8) -#ifdef FT212_STUFF - cur.type = ftc_image_grays | ftc_image_flag_unhinted; -#else - cur.flags = FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING; -#endif - else -#ifdef FT212_STUFF - cur.type = ftc_image_grays; -#else - cur.flags = FT_LOAD_TARGET_NORMAL; -#endif - } - else - { - float f; - use_sbit = 0; - - f = fabs(xx * yy - xy * yx); - if (f > 1) - f = sqrt(f); - else - f = 1.0; - - f = (int)f; - - cur.font.pix_width = cur.font.pix_height = f; - ftmatrix.xx = xx / f * 65536.0; - ftmatrix.xy = xy / f * 65536.0; - ftmatrix.yx = yx / f * 65536.0; - ftmatrix.yy = yy / f * 65536.0; - ftdelta.x = ftdelta.y = 0; - } - } - -/* NSLog(@"drawString: '%s' at: %i:%i to: %i:%i:%i:%i:%p\n", - s, x, y, x0, y0, x1, y1, buf);*/ - - for (; length; length--, glyphs++) - { - glyph = *glyphs - 1; - - if (use_sbit) - { - if ((error = FTC_SBitCache_Lookup(ftc_sbitcache, &cur, glyph, &sbit, NULL))) - { - if (glyph != 0xffffffff) - NSLog(@"FTC_SBitCache_Lookup() failed with error %08x (%08x, %08x, %ix%i, %08x)\n", - error, glyph, cur.font.face_id, cur.font.pix_width, cur.font.pix_height, -#ifdef FT212_STUFF - cur.type -#else - cur.flags -#endif - ); - continue; - } - - if (!sbit->buffer) - { - x += sbit->xadvance; - continue; - } - - if (sbit->format == ft_pixel_mode_grays) - { - int gx = x + sbit->left, gy = y - sbit->top; - int sbpl = sbit->pitch; - int sx = sbit->width, sy = sbit->height; - const unsigned char *src = sbit->buffer; - unsigned char *dst = buf; - unsigned char *adst = abuf; - - if (gy < 0) - { - sy += gy; - src -= sbpl * gy; - gy = 0; - } - else if (gy > 0) - { - dst += bpl * gy; - adst += abpl * gy; - } - - sy += gy; - if (sy > y1) - sy = y1; - - if (gx < 0) - { - sx += gx; - src -= gx; - gx = 0; - } - else if (gx > 0) - { - dst += DI.bytes_per_pixel * gx; - adst += gx; - } - - sx += gx; - if (sx > x1) - sx = x1; - sx -= gx; - - if (sx > 0) - { - for (; gy < sy; gy++, src += sbpl, dst += bpl, adst += abpl) - RENDER_BLIT_ALPHA_A(dst, adst, src, r, g, b, alpha, sx); - } - } - else if (sbit->format == ft_pixel_mode_mono) - { - int gx = x + sbit->left, gy = y - sbit->top; - int sbpl = sbit->pitch; - int sx = sbit->width, sy = sbit->height; - const unsigned char *src = sbit->buffer; - unsigned char *dst = buf; - unsigned char *adst = abuf; - int src_ofs = 0; - - if (gy < 0) - { - sy += gy; - src -= sbpl * gy; - gy = 0; - } - else if (gy > 0) - { - dst += bpl * gy; - adst += abpl * gy; - } - - sy += gy; - if (sy > y1) - sy = y1; - - if (gx < 0) - { - sx += gx; - src -= gx / 8; - src_ofs = (-gx) & 7; - gx = 0; - } - else if (gx > 0) - { - dst += DI.bytes_per_pixel * gx; - adst += gx; - } - - sx += gx; - if (sx > x1) - sx = x1; - sx -= gx; - - if (sx > 0) - { - for (; gy < sy; gy++, src += sbpl, dst += bpl, adst += bpl) - RENDER_BLIT_MONO_A(dst, adst, src, src_ofs, r, g, b, alpha, sx); - } - } - else - { - NSLog(@"unhandled font bitmap format %i", sbit->format); - } - - x += sbit->xadvance; - } - else - { - FT_Face face; - FT_Glyph gl; - FT_BitmapGlyph gb; - - if ((error=FTC_Manager_Lookup_Size(ftc_manager, &cur.font, &face, 0))) - { - NSLog(@"FTC_Manager_Lookup_Size() failed with error %08x\n",error); - continue; - } - - /* TODO: for rotations of 90, 180, 270, and integer - scales hinting might still be a good idea. */ - if ((error=FT_Load_Glyph(face, glyph, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP))) - { - NSLog(@"FT_Load_Glyph() failed with error %08x\n",error); - continue; - } - - if ((error=FT_Get_Glyph(face->glyph, &gl))) - { - NSLog(@"FT_Get_Glyph() failed with error %08x\n",error); - continue; - } - - if ((error=FT_Glyph_Transform(gl, &ftmatrix, &ftdelta))) - { - NSLog(@"FT_Glyph_Transform() failed with error %08x\n",error); - continue; - } - if ((error=FT_Glyph_To_Bitmap(&gl, ft_render_mode_normal, 0, 1))) - { - NSLog(@"FT_Glyph_To_Bitmap() failed with error %08x\n",error); - FT_Done_Glyph(gl); - continue; - } - gb = (FT_BitmapGlyph)gl; - - - if (gb->bitmap.pixel_mode == ft_pixel_mode_grays) - { - int gx = x + gb->left, gy = y - gb->top; - int sbpl = gb->bitmap.pitch; - int sx = gb->bitmap.width, sy = gb->bitmap.rows; - const unsigned char *src = gb->bitmap.buffer; - unsigned char *dst = buf; - unsigned char *adst = abuf; - - if (gy < 0) - { - sy += gy; - src -= sbpl * gy; - gy = 0; - } - else if (gy > 0) - { - dst += bpl * gy; - adst += abpl * gy; - } - - sy += gy; - if (sy > y1) - sy = y1; - - if (gx < 0) - { - sx += gx; - src -= gx; - gx = 0; - } - else if (gx > 0) - { - dst += DI.bytes_per_pixel * gx; - adst += gx; - } - - sx += gx; - if (sx > x1) - sx = x1; - sx -= gx; - - if (sx > 0) - { - for (; gy < sy; gy++, src += sbpl, dst += bpl, adst += bpl) - RENDER_BLIT_ALPHA_A(dst, adst, src, r, g, b, alpha, sx); - } - } -/* TODO: will this case ever appear? */ -/* else if (gb->bitmap.pixel_mode==ft_pixel_mode_mono)*/ - else - { - NSLog(@"unhandled font bitmap format %i", gb->bitmap.pixel_mode); - } - - ftdelta.x += gl->advance.x >> 10; - ftdelta.y += gl->advance.y >> 10; - - FT_Done_Glyph(gl); - } - } -} - - --(BOOL) glyphIsEncoded: (NSGlyph)glyph -{ - FT_Face face; - FT_Error error; - - glyph--; - if ((error=FTC_Manager_Lookup_Size(ftc_manager, &imgd.font, &face, 0))) - { - NSLog(@"FTC_Manager_Lookup_Size() failed with error %08x",error); - return NO; - } - - if ((error=FT_Load_Glyph(face, glyph, 0))) - { - NSLog(@"FT_Load_Glyph() failed with error %08x",error); - return NO; - } - - return YES; -} - - -- (NSSize) advancementForGlyph: (NSGlyph)glyph -{ - FT_Error error; - - if (glyph == NSControlGlyph - || glyph == GSAttachmentGlyph) - return NSZeroSize; - - if (glyph != NSNullGlyph) - glyph--; - if (screenFont) - { - int entry = glyph % CACHE_SIZE; - FTC_SBit sbit; - - if (cachedGlyph[entry] == glyph) - return cachedSize[entry]; - - if ((error=FTC_SBitCache_Lookup(ftc_sbitcache, &advancementImgd, glyph, &sbit, NULL))) - { - NSLog(@"FTC_SBitCache_Lookup() failed with error %08x (%08x, %08x, %ix%i, %08x)\n", - error, glyph, advancementImgd.font.face_id, - advancementImgd.font.pix_width, advancementImgd.font.pix_height, -#ifdef FT212_STUFF - advancementImgd.type -#else - advancementImgd.flags -#endif - ); - return NSZeroSize; - } - - cachedGlyph[entry] = glyph; - cachedSize[entry] = NSMakeSize(sbit->xadvance, sbit->yadvance); - return cachedSize[entry]; - } - else - { - FT_Face face; - FT_Glyph gl; - FT_Matrix ftmatrix; - FT_Vector ftdelta; - float f; - NSSize s; - - f = fabs(matrix[0] * matrix[3] - matrix[1] * matrix[2]); - if (f > 1) - f = sqrt(f); - else - f = 1.0; - - f = (int)f; - - ftmatrix.xx = matrix[0] / f * 65536.0; - ftmatrix.xy = matrix[1] / f * 65536.0; - ftmatrix.yx = matrix[2] / f * 65536.0; - ftmatrix.yy = matrix[3] / f * 65536.0; - ftdelta.x = ftdelta.y = 0; - - if (FTC_Manager_Lookup_Size(ftc_manager, &imgd.font, &face, 0)) - return NSZeroSize; - - if (FT_Load_Glyph(face, glyph, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)) - return NSZeroSize; - - if (FT_Get_Glyph(face->glyph, &gl)) - return NSZeroSize; - - if (FT_Glyph_Transform(gl, &ftmatrix, &ftdelta)) - return NSZeroSize; - - s = NSMakeSize(gl->advance.x / 65536.0, gl->advance.y / 65536.0); - - FT_Done_Glyph(gl); - - return s; - } -} - -- (NSRect) boundingRectForGlyph: (NSGlyph)glyph -{ -#ifdef FT212_STUFF - FTC_ImageDesc *cur; -#else - FTC_ImageTypeRec *cur; -#endif - FT_BBox bbox; - FT_Glyph g; - FT_Error error; - - glyph--; -/* TODO: this is ugly */ - cur = &imgd; - if ((error=FTC_ImageCache_Lookup(ftc_imagecache, cur, glyph, &g, NULL))) - { - NSLog(@"FTC_ImageCache_Lookup() failed with error %08x",error); -// NSLog(@"boundingRectForGlyph: %04x -> %i\n", aGlyph, glyph); - return fontBBox; - } - - FT_Glyph_Get_CBox(g, ft_glyph_bbox_gridfit, &bbox); - -/* printf("got cbox for %04x: %i, %i - %i, %i\n", - aGlyph, bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax);*/ - - return NSMakeRect(bbox.xMin / 64.0, bbox.yMin / 64.0, - (bbox.xMax - bbox.xMin) / 64.0, (bbox.yMax - bbox.yMin) / 64.0); -} - --(NSPoint) positionOfGlyph: (NSGlyph)g - precededByGlyph: (NSGlyph)prev - isNominal: (BOOL *)nominal -{ - NSPoint a; - FT_Face face; - FT_Vector vec; - FT_GlyphSlot glyph; - - if (nominal) - *nominal = YES; - - if (g == NSControlGlyph || prev == NSControlGlyph) - return NSZeroPoint; - - g--; - prev--; - - if (FTC_Manager_Lookup_Size(ftc_manager, &imgd.font, &face, 0)) - return NSZeroPoint; - - if (FT_Load_Glyph(face, prev, FT_LOAD_DEFAULT)) - return NSZeroPoint; - - glyph = face->glyph; - a = NSMakePoint(glyph->advance.x / 64.0, glyph->advance.y / 64.0); - - if (FT_Get_Kerning(face, prev, g, ft_kerning_default, &vec)) - return a; - - if (vec.x == 0 && vec.y == 0) - return a; - - if (nominal) - *nominal = NO; - - a.x += vec.x / 64.0; - a.y += vec.y / 64.0; - return a; -} - - -- (CGFloat) widthOfString: (NSString*)string -{ - unichar ch; - int i, c = [string length]; - int total; - - FTC_CMapDescRec cmap; - unsigned int glyph; - - FTC_SBit sbit; - -#ifdef FT212_STUFF - FTC_ImageDesc *cur; -#else - FTC_ImageTypeRec *cur; -#endif - - - cmap.face_id = imgd.font.face_id; - cmap.u.encoding = ft_encoding_unicode; - cmap.type = FTC_CMAP_BY_ENCODING; - - total = 0; - for (i = 0; i < c; i++) - { - ch = [string characterAtIndex: i]; - cur = &imgd; - glyph = FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, ch); - - /* TODO: shouldn't use sbit cache for this */ - if (1) - { - if (FTC_SBitCache_Lookup(ftc_sbitcache, cur, glyph, &sbit, NULL)) - continue; - - total += sbit->xadvance; - } - else - { - NSLog(@"non-sbit code not implemented"); - } - } - return total; -} - - --(NSGlyph) glyphWithName: (NSString *)glyphName -{ - FT_Face face; - NSGlyph g; - - if (FTC_Manager_Lookup_Size(ftc_manager, &imgd.font, &face, 0)) - return NSNullGlyph; - - g = FT_Get_Name_Index(face, (FT_String *)[glyphName lossyCString]); - if (g) - return g + 1; - - return NSNullGlyph; -} - - -/* - -conic: (a,b,c) -p=(1-t)^2*a + 2*(1-t)*t*b + t^2*c - -cubic: (a,b,c,d) -p=(1-t)^3*a + 3*(1-t)^2*t*b + 3*(1-t)*t^2*c + t^3*d - - - -p(t)=(1-t)^3*a + 3*(1-t)^2*t*b + 3*(1-t)*t^2*c + t^3*d -t=m+ns= -n=l-m - - -q(s)=p(m+ns)= - -(d-3c+3b-a)*n^3 * s^3 + -((3d-9c+9b-3a)*m+3c-6b+3a)*n^2 * s^2 + -((3d-9c+9b-3a)*m^2+(6c-12b+6a)*m+3b-3a)*n * s + -(d-3c+3b-a)*m^3+(3c-6b+3a)*m^2+(3b-3a)m+a - - -q(t)=(1-t)^3*aa + 3*(1-t)^2*t*bb + 3*(1-t)*t^2*cc + t^3*dd = - -(dd-3cc+3bb-aa)*t^3 + -(3cc-6bb+3aa)*t^2 + -(3bb-3aa)*t + -aa - - -aa = (d-3*c+3*b-a)*m^3+(3*c-6*b+3*a)*m^2+(3*b-3*a)*m+a -3*bb-3*aa = ((3*d-9*c+9*b-3*a)*m^2+(6*c-12*b+6*a)*m+3*b-3*a)*n -3*cc-6*bb+3*aa = ((3*d-9*c+9*b-3*a)*m+3*c-6*b+3*a)*n^2 -dd-3*cc+3*bb-aa = (d-3*c+3*b-a)*n^3 - - -aa= (d - 3c + 3b - a) m^3 + (3c - 6b + 3a) m^2 + (3b - 3a) m + a - -bb= ((d - 3c + 3b - a) m^2 + (2c - 4b + 2a) m + b - a) n - + aa - -cc= ((d - 3c + 3b - a) m + c - 2b + a) n^2 - + 2*bb - + aa - -dd= (d - 3c + 3b - a) n^3 - + 3*cc - + 3*bb - + aa - - - - -p(t) = (1-t)^2*e + 2*(1-t)*t*f + t^2*g - ~= -q(t) = (1-t)^3*a + 3*(1-t)^2*t*b + 3*(1-t)*t^2*c + t^3*d - - -p(0)=q(0) && p(1)=q(1) -> -a=e -d=g - - -p(0.5) = 1/8*(2a + 4f + 2d) -q(0.5) = 1/8*(a + 3*b + 3*c + d) - -b+c=1/3*(a+4f+d) - -p(1/4) = 1/64* -p(3/4) = 1/64*(4e+24f+36g) - -q(1/4) = 1/64* -q(3/4) = 1/64*(a + 9b + 27c + 27d) - -3b+c=1/3*(3a+8f+d) - - -3b+c=1/3*(3a+8f+d) - b+c=1/3*(a+4f+d) - -b=1/3*(e+2f) -c=1/3*(2f+g) - - -q(t) = (1-t)^3*e + (1-t)^2*t*(e+2f) + (1-t)*t^2*(2f+g) + t^3*g = -((1-t)^3+(1-t)^2*t)*e + (1-t)^2*t*2f + (1-t)*t^2*2f + (t^3+(1-t)*t^2)*g = - -((1-t)^3+(1-t)^2*t)*e + 2f*(t*(1-t)*((1-t)+t)) + (t^3+(1-t)*t^2)*g = -((1-t)^3+(1-t)^2*t)*e + 2*(1-t)*t*f + (t^3+(1-t)*t^2)*g = -(1-t)^2*e + 2*(1-t)*t*f + t^2*g - -p(t)=q(t) - -*/ - -/* TODO: try to combine charpath and NSBezierPath handling? */ - -static int charpath_move_to(FT_Vector *to, void *user) -{ - GSGState *self = (GSGState *)user; - NSPoint d; - d.x = to->x / 65536.0; - d.y = to->y / 65536.0; - [self DPSclosepath]; /* TODO: this isn't completely correct */ - [self DPSmoveto: d.x:d.y]; - return 0; -} - -static int charpath_line_to(FT_Vector *to, void *user) -{ - GSGState *self = (GSGState *)user; - NSPoint d; - d.x = to->x / 65536.0; - d.y = to->y / 65536.0; - [self DPSlineto: d.x:d.y]; - return 0; -} - -static int charpath_conic_to(FT_Vector *c1, FT_Vector *to, void *user) -{ - GSGState *self = (GSGState *)user; - NSPoint a, b, c, d; - [self DPScurrentpoint: &a.x:&a.y]; - d.x = to->x / 65536.0; - d.y = to->y / 65536.0; - b.x = c1->x / 65536.0; - b.y = c1->y / 65536.0; - c.x = (b.x * 2 + d.x) / 3.0; - c.y = (b.y * 2 + d.y) / 3.0; - b.x = (b.x * 2 + a.x) / 3.0; - b.y = (b.y * 2 + a.y) / 3.0; - [self DPScurveto: b.x:b.y : c.x:c.y : d.x:d.y]; - return 0; -} - -static int charpath_cubic_to(FT_Vector *c1, FT_Vector *c2, FT_Vector *to, void *user) -{ - GSGState *self = (GSGState *)user; - NSPoint b, c, d; - b.x = c1->x / 65536.0; - b.y = c1->y / 65536.0; - c.x = c2->x / 65536.0; - c.y = c2->y / 65536.0; - d.x = to->x / 65536.0; - d.y = to->y / 65536.0; - [self DPScurveto: b.x:b.y : c.x:c.y : d.x:d.y]; - return 0; -} - -static FT_Outline_Funcs charpath_funcs = { -move_to:charpath_move_to, -line_to:charpath_line_to, -conic_to:charpath_conic_to, -cubic_to:charpath_cubic_to, -shift:10, -delta:0, -}; - - -static int bezierpath_move_to(FT_Vector *to, void *user) -{ - NSBezierPath *path = (NSBezierPath *)user; - NSPoint d; - d.x = to->x / 65536.0; - d.y = to->y / 65536.0; - [path closePath]; /* TODO: this isn't completely correct */ - [path moveToPoint: d]; - return 0; -} - -static int bezierpath_line_to(FT_Vector *to, void *user) -{ - NSBezierPath *path = (NSBezierPath *)user; - NSPoint d; - d.x = to->x / 65536.0; - d.y = to->y / 65536.0; - [path lineToPoint: d]; - return 0; -} - -static int bezierpath_conic_to(FT_Vector *c1, FT_Vector *to, void *user) -{ - NSBezierPath *path = (NSBezierPath *)user; - NSPoint a, b, c, d; - a = [path currentPoint]; - d.x = to->x / 65536.0; - d.y = to->y / 65536.0; - b.x = c1->x / 65536.0; - b.y = c1->y / 65536.0; - c.x = (b.x * 2 + d.x) / 3.0; - c.y = (b.y * 2 + d.y) / 3.0; - b.x = (b.x * 2 + a.x) / 3.0; - b.y = (b.y * 2 + a.y) / 3.0; - [path curveToPoint: d controlPoint1: b controlPoint2: c]; - return 0; -} - -static int bezierpath_cubic_to(FT_Vector *c1, FT_Vector *c2, FT_Vector *to, void *user) -{ - NSBezierPath *path = (NSBezierPath *)user; - NSPoint b, c, d; - b.x = c1->x / 65536.0; - b.y = c1->y / 65536.0; - c.x = c2->x / 65536.0; - c.y = c2->y / 65536.0; - d.x = to->x / 65536.0; - d.y = to->y / 65536.0; - [path curveToPoint: d controlPoint1: b controlPoint2: c]; - return 0; -} - -static FT_Outline_Funcs bezierpath_funcs = { -move_to:bezierpath_move_to, -line_to:bezierpath_line_to, -conic_to:bezierpath_conic_to, -cubic_to:bezierpath_cubic_to, -shift:10, -delta:0, -}; - - -/* TODO: sometimes gets 'glyph transformation failed', probably need to -add code to avoid loading bitmaps for glyphs */ --(void) outlineString: (const char *)s - at: (CGFloat)x : (CGFloat)y - gstate: (void *)func_param -{ - unichar *c; - int i; - FTC_CMapDescRec cmap; - unsigned int glyph; - - unichar *uch; - int ulen; - -#ifdef FT212_STUFF - FTC_ImageDesc cur; -#else - FTC_ImageTypeRec cur; -#endif - - - FT_Matrix ftmatrix; - FT_Vector ftdelta; - - ftmatrix.xx = 65536; - ftmatrix.xy = 0; - ftmatrix.yx = 0; - ftmatrix.yy = 65536; - ftdelta.x = x * 64.0; - ftdelta.y = y * 64.0; - - - uch = NULL; - ulen = 0; - GSToUnicode(&uch, &ulen, s, strlen(s), NSUTF8StringEncoding, NSDefaultMallocZone(), 0); - - - cur = imgd; - - cmap.face_id = imgd.font.face_id; - cmap.u.encoding = ft_encoding_unicode; - cmap.type = FTC_CMAP_BY_ENCODING; - - for (c = uch, i = 0; i < ulen; i++, c++) - { - FT_Face face; - FT_Glyph gl; - FT_OutlineGlyph og; - - glyph = FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, *c); - cur.font.face_id = imgd.font.face_id; - - if (FTC_Manager_Lookup_Size(ftc_manager, &cur.font, &face, 0)) - continue; - if (FT_Load_Glyph(face, glyph, FT_LOAD_DEFAULT)) - continue; - - if (FT_Get_Glyph(face->glyph, &gl)) - continue; - - if (FT_Glyph_Transform(gl, &ftmatrix, &ftdelta)) - { - NSLog(@"glyph transformation failed!"); - continue; - } - og = (FT_OutlineGlyph)gl; - - ftdelta.x += gl->advance.x >> 10; - ftdelta.y += gl->advance.y >> 10; - - FT_Outline_Decompose(&og->outline, &charpath_funcs, func_param); - - FT_Done_Glyph(gl); - - } - - if (ulen) - { - [(GSGState *)func_param DPSmoveto: ftdelta.x / 64.0 : ftdelta.y / 64.0]; - } - - free(uch); -} - - --(void) appendBezierPathWithGlyphs: (NSGlyph *)glyphs - count: (int)count - toBezierPath: (NSBezierPath *)path -{ - int i; - NSGlyph glyph; - - FT_Matrix ftmatrix; - FT_Vector ftdelta; - - NSPoint p = [path currentPoint]; - - ftmatrix.xx = 65536; - ftmatrix.xy = 0; - ftmatrix.yx = 0; - ftmatrix.yy = 65536; - ftdelta.x = p.x * 64.0; - ftdelta.y = p.y * 64.0; - - for (i = 0; i < count; i++, glyphs++) - { - FT_Face face; - FT_Glyph gl; - FT_OutlineGlyph og; - - glyph = *glyphs - 1; - - if (FTC_Manager_Lookup_Size(ftc_manager, &imgd.font, &face, 0)) - continue; - if (FT_Load_Glyph(face, glyph, FT_LOAD_DEFAULT)) - continue; - - if (FT_Get_Glyph(face->glyph, &gl)) - continue; - - if (FT_Glyph_Transform(gl, &ftmatrix, &ftdelta)) - { - NSLog(@"glyph transformation failed!"); - continue; - } - og = (FT_OutlineGlyph)gl; - - ftdelta.x += gl->advance.x >> 10; - ftdelta.y += gl->advance.y >> 10; - - FT_Outline_Decompose(&og->outline, &bezierpath_funcs, path); - - FT_Done_Glyph(gl); - } - - if (count) - { - [path moveToPoint: NSMakePoint(ftdelta.x / 64.0, ftdelta.y / 64.0)]; - } -} - - -static int filters[3][7]= -{ -{ 0*65536/9, 1*65536/9, 2*65536/9, 3*65536/9, 2*65536/9, 1*65536/9, 0*65536/9}, -{ 0*65536/9, 1*65536/9, 2*65536/9, 3*65536/9, 2*65536/9, 1*65536/9, 0*65536/9}, -{ 0*65536/9, 1*65536/9, 2*65536/9, 3*65536/9, 2*65536/9, 1*65536/9, 0*65536/9} -}; - - -+(void) initializeBackend -{ - [GSFontEnumerator setDefaultClass: [FTFontEnumerator class]]; - [GSFontInfo setDefaultClass: [FTFontInfo class]]; - - if (FT_Init_FreeType(&ft_library)) - NSLog(@"FT_Init_FreeType failed"); - if (FTC_Manager_New(ft_library, 0, 0, 4096 * 24, ft_get_face, 0, &ftc_manager)) - NSLog(@"FTC_Manager_New failed"); - if (FTC_SBitCache_New(ftc_manager, &ftc_sbitcache)) - NSLog(@"FTC_SBitCache_New failed"); - if (FTC_ImageCache_New(ftc_manager, &ftc_imagecache)) - NSLog(@"FTC_ImageCache_New failed"); - if (FTC_CMapCache_New(ftc_manager, &ftc_cmapcache)) - NSLog(@"FTC_CMapCache_New failed"); - - { - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - NSString *s; - NSArray *a; - int i; - - subpixel_text = [ud integerForKey: @"back-art-subpixel-text"]; - - /* To make it easier to find an optimal (or at least good) filter, - the filters are configurable (for now). */ - for (i = 0; i < 3; i++) - { - s = [ud stringForKey: - [NSString stringWithFormat: @"back-art-subpixel-filter-%i",i]]; - if (s) - { - int j, c, sum, v; - a = [s componentsSeparatedByString: @" "]; - c = [a count]; - if (!c) - continue; - if (!(c & 1) || c > 7) - { - NSLog(@"invalid number of components in filter (must be odd number, 1<=n<=7)"); - continue; - } - memset(filters[i], 0, sizeof(filters[0])); - sum = 0; - for (j = 0; j < c; j++) - { - v = [[a objectAtIndex: j] intValue]; - sum += v; - filters[i][j + (7 - c) / 2] = v * 65536; - } - if (sum) - { - for (j = 0; j < 7; j++) - { - filters[i][j] /= sum; - } - } - NSLog(@"filter %i: %04x %04x %04x %04x %04x %04x %04x", - i, - filters[i][0],filters[i][1],filters[i][2],filters[i][3], - filters[i][4],filters[i][5],filters[i][6]); - } - } - } -} - --(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; -} - -- (NSMultibyteGlyphPacking) glyphPacking -{ - return NSFourByteGlyphPacking; -} - -@end - - -/* TODO: this whole thing needs cleaning up */ -@implementation FTFontInfo_subpixel - --(void) drawGlyphs: (const NSGlyph *)glyphs : (int)length - at: (int)x : (int)y - to: (int)x0 : (int)y0 : (int)x1 : (int)y1 - : (unsigned char *)buf : (int)bpl - color: (unsigned char)r : (unsigned char)g : (unsigned char)b - : (unsigned char)alpha - transform: (NSAffineTransform *)transform - drawinfo: (struct draw_info_s *)di -{ - FTC_CMapDescRec cmap; - unsigned int glyph; - - int use_sbit; - - FTC_SBit sbit; -#ifdef FT212_STUFF - FTC_ImageDesc cur; -#else - FTC_ImageTypeRec cur; -#endif - - FT_Matrix ftmatrix; - FT_Vector ftdelta; - NSAffineTransformStruct ts; - - BOOL subpixel = NO; - - if (!alpha) - return; - - /* TODO: if we had guaranteed upper bounds on glyph image size we - could do some basic clipping here */ - - x1 -= x0; - y1 -= y0; - x -= x0; - y -= y0; - - ts = [transform transformStruct]; - -/* NSLog(@"[%@ draw using matrix: (%g %g %g %g %g %g)]\n", - self, - matrix[0], matrix[1], matrix[2], - matrix[3], matrix[4], matrix[5] - );*/ - - cur = imgd; - { - float xx, xy, yx, yy; - - xx = matrix[0] * ts.m11 + matrix[1] * ts.m21; - yx = matrix[0] * ts.m12 + matrix[1] * ts.m22; - xy = matrix[2] * ts.m11 + matrix[3] * ts.m21; - yy = matrix[2] * ts.m12 + matrix[3] * ts.m22; - - /* if we're drawing 'normal' text (unscaled, unrotated, reasonable - size), we can and should use the sbit cache */ - if (fabs(xx - ((int)xx)) < 0.01 && fabs(yy - ((int)yy)) < 0.01 && - fabs(xy) < 0.01 && fabs(yx) < 0.01 && - xx < 72 && yy < 72 && xx > 0.5 && yy > 0.5) - { - use_sbit = 1; - cur.font.pix_width = xx; - cur.font.pix_height = yy; - -/* if (cur.font.pix_width < 16 && cur.font.pix_height < 16 && - cur.font.pix_width > 6 && cur.font.pix_height > 6) - cur.type = ftc_image_mono; - else*/ -#ifdef FT212_STUFF - cur.type = ftc_image_grays, subpixel = YES, cur.font.pix_width *= 3, x *= 3; -#else - cur.flags = FT_LOAD_TARGET_LCD, subpixel = YES; -#endif -// imgd.type|=|ftc_image_flag_unhinted; /* TODO? when? */ - } - else - { - float f; - use_sbit = 0; - - f = fabs(xx * yy - xy * yx); - if (f > 1) - f = sqrt(f); - else - f = 1.0; - - f = (int)f; - - cur.font.pix_width = cur.font.pix_height = f; - ftmatrix.xx = xx / f * 65536.0; - ftmatrix.xy = xy / f * 65536.0; - ftmatrix.yx = yx / f * 65536.0; - ftmatrix.yy = yy / f * 65536.0; - ftdelta.x = ftdelta.y = 0; - } - } - - -/* NSLog(@"drawString: '%s' at: %i:%i to: %i:%i:%i:%i:%p\n", - s, x, y, x0, y0, x1, y1, buf);*/ - - cmap.face_id = imgd.font.face_id; - cmap.u.encoding = ft_encoding_unicode; - cmap.type = FTC_CMAP_BY_ENCODING; - - for (; length; length--, glyphs++) - { - glyph = *glyphs - 1; - - if (use_sbit) - { - if (FTC_SBitCache_Lookup(ftc_sbitcache, &cur, glyph, &sbit, NULL)) - continue; - - if (!sbit->buffer) - { - x += sbit->xadvance; - continue; - } - -#ifdef FT212_STUFF - if (sbit->format == ft_pixel_mode_grays) -#else - if (sbit->format == FT_PIXEL_MODE_LCD) -#endif - { -#ifdef FT212_STUFF - int gx = x + sbit->left, gy = y - sbit->top; -#else - int gx = 3 * x + sbit->left, gy = y - sbit->top; -#endif - int px0 = (gx - 2 < 0? gx - 4 : gx - 2) / 3; - int px1 = (gx + sbit->width + 2 < 0? gx + sbit->width + 2: gx + sbit->width + 4) / 3; - int llip = gx - px0 * 3; - int sbpl = sbit->pitch; - int sx = sbit->width, sy = sbit->height; - int psx = px1 - px0; - const unsigned char *src = sbit->buffer; - unsigned char *dst = buf; - unsigned char scratch[psx * 3]; - int mode = subpixel_text == 2? 2 : 0; - - if (gy < 0) - { - sy += gy; - src -= sbpl * gy; - gy = 0; - } - else if (gy > 0) - { - dst += bpl * gy; - } - - sy += gy; - if (sy > y1) - sy = y1; - - if (px1 > x1) - px1 = x1; - if (px0 < 0) - { - px0 = -px0; - } - else - { - px1 -= px0; - dst += px0 * DI.bytes_per_pixel; - px0 = 0; - } - - if (px1 <= 0) - { - x += sbit->xadvance; - continue; - } - - for (; gy < sy; gy++, src += sbpl, dst += bpl) - { - int i, j; - int v0, v1, v2; - for (i = 0, j = -llip; i < psx * 3; i+=3) - { - v0 = (0 + - + (j > 2 && j 1 && j 0 && j -1 && j -2 && j -3 && j -4 && j 2 && j 1 && j 0 && j -1 && j -2 && j -3 && j -4 && j 2 && j 1 && j 0 && j -1 && j -2 && j -3 && j -4 && j0?v0:0; - scratch[i + 1] = v1>0?v1:0; - scratch[i + (mode ^ 2)] = v2>0?v2:0; - } - DI.render_blit_subpixel(dst, - scratch + px0 * 3, r, g, b, alpha, - px1); - } - } - else if (sbit->format == ft_pixel_mode_mono) - { - int gx = x + sbit->left, gy = y - sbit->top; - int sbpl = sbit->pitch; - int sx = sbit->width, sy = sbit->height; - const unsigned char *src = sbit->buffer; - unsigned char *dst = buf; - int src_ofs = 0; - - if (gy < 0) - { - sy += gy; - src -= sbpl * gy; - gy = 0; - } - else if (gy > 0) - { - dst += bpl * gy; - } - - sy += gy; - if (sy > y1) - sy = y1; - - if (gx < 0) - { - sx += gx; - src -= gx / 8; - src_ofs = (-gx) & 7; - gx = 0; - } - else if (gx > 0) - { - dst += DI.bytes_per_pixel * gx; - } - - sx += gx; - if (sx > x1) - sx = x1; - sx -= gx; - - if (sx > 0) - { - if (alpha >= 255) - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_MONO_OPAQUE(dst, src, src_ofs, r, g, b, sx); - else - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_MONO(dst, src, src_ofs, r, g, b, alpha, sx); - } - } - else - { - NSLog(@"unhandled font bitmap format %i", sbit->format); - } - - x += sbit->xadvance; - } - else - { - FT_Face face; - FT_Glyph gl; - FT_BitmapGlyph gb; - - if (FTC_Manager_Lookup_Size(ftc_manager, &cur.font, &face, 0)) - continue; - - /* TODO: for rotations of 90, 180, 270, and integer - scales hinting might still be a good idea. */ - if (FT_Load_Glyph(face, glyph, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)) - continue; - - if (FT_Get_Glyph(face->glyph, &gl)) - continue; - - if (FT_Glyph_Transform(gl, &ftmatrix, &ftdelta)) - { - NSLog(@"glyph transformation failed!"); - continue; - } - if (FT_Glyph_To_Bitmap(&gl, ft_render_mode_normal, 0, 1)) - { - FT_Done_Glyph(gl); - continue; - } - gb = (FT_BitmapGlyph)gl; - - - if (gb->bitmap.pixel_mode == ft_pixel_mode_grays) - { - int gx = x + gb->left, gy = y - gb->top; - int sbpl = gb->bitmap.pitch; - int sx = gb->bitmap.width, sy = gb->bitmap.rows; - const unsigned char *src = gb->bitmap.buffer; - unsigned char *dst = buf; - - if (gy < 0) - { - sy += gy; - src -= sbpl * gy; - gy = 0; - } - else if (gy > 0) - { - dst += bpl * gy; - } - - sy += gy; - if (sy > y1) - sy = y1; - - if (gx < 0) - { - sx += gx; - src -= gx; - gx = 0; - } - else if (gx > 0) - { - dst += DI.bytes_per_pixel * gx; - } - - sx += gx; - if (sx > x1) - sx = x1; - sx -= gx; - - if (sx > 0) - { - if (alpha >= 255) - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_ALPHA_OPAQUE(dst, src, r, g, b, sx); - else - for (; gy < sy; gy++, src += sbpl, dst += bpl) - RENDER_BLIT_ALPHA(dst, src, r, g, b, alpha, sx); - } - } -/* TODO: will this case ever appear? */ -/* else if (gb->bitmap.pixel_mode==ft_pixel_mode_mono)*/ - else - { - NSLog(@"unhandled font bitmap format %i", gb->bitmap.pixel_mode); - } - - ftdelta.x += gl->advance.x >> 10; - ftdelta.y += gl->advance.y >> 10; - - FT_Done_Glyph(gl); - } - } -} - -@end - -@interface FTFontInfo (experimental_glyph_printing_extension) --(const char *) nameOfGlyph: (NSGlyph)g; -@end - -@implementation FTFontInfo (experimental_glyph_printing_extension) --(const char *) nameOfGlyph: (NSGlyph)g -{ -static char buf[1024]; /* !!TODO!! */ - FT_Face face; - - g--; - if (FTC_Manager_Lookup_Size(ftc_manager, &imgd.font, &face, 0)) - return ".notdef"; - - if (FT_Get_Glyph_Name(face, g, buf, sizeof(buf))) - return ".notdef"; - - return buf; -} -@end - -