Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package fcft for openSUSE:Factory checked in 
at 2023-07-17 19:23:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/fcft (Old)
 and      /work/SRC/openSUSE:Factory/.fcft.new.3193 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "fcft"

Mon Jul 17 19:23:07 2023 rev:17 rq:1098717 version:3.1.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/fcft/fcft.changes        2022-09-25 
15:35:30.439652449 +0200
+++ /work/SRC/openSUSE:Factory/.fcft.new.3193/fcft.changes      2023-07-17 
19:23:25.313784515 +0200
@@ -1,0 +2,6 @@
+Fri Jul 14 15:44:24 UTC 2023 - Arnav Singh <[email protected]>
+
+- Update to 3.1.6:
+  * Updated bundled nanosvg.
+
+-------------------------------------------------------------------

Old:
----
  fcft-3.1.5.tar.gz

New:
----
  fcft-3.1.6.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ fcft.spec ++++++
--- /var/tmp/diff_new_pack.ThcVCD/_old  2023-07-17 19:23:26.437791026 +0200
+++ /var/tmp/diff_new_pack.ThcVCD/_new  2023-07-17 19:23:26.441791049 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package fcft
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %define libname libfcft4
 Name:           fcft
-Version:        3.1.5
+Version:        3.1.6
 Release:        0
 Summary:        A library for font loading and glyph rasterization using 
FreeType/pixman
 License:        MIT
@@ -38,7 +38,7 @@
 BuildRequires:  pkgconfig(harfbuzz) >= 5.2
 BuildRequires:  pkgconfig(libutf8proc)
 BuildRequires:  pkgconfig(pixman-1)
-BuildRequires:  pkgconfig(tllist)
+BuildRequires:  pkgconfig(tllist) >= 1.0.1
 
 %description
 fcft is a font loading and glyph rasterization library built on-top

++++++ fcft-3.1.5.tar.gz -> fcft-3.1.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/.gitlab-ci.yml new/fcft/.gitlab-ci.yml
--- old/fcft/.gitlab-ci.yml     2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/.gitlab-ci.yml     1970-01-01 01:00:00.000000000 +0100
@@ -1,92 +0,0 @@
-stages:
-  - build
-
-variables:
-  GIT_SUBMODULE_STRATEGY: normal
-
-before_script:
-  - apk update
-  - apk add musl-dev linux-headers meson ninja gcc scdoc
-  - apk add pixman-dev freetype-dev fontconfig-dev harfbuzz-dev
-  - apk add utf8proc-dev wayland-dev wayland-protocols
-  - apk add git
-  - apk add check-dev
-  - apk add ttf-hack font-noto-emoji
-  - mkdir -p subprojects && cd subprojects
-  - git clone https://codeberg.org/dnkl/tllist.git
-  - cd ..
-
-debug-x64:
-  image: alpine:latest
-  stage: build
-  script:
-    - mkdir -p bld/debug
-    - cd bld/debug
-    - meson --buildtype=debug -Drun-shaping=enabled -Dtest-text-shaping=true 
-Dexamples=true ../../
-    - ninja -v -k0
-    - ninja -v test
-  artifacts:
-    reports:
-      junit: bld/debug/meson-logs/testlog.junit.xml
-
-debug-x64-no-text-shaping:
-  image: alpine:latest
-  stage: build
-  script:
-    - apk del harfbuzz harfbuzz-dev
-    - mkdir -p bld/debug
-    - cd bld/debug
-    - meson --buildtype=debug -Dgrapheme-shaping=disabled 
-Drun-shaping=disabled -Dtest-text-shaping=false ../../
-    - ninja -v -k0
-    - ninja -v test
-  artifacts:
-    reports:
-      junit: bld/debug/meson-logs/testlog.junit.xml
-
-release-x64:
-  image: alpine:latest
-  stage: build
-  script:
-    - mkdir -p bld/release
-    - cd bld/release
-    - meson --buildtype=release -Drun-shaping=enabled  
-Dtest-text-shaping=true -Dexamples=true ../../
-    - ninja -v -k0
-    - ninja -v test
-  artifacts:
-    reports:
-      junit: bld/release/meson-logs/testlog.junit.xml
-
-debug-x86:
-  image: i386/alpine:latest
-  stage: build
-  script:
-    - mkdir -p bld/debug
-    - cd bld/debug
-    - meson --buildtype=debug -Drun-shaping=enabled  -Dtest-text-shaping=true 
-Dexamples=true ../../
-    - ninja -v -k0
-    - ninja -v test
-  artifacts:
-    reports:
-      junit: bld/debug/meson-logs/testlog.junit.xml
-
-release-x86:
-  image: i386/alpine:latest
-  stage: build
-  script:
-    - mkdir -p bld/release
-    - cd bld/release
-    - meson --buildtype=release -Drun-shaping=enabled  
-Dtest-text-shaping=true -Dexamples=true ../../
-    - ninja -v -k0
-    - ninja -v test
-  artifacts:
-    reports:
-      junit: bld/release/meson-logs/testlog.junit.xml
-
-codespell:
-  image: alpine:latest
-  stage: build
-  script:
-    - apk add python3
-    - apk add py3-pip
-    - pip install codespell
-    - codespell README.md CHANGELOG.md *.c *.h fcft/*.h doc/*.scd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/3rd-party/nanosvg/CMakeLists.txt 
new/fcft/3rd-party/nanosvg/CMakeLists.txt
--- old/fcft/3rd-party/nanosvg/CMakeLists.txt   1970-01-01 01:00:00.000000000 
+0100
+++ new/fcft/3rd-party/nanosvg/CMakeLists.txt   2023-07-14 12:28:59.000000000 
+0200
@@ -0,0 +1,75 @@
+cmake_minimum_required(VERSION 3.10)
+
+project(NanoSVG C)
+
+# CMake needs *.c files to do something useful
+configure_file(src/nanosvg.h ${CMAKE_CURRENT_BINARY_DIR}/nanosvg.c)
+configure_file(src/nanosvgrast.h ${CMAKE_CURRENT_BINARY_DIR}/nanosvgrast.c)
+
+add_library(nanosvg ${CMAKE_CURRENT_BINARY_DIR}/nanosvg.c)
+
+find_library(MATH_LIBRARY m) # Business as usual
+if(MATH_LIBRARY)
+    target_link_libraries(nanosvg PUBLIC ${MATH_LIBRARY})
+endif()
+
+target_include_directories(nanosvg PUBLIC $<INSTALL_INTERFACE:include/nanosvg>)
+target_compile_definitions(nanosvg PRIVATE NANOSVG_IMPLEMENTATION)
+
+# Same for nanosvgrast
+add_library(nanosvgrast ${CMAKE_CURRENT_BINARY_DIR}/nanosvgrast.c)
+target_link_libraries(nanosvgrast PUBLIC nanosvg)
+target_include_directories(nanosvgrast PRIVATE src)
+target_compile_definitions(nanosvgrast PRIVATE NANOSVGRAST_IMPLEMENTATION)
+
+# Installation and export:
+
+include(CMakePackageConfigHelpers)
+
+write_basic_package_version_file(
+    "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
+    VERSION 1.0
+    COMPATIBILITY AnyNewerVersion
+)
+
+install(TARGETS nanosvg nanosvgrast
+        EXPORT ${PROJECT_NAME}Targets
+)
+
+export(EXPORT ${PROJECT_NAME}Targets 
+       FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake" 
+       NAMESPACE ${PROJECT_NAME}::
+)
+
+set(ConfigPackageLocation lib/cmake/${PROJECT_NAME})
+
+configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
+  "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+  INSTALL_DESTINATION ${ConfigPackageLocation}
+  NO_CHECK_REQUIRED_COMPONENTS_MACRO
+)
+
+install(
+    FILES
+      src/nanosvg.h
+      src/nanosvgrast.h
+    DESTINATION
+      include/nanosvg
+  )
+
+install(EXPORT ${PROJECT_NAME}Targets
+  FILE
+    ${PROJECT_NAME}Targets.cmake
+  NAMESPACE
+    ${PROJECT_NAME}::
+  DESTINATION
+    ${ConfigPackageLocation}
+)
+
+install(
+  FILES
+    "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+    "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
+  DESTINATION
+    ${ConfigPackageLocation}
+)
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/3rd-party/nanosvg/Config.cmake.in 
new/fcft/3rd-party/nanosvg/Config.cmake.in
--- old/fcft/3rd-party/nanosvg/Config.cmake.in  1970-01-01 01:00:00.000000000 
+0100
+++ new/fcft/3rd-party/nanosvg/Config.cmake.in  2023-07-14 12:28:59.000000000 
+0200
@@ -0,0 +1,5 @@
+@PACKAGE_INIT@
+
+if (EXISTS ${CMAKE_CURRENT_LIST_DIR}/NanoSVGTargets.cmake)
+    include("${CMAKE_CURRENT_LIST_DIR}/NanoSVGTargets.cmake")
+endif ()
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/3rd-party/nanosvg/README.md 
new/fcft/3rd-party/nanosvg/README.md
--- old/fcft/3rd-party/nanosvg/README.md        2022-09-20 19:11:37.000000000 
+0200
+++ new/fcft/3rd-party/nanosvg/README.md        2023-07-14 12:28:59.000000000 
+0200
@@ -78,6 +78,16 @@
 #include "nanosvg.h"
 ```
 
+Alternatively, you can install the library using CMake and import it into your 
project using the standard CMake `find_package` command.
+
+```CMake
+add_executable(myexe main.c)
+
+find_package(NanoSVG REQUIRED)
+
+target_link_libraries(myexe NanoSVG::nanosvg NanoSVG::nanosvgrast)
+```
+
 ## Compiling Example Project
 
 In order to compile the demo project, your will need to install 
[GLFW](http://www.glfw.org/) to compile.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/3rd-party/nanosvg/src/nanosvg.h 
new/fcft/3rd-party/nanosvg/src/nanosvg.h
--- old/fcft/3rd-party/nanosvg/src/nanosvg.h    2022-09-20 19:11:37.000000000 
+0200
+++ new/fcft/3rd-party/nanosvg/src/nanosvg.h    2023-07-14 12:28:59.000000000 
+0200
@@ -72,6 +72,7 @@
 */
 
 enum NSVGpaintType {
+       NSVG_PAINT_UNDEF = -1,
        NSVG_PAINT_NONE = 0,
        NSVG_PAINT_COLOR = 1,
        NSVG_PAINT_LINEAR_GRADIENT = 2,
@@ -119,7 +120,7 @@
 } NSVGgradient;
 
 typedef struct NSVGpaint {
-       char type;
+       signed char type;
        union {
                unsigned int color;
                NSVGgradient* gradient;
@@ -143,14 +144,17 @@
        float opacity;                          // Opacity of the shape.
        float strokeWidth;                      // Stroke width (scaled).
        float strokeDashOffset;         // Stroke dash offset (scaled).
-       float strokeDashArray[8];                       // Stroke dash array 
(scaled).
-       char strokeDashCount;                           // Number of dash 
values in dash array.
+       float strokeDashArray[8];       // Stroke dash array (scaled).
+       char strokeDashCount;           // Number of dash values in dash array.
        char strokeLineJoin;            // Stroke join type.
        char strokeLineCap;                     // Stroke cap type.
        float miterLimit;                       // Miter limit
        char fillRule;                          // Fill rule, see NSVGfillRule.
        unsigned char flags;            // Logical or of NSVG_FLAGS_* flags
        float bounds[4];                        // Tight bounding box of the 
shape [minx,miny,maxx,maxy].
+       char fillGradient[64];          // Optional 'id' of fill gradient
+       char strokeGradient[64];        // Optional 'id' of stroke gradient
+       float xform[6];                         // Root transformation for 
fill/stroke gradient
        NSVGpath* paths;                        // Linked list of paths in the 
image.
        struct NSVGshape* next;         // Pointer to next shape, or NULL if 
last element.
 } NSVGshape;
@@ -181,12 +185,11 @@
 #endif
 #endif
 
-#endif // NANOSVG_H
-
 #ifdef NANOSVG_IMPLEMENTATION
 
 #include <string.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <math.h>
 
 #define NSVG_PI (3.14159265358979323846264338327f)
@@ -395,7 +398,7 @@
 {
        char id[64];
        char ref[64];
-       char type;
+       signed char type;
        union {
                NSVGlinearData linear;
                NSVGradialData radial;
@@ -611,7 +614,7 @@
        }
 }
 
-static NSVGparser* nsvg__createParser()
+static NSVGparser* nsvg__createParser(void)
 {
        NSVGparser* p;
        p = (NSVGparser*)malloc(sizeof(NSVGparser));
@@ -815,9 +818,8 @@
        return NULL;
 }
 
-static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const 
float* localBounds, char* paintType)
+static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const 
float* localBounds, float *xform, signed char* paintType)
 {
-       NSVGattrib* attr = nsvg__getAttr(p);
        NSVGgradientData* data = NULL;
        NSVGgradientData* ref = NULL;
        NSVGgradientStop* stops = NULL;
@@ -892,7 +894,7 @@
        }
 
        nsvg__xformMultiply(grad->xform, data->xform);
-       nsvg__xformMultiply(grad->xform, attr->xform);
+       nsvg__xformMultiply(grad->xform, xform);
 
        grad->spread = data->spread;
        memcpy(grad->stops, stops, nstops*sizeof(NSVGgradientStop));
@@ -956,6 +958,9 @@
        memset(shape, 0, sizeof(NSVGshape));
 
        memcpy(shape->id, attr->id, sizeof shape->id);
+       memcpy(shape->fillGradient, attr->fillGradient, sizeof 
shape->fillGradient);
+       memcpy(shape->strokeGradient, attr->strokeGradient, sizeof 
shape->strokeGradient);
+       memcpy(shape->xform, attr->xform, sizeof shape->xform);
        scale = nsvg__getAverageScale(attr->xform);
        shape->strokeWidth = attr->strokeWidth * scale;
        shape->strokeDashOffset = attr->strokeDashOffset * scale;
@@ -991,13 +996,7 @@
                shape->fill.color = attr->fillColor;
                shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 
24;
        } else if (attr->hasFill == 2) {
-               float inv[6], localBounds[4];
-               nsvg__xformInverse(inv, attr->xform);
-               nsvg__getLocalBounds(localBounds, shape, inv);
-               shape->fill.gradient = nsvg__createGradient(p, 
attr->fillGradient, localBounds, &shape->fill.type);
-               if (shape->fill.gradient == NULL) {
-                       shape->fill.type = NSVG_PAINT_NONE;
-               }
+               shape->fill.type = NSVG_PAINT_UNDEF;
        }
 
        // Set stroke
@@ -1008,12 +1007,7 @@
                shape->stroke.color = attr->strokeColor;
                shape->stroke.color |= (unsigned int)(attr->strokeOpacity*255) 
<< 24;
        } else if (attr->hasStroke == 2) {
-               float inv[6], localBounds[4];
-               nsvg__xformInverse(inv, attr->xform);
-               nsvg__getLocalBounds(localBounds, shape, inv);
-               shape->stroke.gradient = nsvg__createGradient(p, 
attr->strokeGradient, localBounds, &shape->stroke.type);
-               if (shape->stroke.gradient == NULL)
-                       shape->stroke.type = NSVG_PAINT_NONE;
+               shape->stroke.type = NSVG_PAINT_UNDEF;
        }
 
        // Set flags
@@ -1195,6 +1189,19 @@
        return s;
 }
 
+static const char* nsvg__getNextPathItemWhenArcFlag(const char* s, char* it)
+{
+       it[0] = '\0';
+       while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
+       if (!*s) return s;
+       if (*s == '0' || *s == '1') {
+               it[0] = *s++;
+               it[1] = '\0';
+               return s;
+       }
+       return s;
+}
+
 static const char* nsvg__getNextPathItem(const char* s, char* it)
 {
        it[0] = '\0';
@@ -1223,15 +1230,58 @@
        return NSVG_RGB(128, 128, 128);
 }
 
+// Parse rgb color. The pointer 'str' must point at "rgb(" (4+ characters).
+// This function returns gray (rgb(128, 128, 128) == '#808080') on parse errors
+// for backwards compatibility. Note: other image viewers return black instead.
+
 static unsigned int nsvg__parseColorRGB(const char* str)
 {
-       unsigned int r=0, g=0, b=0;
-       float rf=0, gf=0, bf=0;
-       if (sscanf(str, "rgb(%u, %u, %u)", &r, &g, &b) == 3)            // 
decimal integers
-               return NSVG_RGB(r, g, b);
-       if (sscanf(str, "rgb(%f%%, %f%%, %f%%)", &rf, &gf, &bf) == 3)   // 
decimal integer percentage
-               return NSVG_RGB(roundf(rf*2.55f), roundf(gf*2.55f), 
roundf(bf*2.55f)); // (255 / 100.0f)
-       return NSVG_RGB(128, 128, 128);
+       int i;
+       unsigned int rgbi[3];
+       float rgbf[3];
+       // try decimal integers first
+       if (sscanf(str, "rgb(%u, %u, %u)", &rgbi[0], &rgbi[1], &rgbi[2]) != 3) {
+               // integers failed, try percent values (float, locale 
independent)
+               const char delimiter[3] = {',', ',', ')'};
+               str += 4; // skip "rgb("
+               for (i = 0; i < 3; i++) {
+                       while (*str && (nsvg__isspace(*str))) str++;    // skip 
leading spaces
+                       if (*str == '+') str++;                         // skip 
'+' (don't allow '-')
+                       if (!*str) break;
+                       rgbf[i] = nsvg__atof(str);
+
+                       // Note 1: it would be great if nsvg__atof() returned 
how many
+                       // bytes it consumed but it doesn't. We need to skip 
the number,
+                       // the '%' character, spaces, and the delimiter ',' or 
')'.
+
+                       // Note 2: The following code does not allow values 
like "33.%",
+                       // i.e. a decimal point w/o fractional part, but this 
is consistent
+                       // with other image viewers, e.g. firefox, chrome, eog, 
gimp.
+
+                       while (*str && nsvg__isdigit(*str)) str++;              
// skip integer part
+                       if (*str == '.') {
+                               str++;
+                               if (!nsvg__isdigit(*str)) break;                
// error: no digit after '.'
+                               while (*str && nsvg__isdigit(*str)) str++;      
// skip fractional part
+                       }
+                       if (*str == '%') str++; else break;
+                       while (nsvg__isspace(*str)) str++;
+                       if (*str == delimiter[i]) str++;
+                       else break;
+               }
+               if (i == 3) {
+                       rgbi[0] = roundf(rgbf[0] * 2.55f);
+                       rgbi[1] = roundf(rgbf[1] * 2.55f);
+                       rgbi[2] = roundf(rgbf[2] * 2.55f);
+               } else {
+                       rgbi[0] = rgbi[1] = rgbi[2] = 128;
+               }
+       }
+       // clip values as the CSS spec requires
+       for (i = 0; i < 3; i++) {
+               if (rgbi[i] > 255) rgbi[i] = 255;
+       }
+       return NSVG_RGB(rgbi[0], rgbi[1], rgbi[2]);
 }
 
 typedef struct NSVGNamedColor {
@@ -1639,9 +1689,9 @@
 {
        int i = 0;
        str += 4; // "url(";
-       if (*str == '#')
+       if (*str && *str == '#')
                str++;
-       while (i < 63 && *str != ')') {
+       while (i < 63 && *str && *str != ')') {
                id[i] = *str++;
                i++;
        }
@@ -2237,7 +2287,11 @@
                nargs = 0;
 
                while (*s) {
-                       s = nsvg__getNextPathItem(s, item);
+                       item[0] = '\0';
+                       if ((cmd == 'A' || cmd == 'a') && (nargs == 3 || nargs 
== 4))
+                               s = nsvg__getNextPathItemWhenArcFlag(s, item);
+                       if (!*item)
+                               s = nsvg__getNextPathItem(s, item);
                        if (!*item) break;
                        if (cmd != '\0' && nsvg__isCoordinate(item)) {
                                if (nargs < 10)
@@ -2582,7 +2636,7 @@
        }
 }
 
-static void nsvg__parseGradient(NSVGparser* p, const char** attr, char type)
+static void nsvg__parseGradient(NSVGparser* p, const char** attr, signed char 
type)
 {
        int i;
        NSVGgradientData* grad = 
(NSVGgradientData*)malloc(sizeof(NSVGgradientData));
@@ -2907,6 +2961,36 @@
        }
 }
 
+static void nsvg__createGradients(NSVGparser* p)
+{
+       NSVGshape* shape;
+
+       for (shape = p->image->shapes; shape != NULL; shape = shape->next) {
+               if (shape->fill.type == NSVG_PAINT_UNDEF) {
+                       if (shape->fillGradient[0] != '\0') {
+                               float inv[6], localBounds[4];
+                               nsvg__xformInverse(inv, shape->xform);
+                               nsvg__getLocalBounds(localBounds, shape, inv);
+                               shape->fill.gradient = nsvg__createGradient(p, 
shape->fillGradient, localBounds, shape->xform, &shape->fill.type);
+                       }
+                       if (shape->fill.type == NSVG_PAINT_UNDEF) {
+                               shape->fill.type = NSVG_PAINT_NONE;
+                       }
+               }
+               if (shape->stroke.type == NSVG_PAINT_UNDEF) {
+                       if (shape->strokeGradient[0] != '\0') {
+                               float inv[6], localBounds[4];
+                               nsvg__xformInverse(inv, shape->xform);
+                               nsvg__getLocalBounds(localBounds, shape, inv);
+                               shape->stroke.gradient = 
nsvg__createGradient(p, shape->strokeGradient, localBounds, shape->xform, 
&shape->stroke.type);
+                       }
+                       if (shape->stroke.type == NSVG_PAINT_UNDEF) {
+                               shape->stroke.type = NSVG_PAINT_NONE;
+                       }
+               }
+       }
+}
+
 NSVGimage* nsvgParse(char* input, const char* units, float dpi)
 {
        NSVGparser* p;
@@ -2920,6 +3004,9 @@
 
        nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, 
nsvg__content, p);
 
+       // Create gradients after all definitions have been parsed
+       nsvg__createGradients(p);
+
        // Scale to viewBox
        nsvg__scaleToViewbox(p, units);
 
@@ -3006,4 +3093,6 @@
        free(image);
 }
 
-#endif
+#endif // NANOSVG_IMPLEMENTATION
+
+#endif // NANOSVG_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/3rd-party/nanosvg/src/nanosvgrast.h 
new/fcft/3rd-party/nanosvg/src/nanosvgrast.h
--- old/fcft/3rd-party/nanosvg/src/nanosvgrast.h        2022-09-20 
19:11:37.000000000 +0200
+++ new/fcft/3rd-party/nanosvg/src/nanosvgrast.h        2023-07-14 
12:28:59.000000000 +0200
@@ -25,6 +25,8 @@
 #ifndef NANOSVGRAST_H
 #define NANOSVGRAST_H
 
+#include "nanosvg.h"
+
 #ifndef NANOSVGRAST_CPLUSPLUS
 #ifdef __cplusplus
 extern "C" {
@@ -47,7 +49,7 @@
 */
 
 // Allocated rasterizer context.
-NSVGrasterizer* nsvgCreateRasterizer();
+NSVGrasterizer* nsvgCreateRasterizer(void);
 
 // Rasterizes SVG image, returns RGBA image (non-premultiplied alpha)
 //   r - pointer to rasterizer context
@@ -72,11 +74,11 @@
 #endif
 #endif
 
-#endif // NANOSVGRAST_H
-
 #ifdef NANOSVGRAST_IMPLEMENTATION
 
 #include <math.h>
+#include <stdlib.h>
+#include <string.h>
 
 #define NSVG__SUBSAMPLES       5
 #define NSVG__FIXSHIFT         10
@@ -112,7 +114,7 @@
 } NSVGmemPage;
 
 typedef struct NSVGcachedPaint {
-       char type;
+       signed char type;
        char spread;
        float xform[6];
        unsigned int colors[256];
@@ -148,7 +150,7 @@
        int width, height, stride;
 };
 
-NSVGrasterizer* nsvgCreateRasterizer()
+NSVGrasterizer* nsvgCreateRasterizer(void)
 {
        NSVGrasterizer* r = (NSVGrasterizer*)malloc(sizeof(NSVGrasterizer));
        if (r == NULL) goto error;
@@ -1361,6 +1363,7 @@
        fclose(fp);
 }
 */
+
 void nsvgRasterize(NSVGrasterizer* r,
                                   NSVGimage* image, float tx, float ty, float 
scale,
                                   unsigned char* dst, int w, int h, int stride)
@@ -1405,7 +1408,8 @@
                        }
 
                        // Rasterize edges
-                       qsort(r->edges, r->nedges, sizeof(NSVGedge), 
nsvg__cmpEdge);
+                       if (r->nedges != 0)
+                               qsort(r->edges, r->nedges, sizeof(NSVGedge), 
nsvg__cmpEdge);
 
                        // now, traverse the scanlines and find the 
intersections on each scanline, use non-zero rule
                        nsvg__initPaint(&cache, &shape->fill, shape->opacity);
@@ -1431,7 +1435,8 @@
                        }
 
                        // Rasterize edges
-                       qsort(r->edges, r->nedges, sizeof(NSVGedge), 
nsvg__cmpEdge);
+                       if (r->nedges != 0)
+                               qsort(r->edges, r->nedges, sizeof(NSVGedge), 
nsvg__cmpEdge);
 
                        // now, traverse the scanlines and find the 
intersections on each scanline, use non-zero rule
                        nsvg__initPaint(&cache, &shape->stroke, shape->opacity);
@@ -1448,4 +1453,6 @@
        r->stride = 0;
 }
 
-#endif
+#endif // NANOSVGRAST_IMPLEMENTATION
+
+#endif // NANOSVGRAST_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/CHANGELOG.md new/fcft/CHANGELOG.md
--- old/fcft/CHANGELOG.md       2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/CHANGELOG.md       2023-07-14 12:28:59.000000000 +0200
@@ -1,5 +1,6 @@
 # Changelog
 
+* [3.1.6][#3-1-6]
 * [3.1.5](#3-1-5)
 * [3.1.4](#3-1-4)
 * [3.1.3](#3-1-3)
@@ -37,6 +38,13 @@
 * [1.1.7](#1-1-7)
 
 
+## 3.1.6
+
+### Added
+
+* nanosvg updated to 9da543e (2022-12-04)
+
+
 ## 3.1.5
 
 ### Changed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/PKGBUILD new/fcft/PKGBUILD
--- old/fcft/PKGBUILD   2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/PKGBUILD   2023-07-14 12:28:59.000000000 +0200
@@ -1,5 +1,5 @@
 pkgname=fcft
-pkgver=3.1.5
+pkgver=3.1.6
 pkgrel=1
 pkgdesc="Simple font loading and glyph rasterization library"
 changelog=CHANGELOG.md
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/README.md new/fcft/README.md
--- old/fcft/README.md  2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/README.md  2023-07-14 12:28:59.000000000 +0200
@@ -31,8 +31,23 @@
 
 ![screenshot](screenshot.png "Screenshot showing the three rasterization 
methods")
 
-_Top: `fcft_glyph_rasterize()`, middle: `fcft_grapheme_rasterize()`,
-bottom: `fcft_text_run_rasterize()`_
+The screenshot above is the output of the example program shipped with
+the fcft sources (but not built by default). It showcases the three
+different levels, at which fcft can rasterize glyphs:
+
+Top: `fcft_glyph_rasterize()`
+: Glyphs are rasterized character by character; no ligatures, no
+  grapheme shaping, and right-to-left scripts are not rendered
+  correctly.
+
+Middle: `fcft_grapheme_rasterize()`
+: Glyphs are rasterized grapheme by grapheme. Here, graphemes are
+  shaped correctly (e.g. the family emoji), but ligatures and RTL
+  scripts are still not rendered correctly.
+
+Bottom: `fcft_text_run_rasterize()`
+: The entire string is rasterized in one go. This means full shaping
+  is applied; ligatures, graphemes, and RTL scripts.
 
 
 ## Requirements
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_capabilities.3.scd 
new/fcft/doc/fcft_capabilities.3.scd
--- old/fcft/doc/fcft_capabilities.3.scd        2022-09-20 19:11:37.000000000 
+0200
+++ new/fcft/doc/fcft_capabilities.3.scd        2023-07-14 12:28:59.000000000 
+0200
@@ -1,4 +1,4 @@
-fcft_capabilities(3) "3.1.5" "fcft"
+fcft_capabilities(3) "3.1.6" "fcft"
 
 # NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_clone.3.scd 
new/fcft/doc/fcft_clone.3.scd
--- old/fcft/doc/fcft_clone.3.scd       2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_clone.3.scd       2023-07-14 12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_clone(3) "3.1.5" "fcft"
+fcft_clone(3) "3.1.6" "fcft"
 
 # NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_destroy.3.scd 
new/fcft/doc/fcft_destroy.3.scd
--- old/fcft/doc/fcft_destroy.3.scd     2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_destroy.3.scd     2023-07-14 12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_destroy(3) "3.1.5" "fcft"
+fcft_destroy(3) "3.1.6" "fcft"
 
 # NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_fini.3.scd new/fcft/doc/fcft_fini.3.scd
--- old/fcft/doc/fcft_fini.3.scd        2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_fini.3.scd        2023-07-14 12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_fini(3) "3.1.5" "fcft"
+fcft_fini(3) "3.1.6" "fcft"
 
 # NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_from_name.3.scd 
new/fcft/doc/fcft_from_name.3.scd
--- old/fcft/doc/fcft_from_name.3.scd   2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_from_name.3.scd   2023-07-14 12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_from_name(3) "3.1.5" "fcft"
+fcft_from_name(3) "3.1.6" "fcft"
 
 # NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_init.3.scd new/fcft/doc/fcft_init.3.scd
--- old/fcft/doc/fcft_init.3.scd        2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_init.3.scd        2023-07-14 12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_init(3) "3.1.5" "fcft"
+fcft_init(3) "3.1.6" "fcft"
 
 # NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_kerning.3.scd 
new/fcft/doc/fcft_kerning.3.scd
--- old/fcft/doc/fcft_kerning.3.scd     2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_kerning.3.scd     2023-07-14 12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_kerning(3) "3.1.5" "fcft"
+fcft_kerning(3) "3.1.6" "fcft"
 
 # NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_log_init.3.scd 
new/fcft/doc/fcft_log_init.3.scd
--- old/fcft/doc/fcft_log_init.3.scd    2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_log_init.3.scd    2023-07-14 12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_log_init(3) "3.1.5" "fcft"
+fcft_log_init(3) "3.1.6" "fcft"
 
 # NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_precompose.3.scd 
new/fcft/doc/fcft_precompose.3.scd
--- old/fcft/doc/fcft_precompose.3.scd  2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_precompose.3.scd  2023-07-14 12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_precompose(3) "3.1.5" "fcft"
+fcft_precompose(3) "3.1.6" "fcft"
 
 # NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_rasterize_char_utf32.3.scd 
new/fcft/doc/fcft_rasterize_char_utf32.3.scd
--- old/fcft/doc/fcft_rasterize_char_utf32.3.scd        2022-09-20 
19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_rasterize_char_utf32.3.scd        2023-07-14 
12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_rasterize_char_utf32(3) "3.1.5" "fcft"
+fcft_rasterize_char_utf32(3) "3.1.6" "fcft"
 
 # NAME
 
@@ -99,7 +99,7 @@
        glyph is an un-antialiased bitmask. Use as a mask when blending.
 
        *PIXMAN\_a8* corresponds to *FT\_PIXEL\_MODE\_GRAY*. I.e. the
-       glyph is a grayscale antialiased bitmask. use as a mask when
+       glyph is a grayscale antialiased bitmask. Use as a mask when
        blending.
 
        *PIXMAN\_x8r8g8b8* corresponds to either *FT\_PIXEL\_MODE\_LCD* or
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_rasterize_grapheme_utf32.3.scd 
new/fcft/doc/fcft_rasterize_grapheme_utf32.3.scd
--- old/fcft/doc/fcft_rasterize_grapheme_utf32.3.scd    2022-09-20 
19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_rasterize_grapheme_utf32.3.scd    2023-07-14 
12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_rasterize_grapheme_utf32(3) "3.1.5" "fcft"
+fcft_rasterize_grapheme_utf32(3) "3.1.6" "fcft"
 
 # NAME
 
@@ -49,13 +49,10 @@
 };
 ```
 
-_cols_ is the number of "columns" the grapheme occupised (effectively)
-_cp_ is the same _cp_ from the *fcft_rasterize_char_utf32*() call.
-
 _cols_ is the number of "columns" the glyph occupies (effectively,
 *wcswidth*(_cluster_*)*).
 
-_glyphs_ is an array of rasterized glyphs. See
+_glyphs_ is an array of _count_ rasterized glyphs. See
 *fcft_rasterize_char_utf32*() for a description of *struct
 fcft_glyph*.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_rasterize_text_run_utf32.3.scd 
new/fcft/doc/fcft_rasterize_text_run_utf32.3.scd
--- old/fcft/doc/fcft_rasterize_text_run_utf32.3.scd    2022-09-20 
19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_rasterize_text_run_utf32.3.scd    2023-07-14 
12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_rasterize_text_run_utf32(3) "3.1.5" "fcft"
+fcft_rasterize_text_run_utf32(3) "3.1.6" "fcft"
 
 # NAME
 
@@ -21,29 +21,16 @@
 _subpixel_ allows you to specify which subpixel mode to use. See
 *fcft_rasterize_char_utf32*() for details.
 
-The string is passed to HarfBuzz for shaping, initially using the
-primary font. The shaping data is parsed, and when an unshaped
-codepoint is encountered, it is retried with the first fallback
-font. If that fails too, the next fallback font is tried. After
-successfully shaping the failed codepoint, the primary font is used to
-shape the rest of the string. This continues until the entire string
-has been shaped.
-
-There is limited support for right-to-left
-scripts. *hb_buffer_guess_segment_properties*() is used to guess
-whether to use left-to-right, or right-to-left, logic, and this is
-done each time we try to shape a part of the string.
-
-As a consequence, the result of mixed LTR and RTL strings depends on
-the font; if the font has glyphs for all characters in the string,
-*hb_buffer_guess_segment_properties*() is only called once, on the
-entire string. Meaning the entire string is subject to either LTR, or
-RTL logic, but not both.
-
-If the (primary) font does not have glyphs for all characters, then
-*hb_buffer_guess_segment_properties*() will be called for each segment
-where shaping failed. In this case, parts of the string may be treated
-as LTR while others are treated as RTL.
+The string is first segmented into grapheme clusters using
+utf8proc. Each grapheme is assigned a font using the normal font
+lookup rules (see *fcft_rasterize_char_utf32*()).
+
+Next, HarfBuzz is used to guess each grapheme's script
+(~language). Consecutiv graphemes that both have been assigned the
+same font, and belong to the same script are merged into a "partial"
+text run.
+
+Finally, each partial text run is shaped with HarfBuzz.
 
 # RETURN VALUE
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_set_emoji_presentation.3.scd 
new/fcft/doc/fcft_set_emoji_presentation.3.scd
--- old/fcft/doc/fcft_set_emoji_presentation.3.scd      2022-09-20 
19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_set_emoji_presentation.3.scd      2023-07-14 
12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_set_emoji_presentation(3) "3.1.5" "fcft"
+fcft_set_emoji_presentation(3) "3.1.6" "fcft"
 
 # NAME
 
@@ -17,16 +17,16 @@
 style to use with emojis with both a text presentation, and an emoji
 presentation style.
 
+These emojis can be followed by an (invisible) variation
+selector. When they are not followed by a selector, the implementation
+must choose a style.
+
 One example of such an emoji is U+263A - WHITE SMILING FACE:
 
 - unqualified: ☺
 - text: ☺︎
 - emoji: ☺️
 
-These emojis can be followed by an (invisible) variation
-selector. When they are not followed by a selector, the implementation
-must choose a style.
-
 The Unicode standard defines the default presentation styles, and this
 is what fcft defaults to.
 
@@ -58,5 +58,5 @@
 
 # SEE ALSO
 
-*fcft_glyph_rasterize*(), *fcft_grapheme_rasterize*(),
-*fcft_text_run_rasterize*()
+*fcft_rasterize_char_utf32*(), *fcft_rasterize_grapheme_utf32*(),
+*fcft_rasterize_text_run_utf32*()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_set_scaling_filter.3.scd 
new/fcft/doc/fcft_set_scaling_filter.3.scd
--- old/fcft/doc/fcft_set_scaling_filter.3.scd  2022-09-20 19:11:37.000000000 
+0200
+++ new/fcft/doc/fcft_set_scaling_filter.3.scd  2023-07-14 12:28:59.000000000 
+0200
@@ -1,4 +1,4 @@
-fcft_set_scaling_filter(3) "3.1.5" "fcft"
+fcft_set_scaling_filter(3) "3.1.6" "fcft"
 
 # NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_size_adjust.3.scd 
new/fcft/doc/fcft_size_adjust.3.scd
--- old/fcft/doc/fcft_size_adjust.3.scd 2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/doc/fcft_size_adjust.3.scd 2023-07-14 12:28:59.000000000 +0200
@@ -1,4 +1,4 @@
-fcft_size_adjust(3) "3.1.5" "fcft"
+fcft_size_adjust(3) "3.1.6" "fcft"
 
 # NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/doc/fcft_text_run_destroy.3.scd 
new/fcft/doc/fcft_text_run_destroy.3.scd
--- old/fcft/doc/fcft_text_run_destroy.3.scd    2022-09-20 19:11:37.000000000 
+0200
+++ new/fcft/doc/fcft_text_run_destroy.3.scd    2023-07-14 12:28:59.000000000 
+0200
@@ -1,4 +1,4 @@
-fcft_text_run_destroy(3) "3.1.5" "fcft"
+fcft_text_run_destroy(3) "3.1.6" "fcft"
 
 # NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/example/main.c new/fcft/example/main.c
--- old/fcft/example/main.c     2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/example/main.c     2023-07-14 12:28:59.000000000 +0200
@@ -116,6 +116,8 @@
 {
     for (size_t i = 0; i < count; i++) {
         const struct fcft_glyph *g = glyphs[i];
+        if (g == NULL)
+            continue;
 
         if (kern != NULL)
             *x += kern[i];
@@ -144,6 +146,8 @@
 
     for (size_t i = 0; i < text_len; i++) {
         glyphs[i] = fcft_rasterize_char_utf32(font, text[i], subpixel_mode);
+        if (glyphs[i] == NULL)
+            continue;
 
         kern[i] = 0;
         if (i > 0) {
@@ -241,6 +245,17 @@
     struct buffer *buf = shm_get_buffer(shm, w, h, 0xdeadbeef);
     assert(buf != NULL);
 
+    /*
+     * Set clip region to the entire surface size. This allows us to
+     * render without considering wether things are outside the buffer
+     * or not.
+     */
+
+    pixman_region32_t clip;
+    pixman_region32_init_rect(&clip, 0, 0, buf->width, buf->height);
+    pixman_image_set_clip_region32(buf->pix, &clip);
+    pixman_region32_fini(&clip);
+
     /* Background */
     pixman_image_fill_rectangles(
         PIXMAN_OP_SRC, buf->pix, &bg, 1,
@@ -415,7 +430,7 @@
         {NULL,         no_argument,       NULL, '\0'},
     };
 
-    const char *user_text = u8"hello world <<<🇸🇪 
👨‍👩‍👧‍👦 👩🏿>>>";
+    const char *user_text = u8"hello world | ligatures: fi | 
اَلْعَرَبِيَّةُ | עִבְרִית‎ | graphemes: 
👨‍👩‍👧‍👦 🇸🇪";
     const char *font_list = "serif:size=24";
 
     while (true) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/meson.build new/fcft/meson.build
--- old/fcft/meson.build        2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/meson.build        2023-07-14 12:28:59.000000000 +0200
@@ -1,5 +1,5 @@
 project('fcft', 'c',
-        version: '3.1.5',  # Don't forget to update version in man pages
+        version: '3.1.6',  # Don't forget to update version in man pages
         license: 'MIT',
         meson_version: '>=0.58.0',
         default_options: [
@@ -20,7 +20,7 @@
 so_version = [
   '4',      # MAJOR: increment on non-backward compatible ABI changes
   '1',      # MINOR: increment with backward compatible ABI changes
-  '5',      # PATCH: increment with non-ABI affecting changes
+  '6',      # PATCH: increment with non-ABI affecting changes
 ]
 
 is_debug_build = get_option('buildtype').startswith('debug')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fcft/nanosvg.c new/fcft/nanosvg.c
--- old/fcft/nanosvg.c  2022-09-20 19:11:37.000000000 +0200
+++ new/fcft/nanosvg.c  2023-07-14 12:28:59.000000000 +0200
@@ -1,5 +1,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <math.h>
+#define NANOSVG_ALL_COLOR_KEYWORDS
 #define NANOSVG_IMPLEMENTATION
 #include <nanosvg.h>
Binary files old/fcft/screenshot.png and new/fcft/screenshot.png differ

Reply via email to