From 3376f7f50ff774030596a2e84dd9f72920ee449c Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Thu, 27 Jan 2011 11:43:48 +0000 Subject: Implemented resolution-independent rendering for the browser view. Still needs to be implemented for the other views. svn path=/trunk/netsurf/; revision=11507 --- cocoa/BrowserView.m | 18 +++++++------ cocoa/NetsurfApp.m | 5 ++-- cocoa/font.h | 2 +- cocoa/font.m | 13 +++++----- cocoa/gui.m | 34 ++++++++++++------------ cocoa/plotter.h | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ cocoa/plotter.m | 46 +++++++++++++++++++++++++-------- 7 files changed, 147 insertions(+), 45 deletions(-) (limited to 'cocoa') diff --git a/cocoa/BrowserView.m b/cocoa/BrowserView.m index ea5147558..b58466cd1 100644 --- a/cocoa/BrowserView.m +++ b/cocoa/BrowserView.m @@ -27,7 +27,7 @@ #import "desktop/selection.h" #import "cocoa/font.h" - +#import "cocoa/plotter.h" @implementation BrowserView @@ -122,12 +122,12 @@ static inline NSRect cocoa_get_caret_rect( BrowserView *view ) content_redraw(browser->current_content, 0, 0, - NSWidth( frame ), - NSHeight( frame ), - NSMinX( rects[i] ), - NSMinY( rects[i] ), - NSMaxX( rects[i] ), - NSMaxY( rects[i] ), + cocoa_pt_to_px( NSWidth( frame ) ), + cocoa_pt_to_px( NSHeight( frame ) ), + cocoa_pt_to_px( NSMinX( rects[i] ) ), + cocoa_pt_to_px( NSMinY( rects[i] ) ), + cocoa_pt_to_px( NSMaxX( rects[i] ) ), + cocoa_pt_to_px( NSMaxY( rects[i] ) ), browser->scale, 0xFFFFFF); } @@ -165,6 +165,8 @@ static browser_mouse_state cocoa_mouse_flags_for_event( NSEvent *evt ) location.x /= browser->scale; location.y /= browser->scale; } + location.x = cocoa_pt_to_px( location.x ); + location.y = cocoa_pt_to_px( location.y ); return location; } @@ -344,7 +346,7 @@ static browser_mouse_state cocoa_mouse_flags_for_event( NSEvent *evt ) { if (!isResizing) { NSSize frameSize = [[self superview] frame].size; - browser_window_reformat( browser, frameSize.width, frameSize.height ); + browser_window_reformat( browser, cocoa_pt_to_px( frameSize.width ), cocoa_pt_to_px( frameSize.height ) ); } [super adjustFrame]; diff --git a/cocoa/NetsurfApp.m b/cocoa/NetsurfApp.m index bcf29edcd..dad37a046 100644 --- a/cocoa/NetsurfApp.m +++ b/cocoa/NetsurfApp.m @@ -19,6 +19,7 @@ #import "NetsurfApp.h" #import "cocoa/gui.h" +#import "cocoa/plotter.h" #import "desktop/gui.h" #include "content/urldb.h" @@ -71,10 +72,10 @@ static NSString *cocoa_get_user_path( NSString *fileName ) ; option_homepage_url = strdup( [[defaults objectForKey: kHomepageURLOption] UTF8String] ); } - nscss_screen_dpi = FLTTOFIX( 72.0 * [[NSScreen mainScreen] userSpaceScaleFactor] ); - urldb_load( [[defaults objectForKey: kURLsFileOption] UTF8String] ); urldb_load_cookies( option_cookie_file ); + + cocoa_update_scale_factor(); } - (void) saveOptions; diff --git a/cocoa/font.h b/cocoa/font.h index 769bd1dd9..fc2c5c95e 100644 --- a/cocoa/font.h +++ b/cocoa/font.h @@ -19,7 +19,7 @@ #ifndef COCOA_FONT_H #define COCOA_FONT_H -void cocoa_draw_string( int x, int 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 ); void cocoa_set_font_scale_factor( float newFactor ); #endif diff --git a/cocoa/font.m b/cocoa/font.m index 73e73e7e1..4e50a48fa 100644 --- a/cocoa/font.m +++ b/cocoa/font.m @@ -28,6 +28,7 @@ #import "font.h" #import "plotter.h" +#import "cocoa/plotter.h" static NSLayoutManager *cocoa_prepare_layout_manager( const char *string, size_t length, const plot_font_style_t *style ); @@ -65,8 +66,8 @@ static bool nsfont_position_in_string(const plot_font_style_t *style, if (chars >= [cocoa_text_storage length]) *char_offset = length; else *char_offset = cocoa_bytes_for_characters( string, chars ); - *actual_x = NSMaxX( [layout boundingRectForGlyphRange: NSMakeRange( glyphIndex - 1, 1 ) - inTextContainer: cocoa_text_container] ); + *actual_x = cocoa_pt_to_px( NSMaxX( [layout boundingRectForGlyphRange: NSMakeRange( glyphIndex - 1, 1 ) + inTextContainer: cocoa_text_container] ) ); return true; } @@ -114,7 +115,7 @@ void cocoa_set_font_scale_factor( float newFactor ) cocoa_font_scale_factor = newFactor; } -void cocoa_draw_string( int x, int 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 ); @@ -134,19 +135,19 @@ static inline CGFloat cocoa_layout_width( NSLayoutManager *layout ) { if (layout == nil) return 0.0; - return NSWidth( [layout usedRectForTextContainer: cocoa_text_container] ); + return cocoa_pt_to_px( NSWidth( [layout usedRectForTextContainer: cocoa_text_container] ) ); } static inline CGFloat cocoa_layout_width_chars( NSLayoutManager *layout, size_t characters ) { NSUInteger glyphIndex = [layout glyphIndexForCharacterAtIndex: characters]; - return [layout locationForGlyphAtIndex: glyphIndex].x; + return cocoa_pt_to_px( [layout locationForGlyphAtIndex: glyphIndex].x ); } static inline NSUInteger cocoa_glyph_for_location( NSLayoutManager *layout, CGFloat x ) { CGFloat fraction = 0.0; - NSUInteger glyphIndex = [layout glyphIndexForPoint: NSMakePoint( x, 0 ) + NSUInteger glyphIndex = [layout glyphIndexForPoint: NSMakePoint( cocoa_px_to_pt( x ), 0 ) inTextContainer: cocoa_text_container fractionOfDistanceThroughGlyph: &fraction]; if (fraction > 0) ++glyphIndex; diff --git a/cocoa/gui.m b/cocoa/gui.m index 1c7105731..fdaa379ef 100644 --- a/cocoa/gui.m +++ b/cocoa/gui.m @@ -19,6 +19,7 @@ #import #import "cocoa/gui.h" +#import "cocoa/plotter.h" #import "BrowserView.h" #import "BrowserViewController.h" @@ -113,7 +114,7 @@ void gui_window_set_title(struct gui_window *g, const char *title) void gui_window_redraw(struct gui_window *g, int x0, int y0, int x1, int y1) { - const NSRect rect = NSMakeRect( x0, y0, x1 - x0, y1 - y0 ); + const NSRect rect = cocoa_rect( x0, y0, x1, y1 ); [[(BrowserViewController *)g browserView] setNeedsDisplayInRect: rect]; } @@ -125,11 +126,9 @@ void gui_window_redraw_window(struct gui_window *g) void gui_window_update_box(struct gui_window *g, const union content_msg_data *data) { - const CGFloat scale = [(BrowserViewController *)g browser]->scale; - const NSRect rect = NSMakeRect( data->redraw.object_x * scale, - data->redraw.object_y * scale, - data->redraw.object_width * scale, - data->redraw.object_height * scale ); + const NSRect rect = cocoa_scaled_rect_wh( [(BrowserViewController *)g browser]->scale, + data->redraw.object_x, data->redraw.object_y, + data->redraw.object_width, data->redraw.object_height ); [[(BrowserViewController *)g browserView] setNeedsDisplayInRect: rect]; } @@ -138,14 +137,14 @@ bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) NSCParameterAssert( g != NULL && sx != NULL && sy != NULL ); NSRect visible = [[(BrowserViewController *)g browserView] visibleRect]; - *sx = NSMinX( visible ); - *sy = NSMinY( visible ); + *sx = cocoa_pt_to_px( NSMinX( visible ) ); + *sy = cocoa_pt_to_px( NSMinY( visible ) ); return true; } void gui_window_set_scroll(struct gui_window *g, int sx, int sy) { - [[(BrowserViewController *)g browserView] scrollPoint: NSMakePoint( sx, sy )]; + [[(BrowserViewController *)g browserView] scrollPoint: cocoa_point( sx, sy )]; } void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, @@ -171,20 +170,20 @@ void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, frame.size.width /= scale; frame.size.height /= scale; } - *width = NSWidth( frame ); - *height = NSHeight( frame ); + *width = cocoa_pt_to_px( NSWidth( frame ) ); + *height = cocoa_pt_to_px( NSHeight( frame ) ); } void gui_window_update_extent(struct gui_window *g) { BrowserViewController * const window = (BrowserViewController *)g; + + struct browser_window *browser = [window browser]; + int width = content_get_width( browser->current_content ); + int height = content_get_height( browser->current_content ); [[window browserView] setResizing: YES]; - struct browser_window *browser = [window browser]; - int width = content_get_width( browser->current_content ) * browser->scale; - int height = content_get_height( browser->current_content ) * browser->scale; - - [[window browserView] setMinimumSize: NSMakeSize( width, height )]; + [[window browserView] setMinimumSize: cocoa_scaled_size( browser->scale, width, height )]; [[window browserView] setResizing: NO]; } @@ -272,7 +271,8 @@ void gui_window_set_search_ico(hlcache_handle *ico) void gui_window_place_caret(struct gui_window *g, int x, int y, int height) { - [[(BrowserViewController *)g browserView] addCaretAt: NSMakePoint( x, y ) height: height]; + [[(BrowserViewController *)g browserView] addCaretAt: cocoa_point( x, y ) + height: cocoa_px_to_pt( height )]; } void gui_window_remove_caret(struct gui_window *g) diff --git a/cocoa/plotter.h b/cocoa/plotter.h index 1b3f1e1be..e756a26f6 100644 --- a/cocoa/plotter.h +++ b/cocoa/plotter.h @@ -19,6 +19,80 @@ #ifndef COCOA_PLOTTER_H #define COCOA_PLOTTER_H +#import +#import "desktop/plot_style.h" + NSColor *cocoa_convert_colour( colour clr ); +void cocoa_update_scale_factor( void ); + +extern CGFloat cocoa_scale_factor; + +static inline CGFloat cocoa_px_to_pt( int location ) __attribute__((always_inline,pure)); +static inline CGFloat cocoa_px_to_pt_f( CGFloat location ) __attribute__((always_inline,pure)); +static inline int cocoa_pt_to_px( CGFloat location ) __attribute__((always_inline,pure)); +static inline NSPoint cocoa_point( int x, int y ) __attribute__((always_inline,pure)); +static inline NSSize cocoa_size( int w, int h ) __attribute__((always_inline,pure)); +static inline NSSize cocoa_scaled_size( float scale, int w, int h ) __attribute__((always_inline,pure)); +static inline NSRect cocoa_rect( int x0, int y0, int x1, int y1 ) __attribute__((always_inline,pure)); +static inline NSRect cocoa_rect_wh( int x, int y, int w, int h ) __attribute__((always_inline,pure)); +static inline NSRect cocoa_scaled_rect_wh( float scale, int x, int y, int w, int h ) __attribute__((always_inline,pure)); + +static inline CGFloat cocoa_px_to_pt( int location ) +{ + return ((CGFloat)location) * cocoa_scale_factor; +} + +static inline CGFloat cocoa_px_to_pt_f( CGFloat location ) +{ + return floor( location ) * cocoa_scale_factor; +} + +static inline int cocoa_pt_to_px( CGFloat location ) +{ + return location / cocoa_scale_factor; +} + +static inline NSPoint cocoa_point( int x, int y ) +{ + return NSMakePoint( cocoa_px_to_pt( x ), cocoa_px_to_pt( y ) ); +} + +static inline NSSize cocoa_size( int w, int h ) +{ + return NSMakeSize( cocoa_px_to_pt( w ), cocoa_px_to_pt( h ) ); +} + +static inline NSSize cocoa_scaled_size( float scale, int w, int h ) +{ + return NSMakeSize( cocoa_px_to_pt_f( scale * w ), cocoa_px_to_pt_f( scale * h ) ); +} + +static inline NSRect cocoa_rect( int x0, int y0, int x1, int y1 ) +{ + const NSRect result = { + .origin = cocoa_point( x0, y0 ), + .size = cocoa_size( x1 - x0, y1 - y0 ) + }; + return result; +} + +static inline NSRect cocoa_rect_wh( int x, int y, int w, int h ) +{ + const NSRect result = { + .origin = cocoa_point( x, y ), + .size = cocoa_size( w, h ) + }; + return result; +} + +static inline NSRect cocoa_scaled_rect_wh( float scale, int x, int y, int w, int h ) +{ + const NSRect result = { + .origin = NSMakePoint( cocoa_px_to_pt_f( scale * x ), cocoa_px_to_pt_f( scale * y ) ), + .size = cocoa_scaled_size( scale, w, h ) + }; + return result; +} + #endif diff --git a/cocoa/plotter.m b/cocoa/plotter.m index cef0b8a99..ffcdbbf47 100644 --- a/cocoa/plotter.m +++ b/cocoa/plotter.m @@ -25,6 +25,7 @@ #import "cocoa/font.h" #import "cocoa/plotter.h" #import "cocoa/bitmap.h" +#import "css/utils.h" 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); @@ -67,14 +68,14 @@ static void cocoa_plot_path_set_stroke_pattern(NSBezierPath *path,const plot_sty break; } - [path setLineWidth: pstyle->stroke_width]; + [path setLineWidth: cocoa_px_to_pt( 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 )]; + [path moveToPoint: cocoa_point( x0, y0 )]; + [path lineToPoint: cocoa_point( x1, y1 )]; cocoa_plot_render_path( path, pstyle ); @@ -83,8 +84,8 @@ static bool plot_line(int x0, int y0, int x1, int y1, const plot_style_t *pstyle 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 )]; - + NSRect rect = cocoa_rect( x0, y0, x1, y1 ); + NSBezierPath *path = [NSBezierPath bezierPathWithRect: rect]; cocoa_plot_render_path( path, pstyle ); return true; @@ -96,7 +97,7 @@ static bool plot_text(int x, int y, const char *text, size_t length, [NSGraphicsContext saveGraphicsState]; [NSBezierPath clipRect: cocoa_plot_clip_rect]; - cocoa_draw_string( x, y, text, length, fstyle ); + cocoa_draw_string( cocoa_px_to_pt( x ), cocoa_px_to_pt( y ), text, length, fstyle ); [NSGraphicsContext restoreGraphicsState]; @@ -106,10 +107,17 @@ static bool plot_text(int x, int y, const char *text, size_t length, 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) ); + cocoa_plot_clip_rect = cocoa_rect( x0, y0, x1, y1 ); return true; } +static void cocoa_center_pixel(void) +{ + NSAffineTransform *transform = [NSAffineTransform transform]; + [transform translateXBy: 0.5 * cocoa_scale_factor yBy: 0.5 * cocoa_scale_factor]; + [transform concat]; +} + void cocoa_plot_render_path(NSBezierPath *path,const plot_style_t *pstyle) { [NSGraphicsContext saveGraphicsState]; @@ -121,6 +129,8 @@ void cocoa_plot_render_path(NSBezierPath *path,const plot_style_t *pstyle) } if (pstyle->stroke_type != PLOT_OP_TYPE_NONE) { + cocoa_center_pixel(); + cocoa_plot_path_set_stroke_pattern(path,pstyle); [cocoa_convert_colour( pstyle->stroke_colour ) set]; @@ -158,9 +168,9 @@ static bool plot_polygon(const int *p, unsigned int n, const plot_style_t *pstyl if (n <= 1) return true; NSBezierPath *path = [NSBezierPath bezierPath]; - [path moveToPoint: NSMakePoint( p[0], p[1] )]; + [path moveToPoint: cocoa_point( p[0], p[1] )]; for (unsigned i = 1; i < n; i++) { - [path lineToPoint: NSMakePoint( p[2*i], p[2*i+1] )]; + [path lineToPoint: cocoa_point( p[2*i], p[2*i+1] )]; } [path closePath]; @@ -230,6 +240,7 @@ static bool plot_path(const float *p, unsigned int n, colour fill, float width, } if (c != NS_TRANSPARENT) { + cocoa_center_pixel(); [cocoa_convert_colour( c ) set]; [path stroke]; } @@ -254,7 +265,8 @@ static bool plot_bitmap(int x, int y, int width, int height, CGImageRef img = cocoa_get_cgimage( bitmap ); - CGRect rect = CGRectMake( x, y, width, height ); + CGRect rect = NSRectToCGRect( cocoa_rect_wh( x, y, width, height ) ); + if (tileX || tileY) { CGContextDrawTiledImage( context, rect, img ); } else { @@ -281,4 +293,16 @@ struct plotter_table plot = { .text = plot_text, .option_knockout = true -}; \ No newline at end of file +}; + + +CGFloat cocoa_scale_factor; +static const CGFloat points_per_inch = 72.0; + +void cocoa_update_scale_factor( void ) +{ + const CGFloat scale = [[NSScreen mainScreen] userSpaceScaleFactor]; + cocoa_scale_factor = scale == 1.0 ? 1.0 : 1.0 / scale; + nscss_screen_dpi = FLTTOFIX( points_per_inch * scale ); +} + -- cgit v1.2.3