summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FL/Fl_Device.H7
-rw-r--r--FL/mac.H1
-rw-r--r--src/Fl_Device.cxx1
-rw-r--r--src/Fl_cocoa.mm21
-rw-r--r--src/fl_rect.cxx30
5 files changed, 53 insertions, 7 deletions
diff --git a/FL/Fl_Device.H b/FL/Fl_Device.H
index 619e41b16..5fc731d69 100644
--- a/FL/Fl_Device.H
+++ b/FL/Fl_Device.H
@@ -546,6 +546,10 @@ public:
*/
class FL_EXPORT Fl_Display_Device : public Fl_Surface_Device {
static Fl_Display_Device *_display; // the platform display device
+#ifdef __APPLE__
+ friend class Fl_X;
+ static bool high_res_window_; // true when drawing to a window of a retina display
+#endif
public:
static const char *class_id;
const char *class_name() {return class_id;};
@@ -553,6 +557,9 @@ public:
Fl_Display_Device(Fl_Graphics_Driver *graphics_driver);
/** Returns the platform display device. */
static inline Fl_Display_Device *display_device() {return _display;};
+#ifdef __APPLE__
+ static bool high_resolution() {return high_res_window_;}
+#endif
};
/**
diff --git a/FL/mac.H b/FL/mac.H
index cb57c4e14..3bb282905 100644
--- a/FL/mac.H
+++ b/FL/mac.H
@@ -162,6 +162,7 @@ public:
static int insertion_point_location(int *px, int *py, int *pheight); // computes window coordinates & height of insertion point
static const int CoreText_threshold; // Mac OS version from which the Core Text API is used to display text
static Fl_Fontdesc* calc_fl_fonts(void); // computes the fl_fonts global variable
+ static void set_high_resolution(bool);
};
extern Window fl_window;
diff --git a/src/Fl_Device.cxx b/src/Fl_Device.cxx
index 83658edca..0657af401 100644
--- a/src/Fl_Device.cxx
+++ b/src/Fl_Device.cxx
@@ -26,6 +26,7 @@ const char *Fl_Display_Device::class_id = "Fl_Display_Device";
const char *Fl_Graphics_Driver::class_id = "Fl_Graphics_Driver";
#if defined(__APPLE__) || defined(FL_DOXYGEN)
const char *Fl_Quartz_Graphics_Driver::class_id = "Fl_Quartz_Graphics_Driver";
+bool Fl_Display_Device::high_res_window_ = false;
#endif
#if defined(WIN32) || defined(FL_DOXYGEN)
const char *Fl_GDI_Graphics_Driver::class_id = "Fl_GDI_Graphics_Driver";
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index 09d42bdd2..433add3a9 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -792,9 +792,8 @@ double fl_mac_flush_and_wait(double time_to_wait) {
time_to_wait = 0.0;
double retval = fl_wait(time_to_wait);
if (fl_gc) {
- CGContextFlush(fl_gc);
- fl_gc = 0;
- }
+ Fl_X::q_release_context();
+ }
[pool release];
return retval;
}
@@ -2989,6 +2988,9 @@ void Fl_Window::make_current()
if (make_current_counts) make_current_counts++;
Fl_X::q_release_context();
fl_window = i->xid;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ Fl_X::set_high_resolution(fl_mac_os_version >= 100700 && [fl_window backingScaleFactor] > 1.0);
+#endif
current_ = this;
NSGraphicsContext *nsgc = through_drawRect ? [NSGraphicsContext currentContext] :
@@ -3048,6 +3050,9 @@ void Fl_X::q_release_context(Fl_X *x) {
if (x && x->gc!=fl_gc) return;
if (!fl_gc) return;
CGContextRestoreGState(fl_gc); // KEEP IT: matches the CGContextSaveGState of make_current
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ Fl_X::set_high_resolution(false);
+#endif
CGContextFlush(fl_gc);
fl_gc = 0;
#if defined(FLTK_USE_CAIRO)
@@ -3073,6 +3078,11 @@ void Fl_X::q_end_image() {
CGContextRestoreGState(fl_gc);
}
+void Fl_X::set_high_resolution(bool new_val)
+{
+ Fl_Display_Device::high_res_window_ = new_val;
+}
+
void Fl_Copy_Surface::complete_copy_pdf_and_tiff()
{
CGContextRestoreGState(gc);
@@ -3583,6 +3593,7 @@ int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
printer.origin(w/2, h/2);
#endif
printer.print_window(win, -ww/2, -wh/2);
+ //printer.print_window_part(win,0,0,win->w(),win->h(), -ww/2, -wh/2);
printer.end_page();
printer.end_job();
fl_unlock_function();
@@ -3933,9 +3944,7 @@ static NSBitmapImageRep* rect_to_NSBitmapImageRep(Fl_Window *win, int x, int y,
} else {
NSView *winview = nil;
if ( through_drawRect && Fl_Window::current() == win ) {
- CGFloat epsilon = 0;
- if (fl_mac_os_version >= 100600) epsilon = 0.5; // STR #2887
- rect = NSMakeRect(x - epsilon, y - epsilon, w, h);
+ rect = NSMakeRect(x - 0.5, y - 0.5, w, h);
}
else {
rect = NSMakeRect(x, win->h()-(y+h), w, h);
diff --git a/src/fl_rect.cxx b/src/fl_rect.cxx
index cc8de7c27..bfcf1262a 100644
--- a/src/fl_rect.cxx
+++ b/src/fl_rect.cxx
@@ -40,7 +40,7 @@ extern int fl_line_width_;
#ifdef __APPLE_QUARTZ__
extern float fl_quartz_line_width_;
-#define USINGQUARTZPRINTER (Fl_Surface_Device::surface() != Fl_Display_Device::display_device())
+#define USINGQUARTZPRINTER (Fl_Surface_Device::surface()->class_name() == Fl_Printer::class_id)
#endif
#ifdef USE_X11
@@ -205,6 +205,14 @@ void Fl_Graphics_Driver::xyline(int x, int y, int x1) {
CGContextMoveToPoint(fl_gc, x, y);
CGContextAddLineToPoint(fl_gc, x1, y);
CGContextStrokePath(fl_gc);
+ if (Fl_Display_Device::high_resolution()) {
+ /* On retina displays, all xyline() and yxline() functions produce lines that are half-unit
+ (or one pixel) too short at both ends. This is corrected by filling at both ends rectangles
+ of size one unit by line-width.
+ */
+ CGContextFillRect(fl_gc, CGRectMake(x-0.5 , y - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_));
+ CGContextFillRect(fl_gc, CGRectMake(x1-0.5 , y - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_));
+ }
if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
#else
# error unsupported platform
@@ -229,6 +237,10 @@ void Fl_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
CGContextAddLineToPoint(fl_gc, x1, y);
CGContextAddLineToPoint(fl_gc, x1, y2);
CGContextStrokePath(fl_gc);
+ if (Fl_Display_Device::high_resolution()) {
+ CGContextFillRect(fl_gc, CGRectMake(x-0.5, y - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_));
+ CGContextFillRect(fl_gc, CGRectMake(x1 - fl_quartz_line_width_/2, y2-0.5, fl_quartz_line_width_, 1));
+ }
if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
#else
#error unsupported platform
@@ -256,6 +268,10 @@ void Fl_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
CGContextAddLineToPoint(fl_gc, x1, y2);
CGContextAddLineToPoint(fl_gc, x3, y2);
CGContextStrokePath(fl_gc);
+ if (Fl_Display_Device::high_resolution()) {
+ CGContextFillRect(fl_gc, CGRectMake(x-0.5, y - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_));
+ CGContextFillRect(fl_gc, CGRectMake(x3-0.5, y2 - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_));
+ }
if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
#else
# error unsupported platform
@@ -274,6 +290,10 @@ void Fl_Graphics_Driver::yxline(int x, int y, int y1) {
CGContextMoveToPoint(fl_gc, x, y);
CGContextAddLineToPoint(fl_gc, x, y1);
CGContextStrokePath(fl_gc);
+ if (Fl_Display_Device::high_resolution()) {
+ CGContextFillRect(fl_gc, CGRectMake(x - fl_quartz_line_width_/2, y-0.5, fl_quartz_line_width_, 1));
+ CGContextFillRect(fl_gc, CGRectMake(x - fl_quartz_line_width_/2, y1-0.5, fl_quartz_line_width_, 1));
+ }
if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
#else
# error unsupported platform
@@ -298,6 +318,10 @@ void Fl_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
CGContextAddLineToPoint(fl_gc, x, y1);
CGContextAddLineToPoint(fl_gc, x2, y1);
CGContextStrokePath(fl_gc);
+ if (Fl_Display_Device::high_resolution()) {
+ CGContextFillRect(fl_gc, CGRectMake(x - fl_quartz_line_width_/2, y-0.5, fl_quartz_line_width_, 1));
+ CGContextFillRect(fl_gc, CGRectMake(x2-0.5, y1 - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_));
+ }
if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
#else
# error unsupported platform
@@ -325,6 +349,10 @@ void Fl_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
CGContextAddLineToPoint(fl_gc, x2, y1);
CGContextAddLineToPoint(fl_gc, x2, y3);
CGContextStrokePath(fl_gc);
+ if (Fl_Display_Device::high_resolution()) {
+ CGContextFillRect(fl_gc, CGRectMake(x - fl_quartz_line_width_/2, y-0.5, fl_quartz_line_width_, 1));
+ CGContextFillRect(fl_gc, CGRectMake(x2 - fl_quartz_line_width_/2, y3-0.5, fl_quartz_line_width_, 1));
+ }
if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
#else
# error unsupported platform