Implemented resolution-independent rendering for the browser view. Still needs to be implemented for the other views.

svn path=/trunk/netsurf/; revision=11507
This commit is contained in:
Sven Weidauer 2011-01-27 11:43:48 +00:00
parent 73885bf3d0
commit 3376f7f50f
7 changed files with 147 additions and 45 deletions

View File

@ -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];

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -19,6 +19,7 @@
#import <Cocoa/Cocoa.h>
#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)

View File

@ -19,6 +19,80 @@
#ifndef COCOA_PLOTTER_H
#define COCOA_PLOTTER_H
#import <Cocoa/Cocoa.h>
#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

View File

@ -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
};
};
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 );
}