From b58dcc351f3f7ec32ecb0553436ff9ee76e52551 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Wed, 12 Jan 2011 20:21:17 +0000 Subject: Cocoa front end (credit: Sven Weidauer) svn path=/trunk/netsurf/; revision=11292 --- cocoa/plotter.m | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 cocoa/plotter.m (limited to 'cocoa/plotter.m') diff --git a/cocoa/plotter.m b/cocoa/plotter.m new file mode 100644 index 000000000..a7652e9ed --- /dev/null +++ b/cocoa/plotter.m @@ -0,0 +1,223 @@ +/* + * Copyright 2011 Sven Weidauer + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "desktop/plotters.h" +#import "desktop/plot_style.h" + +#import "cocoa/font.h" +#import "cocoa/plotter.h" +#import "cocoa/bitmap.h" + +#define UNIMPL() NSLog( @"Function '%s' unimplemented", __func__ ) + +static void cocoa_plot_render_path(NSBezierPath *path,const plot_style_t *pstyle); +static void cocoa_plot_path_set_stroke_pattern(NSBezierPath *path,const plot_style_t *pstyle); +static NSRect cocoa_plot_clip_rect; + +#define colour_red_component( c ) (((c) >> 0) & 0xFF) +#define colour_green_component( c ) (((c) >> 8) & 0xFF) +#define colour_blue_component( c ) (((c) >> 16) & 0xFF) +#define colour_alpha_component( c ) (((c) >> 24) & 0xFF) +#define colour_from_rgba( r, g, b, a) ((((colour)(r)) << 0) | \ + (((colour)(g)) << 8) | \ + (((colour)(b)) << 16) | \ + (((colour)(a)) << 24)) +#define colour_from_rgb( r, g, b ) colour_from_rgba( (r), (g), (b), 0xFF ) + +NSColor *cocoa_convert_colour( colour clr ) +{ + return [NSColor colorWithDeviceRed: (float)colour_red_component( clr ) / 0xFF + green: (float)colour_green_component( clr ) / 0xFF + blue: (float)colour_blue_component( clr ) / 0xFF + alpha: 1.0]; +} + +static void cocoa_plot_path_set_stroke_pattern(NSBezierPath *path,const plot_style_t *pstyle) +{ + static const CGFloat dashed_pattern[2] = { 5.0, 2.0 }; + static const CGFloat dotted_pattern[2] = { 2.0, 2.0 }; + + switch (pstyle->stroke_type) { + case PLOT_OP_TYPE_DASH: + [path setLineDash: dashed_pattern count: 2 phase: 0]; + break; + + case PLOT_OP_TYPE_DOT: + [path setLineDash: dotted_pattern count: 2 phase: 0]; + break; + + default: + // ignore + break; + } + + [path setLineWidth: pstyle->stroke_width]; +} + +static bool plot_line(int x0, int y0, int x1, int y1, const plot_style_t *pstyle) +{ + NSBezierPath *path = [NSBezierPath bezierPath]; + [path moveToPoint: NSMakePoint( x0, y0 )]; + [path lineToPoint: NSMakePoint( x1, y1 )]; + + cocoa_plot_render_path( path, pstyle ); + + return true; +} + +static bool plot_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *pstyle) +{ + NSBezierPath *path = [NSBezierPath bezierPathWithRect: NSMakeRect( x0, y0, x1-x0, y1-y0 )]; + + cocoa_plot_render_path( path, pstyle ); + + return true; +} + +static bool plot_text(int x, int y, const char *text, size_t length, + const plot_font_style_t *fstyle) +{ + [NSGraphicsContext saveGraphicsState]; + [NSBezierPath clipRect: cocoa_plot_clip_rect]; + + cocoa_draw_string( x, y, text, length, fstyle ); + + [NSGraphicsContext restoreGraphicsState]; + + return true; +} + + +static bool plot_clip(int x0, int y0, int x1, int y1) +{ + cocoa_plot_clip_rect = NSMakeRect( x0, y0, abs(x1-x0), abs(y1-y0) ); + return true; +} + +void cocoa_plot_render_path(NSBezierPath *path,const plot_style_t *pstyle) +{ + [NSGraphicsContext saveGraphicsState]; + [NSBezierPath clipRect: cocoa_plot_clip_rect]; + + if (pstyle->fill_type != PLOT_OP_TYPE_NONE) { + [cocoa_convert_colour( pstyle->fill_colour ) setFill]; + [path fill]; + } + + if (pstyle->stroke_type != PLOT_OP_TYPE_NONE) { + cocoa_plot_path_set_stroke_pattern(path,pstyle); + + [cocoa_convert_colour( pstyle->stroke_colour ) set]; + + [path stroke]; + } + + [NSGraphicsContext restoreGraphicsState]; +} + +static bool plot_arc(int x, int y, int radius, int angle1, int angle2, const plot_style_t *pstyle) +{ + NSBezierPath *path = [NSBezierPath bezierPath]; + [path appendBezierPathWithArcWithCenter: NSMakePoint( x, y ) radius: radius + startAngle: angle1 endAngle: angle2 + clockwise: NO]; + + cocoa_plot_render_path( path, pstyle); + + return true; +} + +static bool plot_disc(int x, int y, int radius, const plot_style_t *pstyle) +{ + NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect: + NSMakeRect( x - radius, y-radius, 2*radius, 2*radius )]; + + cocoa_plot_render_path( path, pstyle ); + + return true; +} + +static bool plot_polygon(const int *p, unsigned int n, const plot_style_t *pstyle) +{ + if (n <= 1) return true; + + NSBezierPath *path = [NSBezierPath bezierPath]; + [path moveToPoint: NSMakePoint( p[0], p[1] )]; + for (int i = 1; i < n; i++) { + [path lineToPoint: NSMakePoint( p[2*i], p[2*i+1] )]; + } + [path closePath]; + + cocoa_plot_render_path( path, pstyle ); + + return true; +} + +/* complex path (for SVG) */ +static bool plot_path(const float *p, unsigned int n, colour fill, float width, + colour c, const float transform[6]) +{ + UNIMPL(); + return true; +} + +/* Image */ +static bool plot_bitmap(int x, int y, int width, int height, + struct bitmap *bitmap, colour bg, + bitmap_flags_t flags) +{ + CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; + CGContextSaveGState( context ); + + CGContextClipToRect( context, NSRectToCGRect( cocoa_plot_clip_rect ) ); + + const bool tileX = flags & BITMAPF_REPEAT_X; + const bool tileY = flags & BITMAPF_REPEAT_Y; + + CGImageRef img = cocoa_get_cgimage( bitmap ); + + CGRect rect = CGRectMake( x, y, width, height ); + if (tileX || tileY) { + CGContextDrawTiledImage( context, rect, img ); + } else { + CGContextDrawImage( context, rect, img ); + } + + CGContextRestoreGState( context ); + + return true; +} + +struct plotter_table plot = { + .clip = plot_clip, + .arc = plot_arc, + .disc = plot_disc, + .rectangle = plot_rectangle, + .line = plot_line, + .polygon = plot_polygon, + + .path = plot_path, + + .bitmap = plot_bitmap, + + .text = plot_text, + + .option_knockout = true +}; \ No newline at end of file -- cgit v1.2.3