Add Cairo build support

This commit is contained in:
Janne Liljeblad
2012-11-27 20:09:54 +02:00
committed by Dan Dennedy
parent 2dda670b07
commit 47a479ba5e
4 changed files with 364 additions and 0 deletions

View File

@@ -10,6 +10,8 @@ if (NOT WITHOUT_OPENCV)
find_package (OpenCV)
endif ()
find_package (Cairo)
include(FindPkgConfig)
option (WITHOUT_GAVL "Disable plugins dependent upon gavl" OFF)
if (PKG_CONFIG_FOUND AND NOT WITHOUT_GAVL)

View File

@@ -0,0 +1,41 @@
# - Try to find Cairo
# Once done, this will define
#
# Cairo_FOUND - system has Cairo
# Cairo_INCLUDE_DIRS - the Cairo include directories
# Cairo_LIBRARIES - link these to use Cairo
include(LibFindMacros)
# Freetype is not necessarily required on all platforms...
if(NOT WIN32)
set(cairo_needs_freetype true)
endif(NOT WIN32)
# Dependencies
if(cairo_needs_freetype)
libfind_package(Cairo Freetype)
endif(cairo_needs_freetype)
# Use pkg-config to get hints about paths
libfind_pkg_check_modules(Cairo_PKGCONF cairo)
# Include dir
find_path(Cairo_INCLUDE_DIR
NAMES cairo.h
HINTS ${Cairo_PKGCONF_INCLUDE_DIRS}
PATH_SUFFIXES cairo
)
# Finally the library itself
find_library(Cairo_LIBRARY
NAMES cairo
HINTS ${Cairo_PKGCONF_LIBRARY_DIRS}
)
# Set the include dir variables and the libraries and let libfind_process do the rest.
# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
set(Cairo_PROCESS_INCLUDES Cairo_INCLUDE_DIR)
set(Cairo_PROCESS_LIBS Cairo_LIBRARY)
libfind_process(Cairo)

View File

@@ -0,0 +1,99 @@
# Works the same as find_package, but forwards the "REQUIRED" and "QUIET" arguments
# used for the current package. For this to work, the first parameter must be the
# prefix of the current package, then the prefix of the new package etc, which are
# passed to find_package.
macro (libfind_package PREFIX)
set (LIBFIND_PACKAGE_ARGS ${ARGN})
if (${PREFIX}_FIND_QUIETLY)
set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET)
endif (${PREFIX}_FIND_QUIETLY)
if (${PREFIX}_FIND_REQUIRED)
set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED)
endif (${PREFIX}_FIND_REQUIRED)
find_package(${LIBFIND_PACKAGE_ARGS})
endmacro (libfind_package)
# CMake developers made the UsePkgConfig system deprecated in the same release (2.6)
# where they added pkg_check_modules. Consequently I need to support both in my scripts
# to avoid those deprecated warnings. Here's a helper that does just that.
# Works identically to pkg_check_modules, except that no checks are needed prior to use.
macro (libfind_pkg_check_modules PREFIX PKGNAME)
if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
include(UsePkgConfig)
pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS)
else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(${PREFIX} ${PKGNAME})
endif (PKG_CONFIG_FOUND)
endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
endmacro (libfind_pkg_check_modules)
# Do the final processing once the paths have been detected.
# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain
# all the variables, each of which contain one include directory.
# Ditto for ${PREFIX}_PROCESS_LIBS and library files.
# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES.
# Also handles errors in case library detection was required, etc.
macro (libfind_process PREFIX)
# Skip processing if already processed during this run
if (NOT ${PREFIX}_FOUND)
# Start with the assumption that the library was found
set (${PREFIX}_FOUND TRUE)
# Process all includes and set _FOUND to false if any are missing
foreach (i ${${PREFIX}_PROCESS_INCLUDES})
if (${i})
set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}})
mark_as_advanced(${i})
else (${i})
set (${PREFIX}_FOUND FALSE)
endif (${i})
endforeach (i)
# Process all libraries and set _FOUND to false if any are missing
foreach (i ${${PREFIX}_PROCESS_LIBS})
if (${i})
set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}})
mark_as_advanced(${i})
else (${i})
set (${PREFIX}_FOUND FALSE)
endif (${i})
endforeach (i)
# Print message and/or exit on fatal error
if (${PREFIX}_FOUND)
if (NOT ${PREFIX}_FIND_QUIETLY)
message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
endif (NOT ${PREFIX}_FIND_QUIETLY)
else (${PREFIX}_FOUND)
if (${PREFIX}_FIND_REQUIRED)
foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS})
message("${i}=${${i}}")
endforeach (i)
message (FATAL_ERROR "Required library ${PREFIX} NOT FOUND.\nInstall the library (dev version) and try again. If the library is already installed, use ccmake to set the missing variables manually.")
endif (${PREFIX}_FIND_REQUIRED)
endif (${PREFIX}_FOUND)
endif (NOT ${PREFIX}_FOUND)
endmacro (libfind_process)
macro(libfind_library PREFIX basename)
set(TMP "")
if(MSVC80)
set(TMP -vc80)
endif(MSVC80)
if(MSVC90)
set(TMP -vc90)
endif(MSVC90)
set(${PREFIX}_LIBNAMES ${basename}${TMP})
if(${ARGC} GREATER 2)
set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2})
string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES})
set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP})
endif(${ARGC} GREATER 2)
find_library(${PREFIX}_LIBRARY
NAMES ${${PREFIX}_LIBNAMES}
PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS}
)
endmacro(libfind_library)

222
include/frei0r_cairo.h Normal file
View File

@@ -0,0 +1,222 @@
/*
* frei0r_cairo.h
* Copyright 2012 Janne Liljeblad
*
* This file is part of Frei0r.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <cairo.h>
/**
* String identifiers for gradient types available using Cairo.
*/
#define GRADIENT_LINEAR "gradient_linear"
#define GRADIENT_RADIAL "gradient_radial"
/**
* String identifiers for blend modes available using Cairo.
*/
#define NORMAL "normal"
#define ADD "add"
#define SATURATE "saturate"
#define MULTIPLY "multiply"
#define SCREEN "screen"
#define OVERLAY "overlay"
#define DARKEN "darken"
#define LIGHTEN "lighten"
#define COLORDODGE "colordodge"
#define COLORBURN "colorburn"
#define HARDLIGHT "hardlight"
#define SOFTLIGHT "softlight"
#define DIFFERENCE "difference"
#define EXCLUSION "exclusion"
#define HSLHUE "hslhue"
#define HSLSATURATION "hslsaturation"
#define HSLCOLOR "hslcolor"
#define HSLLUMINOSITY "hslluminosity"
/**
* frei0r_cairo_set_operator
* @cr: Cairo context
* @op: String identifier for a blend mode
*
* Sets cairo context to use the defined blend mode for all paint operations.
*/
void frei0r_cairo_set_operator(cairo_t *cr, char *op)
{
if(strcmp(op, NORMAL) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
}
else if(strcmp(op, ADD) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
}
else if(strcmp(op, SATURATE) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_SATURATE);
}
else if(strcmp(op, MULTIPLY) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_MULTIPLY);
}
else if(strcmp(op, SCREEN) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_SCREEN);
}
else if(strcmp(op, OVERLAY) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_OVERLAY);
}
else if(strcmp(op, DARKEN) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_DARKEN);
}
else if(strcmp(op, LIGHTEN) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_LIGHTEN);
}
else if(strcmp(op, COLORDODGE) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_COLOR_DODGE);
}
else if(strcmp(op, COLORBURN) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_COLOR_BURN);
}
else if(strcmp(op, HARDLIGHT) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_HARD_LIGHT);
}
else if(strcmp(op, SOFTLIGHT) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_SOFT_LIGHT);
}
else if(strcmp(op, DIFFERENCE) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
}
else if(strcmp(op, EXCLUSION) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_EXCLUSION);
}
else if(strcmp(op, HSLHUE) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_HSL_HUE);
}
else if(strcmp(op, HSLSATURATION) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_HSL_SATURATION);
}
else if(strcmp(op, HSLCOLOR) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_HSL_COLOR);
}
else if(strcmp(op, HSLLUMINOSITY ) == 0)
{
cairo_set_operator (cr, CAIRO_OPERATOR_HSL_LUMINOSITY);
}
else
{
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
}
}
/**
* frei0r_cairo_set_rgba_LITTLE_ENDIAN
* @cr: Cairo context
* @red: red component, 0 - 1
* @green: green component, 0 - 1
* @blue: blue component, 0 - 1
* @alpha: opacity of color, 0 -1
*
* Sets cairo context to use the defined color paint operations.
* Switches red and blue channels to get correct color on little endian machines.
* This method only works correctly on little endian machines.
*/
void frei0r_cairo_set_rgba_LITTLE_ENDIAN(cairo_t* cr, double red, double green, double blue, double alpha)
{
cairo_set_source_rgba (cr, blue, green, red, alpha);
}
/**
* frei0r_cairo_set_rgb_LITTLE_ENDIAN
* @cr: Cairo context
* @red: red component, 0 - 1
* @green: green component, 0 - 1
* @blue: blue component, 0 - 1
*
* Sets cairo context to use the defined color paint operations.
* Switches red and blue channels to get correct color on little endian machines.
* This method only works correctly on little endian machines.
*/
void frei0r_cairo_set_rgb_LITTLE_ENDIAN(cairo_t* cr, double red, double green, double blue)
{
cairo_set_source_rgb (cr, blue, green, red);
}
/**
* freior_cairo_set_color_stop_rgba_LITLLE_ENDIAN(
* @pat: Cairo pattern
* @offset: offset of color position in pattern space, 0 - 1
* @red: red component, 0 - 1
* @green: green component, 0 - 1
* @blue: blue component, 0 - 1
* @alpha: opacity of color, 0 -1
*
* Sets color stop for cairo patterns.
* Switches red and blue channels to get correct color on little endian machines.
* This method only works correctly on little endian machines.
*/
void freior_cairo_set_color_stop_rgba_LITLLE_ENDIAN(cairo_pattern_t *pat, double offset,
double red, double green, double blue, double alpha)
{
cairo_pattern_add_color_stop_rgba (pat, offset, blue, green, red, alpha);
}
/**
* frei0r_cairo_get_pixel_position
* @norm_pos: position in range 0 - 1, either x or y
* @dim: dimension, either witdh or height
*
* Converts double range [0 -> 1] to pixel range [-2*dim -> 3*dim]. Input 0.4 gives position 0.
*
* Returns: position in pixels
*/
double frei0r_cairo_get_pixel_position (double norm_pos, int dim)
{
double pos_o = -(dim * 2.0);
return pos_o + norm_pos * dim * 5.0;
}
/**
* frei0r_cairo_get_scale
* @norm_scale: scale in range 0 - 1
*
* Converts double range [0 -> 1] to scale range [0 -> 5]. Input 0.2 gives scale 1.0.
*
* Returns: scale
*/
double frei0r_cairo_get_scale (double norm_scale)
{
return norm_scale * 5.0;
}