summaryrefslogtreecommitdiff
path: root/frontends/cocoa/font.m
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/cocoa/font.m')
-rw-r--r--frontends/cocoa/font.m333
1 files changed, 172 insertions, 161 deletions
diff --git a/frontends/cocoa/font.m b/frontends/cocoa/font.m
index 66ee5d090..daed97fae 100644
--- a/frontends/cocoa/font.m
+++ b/frontends/cocoa/font.m
@@ -26,215 +26,226 @@
#import "cocoa/plotter.h"
#import "cocoa/font.h"
-static NSLayoutManager *cocoa_prepare_layout_manager( const char *string, size_t length,
- const plot_font_style_t *style );
+static NSLayoutManager *cocoa_prepare_layout_manager(const char *string, size_t length,
+ const plot_font_style_t *style);
-static CGFloat cocoa_layout_width( NSLayoutManager *layout );
-static CGFloat cocoa_layout_width_chars( NSLayoutManager *layout, size_t characters );
-static NSUInteger cocoa_glyph_for_location( NSLayoutManager *layout, CGFloat x );
-static size_t cocoa_bytes_for_characters( const char *string, size_t characters );
-static NSDictionary *cocoa_font_attributes( const plot_font_style_t *style );
+static CGFloat cocoa_layout_width(NSLayoutManager *layout);
+static CGFloat cocoa_layout_width_chars(NSLayoutManager *layout, size_t characters);
+static NSUInteger cocoa_glyph_for_location(NSLayoutManager *layout, CGFloat x);
+static size_t cocoa_bytes_for_characters(const char *string, size_t characters);
+static NSDictionary *cocoa_font_attributes(const plot_font_style_t *style);
static NSTextStorage *cocoa_text_storage = nil;
static NSTextContainer *cocoa_text_container = nil;
static nserror cocoa_font_width(const plot_font_style_t *style,
- const char *string, size_t length,
- int *width)
+ const char *string, size_t length,
+ int *width)
{
- NSLayoutManager *layout;
- layout = cocoa_prepare_layout_manager( string, length, style );
- *width = cocoa_layout_width( layout );
- return NSERROR_OK;
+ NSLayoutManager *layout;
+ layout = cocoa_prepare_layout_manager(string, length, style);
+ *width = cocoa_layout_width(layout);
+ return NSERROR_OK;
}
static nserror cocoa_font_position(const plot_font_style_t *style,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
+ const char *string, size_t length,
+ int x, size_t *char_offset, int *actual_x)
{
- NSLayoutManager *layout = cocoa_prepare_layout_manager( string, length, style );
- if (layout == nil) {
- return NSERROR_BAD_PARAMETER;
- }
-
- NSUInteger glyphIndex = cocoa_glyph_for_location( layout, x );
- NSUInteger chars = [layout characterIndexForGlyphAtIndex: glyphIndex];
-
- if (chars >= [cocoa_text_storage length]) *char_offset = length;
- else *char_offset = cocoa_bytes_for_characters( string, chars );
-
- *actual_x = cocoa_pt_to_px( NSMaxX( [layout boundingRectForGlyphRange: NSMakeRange( glyphIndex - 1, 1 )
- inTextContainer: cocoa_text_container] ) );
-
- return NSERROR_OK;
+ NSLayoutManager *layout = cocoa_prepare_layout_manager(string, length, style);
+ if (layout == nil) {
+ return NSERROR_BAD_PARAMETER;
+ }
+
+ NSUInteger glyphIndex = cocoa_glyph_for_location(layout, x);
+ NSUInteger chars = [layout characterIndexForGlyphAtIndex:glyphIndex];
+
+ if (chars >= [cocoa_text_storage length])
+ *char_offset = length;
+ else
+ *char_offset = cocoa_bytes_for_characters(string, chars);
+
+ *actual_x = cocoa_pt_to_px(NSMaxX([layout boundingRectForGlyphRange:NSMakeRange(glyphIndex - 1, 1)
+ inTextContainer:cocoa_text_container]));
+
+ return NSERROR_OK;
}
static nserror cocoa_font_split(const plot_font_style_t *style,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
+ const char *string, size_t length,
+ int x, size_t *char_offset, int *actual_x)
{
- NSLayoutManager *layout = cocoa_prepare_layout_manager( string, length, style );
- if (layout == nil) return NSERROR_BAD_PARAMETER;
-
- NSUInteger glyphIndex = cocoa_glyph_for_location( layout, x );
- NSUInteger chars = [layout characterIndexForGlyphAtIndex: glyphIndex];
-
- if (chars >= [cocoa_text_storage length]) {
- *char_offset = length;
- *actual_x = cocoa_layout_width( layout );
- return NSERROR_OK;
- }
-
-
- chars = [[cocoa_text_storage string] rangeOfString: @" " options: NSBackwardsSearch range: NSMakeRange( 0, chars + 1 )].location;
- if (chars == NSNotFound) {
- *char_offset = 0;
- *actual_x = 0;
- return NSERROR_OK;
- }
-
- *char_offset = cocoa_bytes_for_characters( string, chars );
- *actual_x = cocoa_layout_width_chars( layout, chars );
-
- return NSERROR_OK;
+ NSLayoutManager *layout = cocoa_prepare_layout_manager(string, length, style);
+ if (layout == nil)
+ return NSERROR_BAD_PARAMETER;
+
+ NSUInteger glyphIndex = cocoa_glyph_for_location(layout, x);
+ NSUInteger chars = [layout characterIndexForGlyphAtIndex:glyphIndex];
+
+ if (chars >= [cocoa_text_storage length]) {
+ *char_offset = length;
+ *actual_x = cocoa_layout_width(layout);
+ return NSERROR_OK;
+ }
+
+ chars = [[cocoa_text_storage string] rangeOfString:@" " options:NSBackwardsSearch range:NSMakeRange(0, chars + 1)].location;
+ if (chars == NSNotFound) {
+ *char_offset = 0;
+ *actual_x = 0;
+ return NSERROR_OK;
+ }
+
+ *char_offset = cocoa_bytes_for_characters(string, chars);
+ *actual_x = cocoa_layout_width_chars(layout, chars);
+
+ return NSERROR_OK;
}
-
static struct gui_layout_table layout_table = {
- .width = cocoa_font_width,
- .position = cocoa_font_position,
- .split = cocoa_font_split,
+ .width = cocoa_font_width,
+ .position = cocoa_font_position,
+ .split = cocoa_font_split,
};
struct gui_layout_table *cocoa_layout_table = &layout_table;
-
#pragma mark -
-void cocoa_draw_string( CGFloat x, CGFloat y, const char *bytes, size_t length, const plot_font_style_t *style )
+void cocoa_draw_string(CGFloat x, CGFloat y, const char *bytes, size_t length, const plot_font_style_t *style)
{
- NSLayoutManager *layout = cocoa_prepare_layout_manager( bytes, length, style );
- if (layout == nil) return;
-
- NSFont *font = [cocoa_text_storage attribute: NSFontAttributeName atIndex: 0 effectiveRange: NULL];
- CGFloat baseline = [layout defaultLineHeightForFont: font] * 3.0 / 4.0;
-
- NSRange glyphRange = [layout glyphRangeForTextContainer: cocoa_text_container];
- [layout drawGlyphsForGlyphRange: glyphRange atPoint: NSMakePoint( x, y - baseline )];
-}
+ NSLayoutManager *layout = cocoa_prepare_layout_manager(bytes, length, style);
+ if (layout == nil)
+ return;
+
+ NSFont *font = [cocoa_text_storage attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL];
+ CGFloat baseline = [layout defaultLineHeightForFont:font] * 3.0 / 4.0;
+ NSRange glyphRange = [layout glyphRangeForTextContainer:cocoa_text_container];
+ [layout drawGlyphsForGlyphRange:glyphRange atPoint:NSMakePoint(x, y - baseline)];
+}
#pragma mark -
-static inline CGFloat cocoa_layout_width( NSLayoutManager *layout )
+static inline CGFloat cocoa_layout_width(NSLayoutManager *layout)
{
- if (layout == nil) return 0.0;
-
- return cocoa_pt_to_px( NSWidth( [layout usedRectForTextContainer: cocoa_text_container] ) );
+ if (layout == nil)
+ return 0.0;
+
+ return cocoa_pt_to_px(NSWidth([layout usedRectForTextContainer:cocoa_text_container]));
}
-static inline CGFloat cocoa_layout_width_chars( NSLayoutManager *layout, size_t characters )
+static inline CGFloat cocoa_layout_width_chars(NSLayoutManager *layout, size_t characters)
{
- NSUInteger glyphIndex = [layout glyphIndexForCharacterAtIndex: characters];
- return cocoa_pt_to_px( [layout locationForGlyphAtIndex: glyphIndex].x );
+ NSUInteger glyphIndex = [layout glyphIndexForCharacterAtIndex:characters];
+ return cocoa_pt_to_px([layout locationForGlyphAtIndex:glyphIndex].x);
}
-static inline NSUInteger cocoa_glyph_for_location( NSLayoutManager *layout, CGFloat x )
+static inline NSUInteger cocoa_glyph_for_location(NSLayoutManager *layout, CGFloat x)
{
- CGFloat fraction = 0.0;
- NSUInteger glyphIndex = [layout glyphIndexForPoint: NSMakePoint( cocoa_px_to_pt( x ), 0 )
- inTextContainer: cocoa_text_container
- fractionOfDistanceThroughGlyph: &fraction];
- if (fraction >= 1.0) ++glyphIndex;
- return glyphIndex;
+ CGFloat fraction = 0.0;
+ NSUInteger glyphIndex = [layout glyphIndexForPoint:NSMakePoint(cocoa_px_to_pt(x), 0)
+ inTextContainer:cocoa_text_container
+ fractionOfDistanceThroughGlyph:&fraction];
+ if (fraction >= 1.0)
+ ++glyphIndex;
+ return glyphIndex;
}
-static inline size_t cocoa_bytes_for_characters( const char *string, size_t chars )
+static inline size_t cocoa_bytes_for_characters(const char *string, size_t chars)
{
- size_t offset = 0;
- while (chars-- > 0) {
- uint8_t ch = ((uint8_t *)string)[offset];
-
- if (0xC2 <= ch && ch <= 0xDF) offset += 2;
- else if (0xE0 <= ch && ch <= 0xEF) offset += 3;
- else if (0xF0 <= ch && ch <= 0xF4) offset += 4;
- else offset++;
- }
- return offset;
+ size_t offset = 0;
+ while (chars-- > 0) {
+ uint8_t ch = ((uint8_t *)string)[offset];
+
+ if (0xC2 <= ch && ch <= 0xDF)
+ offset += 2;
+ else if (0xE0 <= ch && ch <= 0xEF)
+ offset += 3;
+ else if (0xF0 <= ch && ch <= 0xF4)
+ offset += 4;
+ else
+ offset++;
+ }
+ return offset;
}
-static NSLayoutManager *cocoa_prepare_layout_manager( const char *bytes, size_t length,
- const plot_font_style_t *style )
+static NSLayoutManager *cocoa_prepare_layout_manager(const char *bytes, size_t length,
+ const plot_font_style_t *style)
{
- if (NULL == bytes || 0 == length) return nil;
-
- NSString *string = [[NSString alloc] initWithBytes: bytes length:length encoding:NSUTF8StringEncoding] ;
- if (string == nil) return nil;
-
- static NSLayoutManager *layout = nil;
- if (nil == layout) {
- cocoa_text_container = [[NSTextContainer alloc] initWithContainerSize: NSMakeSize( CGFLOAT_MAX, CGFLOAT_MAX )];
- [cocoa_text_container setLineFragmentPadding: 0];
-
- layout = [[NSLayoutManager alloc] init];
- [layout addTextContainer: cocoa_text_container];
- }
-
- static NSString *oldString = 0;
- static plot_font_style_t oldStyle = { 0, 0, 0, 0, 0, 0 };
-
- const bool styleChanged = memcmp( style, &oldStyle, sizeof oldStyle ) != 0;
-
- if ([oldString isEqualToString: string] && !styleChanged) {
- return layout;
- }
-
- oldString = [string copy];
- oldStyle = *style;
-
- static NSDictionary *attributes = nil;
- if (styleChanged || attributes == nil) {
- attributes = cocoa_font_attributes( style ) ;
- }
-
- cocoa_text_storage = [[NSTextStorage alloc] initWithString: string attributes: attributes];
- [cocoa_text_storage addLayoutManager: layout];
-
- [layout ensureLayoutForTextContainer: cocoa_text_container];
-
- return layout;
+ if (NULL == bytes || 0 == length)
+ return nil;
+
+ NSString *string = [[NSString alloc] initWithBytes:bytes length:length encoding:NSUTF8StringEncoding];
+ if (string == nil)
+ return nil;
+
+ static NSLayoutManager *layout = nil;
+ if (nil == layout) {
+ cocoa_text_container = [[NSTextContainer alloc] initWithContainerSize:NSMakeSize(CGFLOAT_MAX, CGFLOAT_MAX)];
+ [cocoa_text_container setLineFragmentPadding:0];
+
+ layout = [[NSLayoutManager alloc] init];
+ [layout addTextContainer:cocoa_text_container];
+ }
+
+ static NSString *oldString = 0;
+ static plot_font_style_t oldStyle = { 0, 0, 0, 0, 0, 0 };
+
+ const bool styleChanged = memcmp(style, &oldStyle, sizeof oldStyle) != 0;
+
+ if ([oldString isEqualToString:string] && !styleChanged) {
+ return layout;
+ }
+
+ oldString = [string copy];
+ oldStyle = *style;
+
+ static NSDictionary *attributes = nil;
+ if (styleChanged || attributes == nil) {
+ attributes = cocoa_font_attributes(style);
+ }
+
+ cocoa_text_storage = [[NSTextStorage alloc] initWithString:string attributes:attributes];
+ [cocoa_text_storage addLayoutManager:layout];
+
+ [layout ensureLayoutForTextContainer:cocoa_text_container];
+
+ return layout;
}
-static NSString * const cocoa_font_families[PLOT_FONT_FAMILY_COUNT] = {
- [PLOT_FONT_FAMILY_SERIF] = @"Times",
- [PLOT_FONT_FAMILY_SANS_SERIF] = @"Helvetica",
- [PLOT_FONT_FAMILY_MONOSPACE] = @"Courier",
- [PLOT_FONT_FAMILY_CURSIVE] = @"Apple Chancery",
- [PLOT_FONT_FAMILY_FANTASY] = @"Marker Felt"
+static NSString *const cocoa_font_families[PLOT_FONT_FAMILY_COUNT] = {
+ [PLOT_FONT_FAMILY_SERIF] = @"Times",
+ [PLOT_FONT_FAMILY_SANS_SERIF] = @"Helvetica",
+ [PLOT_FONT_FAMILY_MONOSPACE] = @"Courier",
+ [PLOT_FONT_FAMILY_CURSIVE] = @"Apple Chancery",
+ [PLOT_FONT_FAMILY_FANTASY] = @"Marker Felt"
};
-static inline NSFont *cocoa_font_get_nsfont( const plot_font_style_t *style )
+static inline NSFont *cocoa_font_get_nsfont(const plot_font_style_t *style)
{
- NSFont *font = [NSFont fontWithName: cocoa_font_families[style->family]
- size: (CGFloat)style->size / FONT_SIZE_SCALE];
-
- NSFontTraitMask traits = 0;
- if (style->flags & FONTF_ITALIC || style->flags & FONTF_OBLIQUE) traits |= NSItalicFontMask;
- if (style->flags & FONTF_SMALLCAPS) traits |= NSSmallCapsFontMask;
- if (style->weight > 400) traits |= NSBoldFontMask;
-
- if (0 != traits) {
- NSFontManager *fm = [NSFontManager sharedFontManager];
- font = [fm convertFont: font toHaveTrait: traits];
- }
-
- return font;
+ NSFont *font = [NSFont fontWithName:cocoa_font_families[style->family]
+ size:(CGFloat)style->size / FONT_SIZE_SCALE];
+
+ NSFontTraitMask traits = 0;
+ if (style->flags & FONTF_ITALIC || style->flags & FONTF_OBLIQUE)
+ traits |= NSItalicFontMask;
+ if (style->flags & FONTF_SMALLCAPS)
+ traits |= NSSmallCapsFontMask;
+ if (style->weight > 400)
+ traits |= NSBoldFontMask;
+
+ if (0 != traits) {
+ NSFontManager *fm = [NSFontManager sharedFontManager];
+ font = [fm convertFont:font toHaveTrait:traits];
+ }
+
+ return font;
}
-static inline NSDictionary *cocoa_font_attributes( const plot_font_style_t *style )
+static inline NSDictionary *cocoa_font_attributes(const plot_font_style_t *style)
{
- return [NSDictionary dictionaryWithObjectsAndKeys:
- cocoa_font_get_nsfont( style ), NSFontAttributeName,
- cocoa_convert_colour( style->foreground ), NSForegroundColorAttributeName,
- nil];
+ return [NSDictionary dictionaryWithObjectsAndKeys:
+ cocoa_font_get_nsfont(style), NSFontAttributeName,
+ cocoa_convert_colour(style->foreground), NSForegroundColorAttributeName,
+ nil];
}