add workingdir patch
This commit is contained in:
97
patches/st-workingdir-20200317-51e19ea.diff
Normal file
97
patches/st-workingdir-20200317-51e19ea.diff
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
From ae14b869d7bc0e0cd8ed16157837ad09aaacacc0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Gricar <coppie@protonmail.com>
|
||||||
|
Date: Tue, 17 Mar 2020 13:38:05 +0100
|
||||||
|
Subject: [PATCH] Add switch to provide initial working directory
|
||||||
|
|
||||||
|
This patch adds -p switch which takes one argument 'path' and can be
|
||||||
|
used to set the initial working directory of the new st instance.
|
||||||
|
It acts the same as running 'cd path' command after starting the st
|
||||||
|
instance.
|
||||||
|
---
|
||||||
|
st.1 | 8 ++++++++
|
||||||
|
x.c | 13 +++++++++----
|
||||||
|
2 files changed, 17 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/st.1 b/st.1
|
||||||
|
index e8d6059..a901122 100644
|
||||||
|
--- a/st.1
|
||||||
|
+++ b/st.1
|
||||||
|
@@ -6,6 +6,8 @@ st \- simple terminal
|
||||||
|
.RB [ \-aiv ]
|
||||||
|
.RB [ \-c
|
||||||
|
.IR class ]
|
||||||
|
+.RB [ \-d
|
||||||
|
+.IR path ]
|
||||||
|
.RB [ \-f
|
||||||
|
.IR font ]
|
||||||
|
.RB [ \-g
|
||||||
|
@@ -30,6 +32,8 @@ st \- simple terminal
|
||||||
|
.RB [ \-aiv ]
|
||||||
|
.RB [ \-c
|
||||||
|
.IR class ]
|
||||||
|
+.RB [ \-d
|
||||||
|
+.IR path ]
|
||||||
|
.RB [ \-f
|
||||||
|
.IR font ]
|
||||||
|
.RB [ \-g
|
||||||
|
@@ -58,6 +62,10 @@ disable alternate screens in terminal
|
||||||
|
.BI \-c " class"
|
||||||
|
defines the window class (default $TERM).
|
||||||
|
.TP
|
||||||
|
+.BI \-d " path"
|
||||||
|
+changes the working directory to
|
||||||
|
+.IR path .
|
||||||
|
+.TP
|
||||||
|
.BI \-f " font"
|
||||||
|
defines the
|
||||||
|
.I font
|
||||||
|
diff --git a/x.c b/x.c
|
||||||
|
index 48a6676..fab2ddc 100644
|
||||||
|
--- a/x.c
|
||||||
|
+++ b/x.c
|
||||||
|
@@ -250,6 +250,7 @@ static char *opt_io = NULL;
|
||||||
|
static char *opt_line = NULL;
|
||||||
|
static char *opt_name = NULL;
|
||||||
|
static char *opt_title = NULL;
|
||||||
|
+static char *opt_dir = NULL;
|
||||||
|
|
||||||
|
static int oldbutton = 3; /* button event on startup: 3 = release */
|
||||||
|
|
||||||
|
@@ -1958,12 +1959,12 @@ run(void)
|
||||||
|
void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
- die("usage: %s [-aiv] [-c class] [-f font] [-g geometry]"
|
||||||
|
- " [-n name] [-o file]\n"
|
||||||
|
+ die("usage: %s [-aiv] [-c class] [-d path] [-f font]"
|
||||||
|
+ " [-g geometry] [-n name] [-o file]\n"
|
||||||
|
" [-T title] [-t title] [-w windowid]"
|
||||||
|
" [[-e] command [args ...]]\n"
|
||||||
|
- " %s [-aiv] [-c class] [-f font] [-g geometry]"
|
||||||
|
- " [-n name] [-o file]\n"
|
||||||
|
+ " %s [-aiv] [-c class] [-d path] [-f font]"
|
||||||
|
+ " [-g geometry] [-n name] [-o file]\n"
|
||||||
|
" [-T title] [-t title] [-w windowid] -l line"
|
||||||
|
" [stty_args ...]\n", argv0, argv0);
|
||||||
|
}
|
||||||
|
@@ -2015,6 +2016,9 @@ main(int argc, char *argv[])
|
||||||
|
case 'v':
|
||||||
|
die("%s " VERSION "\n", argv0);
|
||||||
|
break;
|
||||||
|
+ case 'd':
|
||||||
|
+ opt_dir = EARGF(usage());
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
} ARGEND;
|
||||||
|
@@ -2034,6 +2038,7 @@ run:
|
||||||
|
xinit(cols, rows);
|
||||||
|
xsetenv();
|
||||||
|
selinit();
|
||||||
|
+ chdir(opt_dir);
|
||||||
|
run();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
8
st.1
8
st.1
@@ -6,6 +6,8 @@ st \- simple terminal
|
|||||||
.RB [ \-aiv ]
|
.RB [ \-aiv ]
|
||||||
.RB [ \-c
|
.RB [ \-c
|
||||||
.IR class ]
|
.IR class ]
|
||||||
|
.RB [ \-d
|
||||||
|
.IR path ]
|
||||||
.RB [ \-f
|
.RB [ \-f
|
||||||
.IR font ]
|
.IR font ]
|
||||||
.RB [ \-g
|
.RB [ \-g
|
||||||
@@ -30,6 +32,8 @@ st \- simple terminal
|
|||||||
.RB [ \-aiv ]
|
.RB [ \-aiv ]
|
||||||
.RB [ \-c
|
.RB [ \-c
|
||||||
.IR class ]
|
.IR class ]
|
||||||
|
.RB [ \-d
|
||||||
|
.IR path ]
|
||||||
.RB [ \-f
|
.RB [ \-f
|
||||||
.IR font ]
|
.IR font ]
|
||||||
.RB [ \-g
|
.RB [ \-g
|
||||||
@@ -58,6 +62,10 @@ disable alternate screens in terminal
|
|||||||
.BI \-c " class"
|
.BI \-c " class"
|
||||||
defines the window class (default $TERM).
|
defines the window class (default $TERM).
|
||||||
.TP
|
.TP
|
||||||
|
.BI \-d " path"
|
||||||
|
changes the working directory to
|
||||||
|
.IR path .
|
||||||
|
.TP
|
||||||
.BI \-f " font"
|
.BI \-f " font"
|
||||||
defines the
|
defines the
|
||||||
.I font
|
.I font
|
||||||
|
|||||||
13
x.c
13
x.c
@@ -255,6 +255,7 @@ static char *opt_io = NULL;
|
|||||||
static char *opt_line = NULL;
|
static char *opt_line = NULL;
|
||||||
static char *opt_name = NULL;
|
static char *opt_name = NULL;
|
||||||
static char *opt_title = NULL;
|
static char *opt_title = NULL;
|
||||||
|
static char *opt_dir = NULL;
|
||||||
|
|
||||||
static uint buttons; /* bit field of pressed buttons */
|
static uint buttons; /* bit field of pressed buttons */
|
||||||
|
|
||||||
@@ -2159,12 +2160,12 @@ run(void)
|
|||||||
void
|
void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
die("usage: %s [-aiv] [-c class] [-f font] [-g geometry]"
|
die("usage: %s [-aiv] [-c class] [-d path] [-f font]"
|
||||||
" [-n name] [-o file]\n"
|
" [-g geometry] [-n name] [-o file]\n"
|
||||||
" [-T title] [-t title] [-w windowid]"
|
" [-T title] [-t title] [-w windowid]"
|
||||||
" [[-e] command [args ...]]\n"
|
" [[-e] command [args ...]]\n"
|
||||||
" %s [-aiv] [-c class] [-f font] [-g geometry]"
|
" %s [-aiv] [-c class] [-d path] [-f font]"
|
||||||
" [-n name] [-o file]\n"
|
" [-g geometry] [-n name] [-o file]\n"
|
||||||
" [-T title] [-t title] [-w windowid] -l line"
|
" [-T title] [-t title] [-w windowid] -l line"
|
||||||
" [stty_args ...]\n", argv0, argv0);
|
" [stty_args ...]\n", argv0, argv0);
|
||||||
}
|
}
|
||||||
@@ -2216,6 +2217,9 @@ main(int argc, char *argv[])
|
|||||||
case 'v':
|
case 'v':
|
||||||
die("%s " VERSION "\n", argv0);
|
die("%s " VERSION "\n", argv0);
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
opt_dir = EARGF(usage());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
} ARGEND;
|
} ARGEND;
|
||||||
@@ -2235,6 +2239,7 @@ run:
|
|||||||
xinit(cols, rows);
|
xinit(cols, rows);
|
||||||
xsetenv();
|
xsetenv();
|
||||||
selinit();
|
selinit();
|
||||||
|
chdir(opt_dir);
|
||||||
run();
|
run();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
271
x.c.orig
271
x.c.orig
@@ -19,6 +19,7 @@ char *argv0;
|
|||||||
#include "arg.h"
|
#include "arg.h"
|
||||||
#include "st.h"
|
#include "st.h"
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
|
#include "hb.h"
|
||||||
|
|
||||||
/* types used in config.h */
|
/* types used in config.h */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -141,8 +142,9 @@ typedef struct {
|
|||||||
} DC;
|
} DC;
|
||||||
|
|
||||||
static inline ushort sixd_to_16bit(int);
|
static inline ushort sixd_to_16bit(int);
|
||||||
|
static void xresetfontsettings(ushort mode, Font **font, int *frcflags);
|
||||||
static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int);
|
static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int);
|
||||||
static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
|
static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int, int);
|
||||||
static void xdrawglyph(Glyph, int, int);
|
static void xdrawglyph(Glyph, int, int);
|
||||||
static void xclear(int, int, int, int);
|
static void xclear(int, int, int, int);
|
||||||
static int xgeommasktogravity(int);
|
static int xgeommasktogravity(int);
|
||||||
@@ -760,7 +762,7 @@ xresize(int col, int row)
|
|||||||
xclear(0, 0, win.w, win.h);
|
xclear(0, 0, win.w, win.h);
|
||||||
|
|
||||||
/* resize to new width */
|
/* resize to new width */
|
||||||
xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec));
|
xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec) * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
ushort
|
ushort
|
||||||
@@ -1160,6 +1162,9 @@ xunloadfont(Font *f)
|
|||||||
void
|
void
|
||||||
xunloadfonts(void)
|
xunloadfonts(void)
|
||||||
{
|
{
|
||||||
|
/* Clear Harfbuzz font cache. */
|
||||||
|
hbunloadfonts();
|
||||||
|
|
||||||
/* Free the loaded fonts in the font cache. */
|
/* Free the loaded fonts in the font cache. */
|
||||||
while (frclen > 0)
|
while (frclen > 0)
|
||||||
XftFontClose(xw.dpy, frc[--frclen].font);
|
XftFontClose(xw.dpy, frc[--frclen].font);
|
||||||
@@ -1289,7 +1294,7 @@ xinit(int cols, int rows)
|
|||||||
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
||||||
|
|
||||||
/* font spec buffer */
|
/* font spec buffer */
|
||||||
xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec));
|
xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec) * 4);
|
||||||
|
|
||||||
/* Xft rendering context */
|
/* Xft rendering context */
|
||||||
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
|
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
|
||||||
@@ -1345,147 +1350,160 @@ xinit(int cols, int rows)
|
|||||||
boxdraw_xinit(xw.dpy, xw.cmap, xw.draw, xw.vis);
|
boxdraw_xinit(xw.dpy, xw.cmap, xw.draw, xw.vis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xresetfontsettings(ushort mode, Font **font, int *frcflags)
|
||||||
|
{
|
||||||
|
*font = &dc.font;
|
||||||
|
if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) {
|
||||||
|
*font = &dc.ibfont;
|
||||||
|
*frcflags = FRC_ITALICBOLD;
|
||||||
|
} else if (mode & ATTR_ITALIC) {
|
||||||
|
*font = &dc.ifont;
|
||||||
|
*frcflags = FRC_ITALIC;
|
||||||
|
} else if (mode & ATTR_BOLD) {
|
||||||
|
*font = &dc.bfont;
|
||||||
|
*frcflags = FRC_BOLD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
|
xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
|
||||||
{
|
{
|
||||||
float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp;
|
float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp;
|
||||||
ushort mode, prevmode = USHRT_MAX;
|
ushort mode = glyphs[0].mode & ~ATTR_WRAP;
|
||||||
Font *font = &dc.font;
|
Font *font = &dc.font;
|
||||||
int frcflags = FRC_NORMAL;
|
int frcflags = FRC_NORMAL;
|
||||||
float runewidth = win.cw;
|
float runewidth = win.cw * ((glyphs[0].mode & ATTR_WIDE) ? 2.0f : 1.0f);
|
||||||
Rune rune;
|
Rune rune;
|
||||||
FT_UInt glyphidx;
|
FT_UInt glyphidx;
|
||||||
FcResult fcres;
|
FcResult fcres;
|
||||||
FcPattern *fcpattern, *fontpattern;
|
FcPattern *fcpattern, *fontpattern;
|
||||||
FcFontSet *fcsets[] = { NULL };
|
FcFontSet *fcsets[] = { NULL };
|
||||||
FcCharSet *fccharset;
|
FcCharSet *fccharset;
|
||||||
int i, f, numspecs = 0;
|
int f, code_idx, numspecs = 0;
|
||||||
|
float cluster_xp = xp, cluster_yp = yp;
|
||||||
|
HbTransformData shaped = { 0 };
|
||||||
|
|
||||||
for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
|
/* Initial values. */
|
||||||
/* Fetch rune and mode for current glyph. */
|
xresetfontsettings(mode, &font, &frcflags);
|
||||||
rune = glyphs[i].u;
|
|
||||||
mode = glyphs[i].mode;
|
|
||||||
|
|
||||||
/* Skip dummy wide-character spacing. */
|
/* Shape the segment. */
|
||||||
if (mode == ATTR_WDUMMY)
|
hbtransform(&shaped, font->match, glyphs, 0, len);
|
||||||
|
xp = winx; yp = winy + font->ascent;
|
||||||
|
cluster_xp = xp; cluster_yp = yp;
|
||||||
|
|
||||||
|
for (code_idx = 0; code_idx < shaped.count; code_idx++) {
|
||||||
|
int idx = shaped.glyphs[code_idx].cluster;
|
||||||
|
|
||||||
|
if (glyphs[idx].mode & ATTR_WDUMMY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Determine font for glyph if different from previous glyph. */
|
/* Advance the drawing cursor if we've moved to a new cluster */
|
||||||
if (prevmode != mode) {
|
if (code_idx > 0 && idx != shaped.glyphs[code_idx - 1].cluster) {
|
||||||
prevmode = mode;
|
xp += runewidth * (idx - shaped.glyphs[code_idx - 1].cluster);
|
||||||
font = &dc.font;
|
cluster_xp = xp;
|
||||||
frcflags = FRC_NORMAL;
|
cluster_yp = yp;
|
||||||
runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f);
|
|
||||||
if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) {
|
|
||||||
font = &dc.ibfont;
|
|
||||||
frcflags = FRC_ITALICBOLD;
|
|
||||||
} else if (mode & ATTR_ITALIC) {
|
|
||||||
font = &dc.ifont;
|
|
||||||
frcflags = FRC_ITALIC;
|
|
||||||
} else if (mode & ATTR_BOLD) {
|
|
||||||
font = &dc.bfont;
|
|
||||||
frcflags = FRC_BOLD;
|
|
||||||
}
|
|
||||||
yp = winy + font->ascent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode & ATTR_BOXDRAW) {
|
if (glyphs[idx].mode & ATTR_BOXDRAW) {
|
||||||
/* minor shoehorning: boxdraw uses only this ushort */
|
/* minor shoehorning: boxdraw uses only this ushort */
|
||||||
glyphidx = boxdrawindex(&glyphs[i]);
|
|
||||||
} else {
|
|
||||||
/* Lookup character index with default font. */
|
|
||||||
glyphidx = XftCharIndex(xw.dpy, font->match, rune);
|
|
||||||
}
|
|
||||||
if (glyphidx) {
|
|
||||||
specs[numspecs].font = font->match;
|
specs[numspecs].font = font->match;
|
||||||
|
specs[numspecs].glyph = boxdrawindex(&glyphs[idx]);
|
||||||
|
specs[numspecs].x = xp;
|
||||||
|
specs[numspecs].y = yp;
|
||||||
|
numspecs++;
|
||||||
|
} else if (shaped.glyphs[code_idx].codepoint != 0) {
|
||||||
|
/* If symbol is found, put it into the specs. */
|
||||||
|
specs[numspecs].font = font->match;
|
||||||
|
specs[numspecs].glyph = shaped.glyphs[code_idx].codepoint;
|
||||||
|
specs[numspecs].x = cluster_xp + (short)(shaped.positions[code_idx].x_offset / 64.);
|
||||||
|
specs[numspecs].y = cluster_yp - (short)(shaped.positions[code_idx].y_offset / 64.);
|
||||||
|
cluster_xp += shaped.positions[code_idx].x_advance / 64.;
|
||||||
|
cluster_yp += shaped.positions[code_idx].y_advance / 64.;
|
||||||
|
numspecs++;
|
||||||
|
} else {
|
||||||
|
/* If it's not found, try to fetch it through the font cache. */
|
||||||
|
rune = glyphs[idx].u;
|
||||||
|
for (f = 0; f < frclen; f++) {
|
||||||
|
glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune);
|
||||||
|
/* Everything correct. */
|
||||||
|
if (glyphidx && frc[f].flags == frcflags)
|
||||||
|
break;
|
||||||
|
/* We got a default font for a not found glyph. */
|
||||||
|
if (!glyphidx && frc[f].flags == frcflags
|
||||||
|
&& frc[f].unicodep == rune) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nothing was found. Use fontconfig to find matching font. */
|
||||||
|
if (f >= frclen) {
|
||||||
|
if (!font->set)
|
||||||
|
font->set = FcFontSort(0, font->pattern,
|
||||||
|
1, 0, &fcres);
|
||||||
|
fcsets[0] = font->set;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nothing was found in the cache. Now use
|
||||||
|
* some dozen of Fontconfig calls to get the
|
||||||
|
* font for one single character.
|
||||||
|
*
|
||||||
|
* Xft and fontconfig are design failures.
|
||||||
|
*/
|
||||||
|
fcpattern = FcPatternDuplicate(font->pattern);
|
||||||
|
fccharset = FcCharSetCreate();
|
||||||
|
|
||||||
|
FcCharSetAddChar(fccharset, rune);
|
||||||
|
FcPatternAddCharSet(fcpattern, FC_CHARSET,
|
||||||
|
fccharset);
|
||||||
|
FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
|
||||||
|
|
||||||
|
FcConfigSubstitute(0, fcpattern,
|
||||||
|
FcMatchPattern);
|
||||||
|
FcDefaultSubstitute(fcpattern);
|
||||||
|
|
||||||
|
fontpattern = FcFontSetMatch(0, fcsets, 1,
|
||||||
|
fcpattern, &fcres);
|
||||||
|
|
||||||
|
/* Allocate memory for the new cache entry. */
|
||||||
|
if (frclen >= frccap) {
|
||||||
|
frccap += 16;
|
||||||
|
frc = xrealloc(frc, frccap * sizeof(Fontcache));
|
||||||
|
}
|
||||||
|
|
||||||
|
frc[frclen].font = XftFontOpenPattern(xw.dpy,
|
||||||
|
fontpattern);
|
||||||
|
if (!frc[frclen].font)
|
||||||
|
die("XftFontOpenPattern failed seeking fallback font: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
frc[frclen].flags = frcflags;
|
||||||
|
frc[frclen].unicodep = rune;
|
||||||
|
|
||||||
|
glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune);
|
||||||
|
|
||||||
|
f = frclen;
|
||||||
|
frclen++;
|
||||||
|
|
||||||
|
FcPatternDestroy(fcpattern);
|
||||||
|
FcCharSetDestroy(fccharset);
|
||||||
|
}
|
||||||
|
|
||||||
|
specs[numspecs].font = frc[f].font;
|
||||||
specs[numspecs].glyph = glyphidx;
|
specs[numspecs].glyph = glyphidx;
|
||||||
specs[numspecs].x = (short)xp;
|
specs[numspecs].x = (short)xp;
|
||||||
specs[numspecs].y = (short)yp;
|
specs[numspecs].y = (short)yp;
|
||||||
xp += runewidth;
|
|
||||||
numspecs++;
|
numspecs++;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fallback on font cache, search the font cache for match. */
|
|
||||||
for (f = 0; f < frclen; f++) {
|
|
||||||
glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune);
|
|
||||||
/* Everything correct. */
|
|
||||||
if (glyphidx && frc[f].flags == frcflags)
|
|
||||||
break;
|
|
||||||
/* We got a default font for a not found glyph. */
|
|
||||||
if (!glyphidx && frc[f].flags == frcflags
|
|
||||||
&& frc[f].unicodep == rune) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nothing was found. Use fontconfig to find matching font. */
|
|
||||||
if (f >= frclen) {
|
|
||||||
if (!font->set)
|
|
||||||
font->set = FcFontSort(0, font->pattern,
|
|
||||||
1, 0, &fcres);
|
|
||||||
fcsets[0] = font->set;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Nothing was found in the cache. Now use
|
|
||||||
* some dozen of Fontconfig calls to get the
|
|
||||||
* font for one single character.
|
|
||||||
*
|
|
||||||
* Xft and fontconfig are design failures.
|
|
||||||
*/
|
|
||||||
fcpattern = FcPatternDuplicate(font->pattern);
|
|
||||||
fccharset = FcCharSetCreate();
|
|
||||||
|
|
||||||
FcCharSetAddChar(fccharset, rune);
|
|
||||||
FcPatternAddCharSet(fcpattern, FC_CHARSET,
|
|
||||||
fccharset);
|
|
||||||
FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
|
|
||||||
|
|
||||||
FcConfigSubstitute(0, fcpattern,
|
|
||||||
FcMatchPattern);
|
|
||||||
FcDefaultSubstitute(fcpattern);
|
|
||||||
|
|
||||||
fontpattern = FcFontSetMatch(0, fcsets, 1,
|
|
||||||
fcpattern, &fcres);
|
|
||||||
|
|
||||||
/* Allocate memory for the new cache entry. */
|
|
||||||
if (frclen >= frccap) {
|
|
||||||
frccap += 16;
|
|
||||||
frc = xrealloc(frc, frccap * sizeof(Fontcache));
|
|
||||||
}
|
|
||||||
|
|
||||||
frc[frclen].font = XftFontOpenPattern(xw.dpy,
|
|
||||||
fontpattern);
|
|
||||||
if (!frc[frclen].font)
|
|
||||||
die("XftFontOpenPattern failed seeking fallback font: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
frc[frclen].flags = frcflags;
|
|
||||||
frc[frclen].unicodep = rune;
|
|
||||||
|
|
||||||
glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune);
|
|
||||||
|
|
||||||
f = frclen;
|
|
||||||
frclen++;
|
|
||||||
|
|
||||||
FcPatternDestroy(fcpattern);
|
|
||||||
FcCharSetDestroy(fccharset);
|
|
||||||
}
|
|
||||||
|
|
||||||
specs[numspecs].font = frc[f].font;
|
|
||||||
specs[numspecs].glyph = glyphidx;
|
|
||||||
specs[numspecs].x = (short)xp;
|
|
||||||
specs[numspecs].y = (short)yp;
|
|
||||||
xp += runewidth;
|
|
||||||
numspecs++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cleanup and get ready for next segment. */
|
||||||
|
hbcleanup(&shaped);
|
||||||
return numspecs;
|
return numspecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
|
xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y, int charlen)
|
||||||
{
|
{
|
||||||
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
|
|
||||||
int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
|
int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
|
||||||
width = charlen * win.cw;
|
width = charlen * win.cw;
|
||||||
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
|
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
|
||||||
@@ -1625,21 +1643,24 @@ void
|
|||||||
xdrawglyph(Glyph g, int x, int y)
|
xdrawglyph(Glyph g, int x, int y)
|
||||||
{
|
{
|
||||||
int numspecs;
|
int numspecs;
|
||||||
XftGlyphFontSpec spec;
|
XftGlyphFontSpec *specs = xw.specbuf;
|
||||||
|
|
||||||
numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y);
|
numspecs = xmakeglyphfontspecs(specs, &g, 1, x, y);
|
||||||
xdrawglyphfontspecs(&spec, g, numspecs, x, y);
|
xdrawglyphfontspecs(specs, g, numspecs, x, y, (g.mode & ATTR_WIDE) ? 2 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
|
xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int len)
|
||||||
{
|
{
|
||||||
Color drawcol;
|
Color drawcol;
|
||||||
|
|
||||||
/* remove the old cursor */
|
/* remove the old cursor */
|
||||||
if (selected(ox, oy))
|
if (selected(ox, oy))
|
||||||
og.mode ^= ATTR_REVERSE;
|
og.mode ^= ATTR_REVERSE;
|
||||||
xdrawglyph(og, ox, oy);
|
|
||||||
|
/* Redraw the line where cursor was previously.
|
||||||
|
* It will restore the ligatures broken by the cursor. */
|
||||||
|
xdrawline(line, 0, oy, len);
|
||||||
|
|
||||||
if (IS_SET(MODE_HIDE))
|
if (IS_SET(MODE_HIDE))
|
||||||
return;
|
return;
|
||||||
@@ -1773,18 +1794,16 @@ xdrawline(Line line, int x1, int y1, int x2)
|
|||||||
Glyph base, new;
|
Glyph base, new;
|
||||||
XftGlyphFontSpec *specs = xw.specbuf;
|
XftGlyphFontSpec *specs = xw.specbuf;
|
||||||
|
|
||||||
numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
|
|
||||||
i = ox = 0;
|
i = ox = 0;
|
||||||
for (x = x1; x < x2 && i < numspecs; x++) {
|
for (x = x1; x < x2; x++) {
|
||||||
new = line[x];
|
new = line[x];
|
||||||
if (new.mode == ATTR_WDUMMY)
|
if (new.mode == ATTR_WDUMMY)
|
||||||
continue;
|
continue;
|
||||||
if (selected(x, y1))
|
if (selected(x, y1))
|
||||||
new.mode ^= ATTR_REVERSE;
|
new.mode ^= ATTR_REVERSE;
|
||||||
if (i > 0 && ATTRCMP(base, new)) {
|
if ((i > 0) && ATTRCMP(base, new)) {
|
||||||
xdrawglyphfontspecs(specs, base, i, ox, y1);
|
numspecs = xmakeglyphfontspecs(specs, &line[ox], x - ox, ox, y1);
|
||||||
specs += i;
|
xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x - ox);
|
||||||
numspecs -= i;
|
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
@@ -1793,8 +1812,10 @@ xdrawline(Line line, int x1, int y1, int x2)
|
|||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (i > 0)
|
if (i > 0) {
|
||||||
xdrawglyphfontspecs(specs, base, i, ox, y1);
|
numspecs = xmakeglyphfontspecs(specs, &line[ox], x2 - ox, ox, y1);
|
||||||
|
xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x2 - ox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user