diff --git a/ChangeLog b/ChangeLog index a40f6d4..859681a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-03-29 Fred Kiefer + + * Source/cairo/CairoFontEnumerator.m, + * Source/cairo/CairoFaceInfo.m, + * Source/cairo/Win32CairoSurface.m, + * Source/cairo/CairoFontInfo.m, + * Source/cairo/Win32CairoGlitzSurface.m, + * Source/cairo/CairoGState.m: + Clean up and better error check and reporting on cairo and malloc calls. + 2008-03-19 Adam Fedor * Version 0.13.2 diff --git a/Source/cairo/CairoFaceInfo.m b/Source/cairo/CairoFaceInfo.m index 22fff7a..74fc8a0 100644 --- a/Source/cairo/CairoFaceInfo.m +++ b/Source/cairo/CairoFaceInfo.m @@ -32,7 +32,7 @@ #include #include -@ implementation CairoFaceInfo +@implementation CairoFaceInfo - (id) initWithfamilyName: (NSString *)familyName weight: (int)weight @@ -103,21 +103,20 @@ FcResult result; FcPattern *resolved; - FcConfigSubstitute (NULL, _pattern, FcMatchPattern); + FcConfigSubstitute(NULL, _pattern, FcMatchPattern); FcDefaultSubstitute(_pattern); resolved = FcFontMatch(NULL, _pattern, &result); _fontFace = cairo_ft_font_face_create_for_pattern(resolved); FcPatternDestroy(resolved); - if ((!_fontFace) - || (cairo_font_face_status(_fontFace) != CAIRO_STATUS_SUCCESS)) - { - NSLog(@"Creating a font face failed %@", _familyName); - cairo_font_face_destroy(_fontFace); - _fontFace = NULL; - return NULL; - } + if (cairo_font_face_status(_fontFace) != CAIRO_STATUS_SUCCESS) + { + NSLog(@"Creating a font face failed %@", _familyName); + cairo_font_face_destroy(_fontFace); + _fontFace = NULL; + return NULL; + } } return _fontFace; diff --git a/Source/cairo/CairoFontEnumerator.m b/Source/cairo/CairoFontEnumerator.m index 6664498..7c0e157 100644 --- a/Source/cairo/CairoFontEnumerator.m +++ b/Source/cairo/CairoFontEnumerator.m @@ -62,7 +62,7 @@ NSMutableDictionary * __allFonts; return face; } -// Make a GNUStep style font descriptor from a FcPattern +// Make a GNUstep style font descriptor from a FcPattern static NSArray *faFromFc(FcPattern *pat) { int weight, slant, spacing, nsweight; @@ -87,42 +87,42 @@ static NSArray *faFromFc(FcPattern *pat) switch (weight) { case FC_WEIGHT_LIGHT: - [style appendString: @"Light"]; - nsweight = 3; - break; + [style appendString: @"Light"]; + nsweight = 3; + break; case FC_WEIGHT_MEDIUM: - nsweight = 6; - break; + nsweight = 6; + break; case FC_WEIGHT_DEMIBOLD: - [style appendString: @"Demibold"]; - nsweight = 7; - break; + [style appendString: @"Demibold"]; + nsweight = 7; + break; case FC_WEIGHT_BOLD: - [style appendString: @"Bold"]; - nsweight = 9; - nstraits |= NSBoldFontMask; - break; + [style appendString: @"Bold"]; + nsweight = 9; + nstraits |= NSBoldFontMask; + break; case FC_WEIGHT_BLACK: - [style appendString: @"Black"]; - nsweight = 12; - nstraits |= NSBoldFontMask; - break; + [style appendString: @"Black"]; + nsweight = 12; + nstraits |= NSBoldFontMask; + break; default: - nsweight = 6; + nsweight = 6; } switch (slant) { case FC_SLANT_ROMAN: - break; + break; case FC_SLANT_ITALIC: - [style appendString: @"Italic"]; - nstraits |= NSItalicFontMask; - break; + [style appendString: @"Italic"]; + nstraits |= NSItalicFontMask; + break; case FC_SLANT_OBLIQUE: - [style appendString: @"Oblique"]; - nstraits |= NSItalicFontMask; - break; + [style appendString: @"Oblique"]; + nstraits |= NSItalicFontMask; + break; } if ([style length] > 0) @@ -161,7 +161,7 @@ static NSArray *faFromFc(FcPattern *pat) char *family; if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **)&family) - == FcResultMatch) + == FcResultMatch) { NSArray *fontArray; @@ -176,19 +176,19 @@ static NSArray *faFromFc(FcPattern *pat) familyArray = [fcxft_allFontFamilies objectForKey: familyString]; if (familyArray == nil) { - NSDebugLog(@"Found font family %@", familyString); + NSDebugLog(@"Found font family %@", familyString); familyArray = [[NSMutableArray alloc] init]; [fcxft_allFontFamilies setObject: familyArray - forKey: familyString]; + forKey: familyString]; RELEASE(familyArray); } NSDebugLog(@"fc enumerator: adding font: %@", name); [familyArray addObject: fontArray]; [fcxft_allFontNames addObject: name]; aFont = [[CairoFaceInfo alloc] initWithfamilyName: familyString - weight: [[fontArray objectAtIndex: 2] intValue] - traits: [[fontArray objectAtIndex: 3] unsignedIntValue] - pattern: fs->fonts[i]]; + weight: [[fontArray objectAtIndex: 2] intValue] + traits: [[fontArray objectAtIndex: 3] unsignedIntValue] + pattern: fs->fonts[i]]; [fcxft_allFonts setObject: aFont forKey: name]; RELEASE(aFont); } diff --git a/Source/cairo/CairoFontInfo.m b/Source/cairo/CairoFontInfo.m index f637a06..35690bb 100644 --- a/Source/cairo/CairoFontInfo.m +++ b/Source/cairo/CairoFontInfo.m @@ -42,16 +42,22 @@ _cacheSize = size; if (_cachedSizes) { - free(_cachedSizes); + objc_free(_cachedSizes); } if (_cachedGlyphs) { - free(_cachedGlyphs); + objc_free(_cachedGlyphs); + } + _cachedSizes = objc_malloc(sizeof(NSSize) * size); + if (_cachedSizes) + { + memset(_cachedSizes, 0, sizeof(NSSize) * size); + } + _cachedGlyphs = objc_malloc(sizeof(unsigned int) * size); + if (_cachedGlyphs) + { + memset(_cachedGlyphs, 0, sizeof(unsigned int) * size); } - _cachedSizes = malloc(sizeof(NSSize) * size); - memset(_cachedSizes, 0, sizeof(NSSize) * size); - _cachedGlyphs = malloc(sizeof(unsigned int) * size); - memset(_cachedGlyphs, 0, sizeof(unsigned int) * size); } - (BOOL) setupAttributes @@ -62,16 +68,13 @@ cairo_matrix_t ctm; cairo_font_options_t *options; - /* do not forget to check for font specific - * cache size from face info FIXME FIXME - */ ASSIGN(_faceInfo, [CairoFontEnumerator fontWithName: fontName]); if (!_faceInfo) { return NO; } - _cachedSizes = NULL; + // check for font specific cache size from face info [self setCacheSize: [_faceInfo cacheSize]]; /* setting GSFontInfo: @@ -91,6 +94,7 @@ cairo_matrix_init(&font_matrix, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); cairo_matrix_init_identity(&ctm); + // FIXME: Should get default font options from somewhere options = cairo_font_options_create(); face = [_faceInfo fontFace]; @@ -98,6 +102,7 @@ { return NO; } + _scaled = cairo_scaled_font_create(face, &font_matrix, &ctm, options); cairo_font_options_destroy(options); if (!_scaled) @@ -122,8 +127,9 @@ matrix: (const float *)fmatrix screenFont: (BOOL)p_screenFont { - //NSLog(@"initWithFontName %@",name); - [super init]; + self = [super init]; + if (!self) + return nil; _screenFont = p_screenFont; fontName = [name copy]; @@ -155,8 +161,10 @@ { cairo_scaled_font_destroy(_scaled); } - free(_cachedSizes); - free(_cachedGlyphs); + if (_cachedSizes) + objc_free(_cachedSizes); + if (_cachedGlyphs) + objc_free(_cachedGlyphs); [super dealloc]; } @@ -200,21 +208,30 @@ BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph, - (NSSize) advancementForGlyph: (NSGlyph)glyph { cairo_text_extents_t ctext; - int entry; - entry = glyph % _cacheSize; - - if (_cachedGlyphs[entry] == glyph) + if (_cachedSizes) { - return _cachedSizes[entry]; + int entry = glyph % _cacheSize; + + if (_cachedGlyphs[entry] == glyph) + { + return _cachedSizes[entry]; + } + + if (_cairo_extents_for_NSGlyph(_scaled, glyph, &ctext)) + { + _cachedGlyphs[entry] = glyph; + _cachedSizes[entry] = NSMakeSize(ctext.x_advance, ctext.y_advance); + + return _cachedSizes[entry]; + } } - - if (_cairo_extents_for_NSGlyph(_scaled, glyph, &ctext)) + else { - _cachedGlyphs[entry] = glyph; - _cachedSizes[entry] = NSMakeSize(ctext.x_advance, ctext.y_advance); - - return _cachedSizes[entry]; + if (_cairo_extents_for_NSGlyph(_scaled, glyph, &ctext)) + { + return NSMakeSize(ctext.x_advance, ctext.y_advance); + } } return NSZeroSize; @@ -294,24 +311,60 @@ BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph, } cdata = objc_malloc(sizeof(char) * 4 * ix * iy); + if (!cdata) + { + NSLog(@"Could not allocate drawing space for glyphs"); + return; + } + isurface = cairo_image_surface_create_for_data(cdata, format, ix, iy, 4*ix); status = cairo_surface_status(isurface); if (status != CAIRO_STATUS_SUCCESS) { + NSLog(@"Error while creating surface: %s", + cairo_status_to_string(status)); cairo_surface_destroy(isurface); objc_free(cdata); return; } ct = cairo_create(isurface); + if (cairo_status(ct) != CAIRO_STATUS_SUCCESS) + { + NSLog(@"Error while creating context: %s", + cairo_status_to_string(cairo_status(ct))); + cairo_destroy(ct); + cairo_surface_destroy(isurface); + objc_free(cdata); + return; + } cairo_matrix_init(&font_matrix, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); cairo_set_font_matrix(ct, &font_matrix); + if (cairo_status(ct) != CAIRO_STATUS_SUCCESS) + { + NSLog(@"Error while setting font matrix: %s", + cairo_status_to_string(cairo_status(ct))); + cairo_destroy(ct); + cairo_surface_destroy(isurface); + objc_free(cdata); + return; + } + + cairo_set_font_face(ct, [_faceInfo fontFace]); + if (cairo_status(ct) != CAIRO_STATUS_SUCCESS) + { + NSLog(@"Error while setting font face: %s", + cairo_status_to_string(cairo_status(ct))); + cairo_destroy(ct); + cairo_surface_destroy(isurface); + objc_free(cdata); + return; + } cairo_text_path(ct, str); - status = cairo_status(ct); - if (status == CAIRO_STATUS_SUCCESS) + if (cairo_status(ct) == CAIRO_STATUS_SUCCESS) { cairo_path_t *cpath; cairo_path_data_t *data; @@ -381,6 +434,7 @@ BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph, cairo_status_to_string(cairo_status(ct))); return; } + cairo_set_font_face(ct, [_faceInfo fontFace]); if (cairo_status(ct) != CAIRO_STATUS_SUCCESS) { diff --git a/Source/cairo/CairoGState.m b/Source/cairo/CairoGState.m index 6a77858..9a976b1 100644 --- a/Source/cairo/CairoGState.m +++ b/Source/cairo/CairoGState.m @@ -135,7 +135,7 @@ static float floatToUserSpace(NSAffineTransform *ctm, float f) if (status != CAIRO_STATUS_SUCCESS) { NSLog(@"Cairo status '%s' in copy", cairo_status_to_string(status)); - _ct = NULL; + copy->_ct = NULL; } else { @@ -999,8 +999,14 @@ _set_op(cairo_t *ct, NSCompositingOperation op) switch (bitsPerPixel) { case 32: - rowData = (unsigned char *)data[0]; tmp = objc_malloc(pixels * 4); + if (!tmp) + { + NSLog(@"Could not allocate drawing space for image"); + return; + } + + rowData = (unsigned char *)data[0]; index = 0; for (i = 0; i < pixelsHigh; i++) @@ -1027,8 +1033,14 @@ _set_op(cairo_t *ct, NSCompositingOperation op) format = CAIRO_FORMAT_ARGB32; break; case 24: - rowData = (unsigned char *)data[0]; tmp = objc_malloc(pixels * 4); + if (!tmp) + { + NSLog(@"Could not allocate drawing space for image"); + return; + } + + rowData = (unsigned char *)data[0]; index = 0; for (i = 0; i < pixelsHigh; i++) diff --git a/Source/cairo/Win32CairoGlitzSurface.m b/Source/cairo/Win32CairoGlitzSurface.m index bb24897..a784d36 100644 --- a/Source/cairo/Win32CairoGlitzSurface.m +++ b/Source/cairo/Win32CairoGlitzSurface.m @@ -35,35 +35,40 @@ @implementation Win32CairoGlitzSurface ++ (void) initialize +{ + NSLog(@"Win32CairoGlitzSurface : %d : glitz_wgl_init", __LINE__); + glitz_wgl_init(NULL); +} + - (id) initWithDevice: (void *)device { WIN_INTERN *win; - static BOOL first_time = YES; - unsigned long mask = 0; glitz_drawable_format_t dtempl; //static - glitz_drawable_format_t *dformat = NULL; - static unsigned count = 0; + glitz_drawable_format_t *dformat = NULL; glitz_drawable_t *drawable = NULL; glitz_format_t *format = NULL; glitz_surface_t *surface = NULL; RECT sz; -count++; - gsDevice = device; - GetClientRect(GSWINDEVICE,&sz); + GetClientRect(GSWINDEVICE, &sz); win = (WIN_INTERN *)GetWindowLong(GSWINDEVICE, GWL_USERDATA); + if (win && win->useHDC) + { + HGDIOBJ old; - if(first_time) - { - NSLog(@"Win32CairoGlitzSurface : %d (%d) : glitz_wgl_init",__LINE__,count); - glitz_wgl_init(NULL); - first_time=NO; - } + old = SelectObject(win->hdc, win->old); + DeleteObject(old); + DeleteDC(win->hdc); + win->hdc = NULL; + win->old = NULL; + win->useHDC = NO; + } //NSLog(@"Win32CairoGlitzSurface : init window %d (%d,%d-%d,%d)",GSWINDEVICE,sz.left,sz.top,sz.right,sz.bottom); @@ -85,23 +90,10 @@ count++; dtempl.doublebuffer = 0; mask |= GLITZ_FORMAT_DOUBLEBUFFER_MASK; - if(win && win->useHDC) - { - HGDIOBJ old; - - old = SelectObject(win->hdc, win->old); - DeleteObject(old); - DeleteDC(win->hdc); - win->hdc = NULL; - win->old = NULL; - win->useHDC = NO; - } - - dformat = glitz_wgl_find_window_format(mask,&dtempl,0); - + dformat = glitz_wgl_find_window_format(mask, &dtempl, 0); if (!dformat) { - NSLog(@"Win32CairoGlitzSurface : %d (%d) : no format for drawable",__LINE__,count); + NSLog(@"Win32CairoGlitzSurface : %d : no format for drawable",__LINE__); exit(1); } @@ -122,12 +114,11 @@ count++; drawable = glitz_wgl_create_drawable_for_window( dformat, GSWINDEVICE, - sz.right-sz.left, - sz.bottom-sz.top); - + sz.right - sz.left, + sz.bottom - sz.top); if (!drawable) { - NSLog(@"Win32CairoGlitzSurface : %d (%d) : no glitz drawable",__LINE__,count); + NSLog(@"Win32CairoGlitzSurface : %d : no glitz drawable",__LINE__); exit(1); } @@ -140,17 +131,21 @@ count++; surface = glitz_surface_create( drawable, format, - sz.right-sz.left, - sz.bottom-sz.top, + sz.right - sz.left, + sz.bottom - sz.top, 0, NULL); - if (!surface) { - NSLog(@"Win32CairoGlitzSurface : %d (%d) : couldn't create glitz surface",__LINE__,count); + NSLog(@"Win32CairoGlitzSurface : %d : couldn't create glitz surface",__LINE__); exit(1); } + glitz_surface_attach(surface, drawable, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR); _surface = cairo_glitz_surface_create(surface); + if (cairo_surface_status(_surface)) + { + DESTROY(self); + } return self; } @@ -158,8 +153,9 @@ count++; - (NSSize) size { RECT sz; - GetClientRect(GSWINDEVICE,&sz); - return NSMakeSize(sz.right-sz.left, sz.bottom-sz.top); + + GetClientRect(GSWINDEVICE, &sz); + return NSMakeSize(sz.right - sz.left, sz.bottom - sz.top); } @end diff --git a/Source/cairo/Win32CairoSurface.m b/Source/cairo/Win32CairoSurface.m index a5746e6..78f4f3f 100644 --- a/Source/cairo/Win32CairoSurface.m +++ b/Source/cairo/Win32CairoSurface.m @@ -40,19 +40,24 @@ gsDevice = device; win = (WIN_INTERN *)GetWindowLong(GSWINDEVICE, GWL_USERDATA); - if(win && win->useHDC) + if (win && win->useHDC) hDC = win->hdc; else hDC = GetDC(GSWINDEVICE); - if( !hDC ) - { - NSLog(@"Win32CairoSurface : %d : no device context",__LINE__); - exit(1); - } + if (!hDC) + { + NSLog(@"Win32CairoSurface : %d : no device context",__LINE__); + exit(1); + } + _surface = cairo_win32_surface_create(hDC); - if(!(win && win->useHDC)) - ReleaseDC(GSWINDEVICE,hDC); + if (!(win && win->useHDC)) + ReleaseDC(GSWINDEVICE, hDC); + if (cairo_surface_status(_surface)) + { + DESTROY(self); + } return self; } @@ -60,8 +65,9 @@ - (NSSize) size { RECT sz; - GetClientRect(GSWINDEVICE,&sz); - return NSMakeSize(sz.right-sz.left, sz.top-sz.bottom); + + GetClientRect(GSWINDEVICE, &sz); + return NSMakeSize(sz.right - sz.left, sz.top - sz.bottom); } @end