diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 15 | ||||
| -rw-r--r-- | src/Fl_Cairo.cxx | 242 | ||||
| -rw-r--r-- | src/Makefile | 5 | ||||
| -rw-r--r-- | src/makedepend | 37 |
4 files changed, 296 insertions, 3 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 40671d392..741d1f5b8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -172,6 +172,10 @@ set (CPPFILES screen_xywh.cxx ) +if (FLTK_HAVE_CAIRO) # OPTION_CAIRO or OPTION_CAIROEXT + list (APPEND CPPFILES Fl_Cairo.cxx) +endif () + # find all header files in source directory <FL/...> file (GLOB HEADER_FILES @@ -616,6 +620,10 @@ if (HAVE_XRENDER) list (APPEND OPTIONAL_LIBS ${X11_Xrender_LIB}) endif (HAVE_XRENDER) +if (FLTK_HAVE_CAIRO) # OPTION_CAIRO or OPTION_CAIROEXT + list (APPEND OPTIONAL_LIBS ${PKG_CAIRO_LIBRARIES}) +endif() + if (USE_PANGO) ### FIXME ### This needs to use the PKG_* variables directly list (APPEND OPTIONAL_LIBS ${HAVE_LIB_PANGO} ${HAVE_LIB_PANGOCAIRO}) @@ -694,6 +702,10 @@ endif (UNIX AND OPTION_USE_WAYLAND) FL_ADD_LIBRARY (fltk STATIC "${STATIC_FILES}") target_link_libraries (fltk ${OPTIONAL_LIBS}) +if (FLTK_HAVE_CAIRO) + fl_target_link_directories (fltk PUBLIC "${PKG_CAIRO_LIBRARY_DIRS}") +endif() + ####################################################################### FL_ADD_LIBRARY (fltk_forms STATIC "${FORMS_FILES}") @@ -738,7 +750,8 @@ endif (OPENGL_FOUND) if (OPTION_BUILD_SHARED_LIBS AND NOT MSVC) FL_ADD_LIBRARY (fltk SHARED "${SHARED_FILES}") - target_link_libraries (fltk_SHARED ${OPTIONAL_LIBS}) + target_link_libraries (fltk_SHARED ${OPTIONAL_LIBS} ${PKG_CAIRO_LIBRARIES}) + fl_target_link_directories (fltk_SHARED PUBLIC "${PKG_CAIRO_LIBRARY_DIRS}") ################################################################### diff --git a/src/Fl_Cairo.cxx b/src/Fl_Cairo.cxx new file mode 100644 index 000000000..2def2698a --- /dev/null +++ b/src/Fl_Cairo.cxx @@ -0,0 +1,242 @@ +// +// Special Cairo support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2023 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please see the following page on how to report bugs and issues: +// +// https://www.fltk.org/bugs.php +// + +// 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 + +#include <FL/platform.H> +#include <FL/Fl_Window.H> + +// Cairo is currently supported for the following platforms: +// Windows, macOS (Apple Quartz), X11, Wayland + +#if defined(_WIN32) // Windows +# include <cairo-win32.h> +#elif defined(FLTK_USE_WAYLAND) // Wayland or hybrid +# include "../src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H" +# include "../src/drivers/Wayland/Fl_Wayland_Window_Driver.H" +# if defined(FLTK_USE_X11) +# include <cairo-xlib.h> +# else + static void *fl_gc = NULL; +# endif +#elif defined(FLTK_USE_X11) // X11 +# include <cairo-xlib.h> +#elif defined(__APPLE__) // macOS +# include <cairo-quartz.h> +#else +# error Cairo is not supported on this platform. +#endif + +// static initialization + +Fl_Cairo_State Fl::cairo_state_; ///< current Cairo context information + +// Fl_Cairo_State + +void Fl_Cairo_State::autolink(bool b) { +#ifdef FLTK_HAVE_CAIROEXT + autolink_ = b; +#else + Fl::fatal("In Fl::autolink(bool): Cairo autolink() feature is only " + "available with CMake OPTION_CAIROEXT " + "or the enable-cairoext configure option.\n" + "Quitting now."); +#endif +} + +/** + Provides a Cairo context for window \a wi. + + This is needed in a draw() override if Fl::cairo_autolink_context() + returns false, which is the default. + 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 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 + 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, + thus optimizing the drawing performances. + Also, after this call, Fl::cairo_cc() is adequately updated with this + Cairo context. + + \note Only available when configure has the --enable-cairo option + + \return The valid cairo_t *cairo context associated to this window. + \retval NULL if \a wi is NULL or maybe with GL windows under Wayland +*/ +cairo_t *Fl::cairo_make_current(Fl_Window *wi) { + if (!wi) + return NULL; + cairo_t *cairo_ctxt; + +#if defined(FLTK_USE_WAYLAND) + if (fl_wl_display()) { // true means using wayland backend + struct wld_window *xid = fl_wl_xid(wi); + if (!xid->buffer) + return NULL; // this may happen with GL windows + cairo_ctxt = xid->buffer->cairo_; + cairo_state_.cc(cairo_ctxt, false); + return cairo_ctxt; + } +#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 combination + 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__ + float scale = Fl::screen_scale(wi->screen_num()); // get the screen scaling factor +#endif + +#if defined(FLTK_USE_X11) + cairo_ctxt = Fl::cairo_make_current(0, wi->w() * scale, wi->h() * scale); +#else + // on macOS, scaling is done before by Fl_Window::make_current(), on Windows, the size is not used + cairo_ctxt = Fl::cairo_make_current(fl_gc, wi->w(), wi->h()); +#endif + +#ifndef __APPLE__ + cairo_scale(cairo_ctxt, scale, scale); +#endif + return cairo_ctxt; +} + +/* + Creates transparently a cairo_surface_t object. + gc is an HDC context in Windows, a CGContext* in Quartz, and + a display on X11 (not used on this platform) +*/ + +static cairo_surface_t *cairo_create_surface(void *gc, int W, int H) { +#if defined(FLTK_USE_X11) + return cairo_xlib_surface_create(fl_display, fl_window, fl_visual->visual, W, H); +#elif defined(FLTK_USE_WAYLAND) + return NULL; +#elif defined(_WIN32) + return cairo_win32_surface_create((HDC)gc); +#elif defined(__APPLE__) + return cairo_quartz_surface_create_for_cg_context((CGContextRef)gc, W, H); +#else +#error Cairo is not supported on this platform. +#endif +} + +/** + Creates a Cairo context from a \a gc only, gets its window size or + offscreen size if fl_window is null. + + \note Only available if CMake OPTION_CAIRO is enabled + or configure has the --enable-cairo option. +*/ +cairo_t *Fl::cairo_make_current(void *gc) { + int W = 0, H = 0; +#if defined(FLTK_USE_X11) || defined(FLTK_USE_WAYLAND) + // FIXME X11 get W,H + // gc will be the window handle here + // # warning FIXME get W,H for cairo_make_current(void*) +#elif defined(__APPLE__) + if (fl_window) { + W = Fl_Window::current()->w(); + H = Fl_Window::current()->h(); + } else { + W = CGBitmapContextGetWidth(fl_gc); + H = CGBitmapContextGetHeight(fl_gc); + } +#elif defined(_WIN32) + // we don't need any W,H for Windows +#else +#error Cairo is not supported on this platform. +#endif + + if (!gc) { + Fl::cairo_cc(0); + cairo_state_.gc(0); // keep track for next time + return 0; + } + if (gc == Fl::cairo_state_.gc() && + fl_window == (Window)Fl::cairo_state_.window() && + cairo_state_.cc() != 0) + return Fl::cairo_cc(); + cairo_state_.gc(fl_gc); // keep track for next time + cairo_surface_t *s = cairo_create_surface(gc, W, H); + cairo_t *c = cairo_create(s); + cairo_surface_destroy(s); + cairo_state_.cc(c); + return c; +} + +/** + Creates a Cairo context from a \p gc and the given size. + + \note Only available if CMake OPTION_CAIRO is enabled + or 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 ... + 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) + CGAffineTransform at = CGContextGetCTM((CGContextRef)gc); + CGContextSaveGState((CGContextRef)gc); + CGContextConcatCTM((CGContextRef)gc, CGAffineTransformInvert(at)); +#endif + + cairo_t *c = cairo_create(s); + +#if defined(__APPLE__) && defined(FLTK_HAVE_CAIROEXT) + CGContextRestoreGState((CGContextRef)gc); +#endif + + cairo_state_.cc(c); // and purge any previously owned context + cairo_surface_destroy(s); + return c; +} + +// Silence compiler warning if none of the Cairo options has been configured + +#else +FL_EXPORT int fltk_cairo_dummy() { + return 1; +} + +#endif // FLTK_HAVE_CAIRO diff --git a/src/Makefile b/src/Makefile index 4e20b3e56..c025ff1d3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -26,6 +26,7 @@ CPPFILES = \ Fl_Browser_load.cxx \ Fl_Box.cxx \ Fl_Button.cxx \ + Fl_Cairo.cxx \ Fl_Chart.cxx \ Fl_Check_Browser.cxx \ Fl_Check_Button.cxx \ @@ -452,7 +453,7 @@ $(LIBNAME): $(OBJECTS) libfltk.so.$(FL_DSO_VERSION): $(OBJECTS) echo $(DSOCOMMAND) $@ ... - $(DSOCOMMAND) $@ $(OBJECTS) $(LDLIBS) + $(DSOCOMMAND) $@ $(OBJECTS) $(LDLIBS) $(CAIROLIBS) $(RM) libfltk.so $(LN) libfltk.so.$(FL_DSO_VERSION) libfltk.so @@ -468,7 +469,7 @@ libfltk.$(FL_DSO_VERSION).dylib: $(OBJECTS) -install_name $(libdir)/$@ \ -current_version $(FL_VERSION) \ -compatibility_version $(FL_DSO_VERSION).0 \ - $(OBJECTS) $(LDLIBS) + $(OBJECTS) $(LDLIBS) $(CAIROLIBS) $(RM) libfltk.dylib $(LN) libfltk.$(FL_DSO_VERSION).dylib libfltk.dylib diff --git a/src/makedepend b/src/makedepend index 74f3f2d87..bd259df7b 100644 --- a/src/makedepend +++ b/src/makedepend @@ -1279,6 +1279,23 @@ Fl_Button.o: ../FL/fl_utf8.h Fl_Button.o: ../FL/Fl_Widget.H Fl_Button.o: ../FL/Fl_Window.H Fl_Button.o: ../FL/platform_types.h +Fl_Cairo.o: ../FL/Enumerations.H +Fl_Cairo.o: ../FL/Fl.H +Fl_Cairo.o: ../FL/fl_attr.h +Fl_Cairo.o: ../FL/Fl_Bitmap.H +Fl_Cairo.o: ../FL/Fl_Cairo.H +Fl_Cairo.o: ../FL/fl_casts.H +Fl_Cairo.o: ../FL/fl_config.h +Fl_Cairo.o: ../FL/Fl_Export.H +Fl_Cairo.o: ../FL/Fl_Group.H +Fl_Cairo.o: ../FL/Fl_Image.H +Fl_Cairo.o: ../FL/fl_types.h +Fl_Cairo.o: ../FL/fl_utf8.h +Fl_Cairo.o: ../FL/Fl_Widget.H +Fl_Cairo.o: ../FL/Fl_Window.H +Fl_Cairo.o: ../FL/platform.H +Fl_Cairo.o: ../FL/platform_types.h +Fl_Cairo.o: ../FL/x11.H Fl_Chart.o: ../config.h Fl_Chart.o: ../FL/Enumerations.H Fl_Chart.o: ../FL/Fl.H @@ -2313,6 +2330,7 @@ Fl_Help_View.o: ../FL/Fl_RGB_Image.H Fl_Help_View.o: ../FL/Fl_Scrollbar.H Fl_Help_View.o: ../FL/Fl_Shared_Image.H Fl_Help_View.o: ../FL/Fl_Slider.H +Fl_Help_View.o: ../FL/Fl_String.H Fl_Help_View.o: ../FL/fl_string_functions.h Fl_Help_View.o: ../FL/fl_types.h Fl_Help_View.o: ../FL/fl_utf8.h @@ -3219,6 +3237,7 @@ Fl_Preferences.o: ../FL/fl_config.h Fl_Preferences.o: ../FL/Fl_Export.H Fl_Preferences.o: ../FL/Fl_Plugin.H Fl_Preferences.o: ../FL/Fl_Preferences.H +Fl_Preferences.o: ../FL/Fl_String.H Fl_Preferences.o: ../FL/fl_string_functions.h Fl_Preferences.o: ../FL/fl_types.h Fl_Preferences.o: ../FL/fl_utf8.h @@ -3613,6 +3632,22 @@ fl_shortcut.o: ../FL/platform_types.h fl_shortcut.o: flstring.h fl_shortcut.o: Fl_Screen_Driver.H fl_shortcut.o: Fl_System_Driver.H +Fl_Shortcut_Button.o: ../config.h +Fl_Shortcut_Button.o: ../FL/Enumerations.H +Fl_Shortcut_Button.o: ../FL/Fl.H +Fl_Shortcut_Button.o: ../FL/fl_attr.h +Fl_Shortcut_Button.o: ../FL/Fl_Button.H +Fl_Shortcut_Button.o: ../FL/Fl_Cairo.H +Fl_Shortcut_Button.o: ../FL/fl_casts.H +Fl_Shortcut_Button.o: ../FL/fl_config.h +Fl_Shortcut_Button.o: ../FL/fl_draw.H +Fl_Shortcut_Button.o: ../FL/Fl_Export.H +Fl_Shortcut_Button.o: ../FL/Fl_Shortcut_Button.H +Fl_Shortcut_Button.o: ../FL/fl_types.h +Fl_Shortcut_Button.o: ../FL/fl_utf8.h +Fl_Shortcut_Button.o: ../FL/Fl_Widget.H +Fl_Shortcut_Button.o: ../FL/platform_types.h +Fl_Shortcut_Button.o: flstring.h fl_show_colormap.o: ../config.h fl_show_colormap.o: ../FL/Enumerations.H fl_show_colormap.o: ../FL/Fl.H @@ -3691,6 +3726,7 @@ Fl_Spinner.o: ../FL/Fl_Rect.H Fl_Spinner.o: ../FL/Fl_Repeat_Button.H Fl_Spinner.o: ../FL/Fl_Spinner.H Fl_Spinner.o: ../FL/Fl_Widget.H +Fl_String.o: ../FL/Fl_Export.H Fl_String.o: ../FL/Fl_String.H fl_string_functions.o: ../FL/Enumerations.H fl_string_functions.o: ../FL/filename.H @@ -4929,6 +4965,7 @@ gl_start.o: Fl_Gl_Window_Driver.H numericsort.o: ../FL/filename.H numericsort.o: ../FL/fl_config.h numericsort.o: ../FL/Fl_Export.H +numericsort.o: ../FL/fl_utf8.h numericsort.o: ../FL/platform_types.h print_button.o: ../FL/Enumerations.H print_button.o: ../FL/Fl.H |
