Coder Social home page Coder Social logo

mypaint / libmypaint Goto Github PK

View Code? Open in Web Editor NEW
294.0 33.0 87.0 3.11 MB

libmypaint, a.k.a. "brushlib", is a library for making brushstrokes which is used by MyPaint and other projects.

Home Page: http://mypaint.org

License: Other

Python 2.79% C 70.63% C++ 15.03% Makefile 2.15% M4 6.46% Shell 2.95%
graphics painting library libmypaint c mypaint brush

libmypaint's Introduction

libmypaint - MyPaint brush engine library

Translation status Travis Build Status Appveyor Build Status

This is the brush library used by MyPaint. A number of other painting programs use it too.

License: ISC, see COPYING for details.

Dependencies

Install dependencies (Debian and derivatives)

On recent Debian-like systems, you can type the following to get started with a standard configuration:

# apt install -y build-essential
# apt install -y libjson-c-dev libgirepository1.0-dev libglib2.0-dev

When building from git:

# apt install -y python autotools-dev intltool gettext libtool

You might also try using your package manager:

# apt build-dep mypaint # will get additional deps for MyPaint (GUI)
# apt build-dep libmypaint  # may not exist; included in mypaint

Install dependencies (Red Hat and derivatives)

The following works on a minimal CentOS 7 installation:

# yum install -y gcc gobject-introspection-devel json-c-devel glib2-devel

When building from git, you'll want to add:

# yum install -y git python autoconf intltool gettext libtool

You might also try your package manager:

# yum builddep libmypaint

Install dependencies (OpenSUSE)

Works with a fresh OpenSUSE Tumbleweed Docker image:

# zypper install gcc13 gobject-introspection-devel libjson-c-devel glib2-devel

When building from git:

# zypper install git python311 autoconf intltool gettext-tools libtool

Package manager:

# zypper install libmypaint0

Build and install

MyPaint and libmypaint benefit dramatically from autovectorization and other compiler optimizations. You may want to set your CFLAGS before compiling (for gcc):

$ export CFLAGS='-Ofast -ftree-vectorize -fopt-info-vec-optimized -march=native -mtune=native -funsafe-math-optimizations -funsafe-loop-optimizations'

The traditional setup works just fine.

$ ./autogen.sh    # Only needed when building from git.
$ ./configure
# make install
# ldconfig

Maintainer mode

We don't ship a configure script in our git repository. If you're building from git, you have to kickstart the build environment with:

$ git clone https://github.com/mypaint/libmypaint.git
$ cd libmypaint
$ ./autogen.sh

This script generates configure from configure.ac, after running a few checks to make sure your build environment is broadly OK. It also regenerates certain important generated headers if they need it.

Folks building from a release tarball don't need to do this: they will have a configure script from the start.

Configure

$ ./configure
$ ./configure --prefix=/tmp/junk/example

There are several MyPaint-specific options. These can be shown by running

$ ./configure --help

Build

$ make

Once MyPaint is built, you can run the test suite and/or install it.

Test

$ make check

This runs all the unit tests.

Install

# make install

Uninstall libmypaint with make uninstall.

Check availability

Make sure that pkg-config can see libmypaint before trying to build with it.

$ pkg-config --list-all | grep -i mypaint

If it's not found, you'll need to add the relevant pkgconfig directory to the pkg-config search path. For example, on CentOS, with a default install:

# sh -c "echo 'PKG_CONFIG_PATH=/usr/local/lib/pkgconfig' >>/etc/environment"

Make sure ldconfig can see libmypaint as well

# ldconfig -p |grep -i libmypaint

If it's not found, you'll need to add the relevant lib directory to the LD_LIBRARY_PATH:

$ export LD_LIBRARY_PATH=/usr/local/lib
# sh -c "echo 'LD_LIBRARY_PATH=/usr/local/lib' >>/etc/environment

Alternatively, you may want to enable /usr/local for libraries. Arch and Redhat derivatives:

# sh -c "echo '/usr/local/lib' > /etc/ld.so.conf.d/usrlocal.conf"
# ldconfig

Contributing

The MyPaint project welcomes and encourages participation by everyone. We want our community to be skilled and diverse, and we want it to be a community that anybody can feel good about joining. No matter who you are or what your background is, we welcome you.

Please note that MyPaint is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

Please see the file CONTRIBUTING.md for details of how you can begin contributing.

Making releases

The distribution release can be generated with:

$ make dist

And it should be checked before public release with:

$ make distcheck

Localization

Contribute translations here: https://hosted.weblate.org/engage/mypaint/.

The list of languages is maintained in po/LINGUAS. Currently this file lists all the languages we have translations for. It can be regenerated with:

$ ls po/*.po | sed 's$^.*po/\([^.]*\).po$\1$' | sort > po/LINGUAS

You can also disable languages by removing them from the list if needed.

A list of files where localizable strings can be found is maintained in po/POTFILES.in.

Strings update

You can update the .po files when translated strings in the code change using:

$ cd po && make update-po

When the results of this are pushed, Weblate translators will see the new strings immediately.

Documentation

Further documentation can be found in the libmypaint wiki: https://github.com/mypaint/libmypaint/wiki.

Software using libmypaint

libmypaint's People

Contributors

achadwick avatar asereze avatar briend avatar comradekingu avatar cortexer avatar ecron avatar fmommeja avatar geun-tak avatar ihorhordiichuk avatar jehan avatar jonnor avatar josprachi avatar jplloyd avatar martinxyz avatar mdias avatar milotype avatar portnov avatar prescott66 avatar qulogic avatar raimongn avatar shadowkyogre avatar shakaran avatar sveinki avatar taijuin avatar tjhietala avatar tokyogeometry avatar trokenheim avatar weblate avatar yakushabb avatar zoiba avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libmypaint's Issues

Brush Setting: Offset

This is similar to the speed offset and jitter, but with a fixed value: Essentially all dabs are simply moved away for a certain amount from the drawn stroke. I see two different aproaches (or maybe a better idea?):

Simple: Offset by X & Offset by Y (2 new settings)

  • simply moves the dabs there
  • resulting stroke is the same as drawn stroke (with basic value), Strokes will overlap

More Complicated: Offset by padding number

  • keeps a specified distance to the original stroke
  • resulting stroke will be distorted, depending on concave/convex, Stroke will not overlap
  • I guess this needs more calculations

(of course, this only applies to basic value. There are a lot more possibilities with the inputs)

brush-offset

In combination with random/stroke this can be used to make a "real" Rake Brush, with more then one line.
I guess x&y offset are enough: With direction as input it should be possible to build a line that behaves similar to the same-distance-padding-number...

Direction Input: Behavior and new Ideas

Just a place to discuss/brainstorm.

Right now the Direction input goes from 0 to 180, ignoring U-turns. With this, elliptic dabs end up smoother on the canvas and it doesn't matter: a 90 rotated ellipse looks exactly like a 270 one anyway.

However, when using the direction input for anything except rotation the results seem somewhat unexpected (if you're not aware that it isn't 360):

direction

There are always two "breaks". Now what would an user actually expect from a "Direction" input? A circle that grows from 0 to 360, and the break... If you think logically it makes sense to have the break at the top, clockwise, because the direction of the stroke points towards 0°... But my guts say: The break should be on the right, going counterclockwise, because that's how you learn to think about angles in school

Of course, the rotation for ellipses works better with 180 and I agree that it doesn't make sense to have two Inputs for direction. Maybe the 360 can be converted to 180 just before dab rotation is calculated/drawn? (I have not looked at the code)... Oh, and I wonder, changing the direction behavior now could "break" old brushes? This should be avoided :|

While thinking about it, I had an idea for a new input: Direction Deviation - How much the direction changes from the start of a stoke. It would go from 0 to 180 (or 0 to 100%?) and could work without negative values, just representing the delta/difference. In that case, there is no -180 to 180 break.

Mac OSX gegl Error

I am getting the following error:

gegl/mypaint-gegl-surface.c:29:3: error: redefinition of typedef 'MyPaintGeglTiledSurface' is a C11 feature [-Werror,-Wtypedef-redefinition]
} MyPaintGeglTiledSurface;
  ^
gegl/mypaint-gegl-surface.h:27:41: note: previous definition is here
typedef struct _MyPaintGeglTiledSurface MyPaintGeglTiledSurface;
                                        ^
1 error generated.
scons: *** [gegl/mypaint-gegl-surface.os] Error 1
scons: building terminated because of errors.

Release 1.3.0-beta.1 missing file "doc/Doxyfile"?

Hi there!

It seems the release tarball of 1.3.0-beta.1 lacks file doc/Doxyfile.
it would be cool to have a re-release with that file so that packagers have a chance at building and installing documentation. Many thanks!

Best, Sebastian

Compilation fails with GEGL + introspection + as-needed + GNU gold linker

Hi there!

I would like to forward-report a libmypaint compilation/linking error, that I have not been able to fix myself.
To reproduce it, these things are needed together:

  • Enabling support for both GEGL and introspection
  • LDFLAGS="-Wl,--as-needed"
  • Linkling with ld.gold rather than ld.bfd

Below I am doing just that on a shell.
The error is libmypaint-gegl.so.0: undefined symbol: mypaint_surface_unref, a few lines up the end.

I'm aware that combination may not be what everyone is doing but I believe it makes more sense to report it to you rather than just working around symptoms on our end until someone runs into it somewhere else.

Best, Sebastian

# sudo binutils-config --linker ld.gold
# ld --version | head -n 1
GNU gold (Gentoo 2.25.1 p1.1 2.25.1) 1.11

# git clone https://github.com/mypaint/libmypaint.git
# cd libmypaint/
# ./autogen.sh
# ./configure LDFLAGS="-Wl,--as-needed" --enable-introspection --enable-gegl
# make
[..]
make[2]: Entering directory '/mydir/libmypaint/gegl'
CPPFLAGS="" CFLAGS="-D_POSIX_C_SOURCE=200809L -g -O2" LDFLAGS="-Wl,--as-needed" CC="gcc -std=gnu99" PKG_CONFIG="/usr/bin/pkg-config" DLLTOOL="false" CFLAGS="-D_POSIX_C_SOURCE=200809L -g -O2" LDFLAGS="-Wl,--as-needed -lm" CPPFLAGS="" CXXFLAGS="" /usr/bin/g-ir-scanner  --warn-all --pkg="gegl-0.3" --pkg="glib-2.0" --namespace="MyPaintGegl" --nsversion="1.3" --identifier-prefix="MyPaintGegl" --symbol-prefix="mypaint_gegl" --add-include-path="./.." --add-include-path="." --add-include-path="./.." --add-include-path="`/usr/bin/pkg-config --define-variable=datadir="/usr/local/share" --variable=girdir gobject-introspection-1.0`" --namespace=MyPaintGegl --nsversion=1.3 --libtool="/bin/sh ../libtool"  --include=GObject-2.0 --include=MyPaint-1.3 --include=Gegl-0.3   --library=libmypaint-gegl.la --library=../libmypaint.la  --cflags-begin  -I.. -I.. -I. -I.. --cflags-end  ../glib/mypaint-gegl-glib.h mypaint-gegl-surface.h ../glib/mypaint-gegl-glib.c mypaint-gegl-surface.c libmypaint-gegl.la Makefile --output MyPaintGegl-1.3.gir
g-ir-scanner: link: /bin/sh ../libtool --mode=link --tag=CC gcc -std=gnu99 -o /mydir/libmypaint/gegl/tmp-introspectjidC3k/MyPaintGegl-1.3 -export-dynamic -D_POSIX_C_SOURCE=200809L -g -O2 -Wl,--as-needed -lm tmp-introspectjidC3k/mydir/libmypaint/gegl/tmp-introspectjidC3k/MyPaintGegl-1.3.o -L. libmypaint-gegl.la ../libmypaint.la -lgegl-0.3 -lgegl-npd-0.3 -lm -Wl,--export-dynamic -lgmodule-2.0 -pthread -ljson-glib-1.0 -lgio-2.0 -lgobject-2.0 -lbabl-0.1 -lglib-2.0
libtool: link: gcc -std=gnu99 -o /mydir/libmypaint/gegl/tmp-introspectjidC3k/.libs/MyPaintGegl-1.3 -D_POSIX_C_SOURCE=200809L -g -O2 -Wl,--as-needed tmp-introspectjidC3k/mydir/libmypaint/gegl/tmp-introspectjidC3k/MyPaintGegl-1.3.o -Wl,--export-dynamic -pthread -Wl,--export-dynamic  -L. ./.libs/libmypaint-gegl.so ../.libs/libmypaint.so -ljson-c -lgegl-0.3 -lgegl-npd-0.3 -lm -lgmodule-2.0 -ljson-glib-1.0 -lgio-2.0 -lgobject-2.0 -lbabl-0.1 -lglib-2.0 -pthread
/mydir/libmypaint/gegl/tmp-introspectjidC3k/.libs/MyPaintGegl-1.3: symbol lookup error: /mydir/libmypaint/gegl/.libs/libmypaint-gegl.so.0: undefined symbol: mypaint_surface_unref
Command '[u'/mydir/libmypaint/gegl/tmp-introspectjidC3k/MyPaintGegl-1.3', u'--introspect-dump=/mydir/libmypaint/gegl/tmp-introspectjidC3k/functions.txt,/mydir/libmypaint/gegl/tmp-introspectjidC3k/dump.xml']' returned non-zero exit status 127
make[2]: *** [/usr/share/gobject-introspection-1.0/Makefile.introspection:156: MyPaintGegl-1.3.gir] Error 1
make[2]: Leaving directory '/mydir/libmypaint/gegl'
make[1]: *** [Makefile:822: all-recursive] Error 1
make[1]: Leaving directory '/mydir/libmypaint'
make: *** [Makefile:579: all] Error 2

Tag and release libmypaint

When will there be a specific version number of libmypaint tagged and released? libmypaint is a dependency of some other programs/libraries; one needs to be able to refer to a specific version number of libmypaint.

Support for more lines of symmetry

As reported by @android272 in mypaint/mypaint#529, it would be nice to have more lines of symmetry. This may need brush engine support, because symmetry is currently implemented there.

We need to decide:

  • How best to represent infinite lines of symmetry
  • Whether it would be simpler to move symmetry support back into the MyPaint core, and have that manage axes and just fire lots of different brushes at the canvas.

(After the 1.2.0 release though, not now)

Brush inputs/settings not calibrated for viewzoom and viewrotation (ascension, direction, dab-angle, speed, et al.)

Basically, a bunch of inputs and settings are not calibrated to how you are moving your hand/mouse or viewing the canvas (rotated or not).

This can create some odd scenarios as described in issue #65 where brushes start acting very strangely by just zooming in or out of the canvas. I would like to propose that speed is somehow calculated to always reflect the "real world" speed of the mouse/stylus. Maybe by factoring in the DPI of the monitor and the current zoom level. I also think radius should be ignored; a large brush and small brush should have the same speed.

Also, when rotating the canvas the angles involved should be adjusted so that the brush continues to work as you'd expect if you'd rotated a physical canvas in front of you.

Unknown brush settings cause crash on assert

Hi,
I'm trying to use the lib with Anti or "dirty" brushes in Gimp.
Gimp loads brushes from JSON. With some brushes there are unknown settings.

So, it triggers

assert (id >= 0 && id < MYPAINT_BRUSH_SETTINGS_COUNT); 

in mypaint_brush_set_base_value called from update_settings_from_json_object.

My solution is

    // Set settings                                                                  
    json_object *settings = NULL;                                                    
    if (! obj_get(self->brush_json, "settings", &settings)) {                        
        fprintf(stderr, "Error: No 'settings' field for brush\n");                   
        return FALSE;                                                                
    }                                                                                

    json_object_object_foreach(settings, setting_name, setting_obj) {                

        MyPaintBrushSetting setting_id = mypaint_brush_setting_from_cname(setting_name);

       //  NEW CHECK                                                   
        if (!(setting_id >= 0 && setting_id < MYPAINT_BRUSH_SETTINGS_COUNT)) {       
            fprintf(stderr, "Error: Unknown setting_id: %d for setting: %s\n",       
                    setting_id, setting_name);                                       
//          return FALSE;                                                            
            continue;                                                                
        }                                                                            

        if (!json_object_is_type(setting_obj, json_type_object)) {                   
            fprintf(stderr, "Error: Wrong type for setting: %s\n", setting_name);    
            return FALSE;                                                            
        } 

It just ignores some settings but still loads the brush. Alternative behaviour is to return FALSE, but then the brush becomes useless. My code returns:

Error: Unknown setting_id: -1 for setting: offset_angle
Error: Unknown setting_id: -1 for setting: offset_angle_2
Error: Unknown setting_id: -1 for setting: offset_x
Error: Unknown setting_id: -1 for setting: offset_y
Error: Unknown setting_id: -1 for setting: offset_angle
Error: Unknown setting_id: -1 for setting: offset_angle_2
Error: Unknown setting_id: -1 for setting: offset_x
Error: Unknown setting_id: -1 for setting: offset_y
Error: Unknown setting_id: -1 for setting: offset_angle
Error: Unknown setting_id: -1 for setting: offset_angle_2
Error: Unknown setting_id: -1 for setting: offset_x
Error: Unknown setting_id: -1 for setting: offset_y
Error: Unknown setting_id: -1 for setting: offset_angle
Error: Unknown setting_id: -1 for setting: offset_angle_2
Error: Unknown setting_id: -1 for setting: offset_x
Error: Unknown setting_id: -1 for setting: offset_y
Error: Unknown setting_id: -1 for setting: offset_angle
Error: Unknown setting_id: -1 for setting: offset_angle_2
Error: Unknown setting_id: -1 for setting: offset_x
Error: Unknown setting_id: -1 for setting: offset_y
Error: Unknown setting_id: -1 for setting: offset_angle
Error: Unknown setting_id: -1 for setting: offset_angle_2
Error: Unknown setting_id: -1 for setting: offset_x
Error: Unknown setting_id: -1 for setting: offset_y
Error: Unknown setting_id: -1 for setting: offset_angle
Error: Unknown setting_id: -1 for setting: offset_angle_2
Error: Unknown setting_id: -1 for setting: offset_x
Error: Unknown setting_id: -1 for setting: offset_y

So, my question before I've started preparing any pull request, which solution is more fitting there:

  • Return FALSE;
  • Ignore error;
  • Ignore error but print error/set another exit code;
  • Lets caller of the function to decide if he want to ignore errors or not;
  • Current way (assert).

Website link in project summary is expired

The summary section for libmypaint (https://github.com/mypaint/libmypaint) contains the following text:

"libmypaint, a.k.a. "brushlib", is a library for making brushstrokes which is used by MyPaint and other projects.

http://mypaint.info"

However, mypaint.info states that "This domain has expired" and "If you are the owner of this domain, log in so you can retrieve the invoice and renew the domain."

Does this site have to be renewed by someone? Should this be changed to "http://mypaint.intilinux.com/" ? Mypaint does not list this as the official website on the mypaint github page in the summary section, so I'm not sure what is the preferred course of action.

Simulated impasto: possible?

Would it be possible to add support for faked impasto in the brush engine? Simple stuff like repeating dabs one or more times with different brightnesses:

impasto-hypothetical
(Public domain example of real-media impasto taken from Wikimedia Commons "Impasto-detailed_example..jpg"

I envisage it working by adding some extra settings

  • num_repeats: float rounded to integer, the number of times a dab repeats with the same basic calculated size, position, fuzziness, pixel snap etc. Default & min 1.0; max ~10?
  • dab_offset_dx and dab_offset_dy: offset of the dab from its basic calculated position, floating-point multiples of the actual (or base?) brush radius; default 0.0.

and an extra input which could be used to drive HSV/HSL/whatever lightness output as well as dab offset:

  • repeat: the number of this repeated dab. Zero or one-based?

The applications could be quite interesting. Star scatterers too, if dab angle is allowed to vary by repeat number.

Mac OS build issues

I am trying to compile the library on Mac OS X 10.6 (Snow Leopard). It uses a version of GCC that does not support typedef redefinitions [gcc version 4.2.1], so there is an error because of the typedefs in mypaint-glib-compat.h that are also present in glib's definitions. I have tried removing the doubled definitions from mypaint-glib-compat.h, and this did not work. Is there any way to build on Snow Leopard, using this version of GCC?

Here is the full make invocation and error:

gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I/usr/local/include/json-c -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -D_POSIX_C_SOURCE=200809L -g -O2 -MT mypaint-surface.lo -MD -MP -MF .deps/mypaint-surface.Tpo -c mypaint-surface.c  -fno-common -DPIC -o .libs/mypaint-surface.o
In file included from /usr/local/include/glib-2.0/glib/gtypes.h:32,
                 from /usr/local/include/glib-2.0/glib/galloca.h:32,
                 from /usr/local/include/glib-2.0/glib.h:30,
                 from rng-double.h:7,
                 from helpers.h:4,
                 from mypaint-surface.c:24:
/usr/local/lib/glib-2.0/include/glibconfig.h:40: error: redefinition of typedef ‘guint16’
./mypaint-glib-compat.h:28: error: previous declaration of ‘guint16’ was here
In file included from /usr/local/include/glib-2.0/glib/galloca.h:32,
                 from /usr/local/include/glib-2.0/glib.h:30,
                 from rng-double.h:7,
                 from helpers.h:4,
                 from mypaint-surface.c:24:
/usr/local/include/glib-2.0/glib/gtypes.h:46: error: redefinition of typedef ‘gchar’
./mypaint-glib-compat.h:23: error: previous declaration of ‘gchar’ was here
/usr/local/include/glib-2.0/glib/gtypes.h:49: error: redefinition of typedef ‘gint’
./mypaint-glib-compat.h:24: error: previous declaration of ‘gint’ was here
/usr/local/include/glib-2.0/glib/gtypes.h:50: error: redefinition of typedef ‘gboolean’
./mypaint-glib-compat.h:25: error: previous declaration of ‘gboolean’ was here
/usr/local/include/glib-2.0/glib/gtypes.h:77: error: redefinition of typedef ‘gpointer’
./mypaint-glib-compat.h:20: error: previous declaration of ‘gpointer’ was here

PEP-8 compliance

Running pep8 --statistics on libmypaint:

2       E121 continuation line under-indented for hanging indent
6       E122 continuation line missing indentation or outdented
6       E203 whitespace before ':'
1       E222 multiple spaces after operator
5       E225 missing whitespace around operator
3       E261 at least two spaces before inline comment
48      E265 block comment should start with '# '
13      E302 expected 2 blank lines, found 1
1       E303 too many blank lines (3)
3       E401 multiple imports on one line
35      E501 line too long (124 > 79 characters)
1       E701 multiple statements on one line (colon)
4       E703 statement ends with a semicolon
1       W291 trailing whitespace
2       W391 blank line at end of file

I'm making this a separate issue for libmypaint as opposed to mypaint/mypaint#110. I'll fix uncontroversial things first, and then wait for feedback on more style-related things.

Ascension calculation issues (bad input values with negative number) fmodf issue

Currently the ascension state can basically grow forever, either positively or negatively depending on whether the stylus has been turned clockwise vs counter-clockwise. This manifests as strange brush behavior when ascension state goes into the negative range-- the actual input values can get as high as -500, which the brush dynamics settings can interpret incorrectly.
This is normal-looking. Ascension and Ascension state are both the same. But Ascension state can keep growing forever. . .
1

Here after a few revolutions it has grown quite a bit. It just seems wrong to let this variable grow if it isn't necessary, doesn't it?
2
Finally, if you are unlucky enough move you stylus the opposite way a few times, negative values will really mess up the actual input, throwing off brush dynamics in certain cases.
3

I think I finally have a correct fix for both these issues that I will submit as a pull for shortly.

Antialiasing support for brushes

Right now MyPaint doesn't seem to have any kind of antialiasing in place, which makes it almost unsuitable for inking because of brush scaling issues: thicker strokes become blurry and thinner strokes become pixelated. And to make things worse, erasers suffer these issues too.

This is how brush scaling currently works in MyPaint 1.1 with Kabura brush: http://i.imgur.com/9sUQOsv.png

And this is how "Ink_gpen_25" brush in Krita 2.9 scales: http://i.imgur.com/FCTuYwD.png

Krita seems to have a separate anti-aliasing preset for brushes. Perhaps MyPaint should get something like this as well?

Master warnings pending in "make check"

Running make check I get the following warnings, that probably it is good to fix at some point:

mypaint-surface.c:119: Warning: MyPaint: mypaint_surface_end_atomic: invalid return annotation
mypaint-rectangle.h:35: Warning: MyPaint: mypaint_rectangle_copy: return value: Invalid non-constant return of bare structure or union; register as boxed type or (skip)
mypaint-brush.c:128: Warning: MyPaint: mypaint_brush_new: return value: Invalid non-constant return of bare structure or union; register as boxed type or (skip)
mypaint-brush.c:128: Warning: MyPaint: mypaint_brush_new: return value: Invalid non-constant return of bare structure or union; register as boxed type or (skip)
mypaint-fixed-tiled-surface.h:30: Warning: MyPaint: mypaint_fixed_tiled_surface_interface: return value: Invalid non-constant return of bare structure or union; register as boxed type or (skip)
mypaint-fixed-tiled-surface.h:20: Warning: MyPaint: mypaint_fixed_tiled_surface_new: return value: Invalid non-constant return of bare structure or union; register as boxed type or (skip)
mypaint-fixed-tiled-surface.h:20: Warning: MyPaint: mypaint_fixed_tiled_surface_new: return value: Invalid non-constant return of bare structure or union; register as boxed type or (skip)

Switch to autotools

To update my Windows cross-build, I need to cross-compile libmypaint, which is now a mandatory dependency.
Unfortunately I was unable to do so. Well I didn't try much yet, but I at least tried to set $CC, and other environment variable (as I saw in the SConstruct), and used my usual cross-build environment with other environment variables useful for autotools as well as CMake crossbuilds. It was not enough.
Since you also provide MyPaint for Windows, do you have cross-compilation instructions somewhere? I did not find any in the repository.

As an alternative, I am wondering if you would consider switching to another build system which has better support for cross-compilation in a standard way (common to all projects using it), for instance the autotools?

Buiding with GEGL Support Enable Fails

Building libmypaint with the --enable-gegl flag raise cause make to halt saying make[2]: *** No rule to make target '../libmypaint.la', needed by 'libmypaint-gegl.la'. Stop. I think we might have missed something when upping the api to 2.0. Right now it's affecting our AUR pkgbuilds which use libmypaint-git for gimp-git and mypaint-git as a dependency.

@achadwick could you look into this since you made the changes for the API version?

Steps to Reproduce from Git Folder

  1. ./autogen.sh
  2. ./configure --enable-gegl
  3. make -d

Brush Tip: Custom Shapes

Moved from myPaint

Right now the brushes are all based on circular/elliptic shapes. And even with so many options, some brush behaviours simply arent possible. For example a rake brush:
image

Having custom brush tips would especially benefit concept artists, because Speedpaintings usually start with random forms, and mood paintings usually use textured/shaped brushes a lot.

Possible ways for "Custom Brush Tips":

  • A pixel bitmap graphic that gets stamped on the canvas. See Photoshop. Contra: Loss of quality when scaling/rotating/changing-ratio of the tip. Effects like blur/hardness wouldn't work the same like with the dabs. Pro: Probably easiest to implement, Additional GUI is minimal (load file button)
  • An opaque, closed vector shape as replacement for the elliptical dab. See Alchemy (however, alchemy is pure vector based, as far as I know). Everything that's possible with the dab, should be possible with a vector shape too (like blur etc). Additional GUI can be simple like bitmap tip. Contra: Having a complex shape will likely impact performance and I'm not sure how complicated it is to write code that checks if something is masked by a vector or not... Vector shapes could also replace basic inbuilt shapes like rectangle, triangle etc - however this is probably not as efficient as (see next).
  • Inbuilt shapes: Rectangle or Triangle could be implemented as mathematical formulas (like the circle, right now). Pro: Just a single, simple shape like the rectangle opens up a lot of new opportunities and is rather easy to code. Contra: A program would need more buttons to change shapes. And a rake is still not possible
  • Inbuilt shapes 2.0: n-gones, stars, hexagons, hollow circles, circle parts, and the like, that can be defined by the user through a special GUI in the program. See Inkscape shapes. With options to plot out one shape multiple times at once based on settings, a rake brush might be possible. Downside: Even more buttons and specialized GUI dialogues.
  • Extended functionality: Spawning a series of shapes (either vector or from a gif or similar) in order or randomly or based on a pen setting. See Art Rage

Personally I'd prefer the to load one vector from svg as brush tip (in myPaint).

Technical Issues

I'm no programmer and can barely understand the code here... So this is up for comments. I can only guess some issues here:

  • Brush tip has to be stored in the brush preset/settings. This might lead to compatibility problems.
  • Does it have to be stored in the .ora, too? The ora seems to keep track of individual strokes...
  • Right now, it looks like the circular shape is hard coded. At least I noticed a lot of "radius". If we add a rectangle now, wouldn't it be better to use rectangle as "standard" and circular as special case? I have no idea what I'm talking about... a rectangle is also a better bounding box for a bitmap or vector brush tip...
  • One important thing to keep in mind though: Performance of drawing with the elliptical dab has to stay as good as it is now. A round brush is the essential tool, other shapes are helpful, but not as important.

mypaint-mapping: redundant interpolation

Testing the Gridmap settings/inputs might have uncovered a couple bugs. If I set Opacity to use a gridmap input and then, using the liveupdate feature, drag the GridMap Scale setting left and right, eventually mypaint crashes:

python: tilemap.c:62: tile_map_get: Assertion `offset < 2self->size2*self->size' failed.
Aborted

Here's where it gets weird. Even if I click the eraser for the GridMap X, and GridMap Y on the Opacity setting, Mypaint will continue to crash. I have to hand-edit the brush file and actually remove these input lines even though they shouldn't be doing anything (after all I clicked the eraser and all). So this might be a bug in MyPaint gui (I'll make a separate issue for that) that leaves these dangling definitions:

            "gridmap_x": [
                [
                    0.0, 
                    0.0
                ], 
                [
                    256.0, 
                    0.0
                ]
            ], 

So I decided to look at the https://github.com/mypaint/libmypaint/blob/master/mypaint-mapping.c#L177 and noticed it seems to try to skip interpolation if the x0 and x1 values are the same, but it doesn't check y0 and y1. In the above example the x values are different (unless I"m really reading this all wrong), so it tries to do the interpolation anyway:

    if (x0 == x1) {
      y = y0;
    } else {
      // linear interpolation
      y = (y1*(x - x0) + y0*(x1 - x)) / (x1 - x0);
    }

I made a branch here that just adds an extra check for y0 and y1:

if (x0 == x1 || y0 == y1) {

https://github.com/briend/libmypaint/tree/mappingFix

This actually seems to fix reduces the crashing issue I was having with GridMap, but I really don't know the root cause of the assertion error. I've only ever seen it crash when doing LiveUpdate in the brush editor, not when actually drawing. Can someone validate the logic change? I'm really not quite sure what's going on.

viewrotation is not listed in brushsettings.json

After integrating PR #70, I noticed that the View Rotation input is not listed in brushsettings.json, meaning that MyPaint cannot see it or create brushes which depend on it. It is however listed as a state.

Should it be added as an input too? MyPaint code now feeds it through into libmypaint.

Related: mypaint/mypaint#817.

MyPaint Rendering differs between 1.1.0 and git version

I just installed the git version from 2014-08-06
And the Ramon-2B pencil looks a lot more blurry and smoothed:
screenshot from 2014-08-26 11 23 22
The chicken is an old drawing, and even when picking the stroke directly from it, it looks not the same. To make sure, I redowloaded the ramon set.
When switching back to 1.1.0 the brush is correct again.

Scons compilation error

I'm trying build the libmypaint to enable the MyPaint brushes on the last commit of Gimp Git Master.
During the scons to test only, it appears this error:

jag@jagnome:~/devel/libmypaint$ scons
scons: Reading SConscript files ...
KeyError: 'CPPFLAGS':
File "/home/jag/devel/libmypaint/SConstruct", line 45:
env['CCFLAGS'] += SCons.Util.CLVar(os.environ['CPPFLAGS'])
File "/usr/lib/python2.7/UserDict.py", line 23:
raise KeyError(key)

The dependencies to scons are OK, because normally I use to build the MyPaint git master every new commit.
My box is ubuntu gnome 14.04.2, i5, 8Gb memory.

Input clamping needed- Ascension, Fine Speed, Gross Speed

Certain inputs can go beyond the values defined in brushsettings.json, creating unexpected results on the canvas. Consider a brush settings such as below-- there should never be any jitter as all of the points are in the negatives and the base value is zero:

screenshot from 2016-08-10 19-24-43

However, depending on value of Fine Speed Gamma, canvas zoom level, and (small) brush radius, speed values much higher than 4.0 can be achieved and the above brush setting will move into positive values and actually create jitter. Imagine my surprise! I believe this is because the polyline/curve is continued in whatever direction it was already going-- in this case "downward" towards the positive numbers.

I don't think it makes sense to increase speed to beyond 4.0; it wouldn't help much-- with speed gamma set to 8 I can get speeds over 200 when zoomed out on the canvas: edit, actually as I mention in issue #66 we might want to clamp it at 40 to allow for gamma headroom.

screenshot from 2016-08-10 19-38-46

This could totally cripple mypaint if it was mapped to something like radius. Here's a video demo showing the behavior with jitter as an example:

https://www.youtube.com/watch?v=2WJBC4-qpuQ&feature=youtu.be

So I think we should just clamp the values to whatever the soft_maximums in brushsettings.json. I'm not really sure what the hard_minimum and hard_maximum values are supposed to do-- they were null for the speed inputs but setting it to 4.0 did not fix this issue. Also, ascension already had a hard_maximum but it also has this same problem when the values go beyond -180,+180. Git pull #69 actually fixes this Ascension issue without clamping but clamping might be a good idea?

It dawned on me that fine/gross speed should be calibrated against zoom level and radius so these crazy values aren't ever reached, but I'll open another issue for that-- see issue #66

Expand our CI Tools Build Test Configuations

After we address #97, we should add various build configurations tests as well to avoid any commits or pull requests that may potentially break the building process. I'll probably work on this one when it comes time to. In the meantime what build config options should we test out? The obvious first choice should be --gegl-enabled option.

Redundant division done in performance-sensitive areas

There's a bunch of code in brushmodes.c that looks like x / (1<<15). This is a weird calculation to do, as it doesn't need division. As far as I can tell, x >> 15 is identical.

If gcc isn't optimising / (1<<15) to >>15, this is a significant performance hit as divisions are a lot more costly than bitshifts.

brush engine not aware of canvas rotation

I've been working on some pretty complex brushes, and I finally tried them out while rotating the canvas. I noticed all the direction information is kept oriented with the original position. It's as if the canvas has not rotated and only the view of the canvas has rotated. If your brush is affected by X/Y offsets, Ascension, direction, barrel-rotation, etc, it won't behave as you might expect-- suddenly your pen is upside down or the thick/thin angle gets flipped around, etc. This is related to issue #66, and I think view-rotation (degrees) will need to be added as an input in addition to the zoom-level. I've had some success adding barrel-rotation so I think I'll take a stab at adding both of these as inputs and applying them to offset the affected inputs-- hopefully it's as easy as just adding the zoom-rotation degrees the current input value.

issues with how libmypaint, libmypaint-gegl are linked

Hi there, during the review of the libmypaint package for Fedora, a couple of issues were found regarding how the libraries are linked:

libmypaint.x86_64: W: unused-direct-shlib-dependency /usr/lib64/libmypaint-1.3.so.0.0.0 /lib64/libglib-2.0.so.0
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_buffer_get
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 g_object_unref
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 mypaint_tiled_surface_init
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_buffer_set
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_buffer_iterator_next
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 g_assertion_message_expr
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 g_return_if_fail_warning
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_node_new_child
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 g_object_new
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_buffer_get_format
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_node_new
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_malloc
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 g_object_ref
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_free
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 babl_format_get_bytes_per_pixel
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 babl_type
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 babl_format_new
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 mypaint_surface_ref
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 g_log
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_buffer_iterator_new
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_buffer_get_type
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_node_link
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_rectangle_bounding_box
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 g_type_check_instance_is_a
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 babl_component
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 g_type_check_instance_cast
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_buffer_set_extent
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 g_boxed_type_register_static
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 babl_model
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 g_object_get
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 mypaint_surface_unref
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 mypaint_tiled_surface_destroy
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_node_process
libmypaint.x86_64: W: undefined-non-weak-symbol /usr/lib64/libmypaint-gegl.so.0.0.0 gegl_rectangle_set
libmypaint.x86_64: W: unused-direct-shlib-dependency /usr/lib64/libmypaint-gegl.so.0.0.0 /lib64/libm.so.6
libmypaint.x86_64: W: unused-direct-shlib-dependency /usr/lib64/libmypaint-gegl.so.0.0.0 /lib64/libpthread.so.0
1 packages and 0 specfiles checked; 0 errors, 37 warnings.

It looks like on the one hand, both libmypaint and libmypaint-gegl are unnecessarily linked against glib, and libm, libpthread, respectively and on the other that libmypaint-gegl should be additionally linked against libmypaint, gegl, babl, gobject and glib. I've looked into this a bit, but didn't find easily where to fix this myself.

"color erase" and "behind" brush blend modes, colorize to and erase by color all pixels on a layer command

gimp has those implemented and they are great!!

https://www.youtube.com/watch?v=ixfK0qCEmbg
This would be very useful for cleaning up sketch drawings. Tvpaint and PAP use this feature in order to allow the user to draw with multiple colored brushes. So if using a blue brush for a rough pass, then draw with a black brush on top to ink it and then erase the blue brush lines bellow.

It would be nice to have it in mypaint.

User case example :
To illustrate this, lets say we have a hand and need to draw a new variation of it. We will start with the previous drawing, but erase the parts that need to be changed:
screenshot_2015-06-10_11-42-00

Then we use the blue pencil to sketch a drawing of the new hand variation:
screenshot_2015-06-10_11-43-30
The blue pencil is set to NOT affect existing pixels by drawing on top of them.

We finish the blue line sketch, then we do the opposite, we set a black pencil and set it to overwrite already existing pixels with its color and ink with it:
screenshot_2015-06-10_11-59-55

Finally, we execute the "erase all color on a layer" command, with color set to blue! What we are left with is the clean line art:
screenshot_2015-06-10_12-01-48

All done on a single layer!

You can also apply this to selective eraser mode, where the eraser tool can be set to work only on lines that have the same color as the one that is currently set to the eraser tool.

Why else is this useful?

  • When you draw for animation, and in general - it is good practice to draw an object complete, when the object is behind another object and then erase the part of the line that is behind the other object. In this case we have the fingers of the hand covering the handle. We must draw the entire handle, then clean up the part that is behind the fingers.

The draw behind brush blend mode will be very useful for fixing errors left by bad bucket fill results. Filling areas that it missed, without disrupting the ink lines.

The color erase brush blend mode will be useful for erasing color spills without disrupting the lineart. Or erasing parts of lineart without disrupting fills.

LD_LIBRARY_PATH is ignored when running g-ir-scanner

In file SConscript, function add_gobject_introspection:

scanner_cmd = """LD_LIBRARY_PATH=./ g-ir-scanner -o $TARGET --warn-all \    
    --namespace=%(gi_name)s --nsversion=%(version)s --add-include-path=./ \ 
    --identifier-prefix=%(type_prefix)s --symbol-prefix=%(func_prefix)s \   
    %(pkgs)s %(includeflags)s %(gi_includes)s \
    --library=%(libname)s $SOURCES""" % locals()

This ignores the value of LD_LIBRARY_PATH set by the user. If GEGL is installed in a directory that cannot be found without setting LD_LIBRARY_PATH, g-ir-scanner will fail because required shared libraries cannot be found.

GIMP 2.9.5 MyPaint-Brushes weird effect

Lubuntu 16.04, GIMP 2.9.5 PPA (Just updated)
2017-06-20, The latest version of libmypaint-master is installed, but questions remain.

Such as: MyPaint Brushes deevad-v6 (The brush parameter is the default)
spray2: A spacing stroke appeared in the splash effect.
watercolor expressive: Using this brush will cause GIMP to Feign death.
Some MyPaint Brushes: There will be a big of spacing or no flow.

If there is the problem with GIMP, please close this report.

3.0 API: make parameters extensible

As mentioned in #92, methods that take lists of parameters that are only going to grow over time, such as mypaint_brush_stroke_to() should be implemented as variadic functions, or take as parameters an opaque extensible type (GHashTable or one of our own?). The goal is to prevent future pointless API+ABI breaks.

We have to take care to make it compatible with GObject-Introspection, even though that interface is languishing rather. I need to get my head around the almost nonexistent docs for it.

If it looks nicer, stroke_to() could go back to the old implementation before viewzoom and viewrotation were added, and be marked deprecated in favour of a stroke(brush, surface, x, y, pressure, <EXTENSIONBLOB>) method.

Wierd compile error "gcc: error: ... No such file or directory" with valid gcc CFLAGS

Hi!

I'm unsure if I'm hitting a scons bug (running scons 2.4.1) or a libmypaint build system bug here.
Command

CFLAGS="--param l1-cache-size=32 --param l2-cache-size=6144" scons enable_gegl="true"

fails (as seen below while) these two build fine:

CFLAGS="--param l1-cache-size=32 --param l2-cache-size=6144" scons
CFLAGS="--param l1-cache-size=32" scons enable_gegl="true"

In case you are wondering, the param are a result of resolving/inling GCC's -match=native on T400 notebook of mine:

# resolve-march-native -a
-march=core2 -msse4.1 --param l1-cache-line-size=64 --param l1-cache-size=32 --param l2-cache-size=6144 -O2 -pipe

So a non-default option and multiple --param key=value parameters in CFLAGS make libmypaint
compilation fail due to some CFLAGS mis-processing it seems. The full output is:

# CFLAGS="--param l1-cache-size=32 --param l2-cache-size=6144" scons enable_gegl="true"
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
Creating 'mypaint-config.h'
gcc -o brushmodes.os -c -std=c99 -D_POSIX_C_SOURCE=200809L -fopenmp -O3 --param l1-cache-size=32 --param l2-cache-size=6144 -Wall -Wstrict-prototypes -Werror -g -fPIC -DHAVE_JSON_C -DHAVE_GETTEXT -I. -I/usr/include/json-c brushmodes.c
generate_cheaders(["mypaint-brush-settings-gen.h", "brushsettings-gen.h"], ["generate.py", "brushsettings.py", "brushsettings.json"])
python2.7 generate.py mypaint-brush-settings-gen.h brushsettings-gen.h
Writing mypaint-brush-settings-gen.h
Writing brushsettings-gen.h
gcc -o fifo.os -c -std=c99 -D_POSIX_C_SOURCE=200809L -fopenmp -O3 --param l1-cache-size=32 --param l2-cache-size=6144 -Wall -Wstrict-prototypes -Werror -g -fPIC -DHAVE_JSON_C -DHAVE_GETTEXT -I. -I/usr/include/json-c fifo.c
gcc -o gegl/mypaint-gegl-surface.os -c -std=c99 -D_POSIX_C_SOURCE=200809L -fopenmp -O3 l1-cache-size=32 --param l2-cache-size=6144 -Wall -Wstrict-prototypes -Werror -g -pthread -fPIC -DHAVE_JSON_C -DHAVE_GETTEXT -I. -I/usr/include/json-c -I/usr/include/gegl-0.3 -I/usr/include/json-glib-1.0 -I/usr/include/gio-unix-2.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/babl-0.1 gegl/mypaint-gegl-surface.c
gcc: error: l1-cache-size=32: No such file or directory
scons: *** [gegl/mypaint-gegl-surface.os] Error 1
scons: building terminated because of errors.

Do you have it on your systems, too?

Standardize libmypaint build for both GIMP and MyPaint (use_sharedlib by default)

Once libmypaint has split off from MyPaint properly (mypaint/mypaint#535), we should concentrate on standardizing a shared-lib build for both GIMP and MyPaint. We should standardize for packaged distros like Debian or Arch or Fedora where users might be installing GIMP and MyPaint into the same prefix, of course ☺

  • GIMP is going to require GEGL, so enable_gegl should be on by default.
  • Shared libs (use_sharedlib) should be the standard build, not static.
  • MyPaint-only environments (e.g. the MyPaint Windows build) should be able to turn off the GEGL requirement.
  • Does GIMP require introspection? Would MyPaint one day?

Portable MyPaint for PC

I want to take this program with me everywhere I go.

For every stable version, please release two portable 7z archives for us PC users. One 32-bit build, one 64-bit build.

7-Zip compresses well, and most PC users who go portable have enough gumption to learn how to extract a 7z file.

Build fails with UnicodeDecodeError on german locale

log:

scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
Creating 'mypaint-config.h'
gcc -o brushmodes.os -c -std=c99 -D_POSIX_C_SOURCE=200809L -fopenmp -O3 -Wall -Wstrict-prototypes -Werror -g -fPIC -DHAVE_JSON_C -DHAVE_GETTEXT -I. -I/usr/include/json-c brushmodes.c
generate_cheaders(["mypaint-brush-settings-gen.h", "brushsettings-gen.h"], ["generate.py", "brushsettings.py", "brushsettings.json"])
python2.7 generate.py mypaint-brush-settings-gen.h brushsettings-gen.h
Writing mypaint-brush-settings-gen.h
Traceback (most recent call last):
  File "generate.py", line 137, in <module>
    writefile(args[1], generate_internal_settings_code())
  File "generate.py", line 105, in generate_internal_settings_code
    [settings_info_struct(i) for i in brushsettings.settings])
  File "generate.py", line 69, in generate_static_struct_array
    entries.append(indent + "{%s}" % (", ".join(entry)))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 5: ordinal not in range(128)
scons: *** Error 1

state of the repository is master/commit 28eb0bd

locale -v:

LC_CTYPE="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_MESSAGES="de_DE.UTF-8"
LC_PAPER="de_DE.UTF-8"
LC_NAME="de_DE.UTF-8"
LC_ADDRESS="de_DE.UTF-8"
LC_TELEPHONE="de_DE.UTF-8"
LC_MEASUREMENT="de_DE.UTF-8"
LC_IDENTIFICATION="de_DE.UTF-8"
LC_ALL=

locale -a:

C
de_DE
de_DE@euro
de_DE.iso88591
de_DE.iso885915@euro
de_DE.utf8
deutsch
en_US
en_US.iso88591
en_US.utf8
german
POSIX

After adding a print(entry) before the line that throws, I noticed the "u" marker missing in front of the translated strings but not the strings that have no translation (second element of the tuple). The last line is the one that throws, "H\xc3\xa4rte" is the word "Härte".

(u'"opaque"', 'N_("Deckkraft")', 'FALSE', '0.0', '1.0', '2.0', u'N_("0 means brush is transparent, 1 fully visible\\n(also known as alpha or opacity)")')
(u'"opaque_multiply"', u'N_("Opacity multiply")', 'FALSE', '0.0', '0.0', '2.0', u'N_("This gets multiplied with opaque. You should only change the pressure input of this setting. Use \'opaque\' instead to make opacity depend on speed.\\nThis setting is responsible to stop painting when there is zero pressure. This is just a convention, the behaviour is identical to \'opaque\'.")')
...
(u'"hardness"', 'N_("H\xc3\xa4rte")', 'FALSE', '0.0', '0.8', '1.0', u'N_("Hard brush-circle borders (setting to zero will draw nothing). To reach the maximum hardness, you need to disable Pixel feather.")')

[PATCH] Fix "make check" link errors with LDFLAGS="-Wl,--as-needed"

Hi!

We ran into another issue with -Wl,--as-needed.
In contrast to issue #58, this issue is not related to GNU gold.

# ./autogen.sh && ./configure LDFLAGS="-Wl,--as-needed" --enable-gegl && make clean all check
[..]
Making check in gegl
make[2]: Entering directory '/tmp/tmp.0snzncE6pB/libmypaint/tests/gegl'
make  check-TESTS
make[3]: Entering directory '/tmp/tmp.0snzncE6pB/libmypaint/tests/gegl'
make[4]: Entering directory '/tmp/tmp.0snzncE6pB/libmypaint/tests/gegl'
depbase=`echo test-gegl-surface.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../..  -I../.. -I../.. -I../../gegl -I../../tests  -DLIBMYPAINT_TESTING_ABS_TOP_SRCDIR='"/tmp/tmp.0snzncE6pB/libmypaint"' -pthread -I/usr/include/gegl-0.3 -I/usr/include/json-glib-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/babl-0.1 -I../../gegl/ -I.. -D_POSIX_C_SOURCE=200809L -g -O2 -MT test-gegl-surface.o -MD -MP -MF $depbase.Tpo -c -o test-gegl-surface.o test-gegl-surface.c &&\
mv -f $depbase.Tpo $depbase.Po
/bin/sh ../../libtool  --tag=CC   --mode=link gcc -std=gnu99 -DLIBMYPAINT_TESTING_ABS_TOP_SRCDIR='"/tmp/tmp.0snzncE6pB/libmypaint"' -pthread -I/usr/include/gegl-0.3 -I/usr/include/json-glib-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/babl-0.1 -I../../gegl/ -I.. -D_POSIX_C_SOURCE=200809L -g -O2  -Wl,--as-needed -o test-gegl-surface test-gegl-surface.o -lm  -lgegl-0.3 -lgegl-npd-0.3 -lm -Wl,--export-dynamic -lgmodule-2.0 -pthread -ljson-glib-1.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lbabl-0.1 ../../libmypaint.la ../../gegl/libmypaint-gegl.la ../../tests/libmypaint-tests.a -lm 
libtool: link: gcc -std=gnu99 -DLIBMYPAINT_TESTING_ABS_TOP_SRCDIR=\"/tmp/tmp.0snzncE6pB/libmypaint\" -pthread -I/usr/include/gegl-0.3 -I/usr/include/json-glib-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/babl-0.1 -I../../gegl/ -I.. -D_POSIX_C_SOURCE=200809L -g -O2 -Wl,--as-needed -o .libs/test-gegl-surface test-gegl-surface.o -Wl,--export-dynamic -pthread  -lgegl-0.3 -lgegl-npd-0.3 -lgmodule-2.0 -ljson-glib-1.0 -lgio-2.0 -lbabl-0.1 ../../.libs/libmypaint.so -ljson-c -lgobject-2.0 -lglib-2.0 ../../gegl/.libs/libmypaint-gegl.so ../../tests/libmypaint-tests.a -lm -pthread
../../tests/libmypaint-tests.a(mypaint-test-surface.o): In function `test_surface_drawing':
/tmp/tmp.0snzncE6pB/libmypaint/tests/mypaint-test-surface.c:58: undefined reference to `mypaint_brush_new'
/tmp/tmp.0snzncE6pB/libmypaint/tests/mypaint-test-surface.c:61: undefined reference to `mypaint_brush_from_string'
/tmp/tmp.0snzncE6pB/libmypaint/tests/mypaint-test-surface.c:62: undefined reference to `mypaint_brush_set_base_value'
/tmp/tmp.0snzncE6pB/libmypaint/tests/mypaint-test-surface.c:77: undefined reference to `mypaint_surface_begin_atomic'
/tmp/tmp.0snzncE6pB/libmypaint/tests/mypaint-test-surface.c:82: undefined reference to `mypaint_surface_end_atomic'
/tmp/tmp.0snzncE6pB/libmypaint/tests/mypaint-test-surface.c:95: undefined reference to `mypaint_brush_unref'
/tmp/tmp.0snzncE6pB/libmypaint/tests/mypaint-test-surface.c:96: undefined reference to `mypaint_surface_unref'
../../tests/libmypaint-tests.a(mypaint-utils-stroke-player.o): In function `mypaint_utils_stroke_player_iterate':
/tmp/tmp.0snzncE6pB/libmypaint/tests/mypaint-utils-stroke-player.c:142: undefined reference to `mypaint_brush_stroke_to'
/tmp/tmp.0snzncE6pB/libmypaint/tests/mypaint-utils-stroke-player.c:148: undefined reference to `mypaint_surface_end_atomic'
/tmp/tmp.0snzncE6pB/libmypaint/tests/mypaint-utils-stroke-player.c:139: undefined reference to `mypaint_surface_begin_atomic'
../../gegl/.libs/libmypaint-gegl.so: undefined reference to `mypaint_tiled_surface_init'
../../gegl/.libs/libmypaint-gegl.so: undefined reference to `mypaint_surface_ref'
../../gegl/.libs/libmypaint-gegl.so: undefined reference to `mypaint_tiled_surface_destroy'
collect2: error: ld returned 1 exit status
make[4]: *** [Makefile:623: test-gegl-surface] Error 1
make[4]: Leaving directory '/tmp/tmp.0snzncE6pB/libmypaint/tests/gegl'
make[3]: *** [Makefile:839: check-TESTS] Error 2
make[3]: Leaving directory '/tmp/tmp.0snzncE6pB/libmypaint/tests/gegl'
make[2]: *** [Makefile:909: check-am] Error 2
make[2]: Leaving directory '/tmp/tmp.0snzncE6pB/libmypaint/tests/gegl'
make[1]: *** [Makefile:780: check-recursive] Error 1
[..]

Please consider applying the git-am patch attached. I hope you don't mind that way of sharing the patch: It's way easier to me.

libmypaint-1.3.0_beta1-as-needed.patch

Best, Sebastian

mypaint_mapping_is_constant() doesn't catch inert input mappings

mypaint_mapping_is_constant() is supposed to be a way to check that an input has any dynamic inputs defined, however MyPaint seems to leave extra settings that are effectively disabled, like:

            "random": [
                [
                    0.0, 
                    0.0
                ], 
                [
                    1.0, 
                    0.0
                ]
            ]

So not only the does it seem to try to interpolate this (see #99 ), but mypaint_mapping_is_constant will return false if you've ever added an input and then erased it. SO, this can be a huge performance penalty because smudge gets turned on:

mypaint-brush.c:785
// update smudge color
if (self->settings_value[MYPAINT_BRUSH_SETTING_SMUDGE_LENGTH] < 1.0 &&
// optimization, since normal brushes have smudge_length == 0.5 without actually smudging
(self->settings_value[MYPAINT_BRUSH_SETTING_SMUDGE] != 0.0 || !mypaint_mapping_is_constant(self->settings[MYPAINT_BRUSH_SETTING_SMUDGE])))

So basically a lot of brushes might call get_color even when they shouldn't, unless you 1) manually delete any inputs for the Smudge setting from your brush files, or 2) set Smudge_Length to 1.0. Ack!!

Update Windows AppVeyor build to use MSYS2

AppVeyor have support for MSYS2, so we can make the CI build that happens there a bit more useful now.

Since most libmypaint developers are Linux people, a script like universal-ctags's might be more approachable.

"Change color satur. ({HSV,HSL})" settings on pure greys: switch the hue to red

From mypaint/mypaint#256:

I'm working on the wet brushes set. They are very interesting to use but I am not capable to resolve the relationship between with the grey values and HSL saturation instances... always the greys are changing the Hue... they appear redish... Perhaps is not possible to do it.
With other colors works fine my problem is only to modelling de grey tones.
In this model I'm using basically the Opacity and Color HSL saturation.
Some suggestion?
http://pastebin.com/Y7wJjY84 (brush)
-- @americogobbo

Example:

weting-proofs-grey-problem

Steps to reproduce:

  1. Set "Change color satur. (HSV)" to something > 0
  2. Choose #aaaaaa or some other pure grey as the colour
  3. Paint. Expected grey, actually get a pure-hue red or pink

This is especially noticeable when "Smudge" is high, because then the brush becomes sensitive to what's on the surface.

Python bindings

I see that the MyPaint program (which is Python based) uses libmypaint, so, I guess there are bindings out there to some degree?

Anyways, it'd be really nice if I could do something as:

pip install libmypaint

to get the painting engine available in Python -- my own use case would be drawing in numpy arrays or QImages -- and it'd be very nice to use libmypaint on Python.

Is that something which would be feasible to have in the future?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.