* [PR PATCH] libXft: update and include big fixes
@ 2021-08-12 12:24 vigoux
2021-08-12 12:26 ` ericonr
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: vigoux @ 2021-08-12 12:24 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 1810 bytes --]
There is a new pull request by vigoux against master on the void-packages repository
https://github.com/vigoux/void-packages libxft-fix
https://github.com/void-linux/void-packages/pull/32469
libXft: update and include big fixes
<!-- Mark items with [x] where applicable -->
#### General
- [ ] This is a new package and it conforms to the [quality requirements](https://github.com/void-linux/void-packages/blob/master/Manual.md#quality-requirements)
#### Have the results of the proposed changes been tested?
- [x] I use the packages affected by the proposed changes on a regular basis and confirm this PR works for me
- [ ] I generally don't use the affected packages but briefly tested this PR
<!--
If GitHub CI cannot be used to validate the build result (for example, if the
build is likely to take several hours), make sure to
[skip CI](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#continuous-integration).
When skipping CI, uncomment and fill out the following section.
Note: for builds that are likely to complete in less than 2 hours, it is not
acceptable to skip CI.
-->
#### Does it build and run successfully?
(Please choose at least one native build and, if supported, at least one cross build. More are better.)
- [x] I built this PR locally for my native architecture, (x86_64-gnu)
- [ ] I built this PR locally for these architectures (if supported. mark crossbuilds):
- [ ] aarch64-musl
- [ ] armv7l
- [ ] armv6l-musl
#### Other
This PR includes patches that are waiting to be merged upstream, and
fix a bug. Including these patched solved numerous issues with `st`,
where colored emojis caused a hard crash of the terminal emulator.
A patch file from https://github.com/void-linux/void-packages/pull/32469.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-libxft-fix-32469.patch --]
[-- Type: text/x-diff, Size: 29002 bytes --]
From b286302019c57dcf4ccabb05886ad5c02f2f4171 Mon Sep 17 00:00:00 2001
From: Thomas Vigouroux <tomvig38@gmail.com>
Date: Thu, 12 Aug 2021 14:17:53 +0200
Subject: [PATCH 1/2] libXft: update to 2.3.4
---
srcpkgs/libXft/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/libXft/template b/srcpkgs/libXft/template
index dd6263d3a420..1e86cd68fdc3 100644
--- a/srcpkgs/libXft/template
+++ b/srcpkgs/libXft/template
@@ -1,6 +1,6 @@
# Template file for 'libXft'
pkgname=libXft
-version=2.3.3
+version=2.3.4
revision=1
build_style=gnu-configure
hostmakedepends="pkg-config"
@@ -10,7 +10,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="MIT"
homepage="$XORG_SITE"
distfiles="${XORG_SITE}/lib/${pkgname}-${version}.tar.bz2"
-checksum=225c68e616dd29dbb27809e45e9eadf18e4d74c50be43020ef20015274529216
+checksum=57dedaab20914002146bdae0cb0c769ba3f75214c4c91bd2613d6ef79fc9abdd
post_install() {
vlicense COPYING
From 9eddae8e7f5c7029b11ef2ebc4d8f2d785cb0fd1 Mon Sep 17 00:00:00 2001
From: Thomas Vigouroux <tomvig38@gmail.com>
Date: Thu, 12 Aug 2021 14:18:15 +0200
Subject: [PATCH 2/2] libXft: fix colored emoji bug
Include the patches from https://gitlab.freedesktop.org/xorg/lib/libxft/-/merge_requests/1
---
...-_XftCompositeString-helper-function.patch | 94 +++
...-a-_XftCompositeText-helper-function.patch | 123 ++++
...-for-BGRA-glyphs-display-and-scaling.patch | 642 ++++++++++++++++++
3 files changed, 859 insertions(+)
create mode 100644 srcpkgs/libXft/patches/0001-Introduce-a-_XftCompositeString-helper-function.patch
create mode 100644 srcpkgs/libXft/patches/0002-Introduce-a-_XftCompositeText-helper-function.patch
create mode 100644 srcpkgs/libXft/patches/0003-Add-support-for-BGRA-glyphs-display-and-scaling.patch
diff --git a/srcpkgs/libXft/patches/0001-Introduce-a-_XftCompositeString-helper-function.patch b/srcpkgs/libXft/patches/0001-Introduce-a-_XftCompositeString-helper-function.patch
new file mode 100644
index 000000000000..3ba3d72590b0
--- /dev/null
+++ b/srcpkgs/libXft/patches/0001-Introduce-a-_XftCompositeString-helper-function.patch
@@ -0,0 +1,94 @@
+From 723092ece088559f1af299236305911f4ee4d450 Mon Sep 17 00:00:00 2001
+From: Maxime Coste <mawww@kakoune.org>
+Date: Thu, 28 Jan 2021 19:59:10 +1100
+Subject: [PATCH 1/3] Introduce a _XftCompositeString helper function
+
+Dispatch to XRenderCompositeString{8,16,32} based off the given width.
+
+Signed-off-by: Maxime Coste <mawww@kakoune.org>
+---
+ src/xftrender.c | 61 ++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 43 insertions(+), 18 deletions(-)
+
+diff --git a/src/xftrender.c b/src/xftrender.c
+index a352737..181c27a 100644
+--- a/src/xftrender.c
++++ b/src/xftrender.c
+@@ -25,6 +25,47 @@
+ #define NUM_LOCAL 1024
+ #define NUM_ELT_LOCAL 128
+
++/*
++ * Dispatch glyph drawing to the correct XRenderCompositeString function
++ */
++static void
++_XftCompositeString (Display *dpy,
++ int op,
++ Picture src,
++ Picture dst,
++ XRenderPictFormat *format,
++ GlyphSet glyphset,
++ int srcx,
++ int srcy,
++ int dstx,
++ int dsty,
++ int charwidth,
++ unsigned int *chars,
++ int nchars)
++{
++ if (nchars == 0)
++ return;
++
++ switch (charwidth) {
++ case 1:
++ default:
++ XRenderCompositeString8 (dpy, op,
++ src, dst, format, glyphset,
++ srcx, srcy, dstx, dsty, (char*)chars, nchars);
++ break;
++ case 2:
++ XRenderCompositeString16(dpy, op,
++ src, dst, format, glyphset,
++ srcx, srcy, dstx, dsty, (unsigned short*)chars, nchars);
++ break;
++ case 4:
++ XRenderCompositeString32(dpy, op,
++ src, dst, format, glyphset,
++ srcx, srcy, dstx, dsty, (unsigned int*)chars, nchars);
++ break;
++ }
++}
++
+ /*
+ * Use the Render extension to draw the glyphs
+ */
+@@ -114,24 +155,8 @@ XftGlyphRender (Display *dpy,
+ case 4: char32[i] = (unsigned int) wire; break;
+ }
+ }
+- switch (width) {
+- case 1:
+- default:
+- XRenderCompositeString8 (dpy, op,
+- src, dst, font->format, font->glyphset,
+- srcx, srcy, x, y, char8, nglyphs);
+- break;
+- case 2:
+- XRenderCompositeString16(dpy, op,
+- src, dst, font->format, font->glyphset,
+- srcx, srcy, x, y, char16, nglyphs);
+- break;
+- case 4:
+- XRenderCompositeString32(dpy, op,
+- src, dst, font->format, font->glyphset,
+- srcx, srcy, x, y, char32, nglyphs);
+- break;
+- }
++ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset,
++ srcx, srcy, x, y, width, chars, nglyphs);
+ if (chars != char_local)
+ free (chars);
+ bail1:
+--
+2.32.0
+
diff --git a/srcpkgs/libXft/patches/0002-Introduce-a-_XftCompositeText-helper-function.patch b/srcpkgs/libXft/patches/0002-Introduce-a-_XftCompositeText-helper-function.patch
new file mode 100644
index 000000000000..2112c39e4d8a
--- /dev/null
+++ b/srcpkgs/libXft/patches/0002-Introduce-a-_XftCompositeText-helper-function.patch
@@ -0,0 +1,123 @@
+From e0fc4ce7e87ab9c4b47e5c8e693f070dfd0d2f7b Mon Sep 17 00:00:00 2001
+From: Maxime Coste <mawww@kakoune.org>
+Date: Thu, 28 Jan 2021 20:05:13 +1100
+Subject: [PATCH 2/3] Introduce a _XftCompositeText helper function
+
+Dispatch to XRenderCompositeText{8,16,32} based off the given width.
+
+Signed-off-by: Maxime Coste <mawww@kakoune.org>
+---
+ src/xftrender.c | 83 +++++++++++++++++++++++++++++--------------------
+ 1 file changed, 49 insertions(+), 34 deletions(-)
+
+diff --git a/src/xftrender.c b/src/xftrender.c
+index 181c27a..5852b2e 100644
+--- a/src/xftrender.c
++++ b/src/xftrender.c
+@@ -164,6 +164,49 @@ bail1:
+ _XftFontManageMemory (dpy, pub);
+ }
+
++/*
++ * Dispatch glyph drawing to the correct XRenderCompositeText function
++ */
++static void
++_XftCompositeText (Display *dpy,
++ int op,
++ Picture src,
++ Picture dst,
++ XRenderPictFormat *format,
++ int srcx,
++ int srcy,
++ int dstx,
++ int dsty,
++ int eltwidth,
++ XGlyphElt8 *elts,
++ int nelt)
++{
++ if (nelt == 0)
++ return;
++
++ switch (eltwidth) {
++ case 1:
++ default:
++ XRenderCompositeText8 (dpy, op,
++ src, dst, format,
++ srcx, srcy, dstx, dsty,
++ (XGlyphElt8*)elts, nelt);
++ break;
++ case 2:
++ XRenderCompositeText16(dpy, op,
++ src, dst, format,
++ srcx, srcy, dstx, dsty,
++ (XGlyphElt16*)elts, nelt);
++ break;
++ case 4:
++ XRenderCompositeText32(dpy, op,
++ src, dst, format,
++ srcx, srcy, dstx, dsty,
++ (XGlyphElt32*)elts, nelt);
++ break;
++ }
++}
++
+ _X_EXPORT void
+ XftGlyphSpecRender (Display *dpy,
+ int op,
+@@ -345,23 +388,9 @@ XftGlyphSpecRender (Display *dpy,
+ elts[nelt].nchars = n;
+ nelt++;
+ }
+- switch (width) {
+- case 1:
+- XRenderCompositeText8 (dpy, op, src, dst, font->format,
+- srcx, srcy, glyphs[0].x, glyphs[0].y,
+- elts, nelt);
+- break;
+- case 2:
+- XRenderCompositeText16 (dpy, op, src, dst, font->format,
+- srcx, srcy, glyphs[0].x, glyphs[0].y,
+- (XGlyphElt16 *) elts, nelt);
+- break;
+- case 4:
+- XRenderCompositeText32 (dpy, op, src, dst, font->format,
+- srcx, srcy, glyphs[0].x, glyphs[0].y,
+- (XGlyphElt32 *) elts, nelt);
+- break;
+- }
++ _XftCompositeText(dpy, op, src, dst, font->format,
++ srcx, srcy, glyphs[0].x, glyphs[0].y,
++ width, elts, nelt);
+
+ if (elts != elts_local)
+ free (elts);
+@@ -635,23 +664,9 @@ XftGlyphFontSpecRender (Display *dpy,
+ elts[nelt].nchars = n;
+ nelt++;
+ }
+- switch (width) {
+- case 1:
+- XRenderCompositeText8 (dpy, op, src, dst, format,
+- srcx, srcy, glyphs[0].x, glyphs[0].y,
+- elts, nelt);
+- break;
+- case 2:
+- XRenderCompositeText16 (dpy, op, src, dst, format,
+- srcx, srcy, glyphs[0].x, glyphs[0].y,
+- (XGlyphElt16 *) elts, nelt);
+- break;
+- case 4:
+- XRenderCompositeText32 (dpy, op, src, dst, format,
+- srcx, srcy, glyphs[0].x, glyphs[0].y,
+- (XGlyphElt32 *) elts, nelt);
+- break;
+- }
++ _XftCompositeText(dpy, op, src, dst, format,
++ srcx, srcy, glyphs[0].x, glyphs[0].y,
++ width, elts, nelt);
+
+ if (elts != elts_local)
+ free (elts);
+--
+2.32.0
+
diff --git a/srcpkgs/libXft/patches/0003-Add-support-for-BGRA-glyphs-display-and-scaling.patch b/srcpkgs/libXft/patches/0003-Add-support-for-BGRA-glyphs-display-and-scaling.patch
new file mode 100644
index 000000000000..73a7842b6348
--- /dev/null
+++ b/srcpkgs/libXft/patches/0003-Add-support-for-BGRA-glyphs-display-and-scaling.patch
@@ -0,0 +1,642 @@
+From d385aa3e5320d18918413df0e8aef3a713a47e0b Mon Sep 17 00:00:00 2001
+From: Maxime Coste <mawww@kakoune.org>
+Date: Tue, 22 Oct 2019 22:46:49 +1100
+Subject: [PATCH 3/3] Add support for BGRA glyphs display and scaling
+
+Display is done using an XRender Picture, as XRender
+glyphs are incompatible with BGRA rendering due to
+their use of the glyph bitmap as a mask.
+
+Scaling is done by averaging all relevant pixel, which gives
+much better result than nearest pixel sampling while staying
+simple enough and not too computationally expensive.
+
+This enables color emoji rendering support.
+
+Fixes: #6
+
+Signed-off-by: Maxime Coste <mawww@kakoune.org>
+---
+ src/xftfreetype.c | 18 +++-
+ src/xftglyphs.c | 234 +++++++++++++++++++++++++++++++++++++++++++---
+ src/xftint.h | 2 +
+ src/xftrender.c | 69 +++++++++++---
+ 4 files changed, 293 insertions(+), 30 deletions(-)
+
+diff --git a/src/xftfreetype.c b/src/xftfreetype.c
+index 1f79a81..4325d65 100644
+--- a/src/xftfreetype.c
++++ b/src/xftfreetype.c
+@@ -523,7 +523,7 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
+ /*
+ * Compute glyph load flags
+ */
+- fi->load_flags = FT_LOAD_DEFAULT;
++ fi->load_flags = FT_LOAD_DEFAULT | FT_LOAD_COLOR;
+
+ #ifndef XFT_EMBEDDED_BITMAP
+ #define XFT_EMBEDDED_BITMAP "embeddedbitmap"
+@@ -775,6 +775,7 @@ XftFontOpenInfo (Display *dpy,
+ FcChar32 hash_value;
+ FcChar32 rehash_value;
+ FcBool antialias;
++ FcBool color;
+ int max_glyph_memory;
+ int alloc_size;
+ int ascent, descent, height;
+@@ -831,12 +832,18 @@ XftFontOpenInfo (Display *dpy,
+ if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
+ antialias = FcFalse;
+
++ color = FT_HAS_COLOR(face) ? FcTrue : FcFalse;
++
+ /*
+ * Find the appropriate picture format
+ */
+ if (fi->render)
+ {
+- if (antialias)
++ if (color)
++ {
++ format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
++ }
++ else if (antialias)
+ {
+ switch (fi->rgba) {
+ case FC_RGBA_RGB:
+@@ -968,6 +975,13 @@ XftFontOpenInfo (Display *dpy,
+ * which doesn't happen in XftFontInfoFill
+ */
+ font->info.antialias = antialias;
++
++ /*
++ * Set color value, which is only known once the
++ * font was loaded
++ */
++ font->info.color = color;
++
+ /*
+ * bump XftFile reference count
+ */
+diff --git a/src/xftglyphs.c b/src/xftglyphs.c
+index b536df4..e0bad10 100644
+--- a/src/xftglyphs.c
++++ b/src/xftglyphs.c
+@@ -26,6 +26,8 @@
+
+ #include FT_SYNTHESIS_H
+
++#include FT_GLYPH_H
++
+ /*
+ * Validate the memory info for a font
+ */
+@@ -78,9 +80,11 @@ _XftFontValidateMemory (Display *dpy, XftFont *public)
+ static int
+ _compute_xrender_bitmap_size( FT_Bitmap* target,
+ FT_GlyphSlot slot,
+- FT_Render_Mode mode )
++ FT_Render_Mode mode,
++ FT_Matrix* matrix )
+ {
+ FT_Bitmap* ftbit;
++ FT_Vector vector;
+ int width, height, pitch;
+
+ if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
+@@ -91,6 +95,16 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
+
+ width = (int)ftbit->width;
+ height = (int)ftbit->rows;
++
++ if ( matrix && mode == FT_RENDER_MODE_NORMAL )
++ {
++ vector.x = ftbit->width;
++ vector.y = ftbit->rows;
++ FT_Vector_Transform(&vector, matrix);
++
++ width = (int)vector.x;
++ height = (int)vector.y;
++ }
+ pitch = (width+3) & ~3;
+
+ switch ( ftbit->pixel_mode )
+@@ -112,6 +126,10 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
+ }
+ break;
+
++ case FT_PIXEL_MODE_BGRA:
++ pitch = width * 4;
++ break;
++
+ case FT_PIXEL_MODE_LCD:
+ if ( mode != FT_RENDER_MODE_LCD )
+ return -1;
+@@ -142,6 +160,105 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
+ return pitch * height;
+ }
+
++/* this functions converts the glyph bitmap found in a FT_GlyphSlot
++ * into a different format while scaling by applying the given matrix
++ * (see _compute_xrender_bitmap_size)
++ *
++ * you should call this function after _compute_xrender_bitmap_size
++ *
++ * target :: target bitmap descriptor. Note that its 'buffer' pointer
++ * must point to memory allocated by the caller
++ *
++ * source :: the source bitmap descriptor
++ *
++ * matrix :: the scaling matrix to apply
++ */
++static void
++_scaled_fill_xrender_bitmap( FT_Bitmap* target,
++ FT_Bitmap* source,
++ const FT_Matrix* matrix )
++{
++ unsigned char* src_buf = source->buffer;
++ unsigned char* dst_line = target->buffer;
++ int src_pitch = source->pitch;
++ int width = target->width;
++ int height = target->rows;
++ int pitch = target->pitch;
++ int h;
++ FT_Vector vector;
++ FT_Matrix inverse = *matrix;
++ int sampling_width;
++ int sampling_height;
++ int sample_count;
++
++ if ( src_pitch < 0 )
++ src_buf -= src_pitch * (source->rows - 1);
++
++ FT_Matrix_Invert(&inverse);
++
++ /* compute how many source pixels a target pixel spans */
++ vector.x = 1;
++ vector.y = 1;
++ FT_Vector_Transform(&vector, &inverse);
++ sampling_width = vector.x / 2;
++ sampling_height = vector.y / 2;
++ sample_count = (2 * sampling_width + 1) * (2 * sampling_height + 1);
++
++ for ( h = height; h > 0; h--, dst_line += pitch )
++ {
++ int x;
++
++ for ( x = 0; x < width; x++ )
++ {
++ unsigned char* src;
++
++#define CLAMP(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
++
++ /* compute target pixel location in source space */
++ vector.x = (x * 0x10000) + 0x10000 / 2;
++ vector.y = ((height - h) * 0x10000) + 0x10000 / 2;
++ FT_Vector_Transform(&vector, &inverse);
++ vector.x = CLAMP(FT_RoundFix(vector.x) / 0x10000, 0, source->width - 1);
++ vector.y = CLAMP(FT_RoundFix(vector.y) / 0x10000, 0, source->rows - 1);
++
++ switch ( source->pixel_mode )
++ {
++ case FT_PIXEL_MODE_MONO: /* convert mono to 8-bit gray, scale using nearest pixel */
++ src = src_buf + (vector.y * src_pitch);
++ if ( src[(vector.x >> 3)] & (0x80 >> (vector.x & 7)) )
++ dst_line[x] = 0xff;
++ break;
++
++ case FT_PIXEL_MODE_GRAY: /* scale using nearest pixel */
++ src = src_buf + (vector.y * src_pitch);
++ dst_line[x] = src[vector.x];
++ break;
++
++ case FT_PIXEL_MODE_BGRA: /* scale by averaging all relevant source pixels, keep BGRA format */
++ {
++ int sample_x, sample_y;
++ int bgra[4] = {};
++ for (sample_y = - sampling_height; sample_y < sampling_height + 1; ++sample_y)
++ {
++ int src_y = CLAMP(vector.y + sample_y, 0, source->rows - 1);
++ src = src_buf + (src_y * src_pitch);
++ for (sample_x = - sampling_width; sample_x < sampling_width + 1; ++sample_x)
++ {
++ int src_x = CLAMP(vector.x + sample_x, 0, source->width - 1);
++ for (int i = 0; i < 4; ++i)
++ bgra[i] += src[src_x * 4 + i];
++ }
++ }
++
++ for (int i = 0; i < 4; ++i)
++ dst_line[4 * x + i] = bgra[i] / sample_count;
++ break;
++ }
++ }
++ }
++ }
++}
++
+ /* this functions converts the glyph bitmap found in a FT_GlyphSlot
+ * into a different format (see _compute_xrender_bitmap_size)
+ *
+@@ -244,6 +361,11 @@ _fill_xrender_bitmap( FT_Bitmap* target,
+ }
+ break;
+
++ case FT_PIXEL_MODE_BGRA: /* Preserve BGRA format */
++ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
++ memcpy( dstLine, srcLine, width * 4 );
++ break;
++
+ case FT_PIXEL_MODE_LCD:
+ if ( !bgr )
+ {
+@@ -339,6 +461,55 @@ _fill_xrender_bitmap( FT_Bitmap* target,
+ }
+ }
+
++/* This function creates a Picture for the given glyph on the default root window
++ * It will only work in Xinerama mode
++ *
++ * dpy :: target display
++ *
++ * format :: target pixmap format
++ *
++ * width :: picture width
++ *
++ * width :: picture height
++ *
++ * data :: bitmap data
++ *
++ */
++static Picture
++_create_glyph_bgra_picture (Display *dpy,
++ XRenderPictFormat *format,
++ int width,
++ int height,
++ unsigned char *data)
++{
++ XImage image = {
++ width, height, 0, ZPixmap, (char *)data,
++ dpy->byte_order, dpy->bitmap_unit, dpy->bitmap_bit_order, 32,
++ 32, 0, 32,
++ 0, 0, 0
++ };
++ Picture picture;
++ Pixmap pixmap;
++ GC gc;
++
++ pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), width, height, 32);
++ if (!pixmap)
++ return None;
++
++ gc = XCreateGC(dpy, pixmap, 0, NULL);
++ if (!gc)
++ return None;
++
++ XInitImage(&image);
++ XPutImage(dpy, pixmap, gc, &image, 0, 0, 0, 0, width, height);
++ picture = XRenderCreatePicture(dpy, pixmap, format, 0, NULL);
++
++ XFreeGC(dpy, gc);
++ XFreePixmap(dpy, pixmap);
++
++ return picture;
++}
++
+ _X_EXPORT void
+ XftFontLoadGlyphs (Display *dpy,
+ XftFont *pub,
+@@ -365,6 +536,8 @@ XftFontLoadGlyphs (Display *dpy,
+ FT_Vector vector;
+ FT_Face face;
+ FT_Render_Mode mode = FT_RENDER_MODE_MONO;
++ FcBool transform;
++ FcBool glyph_transform;
+
+ if (!info)
+ return;
+@@ -374,6 +547,8 @@ XftFontLoadGlyphs (Display *dpy,
+ if (!face)
+ return;
+
++ if (font->info.color)
++ mode = FT_RENDER_MODE_NORMAL;
+ if (font->info.antialias)
+ {
+ switch (font->info.rgba) {
+@@ -390,6 +565,8 @@ XftFontLoadGlyphs (Display *dpy,
+ }
+ }
+
++ transform = font->info.transform && mode != FT_RENDER_MODE_MONO;
++
+ while (nglyph--)
+ {
+ glyphindex = *glyphs++;
+@@ -440,7 +617,7 @@ XftFontLoadGlyphs (Display *dpy,
+ /*
+ * Compute glyph metrics from FreeType information
+ */
+- if(font->info.transform && glyphslot->format != FT_GLYPH_FORMAT_BITMAP)
++ if (transform)
+ {
+ /*
+ * calculate the true width by transforming all four corners.
+@@ -487,7 +664,7 @@ XftFontLoadGlyphs (Display *dpy,
+ * Clip charcell glyphs to the bounding box
+ * XXX transformed?
+ */
+- if (font->info.spacing >= FC_CHARCELL && !font->info.transform)
++ if (font->info.spacing >= FC_CHARCELL && !transform)
+ {
+ if (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT)
+ {
+@@ -519,18 +696,20 @@ XftFontLoadGlyphs (Display *dpy,
+ }
+ }
+
++ glyph_transform = transform;
+ if ( glyphslot->format != FT_GLYPH_FORMAT_BITMAP )
+ {
+ error = FT_Render_Glyph( face->glyph, mode );
+ if (error)
+ continue;
++ glyph_transform = False;
+ }
+
+ FT_Library_SetLcdFilter( _XftFTlibrary, FT_LCD_FILTER_NONE );
+
+ if (font->info.spacing >= FC_MONO)
+ {
+- if (font->info.transform)
++ if (transform)
+ {
+ if (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT)
+ {
+@@ -613,14 +792,27 @@ XftFontLoadGlyphs (Display *dpy,
+ }
+ }
+
+- size = _compute_xrender_bitmap_size( &local, glyphslot, mode );
++ size = _compute_xrender_bitmap_size( &local, glyphslot, mode, glyph_transform ? &font->info.matrix : NULL );
+ if ( size < 0 )
+ continue;
+
+ xftg->metrics.width = (unsigned short)local.width;
+ xftg->metrics.height = (unsigned short)local.rows;
+- xftg->metrics.x = (short)(- glyphslot->bitmap_left);
+- xftg->metrics.y = (short)( glyphslot->bitmap_top);
++ if (transform)
++ {
++ vector.x = - glyphslot->bitmap_left;
++ vector.y = glyphslot->bitmap_top;
++
++ FT_Vector_Transform(&vector, &font->info.matrix);
++
++ xftg->metrics.x = (short)vector.x;
++ xftg->metrics.y = (short)vector.y;
++ }
++ else
++ {
++ xftg->metrics.x = (short)(- glyphslot->bitmap_left);
++ xftg->metrics.y = (short)( glyphslot->bitmap_top);
++ }
+
+ /*
+ * If the glyph is relatively large (> 1% of server memory),
+@@ -645,9 +837,12 @@ XftFontLoadGlyphs (Display *dpy,
+
+ local.buffer = bufBitmap;
+
+- _fill_xrender_bitmap( &local, glyphslot, mode,
+- (font->info.rgba == FC_RGBA_BGR ||
+- font->info.rgba == FC_RGBA_VBGR ) );
++ if (mode == FT_RENDER_MODE_NORMAL && glyph_transform)
++ _scaled_fill_xrender_bitmap(&local, &glyphslot->bitmap, &font->info.matrix);
++ else
++ _fill_xrender_bitmap( &local, glyphslot, mode,
++ (font->info.rgba == FC_RGBA_BGR ||
++ font->info.rgba == FC_RGBA_VBGR ) );
+
+ /*
+ * Copy or convert into local buffer.
+@@ -662,6 +857,7 @@ XftFontLoadGlyphs (Display *dpy,
+ */
+ glyph = (Glyph) glyphindex;
+
++ xftg->picture = 0;
+ xftg->glyph_memory = (size_t)size + sizeof (XftGlyph);
+ if (font->format)
+ {
+@@ -685,15 +881,21 @@ XftFontLoadGlyphs (Display *dpy,
+ }
+ }
+ }
+- else if ( mode != FT_RENDER_MODE_NORMAL )
++ else if (glyphslot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA || mode != FT_RENDER_MODE_NORMAL)
+ {
+ /* invert ARGB <=> BGRA */
+ if (ImageByteOrder (dpy) != XftNativeByteOrder ())
+ XftSwapCARD32 ((CARD32 *) bufBitmap, size >> 2);
+ }
+- XRenderAddGlyphs (dpy, font->glyphset, &glyph,
+- &xftg->metrics, 1,
+- (char *) bufBitmap, size);
++
++ if (glyphslot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
++ xftg->picture = _create_glyph_bgra_picture(dpy, font->format,
++ local.width, local.rows,
++ bufBitmap);
++ else
++ XRenderAddGlyphs (dpy, font->glyphset, &glyph,
++ &xftg->metrics, 1,
++ (char *) bufBitmap, size);
+ }
+ else
+ {
+@@ -744,7 +946,9 @@ XftFontUnloadGlyphs (Display *dpy,
+ {
+ if (font->format)
+ {
+- if (font->glyphset)
++ if (xftg->picture)
++ XRenderFreePicture(dpy, xftg->picture);
++ else if (font->glyphset)
+ {
+ glyphBuf[nused++] = (Glyph) glyphindex;
+ if (nused == sizeof (glyphBuf) / sizeof (glyphBuf[0]))
+diff --git a/src/xftint.h b/src/xftint.h
+index ced9a02..1af40fe 100644
+--- a/src/xftint.h
++++ b/src/xftint.h
+@@ -85,6 +85,7 @@ typedef struct _XftGlyph {
+ XGlyphInfo metrics;
+ void *bitmap;
+ unsigned long glyph_memory;
++ Picture picture;
+ } XftGlyph;
+
+ /*
+@@ -134,6 +135,7 @@ struct _XftFontInfo {
+ FT_F26Dot6 xsize, ysize; /* pixel size */
+ FcBool antialias; /* doing antialiasing */
+ FcBool embolden; /* force emboldening */
++ FcBool color; /* contains color glyphs */
+ int rgba; /* subpixel order */
+ int lcd_filter; /* lcd filter */
+ FT_Matrix matrix; /* glyph transformation matrix */
+diff --git a/src/xftrender.c b/src/xftrender.c
+index 5852b2e..bd001be 100644
+--- a/src/xftrender.c
++++ b/src/xftrender.c
+@@ -84,12 +84,14 @@ XftGlyphRender (Display *dpy,
+ int nglyphs)
+ {
+ XftFontInt *font = (XftFontInt *) pub;
+- int i;
++ int i, j;
+ FT_UInt missing[XFT_NMISSING];
+ int nmissing;
+ FT_UInt g, max;
+ int size, width;
++ int dstx, dsty;
+ Glyph wire;
++ XftGlyph* glyph;
+ char *char8;
+ unsigned short *char16;
+ unsigned int *char32;
+@@ -141,22 +143,46 @@ XftGlyphRender (Display *dpy,
+ if (!chars)
+ goto bail1;
+ }
++ dstx = x;
++ dsty = y;
+ char8 = (char *) chars;
+ char16 = (unsigned short *) chars;
+ char32 = (unsigned int *) chars;
+- for (i = 0; i < nglyphs; i++)
++ for (i = 0, j = 0; i < nglyphs; i++)
+ {
+ wire = (Glyph) glyphs[i];
+ if (wire >= font->num_glyphs || !font->glyphs[wire])
+ wire = 0;
+- switch (width) {
+- case 1: char8[i] = (char) wire; break;
+- case 2: char16[i] = (unsigned short) wire; break;
+- case 4: char32[i] = (unsigned int) wire; break;
++ glyph = font->glyphs[wire];
++ if (glyph->picture)
++ {
++ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset,
++ srcx, srcy, x, y, width, chars, j);
++ XRenderComposite(dpy, PictOpOver, glyph->picture, None,
++ dst, 0, 0, 0, 0, dstx, dsty - glyph->metrics.y,
++ glyph->metrics.width, glyph->metrics.height);
++
++ dstx += glyph->metrics.xOff;
++ dsty += glyph->metrics.yOff;
++
++ x = dstx;
++ y = dsty;
++ j = 0;
++ }
++ else
++ {
++ switch (width) {
++ case 1: char8[j] = (char) wire; break;
++ case 2: char16[j] = (unsigned short) wire; break;
++ case 4: char32[j] = (unsigned int) wire; break;
++ }
++ dstx += glyph->metrics.xOff;
++ dsty += glyph->metrics.yOff;
++ ++j;
+ }
+ }
+ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset,
+- srcx, srcy, x, y, width, chars, nglyphs);
++ srcx, srcy, x, y, width, chars, j);
+ if (chars != char_local)
+ free (chars);
+ bail1:
+@@ -319,9 +345,10 @@ XftGlyphSpecRender (Display *dpy,
+ g = 0;
+ /*
+ * check to see if the glyph is placed where it would
+- * fall using the normal spacing
++ * fall using the normal spacing and if it would render
++ * as a XRender glyph
+ */
+- if ((glyph = font->glyphs[g]))
++ if ((glyph = font->glyphs[g]) && !glyph->picture)
+ {
+ if (x != glyphs[i].x || y != glyphs[i].y)
+ {
+@@ -335,7 +362,7 @@ XftGlyphSpecRender (Display *dpy,
+ }
+
+ elts = elts_local;
+- if (nelt > NUM_ELT_LOCAL)
++ if (!font->info.color && nelt > NUM_ELT_LOCAL)
+ {
+ elts = malloc ((size_t)nelt * sizeof (XGlyphElt8));
+ if (!elts)
+@@ -343,7 +370,7 @@ XftGlyphSpecRender (Display *dpy,
+ }
+
+ /*
+- * Generate the list of glyph elts
++ * Generate the list of glyph elts or render color glyphs
+ */
+ nelt = 0;
+ x = y = 0;
+@@ -357,6 +384,14 @@ XftGlyphSpecRender (Display *dpy,
+ g = 0;
+ if ((glyph = font->glyphs[g]))
+ {
++ if (glyph->picture)
++ {
++ XRenderComposite(dpy, PictOpOver, glyph->picture, None,
++ dst, 0, 0, 0, 0,
++ glyphs[i].x, glyphs[i].y - glyph->metrics.y,
++ glyph->metrics.width, glyph->metrics.height);
++ continue;
++ }
+ if (!i || x != glyphs[i].x || y != glyphs[i].y)
+ {
+ if (n)
+@@ -589,7 +624,7 @@ XftGlyphFontSpecRender (Display *dpy,
+ * check to see if the glyph is placed where it would
+ * fall using the normal spacing
+ */
+- if ((glyph = font->glyphs[g]))
++ if ((glyph = font->glyphs[g]) && !glyph->picture)
+ {
+ if (pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
+ {
+@@ -614,7 +649,7 @@ XftGlyphFontSpecRender (Display *dpy,
+ }
+
+ /*
+- * Generate the list of glyph elts
++ * Generate the list of glyph elts and render color glyphs
+ */
+ nelt = 0;
+ x = y = 0;
+@@ -632,6 +667,14 @@ XftGlyphFontSpecRender (Display *dpy,
+ g = 0;
+ if ((glyph = font->glyphs[g]))
+ {
++ if (glyph->picture)
++ {
++ XRenderComposite(dpy, PictOpOver, glyph->picture, None,
++ dst, 0, 0, 0, 0,
++ glyphs[i].x, glyphs[i].y - glyph->metrics.y,
++ glyph->metrics.width, glyph->metrics.height);
++ continue;
++ }
+ if (!i || pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
+ {
+ if (n)
+--
+2.32.0
+
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: libXft: update and include big fixes
2021-08-12 12:24 [PR PATCH] libXft: update and include big fixes vigoux
@ 2021-08-12 12:26 ` ericonr
2021-08-12 12:26 ` [PR PATCH] [Closed]: " ericonr
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: ericonr @ 2021-08-12 12:26 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 248 bytes --]
New comment by ericonr on void-packages repository
https://github.com/void-linux/void-packages/pull/32469#issuecomment-897596954
Comment:
Not an acceptable patch: https://github.com/void-linux/void-packages/pull/32371#pullrequestreview-724930578
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PR PATCH] [Closed]: libXft: update and include big fixes
2021-08-12 12:24 [PR PATCH] libXft: update and include big fixes vigoux
2021-08-12 12:26 ` ericonr
@ 2021-08-12 12:26 ` ericonr
2021-08-12 12:32 ` ericonr
2021-08-12 12:32 ` ericonr
3 siblings, 0 replies; 5+ messages in thread
From: ericonr @ 2021-08-12 12:26 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 1658 bytes --]
There's a closed pull request on the void-packages repository
libXft: update and include big fixes
https://github.com/void-linux/void-packages/pull/32469
Description:
<!-- Mark items with [x] where applicable -->
#### General
- [ ] This is a new package and it conforms to the [quality requirements](https://github.com/void-linux/void-packages/blob/master/Manual.md#quality-requirements)
#### Have the results of the proposed changes been tested?
- [x] I use the packages affected by the proposed changes on a regular basis and confirm this PR works for me
- [ ] I generally don't use the affected packages but briefly tested this PR
<!--
If GitHub CI cannot be used to validate the build result (for example, if the
build is likely to take several hours), make sure to
[skip CI](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#continuous-integration).
When skipping CI, uncomment and fill out the following section.
Note: for builds that are likely to complete in less than 2 hours, it is not
acceptable to skip CI.
-->
#### Does it build and run successfully?
(Please choose at least one native build and, if supported, at least one cross build. More are better.)
- [x] I built this PR locally for my native architecture, (x86_64-gnu)
- [ ] I built this PR locally for these architectures (if supported. mark crossbuilds):
- [ ] aarch64-musl
- [ ] armv7l
- [ ] armv6l-musl
#### Other
This PR includes patches that are waiting to be merged upstream, and
fix a bug. Including these patched solved numerous issues with `st`,
where colored emojis caused a hard crash of the terminal emulator.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: libXft: update and include big fixes
2021-08-12 12:24 [PR PATCH] libXft: update and include big fixes vigoux
2021-08-12 12:26 ` ericonr
2021-08-12 12:26 ` [PR PATCH] [Closed]: " ericonr
@ 2021-08-12 12:32 ` ericonr
2021-08-12 12:32 ` ericonr
3 siblings, 0 replies; 5+ messages in thread
From: ericonr @ 2021-08-12 12:32 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 319 bytes --]
New comment by ericonr on void-packages repository
https://github.com/void-linux/void-packages/pull/32469#issuecomment-897600631
Comment:
https://github.com/void-linux/void-packages/pull/32452 was handling the update already.
Sorry if the answer was too brisk, I'm trying to keep the PR queue down where possible.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: libXft: update and include big fixes
2021-08-12 12:24 [PR PATCH] libXft: update and include big fixes vigoux
` (2 preceding siblings ...)
2021-08-12 12:32 ` ericonr
@ 2021-08-12 12:32 ` ericonr
3 siblings, 0 replies; 5+ messages in thread
From: ericonr @ 2021-08-12 12:32 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 224 bytes --]
New comment by ericonr on void-packages repository
https://github.com/void-linux/void-packages/pull/32469#issuecomment-897601145
Comment:
I'm hopeful that if a proper solution appears, it will be merged into mainstream :/
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-08-12 12:32 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-12 12:24 [PR PATCH] libXft: update and include big fixes vigoux
2021-08-12 12:26 ` ericonr
2021-08-12 12:26 ` [PR PATCH] [Closed]: " ericonr
2021-08-12 12:32 ` ericonr
2021-08-12 12:32 ` ericonr
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).