summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt15
-rw-r--r--src/Fl_Cairo.cxx242
-rw-r--r--src/Makefile5
-rw-r--r--src/makedepend37
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