2004-08-02 21:50:17 +00:00
|
|
|
/*
|
2007-10-29 23:25:10 +00:00
|
|
|
CairoFontInfo.m
|
|
|
|
|
|
|
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2007-10-29 23:25:10 +00:00
|
|
|
August 31, 2003
|
|
|
|
Written by Banlu Kemiyatorn <object at gmail dot com>
|
|
|
|
Base on original code of Alex Malmberg
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2007-10-29 23:25:10 +00:00
|
|
|
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
|
2008-06-10 04:12:46 +00:00
|
|
|
version 2 of the License, or (at your option) any later version.
|
2007-10-29 23:25:10 +00:00
|
|
|
|
|
|
|
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 <http://www.gnu.org/licenses/> or write to the
|
|
|
|
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2006-01-30 18:25:11 +00:00
|
|
|
#include "GNUstepBase/Unicode.h"
|
2004-08-02 21:50:17 +00:00
|
|
|
#include <AppKit/NSAffineTransform.h>
|
2007-10-08 21:27:51 +00:00
|
|
|
#include <AppKit/NSBezierPath.h>
|
2004-09-08 22:08:15 +00:00
|
|
|
#include "cairo/CairoFontInfo.h"
|
|
|
|
#include "cairo/CairoFontEnumerator.h"
|
|
|
|
|
2004-08-02 21:50:17 +00:00
|
|
|
#include <math.h>
|
2005-07-27 23:25:32 +00:00
|
|
|
#include <cairo-ft.h>
|
2004-08-02 21:50:17 +00:00
|
|
|
|
|
|
|
@implementation CairoFontInfo
|
|
|
|
|
|
|
|
- (void) setCacheSize: (unsigned int)size
|
|
|
|
{
|
|
|
|
_cacheSize = size;
|
|
|
|
if (_cachedSizes)
|
|
|
|
{
|
2008-03-29 13:16:58 +00:00
|
|
|
objc_free(_cachedSizes);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
if (_cachedGlyphs)
|
|
|
|
{
|
2008-03-29 13:16:58 +00:00
|
|
|
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);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-09-08 22:08:15 +00:00
|
|
|
- (BOOL) setupAttributes
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
|
|
|
cairo_font_extents_t font_extents;
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_font_face_t *face;
|
|
|
|
cairo_matrix_t font_matrix;
|
|
|
|
cairo_matrix_t ctm;
|
|
|
|
cairo_font_options_t *options;
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
ASSIGN(_faceInfo, [CairoFontEnumerator fontWithName: fontName]);
|
2004-09-08 22:08:15 +00:00
|
|
|
if (!_faceInfo)
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2008-03-29 13:16:58 +00:00
|
|
|
// check for font specific cache size from face info
|
2004-09-08 22:08:15 +00:00
|
|
|
[self setCacheSize: [_faceInfo cacheSize]];
|
|
|
|
|
|
|
|
/* setting GSFontInfo:
|
2007-12-11 12:06:42 +00:00
|
|
|
* weight, traits, familyName,
|
2004-09-08 22:08:15 +00:00
|
|
|
* mostCompatibleStringEncoding, encodingScheme,
|
|
|
|
*/
|
|
|
|
|
|
|
|
weight = [_faceInfo weight];
|
|
|
|
traits = [_faceInfo traits];
|
|
|
|
familyName = [[_faceInfo familyName] copy];
|
|
|
|
mostCompatibleStringEncoding = NSUTF8StringEncoding;
|
|
|
|
encodingScheme = @"iso10646-1";
|
|
|
|
|
|
|
|
/* setting GSFontInfo:
|
|
|
|
* xHeight, pix_width, pix_height
|
|
|
|
*/
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_matrix_init(&font_matrix, matrix[0], matrix[1], matrix[2],
|
2007-10-08 21:27:51 +00:00
|
|
|
matrix[3], matrix[4], matrix[5]);
|
2008-07-12 23:47:41 +00:00
|
|
|
//cairo_matrix_scale(&font_matrix, 0.9, 0.9);
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_matrix_init_identity(&ctm);
|
2008-03-29 13:16:58 +00:00
|
|
|
|
2005-08-19 23:42:55 +00:00
|
|
|
face = [_faceInfo fontFace];
|
|
|
|
if (!face)
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
2008-03-29 13:16:58 +00:00
|
|
|
|
2008-07-12 23:47:41 +00:00
|
|
|
// Get default font options
|
|
|
|
options = cairo_font_options_create();
|
|
|
|
if (cairo_font_options_status(options) != CAIRO_STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
_scaled = cairo_scaled_font_create(face, &font_matrix, &ctm, options);
|
2006-03-12 21:50:17 +00:00
|
|
|
cairo_font_options_destroy(options);
|
2008-07-12 23:47:41 +00:00
|
|
|
if (cairo_scaled_font_status(_scaled) != CAIRO_STATUS_SUCCESS)
|
2005-08-19 23:42:55 +00:00
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
2008-07-12 23:47:41 +00:00
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_scaled_font_extents(_scaled, &font_extents);
|
2008-07-12 23:47:41 +00:00
|
|
|
if (cairo_scaled_font_status(_scaled) != CAIRO_STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2007-02-27 16:35:31 +00:00
|
|
|
ascender = font_extents.ascent;
|
|
|
|
descender = -font_extents.descent;
|
|
|
|
xHeight = ascender * 0.6;
|
|
|
|
lineHeight = font_extents.height;
|
2004-08-02 21:50:17 +00:00
|
|
|
maximumAdvancement = NSMakeSize(font_extents.max_x_advance,
|
2007-10-08 21:27:51 +00:00
|
|
|
font_extents.max_y_advance);
|
2004-09-08 22:08:15 +00:00
|
|
|
fontBBox = NSMakeRect(0, descender,
|
2007-10-08 21:27:51 +00:00
|
|
|
maximumAdvancement.width, ascender - descender);
|
2008-07-12 23:47:41 +00:00
|
|
|
/*
|
|
|
|
NSLog(@"Font matrix (%g, %g, %g, %g, %g, %g) type %d",
|
|
|
|
matrix[0], matrix[1], matrix[2],
|
|
|
|
matrix[3], matrix[4], matrix[5], cairo_scaled_font_get_type(_scaled));
|
|
|
|
NSLog(@"(%@) h=%g a=%g d=%g max=(%g %g) (%g %g)+(%g %g)\n", fontName,
|
|
|
|
xHeight, ascender, descender,
|
|
|
|
maximumAdvancement.width, maximumAdvancement.height,
|
|
|
|
fontBBox.origin.x, fontBBox.origin.y,
|
|
|
|
fontBBox.size.width, fontBBox.size.height);
|
|
|
|
*/
|
2004-09-08 22:08:15 +00:00
|
|
|
|
|
|
|
return YES;
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithFontName: (NSString *)name
|
2007-10-08 21:27:51 +00:00
|
|
|
matrix: (const float *)fmatrix
|
|
|
|
screenFont: (BOOL)p_screenFont
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
2008-03-29 13:16:58 +00:00
|
|
|
self = [super init];
|
|
|
|
if (!self)
|
|
|
|
return nil;
|
2004-08-02 21:50:17 +00:00
|
|
|
|
|
|
|
_screenFont = p_screenFont;
|
|
|
|
fontName = [name copy];
|
|
|
|
memcpy(matrix, fmatrix, sizeof(matrix));
|
|
|
|
|
|
|
|
if (_screenFont)
|
|
|
|
{
|
|
|
|
/* Round up; makes the text more legible. */
|
|
|
|
matrix[0] = ceil(matrix[0]);
|
|
|
|
if (matrix[3] < 0.0)
|
2007-10-08 21:27:51 +00:00
|
|
|
matrix[3] = floor(matrix[3]);
|
2004-08-02 21:50:17 +00:00
|
|
|
else
|
2007-10-08 21:27:51 +00:00
|
|
|
matrix[3] = ceil(matrix[3]);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
2004-09-08 22:08:15 +00:00
|
|
|
if (![self setupAttributes])
|
|
|
|
{
|
|
|
|
RELEASE(self);
|
|
|
|
return nil;
|
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
{
|
|
|
|
RELEASE(_faceInfo);
|
2005-08-19 23:42:55 +00:00
|
|
|
if (_scaled)
|
|
|
|
{
|
|
|
|
cairo_scaled_font_destroy(_scaled);
|
|
|
|
}
|
2008-03-29 13:16:58 +00:00
|
|
|
if (_cachedSizes)
|
|
|
|
objc_free(_cachedSizes);
|
|
|
|
if (_cachedGlyphs)
|
|
|
|
objc_free(_cachedGlyphs);
|
2004-08-02 21:50:17 +00:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
2007-02-27 16:35:31 +00:00
|
|
|
- (float) defaultLineHeightForFont
|
|
|
|
{
|
|
|
|
return lineHeight;
|
|
|
|
}
|
|
|
|
|
2004-08-02 21:50:17 +00:00
|
|
|
- (BOOL) glyphIsEncoded: (NSGlyph)glyph
|
|
|
|
{
|
2008-04-04 22:07:03 +00:00
|
|
|
/* 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;
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
2005-11-07 00:11:09 +00:00
|
|
|
static
|
|
|
|
BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph,
|
2007-10-08 21:27:51 +00:00
|
|
|
cairo_text_extents_t *ctext)
|
2005-11-07 00:11:09 +00:00
|
|
|
{
|
2006-01-30 18:25:11 +00:00
|
|
|
unichar ustr[2];
|
|
|
|
char str[4];
|
|
|
|
unsigned char *b;
|
|
|
|
unsigned int size = 4;
|
|
|
|
int length = 1;
|
|
|
|
|
|
|
|
ustr[0] = glyph;
|
|
|
|
ustr[1] = 0;
|
|
|
|
|
|
|
|
b = (unsigned char *)str;
|
|
|
|
if (!GSFromUnicode(&b, &size, ustr, length,
|
2007-10-08 21:27:51 +00:00
|
|
|
NSUTF8StringEncoding, NULL, GSUniTerminate))
|
2006-01-30 18:25:11 +00:00
|
|
|
{
|
|
|
|
NSLog(@"Conversion failed for %@",
|
2007-10-08 21:27:51 +00:00
|
|
|
[NSString stringWithCharacters: ustr length: length]);
|
2006-01-30 18:25:11 +00:00
|
|
|
return NO;
|
|
|
|
}
|
2006-01-23 20:51:40 +00:00
|
|
|
|
|
|
|
cairo_scaled_font_text_extents(scaled_font, str, ctext);
|
|
|
|
return cairo_scaled_font_status(scaled_font) == CAIRO_STATUS_SUCCESS;
|
2005-07-27 23:25:32 +00:00
|
|
|
}
|
|
|
|
|
2004-08-02 21:50:17 +00:00
|
|
|
- (NSSize) advancementForGlyph: (NSGlyph)glyph
|
|
|
|
{
|
|
|
|
cairo_text_extents_t ctext;
|
|
|
|
|
2008-03-29 13:16:58 +00:00
|
|
|
if (_cachedSizes)
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
2008-03-29 13:16:58 +00:00
|
|
|
int entry = glyph % _cacheSize;
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2008-03-29 13:16:58 +00:00
|
|
|
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];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2005-11-07 00:11:09 +00:00
|
|
|
{
|
2008-03-29 13:16:58 +00:00
|
|
|
if (_cairo_extents_for_NSGlyph(_scaled, glyph, &ctext))
|
|
|
|
{
|
|
|
|
return NSMakeSize(ctext.x_advance, ctext.y_advance);
|
|
|
|
}
|
2005-11-07 00:11:09 +00:00
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2005-11-07 00:11:09 +00:00
|
|
|
return NSZeroSize;
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSRect) boundingRectForGlyph: (NSGlyph)glyph
|
|
|
|
{
|
|
|
|
cairo_text_extents_t ctext;
|
|
|
|
|
2005-11-07 00:11:09 +00:00
|
|
|
if (_cairo_extents_for_NSGlyph(_scaled, glyph, &ctext))
|
|
|
|
{
|
|
|
|
return NSMakeRect(ctext.x_bearing, ctext.y_bearing,
|
2007-10-08 21:27:51 +00:00
|
|
|
ctext.width, ctext.height);
|
2005-11-07 00:11:09 +00:00
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2005-11-07 00:11:09 +00:00
|
|
|
return NSZeroRect;
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (float) widthOfString: (NSString *)string
|
|
|
|
{
|
|
|
|
cairo_text_extents_t ctext;
|
|
|
|
|
2007-07-01 22:17:14 +00:00
|
|
|
if (!string)
|
|
|
|
{
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
cairo_scaled_font_text_extents(_scaled, [string UTF8String], &ctext);
|
2006-01-23 20:51:40 +00:00
|
|
|
if (cairo_scaled_font_status(_scaled) == CAIRO_STATUS_SUCCESS)
|
2005-11-07 00:11:09 +00:00
|
|
|
{
|
|
|
|
return ctext.width;
|
|
|
|
}
|
2004-09-08 22:08:15 +00:00
|
|
|
|
2005-11-07 00:11:09 +00:00
|
|
|
return 0.0;
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
2007-01-31 15:52:53 +00:00
|
|
|
- (NSGlyph) glyphWithName: (NSString *) glyphName
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
|
|
|
/* subclass should override */
|
|
|
|
/* terrible! FIXME */
|
|
|
|
NSGlyph g = [glyphName cString][0];
|
|
|
|
|
|
|
|
return g;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) appendBezierPathWithGlyphs: (NSGlyph *)glyphs
|
2007-10-08 21:27:51 +00:00
|
|
|
count: (int)length
|
|
|
|
toBezierPath: (NSBezierPath *)path
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
2007-10-08 21:27:51 +00:00
|
|
|
cairo_format_t format = CAIRO_FORMAT_ARGB32;
|
|
|
|
cairo_surface_t *isurface;
|
|
|
|
cairo_t *ct;
|
|
|
|
int ix = 400;
|
|
|
|
int iy = 400;
|
|
|
|
unsigned char *cdata;
|
|
|
|
int i;
|
|
|
|
unichar ustr[length+1];
|
|
|
|
char str[3*length+1];
|
|
|
|
unsigned char *b;
|
|
|
|
unsigned int size = 3*length+1;
|
|
|
|
cairo_status_t status;
|
|
|
|
cairo_matrix_t font_matrix;
|
|
|
|
|
|
|
|
for (i = 0; i < length; i++)
|
|
|
|
{
|
|
|
|
ustr[i] = glyphs[i];
|
|
|
|
}
|
|
|
|
ustr[length] = 0;
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2007-10-08 21:27:51 +00:00
|
|
|
b = (unsigned char *)str;
|
|
|
|
if (!GSFromUnicode(&b, &size, ustr, length,
|
|
|
|
NSUTF8StringEncoding, NULL, GSUniTerminate))
|
|
|
|
{
|
|
|
|
NSLog(@"Conversion failed for %@",
|
|
|
|
[NSString stringWithCharacters: ustr length: length]);
|
|
|
|
return;
|
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2007-10-08 21:27:51 +00:00
|
|
|
cdata = objc_malloc(sizeof(char) * 4 * ix * iy);
|
2008-03-29 13:16:58 +00:00
|
|
|
if (!cdata)
|
|
|
|
{
|
|
|
|
NSLog(@"Could not allocate drawing space for glyphs");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-10-08 21:27:51 +00:00
|
|
|
isurface = cairo_image_surface_create_for_data(cdata, format, ix, iy, 4*ix);
|
|
|
|
status = cairo_surface_status(isurface);
|
|
|
|
if (status != CAIRO_STATUS_SUCCESS)
|
|
|
|
{
|
2008-03-29 13:16:58 +00:00
|
|
|
NSLog(@"Error while creating surface: %s",
|
|
|
|
cairo_status_to_string(status));
|
2007-10-08 21:27:51 +00:00
|
|
|
cairo_surface_destroy(isurface);
|
|
|
|
objc_free(cdata);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ct = cairo_create(isurface);
|
2008-03-29 13:16:58 +00:00
|
|
|
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;
|
|
|
|
}
|
2008-04-02 22:10:32 +00:00
|
|
|
|
|
|
|
// Use flip matrix
|
2007-10-08 21:27:51 +00:00
|
|
|
cairo_matrix_init(&font_matrix, matrix[0], matrix[1], matrix[2],
|
2008-04-02 22:10:32 +00:00
|
|
|
-matrix[3], matrix[4], matrix[5]);
|
2007-10-08 21:27:51 +00:00
|
|
|
cairo_set_font_matrix(ct, &font_matrix);
|
2008-03-29 13:16:58 +00:00
|
|
|
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;
|
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2008-04-02 22:10:32 +00:00
|
|
|
if ([path elementCount] > 0)
|
|
|
|
{
|
|
|
|
NSPoint p;
|
|
|
|
|
|
|
|
p = [path currentPoint];
|
|
|
|
cairo_move_to(ct, floorf(p.x), floorf(p.y));
|
|
|
|
}
|
|
|
|
|
2007-10-08 21:27:51 +00:00
|
|
|
cairo_text_path(ct, str);
|
2008-03-29 13:16:58 +00:00
|
|
|
if (cairo_status(ct) == CAIRO_STATUS_SUCCESS)
|
2007-10-08 21:27:51 +00:00
|
|
|
{
|
|
|
|
cairo_path_t *cpath;
|
|
|
|
cairo_path_data_t *data;
|
|
|
|
|
|
|
|
cpath = cairo_copy_path(ct);
|
|
|
|
|
|
|
|
for (i = 0; i < cpath->num_data; i += cpath->data[i].header.length)
|
|
|
|
{
|
|
|
|
data = &cpath->data[i];
|
|
|
|
switch (data->header.type)
|
|
|
|
{
|
|
|
|
case CAIRO_PATH_MOVE_TO:
|
|
|
|
[path moveToPoint: NSMakePoint(data[1].point.x, data[1].point.y)];
|
|
|
|
break;
|
|
|
|
case CAIRO_PATH_LINE_TO:
|
|
|
|
[path lineToPoint: NSMakePoint(data[1].point.x, data[1].point.y)];
|
|
|
|
break;
|
|
|
|
case CAIRO_PATH_CURVE_TO:
|
2008-04-02 22:10:32 +00:00
|
|
|
[path curveToPoint: NSMakePoint(data[3].point.x, data[3].point.y)
|
|
|
|
controlPoint1: NSMakePoint(data[1].point.x, data[1].point.y)
|
|
|
|
controlPoint2: NSMakePoint(data[2].point.x, data[2].point.y)];
|
2007-10-08 21:27:51 +00:00
|
|
|
break;
|
|
|
|
case CAIRO_PATH_CLOSE_PATH:
|
|
|
|
[path closePath];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cairo_path_destroy(cpath);
|
|
|
|
}
|
|
|
|
cairo_destroy(ct);
|
|
|
|
cairo_surface_destroy(isurface);
|
|
|
|
objc_free(cdata);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
2004-09-08 22:08:15 +00:00
|
|
|
- (void) drawGlyphs: (const NSGlyph*)glyphs
|
2007-10-08 21:27:51 +00:00
|
|
|
length: (int)length
|
|
|
|
on: (cairo_t*)ct
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_matrix_t font_matrix;
|
2006-01-30 18:25:11 +00:00
|
|
|
unichar ustr[length+1];
|
|
|
|
char str[3*length+1];
|
|
|
|
unsigned char *b;
|
2005-11-07 00:11:09 +00:00
|
|
|
int i;
|
2006-01-30 18:25:11 +00:00
|
|
|
unsigned int size = 3*length+1;
|
2005-08-28 00:48:12 +00:00
|
|
|
|
2005-11-07 00:11:09 +00:00
|
|
|
for (i = 0; i < length; i++)
|
2004-09-08 22:08:15 +00:00
|
|
|
{
|
2006-01-30 18:25:11 +00:00
|
|
|
ustr[i] = glyphs[i];
|
|
|
|
}
|
|
|
|
ustr[length] = 0;
|
|
|
|
|
|
|
|
b = (unsigned char *)str;
|
|
|
|
if (!GSFromUnicode(&b, &size, ustr, length,
|
2007-10-08 21:27:51 +00:00
|
|
|
NSUTF8StringEncoding, NULL, GSUniTerminate))
|
2006-01-30 18:25:11 +00:00
|
|
|
{
|
|
|
|
NSLog(@"Conversion failed for %@",
|
2007-10-08 21:27:51 +00:00
|
|
|
[NSString stringWithCharacters: ustr length: length]);
|
2006-01-30 18:25:11 +00:00
|
|
|
return;
|
2004-09-08 22:08:15 +00:00
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_matrix_init(&font_matrix, matrix[0], matrix[1], matrix[2],
|
2007-10-08 21:27:51 +00:00
|
|
|
matrix[3], matrix[4], matrix[5]);
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_set_font_matrix(ct, &font_matrix);
|
2006-01-30 18:25:11 +00:00
|
|
|
if (cairo_status(ct) != CAIRO_STATUS_SUCCESS)
|
|
|
|
{
|
2007-10-08 21:27:51 +00:00
|
|
|
NSLog(@"Error while setting font matrix: %s",
|
|
|
|
cairo_status_to_string(cairo_status(ct)));
|
|
|
|
return;
|
2006-01-30 18:25:11 +00:00
|
|
|
}
|
2008-03-29 13:16:58 +00:00
|
|
|
|
2006-01-30 18:25:11 +00:00
|
|
|
cairo_set_font_face(ct, [_faceInfo fontFace]);
|
|
|
|
if (cairo_status(ct) != CAIRO_STATUS_SUCCESS)
|
|
|
|
{
|
2007-10-08 21:27:51 +00:00
|
|
|
NSLog(@"Error while setting font face: %s",
|
|
|
|
cairo_status_to_string(cairo_status(ct)));
|
|
|
|
return;
|
2006-01-30 18:25:11 +00:00
|
|
|
}
|
2005-07-27 23:25:32 +00:00
|
|
|
|
2005-11-07 00:11:09 +00:00
|
|
|
cairo_show_text(ct, str);
|
2006-01-30 18:25:11 +00:00
|
|
|
if (cairo_status(ct) != CAIRO_STATUS_SUCCESS)
|
|
|
|
{
|
2007-10-08 21:27:51 +00:00
|
|
|
NSLog(@"Error drawing string: '%s' for string %s",
|
|
|
|
cairo_status_to_string(cairo_status(ct)), str);
|
2006-01-30 18:25:11 +00:00
|
|
|
}
|
2004-09-08 22:08:15 +00:00
|
|
|
}
|
2008-04-04 22:07:03 +00:00
|
|
|
|
2004-08-02 21:50:17 +00:00
|
|
|
@end
|