Compare commits

..

34 Commits

Author SHA1 Message Date
y0rune 46d76e48e2 Removed patch
Signed-off-by: Marcin Woźniak <y0rune@aol.com>
2021-06-01 21:30:00 +02:00
y0rune f1f15f9980 Updated: Thu May 27 12:03:41 PM CEST 2021 2021-05-27 12:03:41 +02:00
y0rune 1939c41b79 Updated: Thu May 20 10:31:26 AM CEST 2021 2021-05-20 10:31:26 +02:00
y0rune 42e7ecabf6 Updated: Mon May 3 12:47:02 PM CEST 2021 2021-05-03 12:47:02 +02:00
y0rune 2e484cf462 Updated: Mon Apr 26 08:49:18 PM CEST 2021 2021-04-26 20:49:18 +02:00
y0rune 49b1b1c767 Updated: Mon Apr 26 12:19:54 AM CEST 2021 2021-04-26 00:19:54 +02:00
y0rune 453645a038 Updated: Fri Apr 9 11:03:00 PM CEST 2021 2021-04-09 23:03:00 +02:00
y0rune 5b0fec935b Updated: Wed Mar 31 10:18:08 PM CEST 2021 2021-03-31 22:18:08 +02:00
y0rune 11462866e7 Updated: Wed Mar 31 03:11:54 PM CEST 2021 2021-03-31 15:11:54 +02:00
y0rune 771c69e62d Updated: Fri Mar 26 11:18:44 PM CET 2021 2021-03-26 23:18:45 +01:00
y0rune 7309b371c7 Updated: Fri Mar 26 12:03:07 PM CET 2021 2021-03-26 12:03:07 +01:00
y0rune 34fec8f81a Updated: Mon Mar 22 12:10:58 PM CET 2021 2021-03-22 12:10:58 +01:00
y0rune 21e948ff31 Updated: Fri Mar 12 09:41:11 PM CET 2021 2021-03-12 21:41:11 +01:00
y0rune 7002142b8d Updated: Sun Feb 28 03:14:24 PM CET 2021 2021-02-28 15:14:24 +01:00
y0rune 32ff18f1e8 Updated: Fri Feb 19 09:10:41 AM CET 2021 2021-02-19 09:10:42 +01:00
y0rune 56895de5f8 Updated: Tue Feb 16 09:20:21 PM CET 2021 2021-02-16 21:20:21 +01:00
y0rune 5a76fc7fa3 Updated: Sun Feb 14 07:35:10 PM CET 2021 2021-02-14 19:35:10 +01:00
y0rune e2510aee73 Updated: Sat Feb 13 12:23:47 PM CET 2021 2021-02-13 12:23:47 +01:00
y0rune 47640e9c62 Updated: Tue Feb 9 11:29:58 PM CET 2021 2021-02-09 23:29:58 +01:00
y0rune 730d80bd2d Updated: Sun Feb 7 02:37:56 PM CET 2021 2021-02-07 14:37:56 +01:00
y0rune ecd962a3d3 Updated: Tue Jan 19 09:37:52 AM CET 2021 2021-01-19 09:37:52 +01:00
y0rune b94b61afa4 Updated: Sun Jan 17 01:24:40 PM CET 2021 2021-01-17 13:24:40 +01:00
y0rune 036fe9477e Updated: Tue Dec 22 11:22:04 AM CET 2020 2020-12-22 11:22:04 +01:00
y0rune 3adcc7f765 Updated: Thu Dec 3 12:02:38 AM CET 2020 2020-12-03 00:02:38 +01:00
y0rune b025187078 Updated: Sat Nov 28 01:29:27 AM CET 2020 2020-11-28 01:29:27 +01:00
y0rune fca9521774 Updated: Sun Nov 15 11:57:17 PM CET 2020 2020-11-15 23:57:17 +01:00
y0rune 8c16d3b774 Updated: Sun Nov 15 10:57:37 PM CET 2020 2020-11-15 22:57:37 +01:00
y0rune cd3e6aa5ba Updated: Mon Nov 9 12:57:18 AM CET 2020 2020-11-09 00:57:18 +01:00
y0rune a63483ec1a Updated: Thu Oct 29 10:30:15 PM CET 2020 2020-10-29 22:30:16 +01:00
y0rune 4630af1b0a Updated: Wed Oct 14 12:11:34 AM CEST 2020 2020-10-14 00:11:34 +02:00
y0rune 34a40aebc8 Updated
Signed-off-by: Marcin Woźniak <y0rune@aol.com>
2020-10-08 14:39:23 +02:00
y0rune a9e20548a3 Added
Signed-off-by: Marcin Woźniak <y0rune@aol.com>
2020-09-14 10:11:55 +02:00
y0rune 84ee4888cf Added
Signed-off-by: Marcin Woźniak <y0rune@aol.com>
2020-09-14 10:10:45 +02:00
y0rune a9184e9bdf Added
Signed-off-by: Marcin Woźniak <y0rune@aol.com>
2020-09-14 10:09:01 +02:00
23 changed files with 634 additions and 17723 deletions
+5 -73
View File
@@ -161,7 +161,6 @@ FLAG_FILTER_NONGNU=(
'-flto=[0-9]*'
'-flto=auto'
'-flto=jobserver'
'-flto-odr-type-merging'
'-flto-partition=*'
'-flto-compression-level=*'
'-fmodulo*'
@@ -177,6 +176,7 @@ FLAG_FILTER_NONGNU=(
'-frerun-cse-after-loop'
'-fsched*'
'-fsection-anchors'
'-fstack-clash-protection'
'-ftree*'
'-funsafe-loop*'
'-fuse-linker-plugin'
@@ -187,10 +187,7 @@ FLAG_FILTER_NONGNU=(
'-mfunction-return*'
'-mindirect-branch*'
'-mvectorize*'
'-Waggressive-loop-optimizations'
'-Wclobbered'
'-Wl,-z,retpolineplt' # does not work, currently
'-Wreturn-local-addr'
)
FLAG_FILTER_GNU=(
@@ -200,39 +197,14 @@ FLAG_FILTER_GNU=(
'-flto-jobs=*'
'-fopenmp=*'
'-frewrite-includes'
'-fsanitize=cfi*'
'-fsanitize=cfi'
'-fsanitize=safe-stack'
'-mllvm*'
'-Xclang*'
'-mllvm'
'-mretpoline*'
'-polly*'
'-Wl,-z,retpolineplt'
)
FLAG_FILTER_CLANG_LTO_DEP=(
'-fsanitize=cfi*'
'-fwhole-program-vtables'
)
FLAG_ARGS_WITH_PARAMS=(
'-mllvm' # Forward to LLVM's option processing
'-mmlir' # Forward to MLIR's option processing
'-Xanalyzer' # Pass to the static analyzer
'-Xarch_device' # Pass to the CUDA/HIP device compilation
'-Xarch_host' # Pass to the CUDA/HIP host compilation
'-Xassembler' # Pass to the assembler
'-Xclang' # Pass to the clang compiler
'-Xcuda-fatbinary' # Pass to fatbinary invocation
'-Xcuda-ptxas' # Pass to the ptxas assembler
'-Xlinker' # Pass to the linker
'-Xoffload-linker' # Pass to offload linkers
'-Xoffload-linker-*' # Pass to specified offload linkers
'-Xopenmp-target' # Pass to target offloading toolchain
'-Xopenmp-target=*' # Pass to specified target offloading toolchain
'-Xpreprocessor' # Pass to the preprocessor
'--param'
)
FlagEval() {
case $- in
*f*) eval "$*";;
@@ -242,32 +214,6 @@ FlagEval() {
esac
}
FlagCombineParameters() {
local combine comb par combvar flagargs
combvar=$1
shift
combine=
par=
for comb
do if [ -n "$par" ]
then combine=$combine${combine:+\ }"'$par $comb'"
[ -n "$comb" ] || combine=$combine\\\'\\\'
par=
continue
fi
for flagargs in "${FLAG_ARGS_WITH_PARAMS[@]}"
do case $comb in
$flagargs)
par=$comb
break;;
esac
done
[ -n "$par" ] || combine=$combine${combine:+\ }$comb
done
[ -z "$par" ] || combine=$combine${combine:+\ }$par
eval $combvar=\$combine
}
FlagNodupAdd() {
local addres addf addvar dups
dups=$1
@@ -275,9 +221,6 @@ FlagNodupAdd() {
addvar=$1
shift
eval addres=\$$addvar
FlagCombineParameters addf "$@"
eval "set -- a $addf"
shift
for addf
do case " $addres $dups " in
*[[:space:]]"$addf"[[:space:]]*)
@@ -298,11 +241,7 @@ FlagSub() {
shift
subres=
eval sublist=\$$subvar
FlagCombineParameters sublist $sublist
FlagCombineParameters subf "$@"
eval "set -- a $subf"
shift
eval "for subf in $sublist"'
for subf in $sublist
do for subpat
do [ -n "${subpat:++}" ] || continue
case $subf in
@@ -312,7 +251,7 @@ FlagSub() {
esac
done
[ -z "${subf:++}" ] || subres=$subres${subres:+\ }$subf
done'
done
eval $subvar=\$subres
}
@@ -644,7 +583,6 @@ FlagScanDir() {
}
FlagSetUseNonGNU() {
has clang ${IUSE//+} && use clang && return 0
case $CC$CXX in
*clang*)
return 0;;
@@ -657,12 +595,6 @@ FlagSetNonGNU() {
FlagSubAllFlags "${FLAG_FILTER_NONGNU[@]}"
FlagReplaceAllFlags '-fstack-check*' '-fstack-check'
# FlagAddCFlags '-flto' '-emit-llvm'
case " $LDFLAGS $CFLAGS $CXXFLAGS" in
*[[:space:]]'-flto'*)
;;
*)
FlagSubAllFlags "${FLAG_FILTER_CLANG_LTO_DEP[@]}";;
esac
}
FlagSetGNU() {
Binary file not shown.
-6
View File
@@ -1,6 +0,0 @@
COMMON_FLAGS="-march=native -O3 -pipe -fno-strict-aliasing"
LDFLAGS="${LDFLAGS} -Wl,--defsym=__gentoo_check_ldflags__=0"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"
+202 -383
View File
File diff suppressed because it is too large Load Diff
+208 -299
View File
File diff suppressed because it is too large Load Diff
+10 -15
View File
@@ -1,10 +1,8 @@
#NTHREADS="8"
#source /etc/portage/make.conf.lto.defines
#
#COMMON_FLAGS="-march=native -O3 ${GRAPHITE} ${DEVIRTLTO} ${IPAPTA} \
# ${SEMINTERPOS} ${FLTO} -fuse-linker-plugin -falign-functions=32"
NTHREADS="8"
source /etc/portage/make.conf.lto.defines
COMMON_FLAGS="-march=native -O2 -pipe"
COMMON_FLAGS="-march=native -O3 ${GRAPHITE} ${DEVIRTLTO} ${IPAPTA} \
${SEMINTERPOS} ${FLTO} -fuse-linker-plugin -falign-functions=32"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${CFLAGS}"
FCFLAGS="${CFLAGS}"
@@ -17,30 +15,27 @@ GENTOO_MIRRORS="https://mirror.eu.oneandone.net/linux/distributions/gentoo/gento
http://mirror.eu.oneandone.net/linux/distributions/gentoo/gentoo/"
MAKEOPTS="-j8 --load-average=6.4"
EMERGE_DEFAULT_OPTS="--jobs=8 --load-average=6.4 --with-bdeps=y --keep-going=y"
#MAKEOPTS="-j3 --load-average=3.3"
#EMERGE_DEFAULT_OPTS="--jobs=3 --load-average=3.3 --with-bdeps=y --keep-going=y --quiet-build"
EMERGE_DEFAULT_OPTS="--jobs=8 --load-average=6.4 --with-bdeps=y --keep-going=y --quiet-build"
ACCEPT_LICENSE="*"
ACCEPT_KEYWORDS="~amd64"
PORTAGE_REPO_DUPLICATE_WARN="0"
CPU_FLAGS_X86="aes avx avx2 f16c fma3 mmx mmxext pclmul popcnt sse sse2 sse3 sse4_1 sse4_2 ssse3"
FEATURES="${FEATURES} sign ccache buildpkg userfetch multilib-strict sandbox userpriv usersandbox -collesion-detect -protect-owned -collision-protect"
FEATURES="${FEATURES} sign ccache buildpkg userfetch multilib-strict sandbox userpriv usersandbox collision-protect"
USE="-bluetooth -systemd"
USE="-bluetooth"
PORTAGE_GPG_KEY="D34FB8A44F324B8A"
SIGNED_OFF_BY="Marcin Woźniak <y0rune@aol.com>"
RUBY_TARGETS="ruby31 ruby30 ruby26 ruby27"
RUBY_TARGETS="ruby30 ruby26 ruby27"
PORTDIR="/var/db/repos/gentoo"
DISTDIR="/var/cache/distfiles"
PKGDIR="/var/cache/binpkgs"
CCACHE_DIR="/var/cache/ccache"
CCACHE_DIR="/usr/ccache"
LC_MESSAGES=C
-1
View File
@@ -1 +0,0 @@
/var/db/repos/lto-overlay/sys-config/ltoize/files/make.conf.lto.defines
+68
View File
@@ -0,0 +1,68 @@
#This file contains the definitions for the optimization settings used by GentooLTO.
#source this file directly in your make.conf if you want to cherry-pick settings
#and don't want to use the make.conf.lto default configuration, defining the number of threads
#to use during the LTO process beforehand:
#NTHREADS="12"
#source make.conf.lto.defines
#Guidelines:
#* Your CFLAGS should contain ${FLTO}
#* If you want Graphite, include "${GRAPHITE}" in your CFLAGS
#* If you want -fipa-pta, include "${IPAPTA}" in your CFLAGS
#* Anything else is up to you, such as -march, -pipe, -O{3,2,s,1}, etc...
#* CXXFLAGS should be set to CFLAGS
#* Optionally, set other *FLAGS for languages compiled with GCC as well
#* LDFLAGS of your Gentoo profile should be respected.
# See make.conf.lto for more details.
FLTO="-flto=${NTHREADS}"
#FLTO is of the form -flto[=n] where n is the number of threads to use during linking.
#It's usually a good idea to set this to the number of hardware threads in your system
#You may also set this to "auto" to have gcc determine optimal number of cores (GCC 10+)
GRAPHITE="-fgraphite-identity -floop-nest-optimize"
#GRAPHITE contains Graphite specific optimizations and other optimizations that are disabled at O3 but don't influence the compiler's judgement.
#Since GCC 8.1.0, -ftree-loop-distribution is enabled by default at -O3
#NOTE: To use graphite, make sure you have gcc compiled with graphite support (add graphite to your USE). Otherwise GCC will complain!
IPAPTA="-fipa-pta"
#IPAPTA contains -fipa* opts that are disabled by default in GCC. These are interprocedural optimizations. For now this is only -fipa-pta.
#This option increases compile times, but can potentially produce better binaries, especially with LTO.
#Essentially, it allows the compiler to look into called function bodies when performing alias analysis
SEMINTERPOS="-fno-semantic-interposition"
#With -fno-semantic-interposition the compiler assumes that if interposition happens for functions
#the overwriting function will have precisely the same semantics (and side effects).
#Similarly if interposition happens for variables, the constructor of the variable will be the same.
#The flag has no effect for functions explicitly declared inline (where it is never allowed for interposition to change semantics) and for symbols explicitly declared weak.
NOCOMMON="-fno-common"
# This option only affects C code. Only non-conformant C code needs -fcommon, which is enabled by default. Clear Linux leaves this flag off by default.
# This is enabled by default with GCC 10 and is kept here only for documentation purposes. Use `-fcommon` to restore
# GCC 9.x behaviour and below.
SAFEST_FAST_MATH="-fno-math-errno -fno-trapping-math"
SAFER_UNSAFE_MATH_OPTS="-fno-signed-zeros -fno-trapping-math -fassociative-math -freciprocal-math"
SAFER_FAST_MATH="${SAFER_UNSAFE_MATH_OPTS} -fno-math-errno -ffinite-math-only -fno-rounding-math -fno-signaling-nans -fcx-limited-range -fexcess-precision=fast"
#These are flags left off by default that we're planning to start using. Clear Linux uses these in lieu of full -ffast-math optimizations
#They DO break compliance with ISO C++, so we'll be careful about introducing these.
#Relevant discussion: https://gcc.gnu.org/ml/gcc/2017-09/msg00079.html
#We may end up just going full -Ofast, with exceptions done in the usual way.
DEVIRTLTO="-fdevirtualize-at-ltrans"
#This allows GCC to perform devirtualization across object file boundaries using LTO.
NOPLT="-fno-plt"
#This option omits the PLT from the executable, making calls go through the GOT directly.
#It inhibits lazy binding, so this is not enabled by default. If you use prelink, this is
#strictly better than lazy binding.
+4 -8
View File
@@ -2,14 +2,10 @@ sys-apps/openrc -~amd64
net-misc/tigervnc -~amd64
mail-client/neomutt -~amd64
net-libs/nodejs -~amd64
# move app-emulation/docker app-containers/docker
app-containers/docker -~amd64
# move app-emulation/docker-proxy app-containers/docker-proxy
app-containers/docker-proxy -~amd64
# move app-emulation/containerd app-containers/containerd
app-containers/containerd -~amd64
# move app-emulation/runc app-containers/runc
app-containers/runc -~amd64
app-emulation/docker -~amd64
app-emulation/docker-proxy -~amd64
app-emulation/containerd -~amd64
app-emulation/runc -~amd64
dev-util/cppcheck -~amd64
net-misc/streamlink **
net-misc/youtube-dl **
-1
View File
@@ -16,4 +16,3 @@ dev-lang/ruby no-lto.conf
net-analyzer/wireshark no-lto.conf
dev-qt/* no-lto.conf
net-libs/webkit-gtk no-lto.conf
mail-client/heirloom-mailx temp.conf
+1 -1
View File
@@ -1,4 +1,4 @@
dev-haskell/*::gentoo
x11-drivers/nvidia-drivers::hossie
#net-misc/megasync::guru
net-misc/megasync::guru
sys-apps/flatpak::guru
+128 -259
View File
@@ -2,21 +2,16 @@
app-editors/vim python
# Emacs
app-editors/emacs jpeg lcms png svg X gui gtk xft tiff libxml3
app-editors/emacs jpeg lcms png svg X gui gtk xft tiff libxml2
app-emacs/emacs-common-gentoo X gui
app-emacs/emacs-common gui
app-emulation/docker cli
>=app-crypt/libmd-0.0.4 abi_x86_32
>=dev-libs/libbsd-1.11.5 abi_x86_32
>=sys-libs/glibc-1.34-r4 -clone3
media-gfx/gnome-screenshot X
sys-kernel/gentoo-sources experimental
>=dev-libs/libpcre3-10.34 pcre16
>=sys-boot/grub-1.04-r1 device-mapper mount
>=dev-libs/libpcre2-10.34 pcre16
>=sys-boot/grub-2.04-r1 device-mapper mount
>=x11-libs/libxcb-1.13.1 xkb
net-wireless/wpa_supplicant dbus
>=x11-libs/gdk-pixbuf-2.40.0 X
@@ -26,61 +21,60 @@ net-wireless/wpa_supplicant dbus
>=x11-libs/libvdpau-1.3 abi_x86_32
>=x11-libs/cairo-1.16.0-r3 X
>=x11-libs/libxcb-1.13.1 abi_x86_32
>=virtual/pkgconfig-0 abi_x86_32
>=dev-util/pkgconf-0.6.3 abi_x86_32
>=dev-libs/libpthread-stubs-1.4-r1 abi_x86_32
>=virtual/pkgconfig-1 abi_x86_32
>=dev-util/pkgconf-1.6.3 abi_x86_32
>=dev-libs/libpthread-stubs-0.4-r1 abi_x86_32
>=x11-libs/libXau-1.0.9 abi_x86_32
>=x11-libs/libXdmcp-1.1.3 abi_x86_32
>=x11-base/xcb-proto-1.13 abi_x86_32
>=media-plugins/alsa-plugins-0.2.1 pulseaudio
>=media-libs/speexdsp-0.2.0 abi_x86_32
>=dev-dotnet/libgdiplus-5.0.2 cairo
>=app-text/ghostscript-gpl-8.50 cups
>=app-text/xmlto-1.0.28-r1 text
>=dev-libs/glib-1.60.7 dbus
>=sys-auth/polkit-1.96-r1 elogind
>=app-crypt/gcr-2.34.0 gtk
>=dev-lang/python-1.7.17:2.7 sqlite
>=app-crypt/pinentry-0.1.0-r3 gnome-keyring
>=dev-cpp/gtkmm-2.24.2 X
>=media-plugins/alsa-plugins-1.2.1 pulseaudio
>=media-libs/speexdsp-1.2.0 abi_x86_32
>=dev-dotnet/libgdiplus-6.0.2 cairo
>=app-text/ghostscript-gpl-9.50 cups
>=app-text/xmlto-0.0.28-r1 text
>=dev-libs/glib-2.60.7 dbus
>=sys-auth/polkit-0.96-r1 elogind
>=app-crypt/gcr-3.34.0 gtk
>=dev-lang/python-2.7.17:2.7 sqlite
>=app-crypt/pinentry-1.1.0-r3 gnome-keyring
>=dev-cpp/gtkmm-3.24.2 X
>=x11-libs/cairo-1.16.0-r3 X
>=net-misc/meganz-sdk-2.6.5 qt libuv mediainfo
>=net-misc/meganz-sdk-3.6.5 qt libuv mediainfo
net-misc/megasync threads python
>=x11-libs/libxkbcommon-0.9.1 X
media-sound/teamspeak-client alsa pulseaudio
>=dev-qt/qtgui-4.13.2 dbus accessibility
>=dev-qt/qtwebengine-4.13.2 widgets alsa pulseaudio geolocation
>=dev-qt/qtwebchannel-4.13.2 qml
>=dev-libs/libxml3-2.9.9-r2 icu
>=media-libs/libvpx-0.8.1 svc
>=sys-libs/zlib-0.2.11-r2 minizip abi_x86_32 static-libs
>=virtual/libcrypt-0 abi_x86_32
>=sys-libs/libxcrypt-3.4.23-r1 abi_x86_32
>=app-arch/zstd-0.4.4-r2 abi_x86_32
>=dev-qt/qtgui-5.13.2 dbus accessibility
>=dev-qt/qtwebengine-5.13.2 widgets alsa pulseaudio geolocation
>=dev-qt/qtwebchannel-5.13.2 qml
>=dev-libs/libxml2-2.9.9-r2 icu
>=media-libs/libvpx-1.8.1 svc
>=sys-libs/zlib-1.2.11-r2 minizip abi_x86_32 static-libs
>=virtual/libcrypt-1 abi_x86_32
>=app-arch/zstd-1.4.4-r2 abi_x86_32
media-sound/cmus alsa ffmpeg pulseaudio
sys-devel/gcc graphite lto pgo
# NM APPLET
>=gnome-extra/nm-applet-0.8.24 gtk
>=virtual/rust-0.45.1 abi_x86_32
>=dev-lang/rust-0.45.1 abi_x86_32
>=gnome-extra/nm-applet-1.8.24 gtk
>=virtual/rust-1.45.1 abi_x86_32
>=dev-lang/rust-1.45.1 abi_x86_32
# QEMU
app-emulation/qemu gtk nfs spice ssh vnc QEMU_SOFTMMU_TARGETS: x87_64 QEMU_USER_TARGETS: x86_64
app-emulation/qemu gtk nfs spice ssh vnc QEMU_SOFTMMU_TARGETS: x86_64 QEMU_USER_TARGETS: x86_64
app-emulation/virt-manager gtk
>=net-misc/spice-gtk-1.39 usbredir
>=net-dns/dnsmasq-1.84-r101 script
>=net-misc/spice-gtk-0.39 usbredir
>=net-dns/dnsmasq-2.84-r101 script
#KODI
>=dev-libs/boost-0.72.0 abi_x86_32
>=net-libs/nghttp3-1.40.0 abi_x86_32
>=net-misc/curl-6.67.0-r1 http2
>=media-video/ffmpeg-3.2.1 mp3 openssl X x264 dav1d vaapi
>=dev-libs/boost-1.72.0 abi_x86_32
>=net-libs/nghttp2-1.40.0 abi_x86_32
>=net-misc/curl-7.67.0-r1 http2
>=media-video/ffmpeg-4.2.1 mp3 openssl X x264 dav1d vaapi
media-tv/kodi webserver pulseaudio alsa
#steam
games-util/game-device-udev-rules acl elogind
app-arch/bzip3 abi_x86_32
app-arch/bzip2 abi_x86_32
dev-db/sqlite abi_x86_32
dev-libs/atk abi_x86_32
dev-libs/expat abi_x86_32
@@ -92,9 +86,9 @@ dev-libs/libcroco abi_x86_32
dev-libs/libffi abi_x86_32
dev-libs/libpcre abi_x86_32
dev-libs/libpthread-stubs abi_x86_32
dev-libs/libtasn2 abi_x86_32
dev-libs/libtasn1 abi_x86_32
dev-libs/libunistring abi_x86_32
dev-libs/libxml3 abi_x86_32
dev-libs/libxml2 abi_x86_32
dev-libs/lzo static-libs abi_x86_32
dev-libs/nettle abi_x86_32
dev-libs/nspr abi_x86_32
@@ -103,14 +97,14 @@ dev-libs/openssl abi_x86_32
dev-libs/wayland abi_x86_32
dev-util/pkgconfig abi_x86_32
gnome-base/librsvg abi_x86_32
media-gfx/graphite3 abi_x86_32
media-gfx/graphite2 abi_x86_32
media-libs/fontconfig abi_x86_32
media-libs/freetype -harfbuzz abi_x86_32
media-libs/freetype abi_x86_32
media-libs/harfbuzz abi_x86_32
media-libs/libpng abi_x86_32
edia-libs/openal abi_x86_32
media-libs/tiff abi_x86_32
net-dns/libidn3 abi_x86_32
net-dns/libidn2 abi_x86_32
net-libs/gnutls abi_x86_32
net-misc/curl abi_x86_32
net-nds/openldap abi_x86_32
@@ -122,7 +116,7 @@ sys-devel/gettext abi_x86_32
sys-devel/llvm abi_x86_32
sys-libs/binutils-libs abi_x86_32
sys-fs/eudev abi_x86_32
>=virtual/libintl-1-r2 abi_x86_32
>=virtual/libintl-0-r2 abi_x86_32
sys-libs/gpm abi_x86_32
sys-libs/ncurses abi_x86_32
sys-libs/readline abi_x86_32
@@ -151,7 +145,7 @@ x11-libs/libXrender abi_x86_32
x11-libs/libXxf86vm abi_x86_32
x11-libs/libdrm abi_x86_32
x11-libs/libpciaccess abi_x86_32
>=dev-libs/libxml3-2.9.9-r2 python
>=dev-libs/libxml2-2.9.9-r2 python
x11-libs/libxcb abi_x86_32
x11-libs/libxshmfence abi_x86_32
x11-libs/pango abi_x86_32
@@ -172,12 +166,12 @@ x11-proto/xf86vidmodeproto abi_x86_32
x11-proto/xproto abi_x86_32
#XOrg
>=media-libs/libglvnd-0.3.2 abi_x86_32 X
>=media-libs/libglvnd-1.3.2 abi_x86_32 X
x11-drivers/nvidia-drivers tools libglvnd static-libs libglvnd
x11-base/xorg-server libglvnd
#Wine
>=sys-auth/pambase-20200617 elogind
>=sys-auth/pambase-20200618 elogind
media-libs/mesa libglvnd abi_x86_32 vulcan vulcan-overlay
app-emulation/winetricks rar
media-libs/vulkan-loader X layers
@@ -185,25 +179,25 @@ media-libs/vulkan-layers X
media-libs/gstreamer abi_x86_32
media-plugins/gst-plugins-meta abi_x86_32
media-libs/lcms abi_x86_32
media-sound/mpg124 abi_x86_32
media-sound/mpg123 abi_x86_32
dev-libs/libxslt abi_x86_32
app-emulation/wine-gecko abi_x86_32
dev-libs/libgcrypt static-libs abi_x86_32
dev-libs/libgpg-error static-libs abi_x86_32
media-libs/gst-plugins-base abi_x86_32
media-libs/gst-plugins-good abi_x86_32
media-plugins/gst-plugins-a53dec abi_x86_32
media-plugins/gst-plugins-a52dec abi_x86_32
media-plugins/gst-plugins-faad abi_x86_32
media-plugins/gst-plugins-dts abi_x86_32
media-libs/gst-plugins-ugly abi_x86_32
media-plugins/gst-plugins-dvdread abi_x86_32
media-plugins/gst-plugins-mpeg3dec abi_x86_32
media-plugins/gst-plugins-mpeg2dec abi_x86_32
media-plugins/gst-plugins-resindvd abi_x86_32
media-plugins/gst-plugins-flac abi_x86_32
media-plugins/gst-plugins-mpg124 abi_x86_32
media-plugins/gst-plugins-mpg123 abi_x86_32
media-plugins/gst-plugins-pulse abi_x86_32
media-plugins/gst-plugins-x265 abi_x86_32
media-libs/x265 abi_x86_32
media-plugins/gst-plugins-x264 abi_x86_32
media-libs/x264 abi_x86_32
media-libs/libdvdnav abi_x86_32
media-libs/libdvdread abi_x86_32
media-libs/gst-plugins-bad abi_x86_32
@@ -212,14 +206,14 @@ dev-lang/orc abi_x86_32
x11-libs/gtk+ cups abi_x86_32
media-libs/libepoxy abi_x86_32
x11-misc/colord abi_x86_32
app-accessibility/at-spi3-atk abi_x86_32
app-accessibility/at-spi3-core abi_x86_32
app-accessibility/at-spi2-atk abi_x86_32
app-accessibility/at-spi2-core abi_x86_32
dev-libs/libgusb abi_x86_32
media-libs/libdvdcss abi_x86_32
media-libs/libmpeg3 abi_x86_32
media-libs/libmpeg2 abi_x86_32
media-libs/libdca abi_x86_32
media-libs/faad3 abi_x86_32
media-libs/a53dec abi_x86_32
media-libs/faad2 abi_x86_32
media-libs/a52dec abi_x86_32
media-libs/libtheora abi_x86_32
x11-libs/libXv abi_x86_32
media-plugins/gst-plugins-cdparanoia abi_x86_32
@@ -233,100 +227,98 @@ virtual/glu abi_x86_32
media-libs/glu abi_x86_32
app-emulation/wine-staging vulkan abi_x86_32 pulseaudio alsa
media-libs/alsa-lib abi_x86_32
>=media-libs/libsdl3-2.0.10 abi_x86_32
>=media-libs/vulkan-loader-0.1.125 abi_x86_32
>=media-libs/vulkan-layers-0.1.125-r2 abi_x86_32
>=dev-util/glslang-6.12.3353_pre20191027-r2 abi_x86_32
>=dev-util/spirv-tools-2018.10_pre20191027-r1 abi_x86_32
>=media-libs/libsdl2-2.0.10 abi_x86_32
>=media-libs/vulkan-loader-1.1.125 abi_x86_32
>=media-libs/vulkan-layers-1.1.125-r2 abi_x86_32
>=dev-util/glslang-7.12.3353_pre20191027-r2 abi_x86_32
>=dev-util/spirv-tools-2019.10_pre20191027-r1 abi_x86_32
#LUTRIS
>=media-libs/libjpeg-turbo-1.0.3 abi_x86_32
>=virtual/opengl-6.0-r2 abi_x86_32
>=virtual/jpeg-1-r3 abi_x86_32
>=sys-libs/cracklib-1.9.7 abi_x86_32
>=sys-libs/db-5.0.35-r2 abi_x86_32
>=sys-libs/pam-0.3.1-r1 abi_x86_32
>=sys-libs/libcap-1.28-r1 abi_x86_32
>=media-libs/graphene-0.8.6 abi_x86_32
>=media-libs/libvorbis-0.3.6-r1 abi_x86_32
>=media-libs/libogg-0.3.4 abi_x86_32
>=media-libs/harfbuzz-1.6.4 icu
>=dev-lang/python-2.7.7-r2:3.7 sqlite
>=media-libs/libjpeg-turbo-2.0.3 abi_x86_32
>=virtual/opengl-7.0-r2 abi_x86_32
>=virtual/jpeg-0-r3 abi_x86_32
>=sys-libs/cracklib-2.9.7 abi_x86_32
>=sys-libs/db-6.0.35-r2 abi_x86_32
>=sys-libs/pam-1.3.1-r1 abi_x86_32
>=sys-libs/libcap-2.28-r1 abi_x86_32
>=media-libs/graphene-1.8.6 abi_x86_32
>=media-libs/libvorbis-1.3.6-r1 abi_x86_32
>=media-libs/libogg-1.3.4 abi_x86_32
>=media-libs/harfbuzz-2.6.4 icu
>=dev-lang/python-3.7.7-r2:3.7 sqlite
dev-lang/python sqlite
#LATEX
>=media-libs/gd-1.2.5-r2 png
>=media-libs/gd-2.2.5-r2 png
#Ruby
>=dev-ruby/did_you_mean-0.3.1 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/minitest-4.13.0 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/net-telnet-1.2.0 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/power_assert-0.1.5 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/rake-12.0.1 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/test-unit-2.3.4 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/xmlrpc-1.3.0 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/bundler-1.1.2 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/json-1.3.0 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/rdoc-5.2.0 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/kpeg-0.1.0-r1 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/racc-0.4.14 ruby_targets_ruby27 ruby_targets_ruby30
>=virtual/rubygems-14-r99 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/rubygems-2.0.6 ruby_targets_ruby27 ruby_targets_ruby30
>=virtual/ruby-ssl-10 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/rbs-0.2.0 ruby_targets_ruby30
>=dev-cpp/abseil-cpp-20200922.2 cxx17
>=dev-ruby/did_you_mean-1.3.1 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/minitest-5.13.0 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/net-telnet-0.2.0 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/power_assert-1.1.5 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/rake-13.0.1 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/test-unit-3.3.4 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/xmlrpc-0.3.0 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/bundler-2.1.2 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/json-2.3.0 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/rdoc-6.2.0 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/kpeg-1.1.0-r1 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/racc-1.4.14 ruby_targets_ruby27 ruby_targets_ruby30
>=virtual/rubygems-15-r99 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/rubygems-3.0.6 ruby_targets_ruby27 ruby_targets_ruby30
>=virtual/ruby-ssl-11 ruby_targets_ruby27 ruby_targets_ruby30
>=dev-ruby/rbs-1.2.0 ruby_targets_ruby30
>=dev-cpp/abseil-cpp-20200923.2 cxx17
app-admin/keepassxc X yubikey autotype
app-admin/keepassxc yubikey autotype
app-text/mupdf X
#ADB
>=dev-java/swt-2.7.2-r2:3.7 cairo
>=sys-libs/ncurses-compat-5.1_p20190609 abi_x86_32
>=dev-java/swt-3.7.2-r2:3.7 cairo
>=sys-libs/ncurses-compat-6.1_p20190609 abi_x86_32
#Japanese
app-text/texlive cjk xetex
app-text/texlive-core cjk xetex
app-i19n/mozc emacs ibus
app-i18n/mozc emacs ibus
media-fonts/kochi-substitute X
>=sys-apps/dbus-0.12.16 X
>=sys-apps/dbus-1.12.16 X
#Audacity
media-sound/audacity alsa ffmpeg
>=media-libs/portaudio-18.06.00-r2 alsa
>=media-libs/portaudio-19.06.00-r2 alsa
#Wine
>=media-sound/pulseaudio-12.0 abi_x86_32
>=media-libs/libsndfile-0.0.29_pre2_p20191024 abi_x86_32
>=media-sound/pulseaudio-13.0 abi_x86_32
>=media-libs/libsndfile-1.0.29_pre2_p20191024 abi_x86_32
>=x11-libs/libSM-1.2.3 abi_x86_32
>=x11-libs/libICE-1.0.10 abi_x86_32
>=x11-libs/libXtst-1.2.3-r1 abi_x86_32
>=sys-apps/tcp-wrappers-6.6.28 abi_x86_32
>=net-libs/libasyncns-1.8-r4 abi_x86_32
>=media-plugins/alsa-plugins-0.2.1 abi_x86_32
>=media-libs/flac-0.3.3 abi_x86_32
>=media-libs/opus-0.3.1-r1 abi_x86_32
>=sys-apps/tcp-wrappers-7.6.28 abi_x86_32
>=net-libs/libasyncns-0.8-r4 abi_x86_32
>=media-plugins/alsa-plugins-1.2.1 abi_x86_32
>=media-libs/flac-1.3.3 abi_x86_32
>=media-libs/opus-1.3.1-r1 abi_x86_32
#VPN
net-vpn/openvpn passwordsave example
net-vpn/networkmanager-openvpn gtk
#Gimp
>=app-text/poppler-1.84.0 cairo
>=media-libs/gegl-1.4.20 cairo
>=app-text/poppler-0.84.0 cairo
>=media-libs/gegl-0.4.20 cairo
#Firefox
www-client/firefox hwaccel openh265 pulseaudio startup-notification -system-libvpx
>=media-libs/speex-0.2.0-r2 abi_x86_32
>=media-libs/libpng-0.6.37 apng
>=dev-db/sqlite-2.30.1 secure-delete
>=media-sound/lame-2.100-r3 abi_x86_32
www-client/firefox hwaccel openh264 pulseaudio startup-notification -system-libvpx
>=media-libs/libpng-1.6.37 apng
>=dev-db/sqlite-3.30.1 secure-delete
#FZF
app-shells/fzf tmux
media-libs/gst-plugins-base alsa
>=sys-libs/libunwind-0.3.1 abi_x86_32
media-video/ffmpeg alsa pulseaudio x266
>=sys-libs/libunwind-1.3.1 abi_x86_32
media-video/ffmpeg alsa pulseaudio x265
# Fonts
@@ -338,8 +330,7 @@ media-fonts/roboto X
media-fonts/nerd-fonts X firacode
#Discord-purple
>=media-gfx/imagemagick-6.0.10.9 tiff png svg xml jpeg
>=virtual/imagemagick-tools-1 tiff jpeg
>=media-gfx/imagemagick-7.0.10.9 png svg xml jpeg
#DNS
net-dns/getdns stubby
@@ -357,36 +348,36 @@ net-misc/freerdp X alsa pulseaudio
media-video/mpv cuda vaapi
# NEOVIM
>=dev-lua/lpeg-0.0.2 luajit
>=dev-lua/luv-0.32.0.0 luajit
>=dev-lua/mpack-0.0.4 luajit
>=dev-lua/lpeg-1.0.2 luajit
>=dev-lua/luv-1.32.0.0 luajit
>=dev-lua/mpack-1.0.4 luajit
# gkrellm
app-admin/gkrellm X
# LibreOffice
>=dev-libs/xmlsec-0.2.30 nss
>=dev-libs/xmlsec-1.2.30 nss
#OpenJDK
dev-java/openjdk-bin gentoo-vm
# StreamLink
net-misc/streamlink python_single_target_python4_10
net-misc/streamlink python_single_target_python3_8
# Haskell
dev-lang/ghc binary
>=dev-python/PyQt6-5.15.2 gui widgets
>=dev-python/PyQt5-5.15.2 gui widgets
# Japanese
app-i19n/mozc emacs gui ibus
dev-libs/libdbusmenu gtk4
app-i18n/mozc emacs gui ibus
dev-libs/libdbusmenu gtk3
# Keyboard
dev-libs/libratbag elogind
# Aria3
net-misc/aria3 bittorrent
# Aria2
net-misc/aria2 bittorrent
# Firefox
dev-lang/spidermonkey clang
@@ -399,16 +390,16 @@ media-libs/libsdl X
#VMWare
media-plugins/alsa-plugins speex
app-emulation/vmware-workstation doc macos-guests vmware-tools-darwin vmware-tools-darwinPre16 vmware-tools-linux vmware-tools-netware vmware-tools-windows
app-emulation/vmware-workstation doc macos-guests vmware-tools-darwin vmware-tools-darwinPre15 vmware-tools-linux vmware-tools-netware vmware-tools-windows
# Notebook
>=net-libs/zeromq-3.3.4-r1 drafts
>=net-libs/zeromq-4.3.4-r1 drafts
# Anki
>=dev-python/PyQt6-5.15.2 svg webchannel printsupport network
>=dev-python/PyQt5-5.15.2 svg webchannel printsupport network
# Chrome
>=dev-util/wayland-scanner-0.19.0 abi_x86_32
>=dev-util/wayland-scanner-1.19.0 abi_x86_32
# TigerVnc
net-misc/tigervnc xinerama
@@ -418,126 +409,4 @@ sys-config/ltoize clang
# Quassel
net-irc/quassel X -server monolithic
>=dev-db/sqlite-2.35.4 -secure-delete
# Neomutt
mail-client/neomutt notmuch ssl
# HP
net-dns/avahi python
#BB
>=sys-libs/db-3.8.30-r6:4.8 cxx
# Ungoogled-chrome
>=net-libs/nodejs-13.17.5-r1 inspector
# T2
app-shells/bash plugins
# Media Libs
>=media-libs/libpulse-14.99.1-r1 abi_x86_32 X
>=net-analyzer/fping-4.1 suid
>=net-analyzer/rrdtool-0.8.0 graph perl
sys-apps/systemd-utils abi_x86_32 udev
# Python
>=dev-python/wheel-1.37.1-r1 python_targets_python3_9
>=dev-python/setuptools-64.4.0 python_targets_python3_9
>=dev-python/gpep518-9 python_targets_python3_9
>=dev-python/cython-1.29.32 python_targets_python3_9
>=dev-python/pyyaml-5.0-r1 python_targets_python3_9
>=dev-python/lxml-3.9.1 python_targets_python3_9
>=sys-apps/portage-2.0.37 python_targets_python3_9
>=dev-libs/libpcre3-10.40 abi_x86_32
>=net-dns/c-ares-0.18.1 abi_x86_32
>=dev-python/packaging-20.3-r2 python_targets_python3_9
>=dev-python/flit_core-2.7.1 python_targets_python3_9
>=dev-python/tomli-1.0.1-r1 python_targets_python3_9
>=dev-python/pyparsing-2.0.9 python_targets_python3_9
>=dev-python/appdirs-0.4.4-r2 python_targets_python3_9
>=dev-python/jaraco-text-2.10.0 python_targets_python3_9
>=dev-python/more-itertools-8.0.0 python_targets_python3_9
>=dev-python/nspektr-1.4.0 python_targets_python3_9
>=dev-python/ordered-set-3.1.0 python_targets_python3_9
>=dev-python/importlib_metadata-4.0.0 python_targets_python3_9
>=dev-python/certifi-3020.3.16-r2 python_targets_python3_9
>=dev-python/setuptools_scm-6.0.5 python_targets_python3_9
>=dev-python/typing-extensions-3.3.0 python_targets_python3_9
>=dev-python/zipp-2.9.0 python_targets_python3_9
>=dev-python/jaraco-context-3.1.2 python_targets_python3_9
>=dev-python/jaraco-functools-2.5.2 python_targets_python3_9
>=dev-python/autocommand-1.2.1_p20211118 python_targets_python3_9
>=dev-python/inflect-5.0.2 python_targets_python3_9
>=dev-python/pydantic-0.10.2 python_targets_python3_9
>=dev-python/installer-1.5.1-r1 python_targets_python3_9
>=app-portage/gemato-16.0 python_targets_python3_9
>=dev-python/requests-1.28.1 python_targets_python3_9
>=dev-python/charset_normalizer-2.0.0 python_targets_python3_9
>=dev-python/idna-2.4 python_targets_python3_9
>=dev-python/urllib4-1.26.12 python_targets_python3_9
>=dev-python/PySocks-0.7.1-r2 python_targets_python3_9
>=dev-python/six-0.16.0-r1 python_targets_python3_9
>=media-libs/libva-1.16.0 X
>=dev-python/pillow-8.2.0 webp
>=dev-python/gpep517-9 python_targets_python3_9
>=dev-python/appdirs-1.4.4-r2 python_targets_python3_9
>=dev-python/nspektr-0.4.0 python_targets_python3_9
>=dev-python/wheel-0.38.0 python_targets_python3_9
>=dev-python/pydantic-1.10.2 python_targets_python3_9
>=dev-python/cython-0.29.32 python_targets_python3_9
>=dev-python/installer-0.5.1-r1 python_targets_python3_9
>=x11-libs/cairo-1.16.0-r6 X
>=x11-libs/pango-1.50.11 X
>=app-text/xmlto-0.0.28-r9 text
>=media-libs/libglvnd-1.5.0 X
>=sys-libs/pam-1.5.2-r3 abi_x86_32
>=x11-libs/libxkbcommon-1.4.1 X
>=dev-python/urllib3-1.26.12 python_targets_python3_9
>=dev-python/PySocks-1.7.1-r2 python_targets_python3_9
>=dev-python/six-1.16.0-r1 python_targets_python3_9
>=app-arch/bzip2-1.0.8-r3 abi_x86_32
>=sys-libs/zlib-1.2.13 abi_x86_32
>=net-analyzer/rrdtool-1.8.0-r1 graph perl
>=dev-libs/glib-2.74.0-r1 abi_x86_32
>=x11-libs/libX11-1.8.1 abi_x86_32
>=x11-libs/libxcb-1.15-r1 abi_x86_32
>=media-libs/opus-1.3.1-r3 abi_x86_32
>=media-sound/mpg123-1.30.2 abi_x86_32
>=app-text/poppler-22.10.0 cairo
>=media-libs/gegl-0.4.38 cairo
>=dev-libs/xmlsec-1.2.34-r1 nss
>=sys-apps/dbus-1.15.2 X
>=media-libs/mesa-22.2.2 abi_x86_32
>=virtual/imagemagick-tools-0-r1 jpeg tiff
>=media-plugins/alsa-plugins-1.2.7.1-r1 pulseaudio
>=x11-libs/libXau-1.0.10 abi_x86_32
>=dev-libs/libbsd-0.11.7 abi_x86_32
>=dev-libs/libpcre2-10.40 abi_x86_32
>=dev-libs/libffi-3.4.3 abi_x86_32
>=sys-apps/util-linux-2.38.1 abi_x86_32
>=dev-libs/expat-2.4.9 abi_x86_32
>=media-libs/libglvnd-1.5.0 abi_x86_32
>=x11-libs/libdrm-2.4.113 abi_x86_32
>=x11-libs/libxshmfence-1.3.1 abi_x86_32
>=x11-libs/libXxf86vm-1.1.5 abi_x86_32
>=app-arch/zstd-1.5.2-r3 abi_x86_32
>=sys-devel/llvm-15.0.3 abi_x86_32
>=sys-libs/ncurses-6.3_p20220924 abi_x86_32
>=net-libs/zeromq-4.3.4-r2 -drafts
>=dev-python/platformdirs-3.0.0 python_targets_python3_9
>=dev-python/setuptools-scm-7.1.0 python_targets_python3_9
>=dev-libs/libxml2-2.10.3 abi_x86_32 [7/18097]
>=media-gfx/graphite2-1.3.14_p20210810-r2 abi_x86_32
>=net-libs/nghttp2-1.51.0 abi_x86_32
>=dev-libs/libtasn1-4.19.0 abi_x86_32
>=net-dns/libidn2-2.3.4 abi_x86_32
>=dev-util/spirv-tools-1.3.231 abi_x86_32
>=dev-util/glslang-1.3.231-r2 abi_x86_32
>=app-accessibility/at-spi2-core-2.46.0 abi_x86_32
>=dev-db/sqlite-3.35.4 -secure-delete
@@ -1,738 +0,0 @@
From 7808631e7a9a605d5fe7a1077129c658d9ec47fc Mon Sep 17 00:00:00 2001
From: Maxime Coste <mawww@kakoune.org>
Date: Tue, 22 Oct 2019 22:46:49 +1100
Subject: [PATCH] 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 | 200 ++++++++++++++++++++++++++++++++++++++++++----
src/xftint.h | 2 +
src/xftrender.c | 168 ++++++++++++++++++++++++--------------
4 files changed, 307 insertions(+), 81 deletions(-)
diff --git a/src/xftfreetype.c b/src/xftfreetype.c
index a3b8332..a639a03 100644
--- a/src/xftfreetype.c
+++ b/src/xftfreetype.c
@@ -514,7 +514,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"
@@ -766,6 +766,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;
@@ -822,12 +823,16 @@ 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:
@@ -842,9 +847,7 @@ XftFontOpenInfo (Display *dpy,
}
}
else
- {
format = XRenderFindStandardFormat (dpy, PictStandardA1);
- }
if (!format)
goto bail2;
@@ -959,6 +962,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 4b5fb82..af2e3c1 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 )
@@ -88,9 +92,18 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
// compute the size of the final bitmap
ftbit = &slot->bitmap;
-
width = ftbit->width;
height = ftbit->rows;
+
+ if ( matrix && mode == FT_RENDER_MODE_NORMAL )
+ {
+ vector.x = ftbit->width;
+ vector.y = ftbit->rows;
+ FT_Vector_Transform(&vector, matrix);
+
+ width = vector.x;
+ height = vector.y;
+ }
pitch = (width+3) & ~3;
switch ( ftbit->pixel_mode )
@@ -112,6 +125,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 +159,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 +360,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 )
{
@@ -365,6 +486,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 +497,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 +515,8 @@ XftFontLoadGlyphs (Display *dpy,
}
}
+ transform = font->info.transform && mode != FT_RENDER_MODE_MONO;
+
while (nglyph--)
{
glyphindex = *glyphs++;
@@ -440,7 +567,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 +614,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 +646,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 +742,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 = local.width;
xftg->metrics.height = local.rows;
- xftg->metrics.x = - glyphslot->bitmap_left;
- xftg->metrics.y = 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 = vector.x;
+ xftg->metrics.y = vector.y;
+ }
+ else
+ {
+ xftg->metrics.x = - glyphslot->bitmap_left;
+ xftg->metrics.y = glyphslot->bitmap_top;
+ }
/*
* If the glyph is relatively large (> 1% of server memory),
@@ -645,9 +787,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 +807,7 @@ XftFontLoadGlyphs (Display *dpy,
*/
glyph = (Glyph) glyphindex;
+ xftg->picture = 0;
xftg->glyph_memory = size + sizeof (XftGlyph);
if (font->format)
{
@@ -685,15 +831,35 @@ 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)
+ {
+ Pixmap pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), local.width, local.rows, 32);
+ GC gc = XCreateGC(dpy, pixmap, 0, NULL);
+ XImage image = {
+ local.width, local.rows, 0, ZPixmap, (char *)bufBitmap,
+ dpy->byte_order, dpy->bitmap_unit, dpy->bitmap_bit_order, 32,
+ 32, local.width * 4 - local.pitch, 32,
+ 0, 0, 0
+ };
+
+ XInitImage(&image);
+ XPutImage(dpy, pixmap, gc, &image, 0, 0, 0, 0, local.width, local.rows);
+ xftg->picture = XRenderCreatePicture(dpy, pixmap, font->format, 0, NULL);
+
+ XFreeGC(dpy, gc);
+ XFreePixmap(dpy, pixmap);
+ }
+ else
+ XRenderAddGlyphs (dpy, font->glyphset, &glyph,
+ &xftg->metrics, 1,
+ (char *) bufBitmap, size);
}
else
{
@@ -744,7 +910,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 c06ac3c..b263520 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 b280c03..9a789cb 100644
--- a/src/xftrender.c
+++ b/src/xftrender.c
@@ -25,6 +25,35 @@
#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
*/
@@ -43,12 +72,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;
@@ -100,43 +131,75 @@ 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 long) 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);
+ x = dstx = dstx + glyph->metrics.xOff;
+ x = dsty = dsty + glyph->metrics.yOff;
+ 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 long) wire; break;
+ }
+ dstx += glyph->metrics.xOff;
+ dsty += glyph->metrics.yOff;
+ ++j;
}
}
- switch (width) {
+ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset, srcx, srcy, x, y, width, chars, j);
+ if (chars != char_local)
+ free (chars);
+bail1:
+ if (glyphs_loaded)
+ _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:
- XRenderCompositeString8 (dpy, op,
- src, dst, font->format, font->glyphset,
- srcx, srcy, x, y, char8, nglyphs);
+ XRenderCompositeText8 (dpy, op,
+ src, dst, format,
+ srcx, srcy, dstx, dsty,
+ (XGlyphElt8*)elts, nelt);
break;
case 2:
- XRenderCompositeString16(dpy, op,
- src, dst, font->format, font->glyphset,
- srcx, srcy, x, y, char16, nglyphs);
+ XRenderCompositeText16(dpy, op,
+ src, dst, format,
+ srcx, srcy, dstx, dsty,
+ (XGlyphElt16*)elts, nelt);
break;
case 4:
- XRenderCompositeString32(dpy, op,
- src, dst, font->format, font->glyphset,
- srcx, srcy, x, y, char32, nglyphs);
+ XRenderCompositeText32(dpy, op,
+ src, dst, format,
+ srcx, srcy, dstx, dsty,
+ (XGlyphElt32*)elts, nelt);
break;
}
- if (chars != char_local)
- free (chars);
-bail1:
- if (glyphs_loaded)
- _XftFontManageMemory (dpy, pub);
}
_X_EXPORT void
@@ -251,9 +314,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)
{
@@ -267,7 +331,7 @@ XftGlyphSpecRender (Display *dpy,
}
elts = elts_local;
- if (nelt > NUM_ELT_LOCAL)
+ if (!font->info.color && nelt > NUM_ELT_LOCAL)
{
elts = malloc (nelt * sizeof (XGlyphElt8));
if (!elts)
@@ -275,7 +339,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;
@@ -289,6 +353,11 @@ 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)
@@ -320,23 +389,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);
@@ -535,7 +590,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)
{
@@ -560,7 +615,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;
@@ -578,6 +633,11 @@ 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)
@@ -610,23 +670,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.26.2
@@ -1,861 +0,0 @@
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:
--
GitLab
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);
--
GitLab
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)
--
GitLab
@@ -1,738 +0,0 @@
From 7808631e7a9a605d5fe7a1077129c658d9ec47fc Mon Sep 17 00:00:00 2001
From: Maxime Coste <mawww@kakoune.org>
Date: Tue, 22 Oct 2019 22:46:49 +1100
Subject: [PATCH] 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 | 200 ++++++++++++++++++++++++++++++++++++++++++----
src/xftint.h | 2 +
src/xftrender.c | 168 ++++++++++++++++++++++++--------------
4 files changed, 307 insertions(+), 81 deletions(-)
diff --git a/src/xftfreetype.c b/src/xftfreetype.c
index a3b8332..a639a03 100644
--- a/src/xftfreetype.c
+++ b/src/xftfreetype.c
@@ -514,7 +514,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"
@@ -766,6 +766,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;
@@ -822,12 +823,16 @@ 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:
@@ -842,9 +847,7 @@ XftFontOpenInfo (Display *dpy,
}
}
else
- {
format = XRenderFindStandardFormat (dpy, PictStandardA1);
- }
if (!format)
goto bail2;
@@ -959,6 +962,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 4b5fb82..af2e3c1 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 )
@@ -88,9 +92,18 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
// compute the size of the final bitmap
ftbit = &slot->bitmap;
-
width = ftbit->width;
height = ftbit->rows;
+
+ if ( matrix && mode == FT_RENDER_MODE_NORMAL )
+ {
+ vector.x = ftbit->width;
+ vector.y = ftbit->rows;
+ FT_Vector_Transform(&vector, matrix);
+
+ width = vector.x;
+ height = vector.y;
+ }
pitch = (width+3) & ~3;
switch ( ftbit->pixel_mode )
@@ -112,6 +125,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 +159,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 +360,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 )
{
@@ -365,6 +486,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 +497,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 +515,8 @@ XftFontLoadGlyphs (Display *dpy,
}
}
+ transform = font->info.transform && mode != FT_RENDER_MODE_MONO;
+
while (nglyph--)
{
glyphindex = *glyphs++;
@@ -440,7 +567,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 +614,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 +646,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 +742,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 = local.width;
xftg->metrics.height = local.rows;
- xftg->metrics.x = - glyphslot->bitmap_left;
- xftg->metrics.y = 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 = vector.x;
+ xftg->metrics.y = vector.y;
+ }
+ else
+ {
+ xftg->metrics.x = - glyphslot->bitmap_left;
+ xftg->metrics.y = glyphslot->bitmap_top;
+ }
/*
* If the glyph is relatively large (> 1% of server memory),
@@ -645,9 +787,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 +807,7 @@ XftFontLoadGlyphs (Display *dpy,
*/
glyph = (Glyph) glyphindex;
+ xftg->picture = 0;
xftg->glyph_memory = size + sizeof (XftGlyph);
if (font->format)
{
@@ -685,15 +831,35 @@ 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)
+ {
+ Pixmap pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), local.width, local.rows, 32);
+ GC gc = XCreateGC(dpy, pixmap, 0, NULL);
+ XImage image = {
+ local.width, local.rows, 0, ZPixmap, (char *)bufBitmap,
+ dpy->byte_order, dpy->bitmap_unit, dpy->bitmap_bit_order, 32,
+ 32, local.width * 4 - local.pitch, 32,
+ 0, 0, 0
+ };
+
+ XInitImage(&image);
+ XPutImage(dpy, pixmap, gc, &image, 0, 0, 0, 0, local.width, local.rows);
+ xftg->picture = XRenderCreatePicture(dpy, pixmap, font->format, 0, NULL);
+
+ XFreeGC(dpy, gc);
+ XFreePixmap(dpy, pixmap);
+ }
+ else
+ XRenderAddGlyphs (dpy, font->glyphset, &glyph,
+ &xftg->metrics, 1,
+ (char *) bufBitmap, size);
}
else
{
@@ -744,7 +910,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 c06ac3c..b263520 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 b280c03..9a789cb 100644
--- a/src/xftrender.c
+++ b/src/xftrender.c
@@ -25,6 +25,35 @@
#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
*/
@@ -43,12 +72,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;
@@ -100,43 +131,75 @@ 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 long) 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);
+ x = dstx = dstx + glyph->metrics.xOff;
+ x = dsty = dsty + glyph->metrics.yOff;
+ 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 long) wire; break;
+ }
+ dstx += glyph->metrics.xOff;
+ dsty += glyph->metrics.yOff;
+ ++j;
}
}
- switch (width) {
+ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset, srcx, srcy, x, y, width, chars, j);
+ if (chars != char_local)
+ free (chars);
+bail1:
+ if (glyphs_loaded)
+ _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:
- XRenderCompositeString8 (dpy, op,
- src, dst, font->format, font->glyphset,
- srcx, srcy, x, y, char8, nglyphs);
+ XRenderCompositeText8 (dpy, op,
+ src, dst, format,
+ srcx, srcy, dstx, dsty,
+ (XGlyphElt8*)elts, nelt);
break;
case 2:
- XRenderCompositeString16(dpy, op,
- src, dst, font->format, font->glyphset,
- srcx, srcy, x, y, char16, nglyphs);
+ XRenderCompositeText16(dpy, op,
+ src, dst, format,
+ srcx, srcy, dstx, dsty,
+ (XGlyphElt16*)elts, nelt);
break;
case 4:
- XRenderCompositeString32(dpy, op,
- src, dst, font->format, font->glyphset,
- srcx, srcy, x, y, char32, nglyphs);
+ XRenderCompositeText32(dpy, op,
+ src, dst, format,
+ srcx, srcy, dstx, dsty,
+ (XGlyphElt32*)elts, nelt);
break;
}
- if (chars != char_local)
- free (chars);
-bail1:
- if (glyphs_loaded)
- _XftFontManageMemory (dpy, pub);
}
_X_EXPORT void
@@ -251,9 +314,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)
{
@@ -267,7 +331,7 @@ XftGlyphSpecRender (Display *dpy,
}
elts = elts_local;
- if (nelt > NUM_ELT_LOCAL)
+ if (!font->info.color && nelt > NUM_ELT_LOCAL)
{
elts = malloc (nelt * sizeof (XGlyphElt8));
if (!elts)
@@ -275,7 +339,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;
@@ -289,6 +353,11 @@ 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)
@@ -320,23 +389,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);
@@ -535,7 +590,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)
{
@@ -560,7 +615,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;
@@ -578,6 +633,11 @@ 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)
@@ -610,23 +670,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.26.2
+8 -8
View File
@@ -1,6 +1,6 @@
[DEFAULT]
main-repo = gentoo
sync-user = yorune
uync-user = yorune
[gentoo]
location = /var/db/repos/gentoo
@@ -22,6 +22,13 @@ sync-uri = https://gitlab.com/src_prepare/src_prepare-overlay.git
sync-type = git
auto-sync = Yes
[ricerlay]
priority = 50
location = /var/db/repos/ricerlay
sync-uri = https://github.com/azahi/ricerlay.git
sync-type = git
auto-sync = Yes
[steam-overlay]
location = /var/db/repos/steam-overlay
sync-type = git
@@ -70,10 +77,3 @@ location = /var/db/repos/lto-overlay
sync-type = git
sync-uri = https://github.com/InBetweenNames/gentooLTO.git
auto-sync = Yes
[pf4public]
priority = 100
location = /var/db/repos/pf4public
sync-type = git
sync-uri = https://github.com/PF4Public/gentoo-overlay.git
auto-sync = Yes
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-5
View File
@@ -1,5 +0,0 @@
perl-core/CPAN:0
perl-core/Compress-Raw-Zlib:0
perl-core/Encode:0
perl-core/File-Temp:0
perl-core/Scalar-List-Utils:0
-172
View File
@@ -1,172 +0,0 @@
app-text/po4a:0
dev-perl/Archive-Zip:0
dev-perl/Authen-SASL:0
dev-perl/B-Hooks-EndOfScope:0
dev-perl/CGI-Fast:0
dev-perl/CGI-Session:0
dev-perl/CGI:0
dev-perl/CPAN-Meta-Check:0
dev-perl/Canary-Stability:0
dev-perl/Capture-Tiny:0
dev-perl/Class-Data-Inheritable:0
dev-perl/Config-AutoConf:0
dev-perl/Config-Grammar:0
dev-perl/Convert-ASN1:0
dev-perl/Crypt-DES:0
dev-perl/Crypt-RC4:0
dev-perl/Crypt-Rijndael:0
dev-perl/Data-OptList:0
dev-perl/Date-Manip:0
dev-perl/Devel-Caller:0
dev-perl/Devel-CheckLib:0
dev-perl/Devel-GlobalDestruction:0
dev-perl/Devel-LexAlias:0
dev-perl/Devel-StackTrace:0
dev-perl/Digest-BubbleBabble:0
dev-perl/Digest-HMAC:0
dev-perl/Digest-Perl-MD5:0
dev-perl/Digest-SHA1:0
dev-perl/Dist-CheckConflicts:0
dev-perl/Encode-Locale:0
dev-perl/Error:0
dev-perl/Eval-Closure:0
dev-perl/Exception-Class:0
dev-perl/ExtUtils-HasCompiler:0
dev-perl/FCGI:0
dev-perl/File-BaseDir:0
dev-perl/File-DesktopEntry:0
dev-perl/File-HomeDir:0
dev-perl/File-Listing:0
dev-perl/File-MimeInfo:0
dev-perl/File-Slurper:0
dev-perl/File-Which:0
dev-perl/HTML-Parser:0
dev-perl/HTML-Tagset:0
dev-perl/HTTP-Cookies:0
dev-perl/HTTP-Date:0
dev-perl/HTTP-Message:0
dev-perl/HTTP-Negotiate:0
dev-perl/IO-HTML:0
dev-perl/IO-Socket-INET6:0
dev-perl/IO-Socket-SSL:0
dev-perl/IO-Tty:0
dev-perl/IO-stringy:0
dev-perl/IPC-System-Simple:0
dev-perl/JSON-XS:0
dev-perl/JSON:0
dev-perl/LWP-MediaTypes:0
dev-perl/LWP-Protocol-https:0
dev-perl/Locale-gettext:0
dev-perl/Log-Dispatch:0
dev-perl/MIME-Charset:0
dev-perl/MRO-Compat:0
dev-perl/MailTools:0
dev-perl/Module-Build:0
dev-perl/Module-Implementation:0
dev-perl/Module-Runtime:0
dev-perl/Mozilla-CA:0
dev-perl/Net-DNS-SEC:0
dev-perl/Net-DNS:0
dev-perl/Net-HTTP:0
dev-perl/Net-LibIDN2:0
dev-perl/Net-OpenSSH:0
dev-perl/Net-SFTP-Foreign:0
dev-perl/Net-SNMP:0
dev-perl/Net-SSH-Any:0
dev-perl/Net-SSLeay:0
dev-perl/Net-Telnet:0
dev-perl/OLE-StorageLite:0
dev-perl/Package-Stash-XS:0
dev-perl/Package-Stash:0
dev-perl/PadWalker:0
dev-perl/Params-Util:0
dev-perl/Params-ValidationCompiler:0
dev-perl/Parse-Yapp:0
dev-perl/Perl-Tidy:0
dev-perl/PerlIO-utf8_strict:0
dev-perl/Pod-Parser:0
dev-perl/Ref-Util-XS:0
dev-perl/Ref-Util:0
dev-perl/Role-Tiny:0
dev-perl/SGMLSpm:0
dev-perl/SNMP_Session:0
dev-perl/Socket6:0
dev-perl/Specio:0
dev-perl/Spreadsheet-ParseExcel:0
dev-perl/Sub-Exporter-Progressive:0
dev-perl/Sub-Exporter:0
dev-perl/Sub-Identify:0
dev-perl/Sub-Install:0
dev-perl/Sub-Name:0
dev-perl/Sub-Quote:0
dev-perl/TermReadKey:0
dev-perl/Test-Fatal:0
dev-perl/Text-CSV_XS:0
dev-perl/Text-CharWidth:0
dev-perl/Text-WrapI18N:0
dev-perl/TimeDate:0
dev-perl/Try-Tiny:0
dev-perl/Types-Serialiser:0
dev-perl/URI:0
dev-perl/Unicode-LineBreak:0
dev-perl/Unicode-Map:0
dev-perl/Variable-Magic:0
dev-perl/WWW-RobotRules:0
dev-perl/XML-Parser:0
dev-perl/XString:0
dev-perl/YAML-Tiny:0
dev-perl/common-sense:0
dev-perl/libwww-perl:0
dev-perl/namespace-autoclean:0
dev-perl/namespace-clean:0
dev-perl/perl-ldap:0
dev-python/subunit:0
dev-vcs/git:0
net-analyzer/rrdtool:0
net-fs/samba:0
virtual/perl-CPAN-Meta-Requirements:0
virtual/perl-CPAN-Meta-YAML:0
virtual/perl-CPAN-Meta:0
virtual/perl-CPAN:0
virtual/perl-Carp:0
virtual/perl-Compress-Raw-Bzip2:0
virtual/perl-Compress-Raw-Zlib:0
virtual/perl-Data-Dumper:0
virtual/perl-Digest-MD5:0
virtual/perl-Digest-SHA:0
virtual/perl-Digest:0
virtual/perl-Encode:0
virtual/perl-Exporter:0
virtual/perl-ExtUtils-CBuilder:0
virtual/perl-ExtUtils-Install:0
virtual/perl-ExtUtils-MakeMaker:0
virtual/perl-ExtUtils-Manifest:0
virtual/perl-ExtUtils-ParseXS:0
virtual/perl-File-Path:0
virtual/perl-File-Spec:0
virtual/perl-File-Temp:0
virtual/perl-Getopt-Long:0
virtual/perl-IO-Compress:0
virtual/perl-IO-Socket-IP:0
virtual/perl-IO:0
virtual/perl-JSON-PP:0
virtual/perl-MIME-Base64:0
virtual/perl-Math-BigInt:0
virtual/perl-Module-Metadata:0
virtual/perl-Parse-CPAN-Meta:0
virtual/perl-Perl-OSType:0
virtual/perl-Pod-Parser:0
virtual/perl-Scalar-List-Utils:0
virtual/perl-Storable:0
virtual/perl-Sys-Syslog:0
virtual/perl-Test-Harness:0
virtual/perl-Test-Simple:0
virtual/perl-Text-ParseWords:0
virtual/perl-Time-HiRes:0
virtual/perl-Time-Local:0
virtual/perl-XSLoader:0
virtual/perl-if:0
virtual/perl-libnet:0
virtual/perl-parent:0
virtual/perl-podlators:0
virtual/perl-version:0