Reformat Cairo support Fl_Cairo.cxx for CMP compliance

Only formatting, no code changes.
This commit is contained in:
Albrecht Schlosser
2022-11-12 20:14:44 +01:00
parent 350038983f
commit 85af0036f9
+114 -96
View File
@@ -1,5 +1,5 @@
// //
// Main header file for the Fast Light Tool Kit (FLTK). // Special Cairo support for the Fast Light Tool Kit (FLTK).
// //
// Copyright 1998-2022 by Bill Spitzak and others. // Copyright 1998-2022 by Bill Spitzak and others.
// //
@@ -14,38 +14,45 @@
// https://www.fltk.org/bugs.php // https://www.fltk.org/bugs.php
// //
#include <FL/Fl.H> // includes <FL/fl_config.h> // This file implements the FLTK Cairo support (since 1.3.x):
//
// - ./configure --enable-cairo and/or --enable-cairoext
// - cmake -DOPTION_CAIRO and/or -DOPTION_CAIROEXT
//
// Preprocessor macro FLTK_HAVE_CAIRO is defined for both options.
// Preprocessor macro FLTK_HAVE_CAIRO_EXT is defined only for "cairoext"
#include <FL/Fl.H> // includes <FL/fl_config.h>
#ifdef FLTK_HAVE_CAIRO #ifdef FLTK_HAVE_CAIRO
#include <FL/platform.H> #include <FL/platform.H>
#include <FL/Fl_Window.H> #include <FL/Fl_Window.H>
// Cairo is currently supported for the following platforms: // Cairo is currently supported for the following platforms:
// Win32, Apple Quartz, X11, Wayland // Windows, macOS (Apple Quartz), X11, Wayland
#if defined(_WIN32) // Windows #if defined(_WIN32) // Windows
# include <cairo-win32.h> # include <cairo-win32.h>
#elif defined(__APPLE__) // macOS #elif defined(__APPLE__) // macOS
# include <cairo-quartz.h> # include <cairo-quartz.h>
#elif defined(FLTK_USE_WAYLAND) // Wayland or hybrid #elif defined(FLTK_USE_WAYLAND) // Wayland or hybrid
# include "../src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H" # include "../src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H"
# include "../src/drivers/Wayland/Fl_Wayland_Window_Driver.H" # include "../src/drivers/Wayland/Fl_Wayland_Window_Driver.H"
# include <cairo-xlib.h> # include <cairo-xlib.h>
#elif defined(FLTK_USE_X11) // X11 #elif defined(FLTK_USE_X11) // X11
# include <cairo-xlib.h> # include <cairo-xlib.h>
#else #else
# error Cairo is not supported on this platform. # error Cairo is not supported on this platform.
#endif #endif
// static Fl module initialization : // static initialization
Fl_Cairo_State Fl::cairo_state_; ///< contains all necessary info for current cairo context mapping
Fl_Cairo_State Fl::cairo_state_; ///< contains all necessary info for current Cairo context mapping
// Fl cairo features implementation // Fl_Cairo_State class
// Fl_Cairo_State class impl void Fl_Cairo_State::autolink(bool b) {
void Fl_Cairo_State::autolink(bool b) {
#ifdef FLTK_HAVE_CAIROEXT #ifdef FLTK_HAVE_CAIROEXT
autolink_ = b; autolink_ = b;
#else #else
@@ -55,44 +62,54 @@ void Fl_Cairo_State::autolink(bool b) {
} }
/** /**
Provides a corresponding cairo context for window \a wi. Provides a corresponding Cairo context for window \a wi.
This is needed in a draw() override if Fl::cairo_autolink_context() This is needed in a draw() override if Fl::cairo_autolink_context()
returns false, which is the default. returns false, which is the default.
The cairo_context() does not need to be freed as it is freed every time The cairo_context() does not need to be freed as it is freed every time
a new cairo context is created. When the program terminates, a new Cairo context is created. When the program terminates,
a call to Fl::cairo_make_current(0) will destroy any residual context. a call to Fl::cairo_make_current(0) will destroy any residual context.
\note A new cairo context is not always re-created when this method
\note A new Cairo context is not always re-created when this method
is used. In particular, if the current graphical context and the current is used. In particular, if the current graphical context and the current
window didn't change between two calls, the previous gc is internally kept, window didn't change between two calls, the previous gc is internally kept,
thus optimizing the drawing performances. thus optimizing the drawing performances.
Also, after this call, Fl::cairo_cc() is adequately updated with this Also, after this call, Fl::cairo_cc() is adequately updated with this
cairo context. Cairo context.
\note Only available when configure has the --enable-cairo option
\return the valid cairo_t* cairo context associated to this window. \note Only available when configure has the --enable-cairo option
\return the valid cairo_t* Cairo context associated to this window.
\retval NULL if \wi is NULL or maybe with GL windows under Wayland
*/ */
cairo_t * Fl::cairo_make_current(Fl_Window* wi) { cairo_t *Fl::cairo_make_current(Fl_Window *wi) {
if (!wi) return NULL; // Precondition if (!wi)
cairo_t * cairo_ctxt; return NULL;
cairo_t *cairo_ctxt;
#if defined(FLTK_USE_WAYLAND) #if defined(FLTK_USE_WAYLAND)
if (fl_wl_display()) { // true means using wayland backend if (fl_wl_display()) { // true means using wayland backend
struct wld_window *xid = fl_wl_xid(wi); struct wld_window *xid = fl_wl_xid(wi);
if (!xid->buffer) return NULL; // this may happen with GL windows if (!xid->buffer)
return NULL; // this may happen with GL windows
cairo_ctxt = xid->buffer->cairo_; cairo_ctxt = xid->buffer->cairo_;
cairo_state_.cc(cairo_ctxt, false); cairo_state_.cc(cairo_ctxt, false);
return cairo_ctxt; return cairo_ctxt;
} }
#endif #endif
if (fl_gc==0) { // means remove current cc
Fl::cairo_cc(0); // destroy any previous cc
cairo_state_.window(0);
return 0;
}
// don't re-create a context if it's the same gc/window couple if (fl_gc == 0) { // means remove current cc
if (fl_gc==Fl::cairo_state_.gc() && fl_xid(wi) == (Window) Fl::cairo_state_.window()) Fl::cairo_cc(0); // destroy any previous cc
return Fl::cairo_cc(); cairo_state_.window(0);
return 0;
}
cairo_state_.window((void*)fl_xid(wi)); // don't re-create a context if it's the same gc/window couple
if (fl_gc == Fl::cairo_state_.gc() && fl_xid(wi) == (Window)Fl::cairo_state_.window())
return Fl::cairo_cc();
cairo_state_.window((void *)fl_xid(wi));
// Scale the Cairo context appropriately. This is platform dependent
#ifndef __APPLE__ #ifndef __APPLE__
float scale = Fl::screen_scale(wi->screen_num()); // get the screen scaling factor float scale = Fl::screen_scale(wi->screen_num()); // get the screen scaling factor
@@ -115,90 +132,91 @@ cairo_t * Fl::cairo_make_current(Fl_Window* wi) {
a display on X11 (not used on this platform) a display on X11 (not used on this platform)
*/ */
static cairo_surface_t * cairo_create_surface(void * gc, int W, int H) { static cairo_surface_t *cairo_create_surface(void *gc, int W, int H) {
# if defined(FLTK_USE_X11) #if defined(FLTK_USE_X11)
return cairo_xlib_surface_create(fl_display, fl_window, fl_visual->visual, W, H); return cairo_xlib_surface_create(fl_display, fl_window, fl_visual->visual, W, H);
# elif defined(_WIN32) #elif defined(_WIN32)
return cairo_win32_surface_create((HDC) gc); return cairo_win32_surface_create((HDC)gc);
# elif defined(__APPLE__) #elif defined(__APPLE__)
return cairo_quartz_surface_create_for_cg_context((CGContextRef) gc, W, H); return cairo_quartz_surface_create_for_cg_context((CGContextRef)gc, W, H);
# else #else
# error Cairo is not supported under this platform. #error Cairo is not supported on this platform.
# endif #endif
} }
/** /**
Creates a cairo context from a \a gc only, gets its window size or Creates a Cairo context from a \a gc only, gets its window size or
offscreen size if fl_window is null. offscreen size if fl_window is null.
\note Only available when configure has the --enable-cairo option \note Only available when configure has the --enable-cairo option
*/ */
cairo_t * Fl::cairo_make_current(void *gc) { cairo_t *Fl::cairo_make_current(void *gc) {
int W=0,H=0; int W = 0, H = 0;
#if defined(FLTK_USE_X11) #if defined(FLTK_USE_X11)
// FIXME X11 get W,H // FIXME X11 get W,H
// gc will be the window handle here // gc will be the window handle here
// # warning FIXME get W,H for cairo_make_current(void*) // # warning FIXME get W,H for cairo_make_current(void*)
#elif defined(__APPLE__) #elif defined(__APPLE__)
if (fl_window) { if (fl_window) {
W = Fl_Window::current()->w(); W = Fl_Window::current()->w();
H = Fl_Window::current()->h(); H = Fl_Window::current()->h();
} } else {
else { W = CGBitmapContextGetWidth(fl_gc);
W = CGBitmapContextGetWidth(fl_gc); H = CGBitmapContextGetHeight(fl_gc);
H = CGBitmapContextGetHeight(fl_gc); }
}
#elif defined(_WIN32) #elif defined(_WIN32)
// we don't need any W,H for Windows // we don't need any W,H for Windows
#else #else
# error Cairo is not supported on this platform. #error Cairo is not supported on this platform.
#endif #endif
if (!gc) { if (!gc) {
Fl::cairo_cc(0); Fl::cairo_cc(0);
cairo_state_.gc(0); // keep track for next time cairo_state_.gc(0); // keep track for next time
return 0; return 0;
} }
if (gc==Fl::cairo_state_.gc() && if (gc == Fl::cairo_state_.gc() && fl_window == (Window)Fl::cairo_state_.window() &&
fl_window== (Window) Fl::cairo_state_.window() && cairo_state_.cc() != 0)
cairo_state_.cc()!=0) return Fl::cairo_cc();
return Fl::cairo_cc(); cairo_state_.gc(fl_gc); // keep track for next time
cairo_state_.gc(fl_gc); // keep track for next time cairo_surface_t *s = cairo_create_surface(gc, W, H);
cairo_surface_t * s = cairo_create_surface(gc, W, H); cairo_t *c = cairo_create(s);
cairo_t * c = cairo_create(s); cairo_surface_destroy(s);
cairo_surface_destroy(s); cairo_state_.cc(c);
cairo_state_.cc(c); return c;
return c;
} }
/** /**
Creates a cairo context from a \a gc and its size Creates a Cairo context from a \a gc and its size
\note Only available when configure has the --enable-cairo option
*/
cairo_t * Fl::cairo_make_current(void *gc, int W, int H) {
if (gc==Fl::cairo_state_.gc() &&
fl_window== (Window) Fl::cairo_state_.window() &&
cairo_state_.cc()!=0) // no need to create a cc, just return that one
return cairo_state_.cc();
// we need to (re-)create a fresh cc ... \note Only available if FLTK has been configured with one of the Cairo options
cairo_state_.gc(gc); // keep track for next time */
cairo_surface_t * s = cairo_create_surface(gc, W, H); cairo_t *Fl::cairo_make_current(void *gc, int W, int H) {
if (gc == Fl::cairo_state_.gc() && fl_window == (Window)Fl::cairo_state_.window() &&
cairo_state_.cc() != 0) // no need to create a cc, just return that one
return cairo_state_.cc();
// we need to (re-)create a fresh cc ...
cairo_state_.gc(gc); // keep track for next time
cairo_surface_t *s = cairo_create_surface(gc, W, H);
#if defined(__APPLE__) && defined(FLTK_HAVE_CAIROEXT) #if defined(__APPLE__) && defined(FLTK_HAVE_CAIROEXT)
CGAffineTransform at = CGContextGetCTM((CGContextRef)gc); CGAffineTransform at = CGContextGetCTM((CGContextRef)gc);
CGContextSaveGState((CGContextRef)gc); CGContextSaveGState((CGContextRef)gc);
CGContextConcatCTM((CGContextRef)gc, CGAffineTransformInvert(at)); CGContextConcatCTM((CGContextRef)gc, CGAffineTransformInvert(at));
#endif #endif
cairo_t * c = cairo_create(s); cairo_t *c = cairo_create(s);
#if defined(__APPLE__) && defined(FLTK_HAVE_CAIROEXT) #if defined(__APPLE__) && defined(FLTK_HAVE_CAIROEXT)
CGContextRestoreGState((CGContextRef)gc); CGContextRestoreGState((CGContextRef)gc);
#endif #endif
cairo_state_.cc(c); // and purge any previously owned context cairo_state_.cc(c); // and purge any previously owned context
cairo_surface_destroy(s); cairo_surface_destroy(s);
return c; return c;
} }
// Silence compiler warning if none of the Cairo options has been configured
#else #else
// just don't leave the libfltk_cairo lib empty to avoid warnings #warning xxx
#include <FL/Fl_Export.H> FL_EXPORT int fltk_cairo_dummy() {
FL_EXPORT int fltk_cairo_dummy() { return 1;} return 1;
}
#endif // FLTK_HAVE_CAIRO #endif // FLTK_HAVE_CAIRO