1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

Support for double-width (CJK) characters, using the xterm-like

options -fw and -fwb to specify wide and wide-bold fonts.

[originally from svn r2412]
This commit is contained in:
Simon Tatham 2003-01-01 21:53:22 +00:00
parent 7bdd57f300
commit d97ac46223
3 changed files with 100 additions and 26 deletions

View File

@ -349,7 +349,9 @@ struct config_tag {
int stamp_utmp;
int login_shell;
int scrollbar_on_left;
char boldfont[64];
char boldfont[256];
char widefont[256];
char wideboldfont[256];
int shadowboldoffset;
};

View File

@ -36,6 +36,13 @@ will be displayed in different colours instead of a different font,
so this option will be ignored. If \fIBoldAsColour\fP is set to 0
and you do not specify a bold font, \fIpterm\fP will overprint the
normal font to make it look bolder.
.IP "\fB\-fw\fP \fIfont-name\fP"
Specify the font to use for double-width characters (typically
Chinese, Japanese and Korean text) displayed in the terminal.
.IP "\fB\-fwb\fP \fIfont-name\fP"
Specify the font to use for bold double-width characters (typically
Chinese, Japanese and Korean text) Like \fI-fb\fP, this will be
ignored unless the \fIBoldAsColour\fP resource is set to 0.
.IP "\fB\-geometry\fP \fIwidth\fPx\fIheight\fP"
Specify the size of the terminal, in rows and columns of text.
Unfortunately \fIpterm\fP does not currently support specifying the
@ -306,6 +313,16 @@ This resource is the same as the \fI\-fb\fP command-line option: it
controls the font used to display bold text when \fIBoldAsColour\fP
is turned off. The default is unset (the font will be bolded by
printing it twice at a one-pixel offset).
.IP "\fBpterm.WideFont\fP"
This resource is the same as the \fI\-fw\fP command-line option: it
controls the font used to display double-width characters. The
default is unset (double-width characters cannot be displayed).
.IP "\fBpterm.WideBoldFont\fP"
This resource is the same as the \fI\-fwb\fP command-line option: it
controls the font used to display double-width characters in bold,
when \fIBoldAsColour\fP is turned off. The default is unset
(double-width characters are displayed in bold by printing them
twice at a one-pixel offset).
.IP "\fBpterm.ShadowBoldOffset\fP"
This resource can be set to an integer; the default is \-1. It
specifies the offset at which text is overprinted when using "shadow

View File

@ -39,11 +39,11 @@ struct gui_data {
GtkBox *hbox;
GtkAdjustment *sbar_adjust;
GdkPixmap *pixmap;
GdkFont *fonts[2]; /* normal and bold (for now!) */
GdkFont *fonts[4]; /* normal, bold, wide, widebold */
struct {
int charset;
int is_wide;
} fontinfo[2];
} fontinfo[4];
GdkCursor *rawcursor, *textcursor, *blankcursor, *currcursor;
GdkColor cols[NCOLOURS];
GdkColormap *colmap;
@ -1469,12 +1469,7 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
struct gui_data *inst = dctx->inst;
GdkGC *gc = dctx->gc;
int nfg, nbg, t, fontid, shadow, rlen;
/*
* NYI:
* - Unicode, code pages, and ATTR_WIDE for CJK support.
*/
int nfg, nbg, t, fontid, shadow, rlen, widefactor;
nfg = 2 * ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT);
nbg = 2 * ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT);
@ -1493,9 +1488,17 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
}
fontid = shadow = 0;
if (attr & ATTR_WIDE) {
widefactor = 2;
fontid |= 2;
} else {
widefactor = 1;
}
if ((attr & ATTR_BOLD) && !cfg.bold_colour) {
if (inst->fonts[1])
fontid = 1;
if (inst->fonts[fontid | 1])
fontid |= 1;
else
shadow = 1;
}
@ -1504,8 +1507,8 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
x *= 2;
if (x >= inst->term->cols)
return;
if (x + len*2 > inst->term->cols)
len = (inst->term->cols-x)/2; /* trim to LH half */
if (x + len*2*widefactor > inst->term->cols)
len = (inst->term->cols-x)/2/widefactor;/* trim to LH half */
rlen = len * 2;
} else
rlen = len;
@ -1515,7 +1518,7 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
r.x = x*inst->font_width+cfg.window_border;
r.y = y*inst->font_height+cfg.window_border;
r.width = rlen*inst->font_width;
r.width = rlen*widefactor*inst->font_width;
r.height = inst->font_height;
gdk_gc_set_clip_rectangle(gc, &r);
}
@ -1524,7 +1527,7 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
gdk_draw_rectangle(inst->pixmap, gc, 1,
x*inst->font_width+cfg.window_border,
y*inst->font_height+cfg.window_border,
rlen*inst->font_width, inst->font_height);
rlen*widefactor*inst->font_width, inst->font_height);
gdk_gc_set_foreground(gc, &inst->cols[nfg]);
{
@ -1538,7 +1541,14 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
wcs[i] = (wchar_t) ((attr & CSET_MASK) + (text[i] & CHAR_MASK));
}
if (inst->fontinfo[fontid].is_wide) {
if (inst->fonts[fontid] == NULL) {
/*
* The font for this contingency does not exist.
* Typically this means we've been given ATTR_WIDE
* character and have no wide font. So we display
* nothing at all; such is life.
*/
} else if (inst->fontinfo[fontid].is_wide) {
gwcs = smalloc(sizeof(GdkWChar) * (len+1));
/*
* FIXME: when we have a wide-char equivalent of
@ -1580,7 +1590,7 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
uheight = inst->font_height - 1;
gdk_draw_line(inst->pixmap, gc, x*inst->font_width+cfg.window_border,
y*inst->font_height + uheight + cfg.window_border,
(x+len)*inst->font_width-1+cfg.window_border,
(x+len)*widefactor*inst->font_width-1+cfg.window_border,
y*inst->font_height + uheight + cfg.window_border);
}
@ -1594,7 +1604,7 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
* try thinking of a better way. :-(
*/
int i;
for (i = 0; i < len * inst->font_width; i++) {
for (i = 0; i < len * widefactor * inst->font_width; i++) {
gdk_draw_pixmap(inst->pixmap, gc, inst->pixmap,
x*inst->font_width+cfg.window_border + 2*i,
y*inst->font_height+cfg.window_border,
@ -1614,7 +1624,7 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
gdk_draw_pixmap(inst->pixmap, gc, inst->pixmap,
x*inst->font_width+cfg.window_border,
y*inst->font_height+cfg.window_border+dt*i+db,
x*inst->font_width+cfg.window_border,
x*widefactor*inst->font_width+cfg.window_border,
y*inst->font_height+cfg.window_border+dt*(i+1),
len * inst->font_width, inst->font_height-i-1);
}
@ -1628,15 +1638,22 @@ void do_text(Context ctx, int x, int y, char *text, int len,
struct draw_ctx *dctx = (struct draw_ctx *)ctx;
struct gui_data *inst = dctx->inst;
GdkGC *gc = dctx->gc;
int widefactor;
do_text_internal(ctx, x, y, text, len, attr, lattr);
if (attr & ATTR_WIDE) {
widefactor = 2;
} else {
widefactor = 1;
}
if (lattr != LATTR_NORM) {
x *= 2;
if (x >= inst->term->cols)
return;
if (x + len*2 > inst->term->cols)
len = (inst->term->cols-x)/2; /* trim to LH half */
if (x + len*2*widefactor > inst->term->cols)
len = (inst->term->cols-x)/2/widefactor;/* trim to LH half */
len *= 2;
}
@ -1645,7 +1662,7 @@ void do_text(Context ctx, int x, int y, char *text, int len,
y*inst->font_height+cfg.window_border,
x*inst->font_width+cfg.window_border,
y*inst->font_height+cfg.window_border,
len*inst->font_width, inst->font_height);
len*widefactor*inst->font_width, inst->font_height);
}
void do_cursor(Context ctx, int x, int y, char *text, int len,
@ -1655,7 +1672,7 @@ void do_cursor(Context ctx, int x, int y, char *text, int len,
struct gui_data *inst = dctx->inst;
GdkGC *gc = dctx->gc;
int passive;
int passive, widefactor;
if (attr & TATTR_PASCURS) {
attr &= ~TATTR_PASCURS;
@ -1667,12 +1684,18 @@ void do_cursor(Context ctx, int x, int y, char *text, int len,
}
do_text_internal(ctx, x, y, text, len, attr, lattr);
if (attr & ATTR_WIDE) {
widefactor = 2;
} else {
widefactor = 1;
}
if (lattr != LATTR_NORM) {
x *= 2;
if (x >= inst->term->cols)
return;
if (x + len*2 > inst->term->cols)
len = (inst->term->cols-x)/2; /* trim to LH half */
if (x + len*2*widefactor > inst->term->cols)
len = (inst->term->cols-x)/2/widefactor;/* trim to LH half */
len *= 2;
}
@ -1741,7 +1764,7 @@ void do_cursor(Context ctx, int x, int y, char *text, int len,
y*inst->font_height+cfg.window_border,
x*inst->font_width+cfg.window_border,
y*inst->font_height+cfg.window_border,
len*inst->font_width, inst->font_height);
len*widefactor*inst->font_width, inst->font_height);
}
GdkCursor *make_mouse_ptr(struct gui_data *inst, int cursor_val)
@ -1923,6 +1946,18 @@ int do_cmdline(int argc, char **argv, int do_everything)
strncpy(cfg.boldfont, val, sizeof(cfg.boldfont));
cfg.boldfont[sizeof(cfg.boldfont)-1] = '\0';
} else if (!strcmp(p, "-fw")) {
EXPECTS_ARG;
SECOND_PASS_ONLY;
strncpy(cfg.widefont, val, sizeof(cfg.widefont));
cfg.widefont[sizeof(cfg.widefont)-1] = '\0';
} else if (!strcmp(p, "-fwb")) {
EXPECTS_ARG;
SECOND_PASS_ONLY;
strncpy(cfg.wideboldfont, val, sizeof(cfg.wideboldfont));
cfg.wideboldfont[sizeof(cfg.wideboldfont)-1] = '\0';
} else if (!strcmp(p, "-cs")) {
EXPECTS_ARG;
SECOND_PASS_ONLY;
@ -2171,6 +2206,26 @@ int main(int argc, char **argv)
set_font_info(inst, 1);
} else
inst->fonts[1] = NULL;
if (cfg.widefont[0]) {
inst->fonts[2] = gdk_font_load(cfg.widefont);
if (!inst->fonts[2]) {
fprintf(stderr, "pterm: unable to load wide font \"%s\"\n",
cfg.boldfont);
exit(1);
}
set_font_info(inst, 2);
} else
inst->fonts[2] = NULL;
if (cfg.wideboldfont[0]) {
inst->fonts[3] = gdk_font_load(cfg.wideboldfont);
if (!inst->fonts[3]) {
fprintf(stderr, "pterm: unable to load wide/bold font \"%s\"\n",
cfg.boldfont);
exit(1);
}
set_font_info(inst, 3);
} else
inst->fonts[3] = NULL;
inst->font_width = gdk_char_width(inst->fonts[0], ' ');
inst->font_height = inst->fonts[0]->ascent + inst->fonts[0]->descent;