Files
emacs/src/ftxfont.c
Paul Eggert 63cfb75f3a Include-file cleanup for src directory
Omit ‘#include "foo.h"’ unless the file needs foo.h (Bug#21707).
In a few cases, add ‘#include "foo.h"’ if the file needs foo.h
but does not include it directly.  As a general rule, a source
file should include foo.h if it needs the interfaces that foo.h
defines.
* src/alloc.c: Don’t include process.h.  Include dispextern.h,
systime.h.
* src/atimer.c: Don’t include blockinput.h.
* src/buffer.c: Include coding.h, systime.h.  Don’t include
keyboard.h, coding.h.
* src/callint.c: Don’t include commands.h, keymap.h.
* src/callproc.c: Don’t include character.h, ccl.h, composite.h,
systty.h, termhooks.h.
* src/casetab.c: Don’t include character.h.
* src/category.c: Don’t include charset.h, keymap.h.
* src/ccl.h: Don’t include character.h.
* src/character.c: Don’t include charset.h.
* src/charset.c: Don’t include disptab.h.
* src/chartab.c: Don’t include ccl.h.
* src/cm.c: Don’t include frame.h, termhooks.h.
* src/cmds.c: Don’t include window.h, dispextern.h.
* src/coding.c: Don’t include window.h, frame.h.
* src/composite.c: Include composite.h.  Don’t include window.h,
font.h.
* src/data.c: Don’t include syssignal.h, termhooks.h, font.h.
* src/dbusbind.c: Don’t include frame.h.
* src/decompress.c: Don’t include character.h.
* src/dired.c: Don’t include character.h, commands.h, charset.h.
* src/dispnew.c: Don’t include character.h, indent.h, intervals.h,
process.h, timespec.h.  Include systime.h.
* src/doc.c: Include coding.h.  Don’t include keyboard.h.
* src/editfns.c: Include composite.h.  Don’t include frame.h.
* src/emacs.c: Include fcntl.h, coding.h.  Don’t include
commands.h, systty.h..
* src/fileio.c: Don’t include intervals.h, dispextern.h.
Include composite.h.
* src/filelock.c: Don’t include character.h, systime.h.
* src/fns.c: Don’t include time.h, commands.h, keyboard.h,
keymap.h, frame.h, blockinput.h, xterm.h.  Include composite.h.
* src/font.c: Include termhooks.h.
* src/font.h: Don’t include ccl.h, frame.h.  Add forward decls of
struct composition_it, struct face, struct glyph_string.
* src/fontset.c: Don’t include buffer.h, ccl.h, keyboard.h,
intervals.h, window.h, termhooks.h.
* src/frame.c: Don’t include character.h, commands.h, font.h.
* src/frame.h: Don’t include dispextern.h.
* src/fringe.c: Don’t include character.h.
* src/ftcrfont.c: Don’t include dispextern.h, frame.h,
character.h, charset.h, fontset.h.
* src/ftfont.c: Don’t include frame.h, blockinput.h, coding.h,
fontset.h.
* src/ftxfont.c: Don’t include dispextern.h, character.h,
charset.h, fontset.h.
* src/gfilenotify.c: Don’t include frame.h, process.h.
* src/gtkutil.c: Include dispextern.h, frame.h, systime.h.
Don’t include syssignal.h, buffer.h, charset.h, font.h.
* src/gtkutil.h: Don’t include frame.h.
* src/image.c: Include fcntl.h and stdio.h instead of sysstdio.h.
Don’t include character.h.
* src/indent.c: Don’t include keyboard.h, termchar.h.
* src/inotify.c: Don’t include character.h, frame.h.
* src/insdel.c: Include composite.h.  Don’t include blockinput.h.
* src/intervals.c: Don’t include character.h, keyboard.h.
* src/intervals.h: Don’t include dispextern.h, composite.h.
* src/keyboard.c: Don’t include sysstdio.h, disptab.h, puresize.h.
Include coding.h.
* src/keyboard.h: Don’t incldue systime.h.
* src/keymap.c: Don’t include charset.h, frame.h.
* src/lread.c: Include dispextern.h and systime.h.
Don’t include frame.h.  Include systime.h.
* src/macros.c: Don’t include commands.h, character.h, buffer.h.
* src/menu.c: Include character.h, coding.h.  Don’t include
dispextern.h.
* src/menu.h: Don’t include systime.h.
* src/minibuf.c: Don’t include commands.h, dispextern.h, syntax.h,
intervals.h, termhooks.h.
* src/print.c: Include coding.h.  Don’t include keyboard.h,
window.h, dispextern.h, termchar.h, termhooks.h, font.h.
Add forward decl of struct terminal.
* src/process.c: Don’t include termhooks.h, commands.h,
dispextern.h, composite.h.
* src/region-cache.c: Don’t include character.h.
* src/scroll.c: Don’t include keyboard.h, window.h.
* src/search.c: Don’t include category.h, commands.h.
* src/sound.c: Don’t include dispextern.h.
* src/syntax.c: Don’t include command.h, keymap.h.
* src/sysdep.c: Don’t include window.h, dispextern.h.
* src/systime.h: Use ‘#ifdef emacs’, not ‘#ifdef EMACS_LISP_H’,
* src/term.c: Don’t include systty.h, intervals.h, xterm.h.
* src/terminal.c: Include character.h.
Don’t include charset.h, coding.h.
* src/textprop.c: Don’t include character.h.
* src/undo.c: Don’t include character.h, commands.h, window.h.
* src/unexsol.c: Don’t include character.h, charset.h.
* src/widget.c: Include widget.h.  Don’t include keyboard.h,
window.h, dispextern.h, blockinput.h, character.h, font.h.
* src/widgetprv.h: Don’t include widget.h.
* src/window.c: Don’t include character.h, menu.h, intervals.h.
* src/xdisp.c: Include composite.h, systime.h.  Don’t include
macros.h, process.h.
* src/xfaces.c: Don’t include charset.h, keyboard.h, termhooks.h,
intervals.h.
* src/xfns.c: Don’t include menu.h, character.h, intervals.h,
epaths.h, fontset.h, systime.h, atimer.h, termchar.h.
* src/xfont.c: Don’t include dispextern.h, fontset.h, ccl.h.
* src/xftfont.c: Don’t include dispextern.h, character.h, fontset.h.
* src/xgselect.c: Don’t include timespec.h, frame.h.
Include systime.h.
* src/xgselect.h: Don’t include time.h.
Use a forward decl to struct timespec instead.
* src/xmenu.c: Don’t include keymap.h, character.h, charset.h,
dispextern.h.  Include systime.h.
* src/xml.c: Don’t include character.h.
* src/xrdb.c [USE_MOTIF]: Don’t include keyboard.h.
* src/xselect.c: Don’t include dispextern.h, character.h,
buffer.h, process.h.
* src/xsmfns.c: Don’t include systime.h, sysselect.h.
* src/xterm.c: Don’t include syssignal.h, charset.h, disptab.h,
intervals.h process.h, keymap.h, xgselect.h.  Include composite.h.
2015-10-20 18:35:53 -07:00

363 lines
9.0 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ftxfont.c -- FreeType font driver on X (without using XFT).
Copyright (C) 2006-2015 Free Software Foundation, Inc.
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H13PRO009
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include "lisp.h"
#include "xterm.h"
#include "frame.h"
#include "blockinput.h"
#include "font.h"
/* FTX font driver. */
struct font_driver ftxfont_driver;
struct ftxfont_frame_data
{
/* Background and foreground colors. */
XColor colors[2];
/* GCs interpolating the above colors. gcs[0] is for a color
closest to BACKGROUND, and gcs[5] is for a color closest to
FOREGROUND. */
GC gcs[6];
struct ftxfont_frame_data *next;
};
/* Return an array of 6 GCs for antialiasing. */
static GC *
ftxfont_get_gcs (struct frame *f, unsigned long foreground, unsigned long background)
{
XColor color;
XGCValues xgcv;
int i;
struct ftxfont_frame_data *data = font_get_frame_data (f, Qftx);
struct ftxfont_frame_data *prev = NULL, *this = NULL, *new;
if (data)
{
for (this = data; this; prev = this, this = this->next)
{
if (this->colors[0].pixel < background)
continue;
if (this->colors[0].pixel > background)
break;
if (this->colors[1].pixel < foreground)
continue;
if (this->colors[1].pixel > foreground)
break;
return this->gcs;
}
}
new = xmalloc (sizeof *new);
new->next = this;
if (prev)
prev->next = new;
font_put_frame_data (f, Qftx, new);
new->colors[0].pixel = background;
new->colors[1].pixel = foreground;
block_input ();
XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), new->colors, 2);
for (i = 1; i < 7; i++)
{
/* Interpolate colors linearly. Any better algorithm? */
color.red
= (new->colors[1].red * i + new->colors[0].red * (8 - i)) / 8;
color.green
= (new->colors[1].green * i + new->colors[0].green * (8 - i)) / 8;
color.blue
= (new->colors[1].blue * i + new->colors[0].blue * (8 - i)) / 8;
if (! x_alloc_nearest_color (f, FRAME_X_COLORMAP (f), &color))
break;
xgcv.foreground = color.pixel;
new->gcs[i - 1] = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
GCForeground, &xgcv);
}
unblock_input ();
if (i < 7)
{
block_input ();
for (i--; i >= 0; i--)
XFreeGC (FRAME_X_DISPLAY (f), new->gcs[i]);
unblock_input ();
if (prev)
prev->next = new->next;
else if (data)
font_put_frame_data (f, Qftx, new->next);
xfree (new);
return NULL;
}
return new->gcs;
}
static int
ftxfont_draw_bitmap (struct frame *f, GC gc_fore, GC *gcs, struct font *font,
unsigned int code, int x, int y, XPoint *p, int size,
int *n, bool flush)
{
struct font_bitmap bitmap;
unsigned char *b;
int i, j;
if (ftfont_driver.get_bitmap (font, code, &bitmap, size > 0x100 ? 1 : 8) < 0)
return 0;
if (size > 0x100)
{
for (i = 0, b = bitmap.buffer; i < bitmap.rows;
i++, b += bitmap.pitch)
{
for (j = 0; j < bitmap.width; j++)
if (b[j / 8] & (1 << (7 - (j % 8))))
{
p[n[0]].x = x + bitmap.left + j;
p[n[0]].y = y - bitmap.top + i;
if (++n[0] == size)
{
XDrawPoints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
gc_fore, p, size, CoordModeOrigin);
n[0] = 0;
}
}
}
if (flush && n[0] > 0)
XDrawPoints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
gc_fore, p, n[0], CoordModeOrigin);
}
else
{
for (i = 0, b = bitmap.buffer; i < bitmap.rows;
i++, b += bitmap.pitch)
{
for (j = 0; j < bitmap.width; j++)
{
int idx = (bitmap.bits_per_pixel == 1
? ((b[j / 8] & (1 << (7 - (j % 8)))) ? 6 : -1)
: (b[j] >> 5) - 1);
if (idx >= 0)
{
XPoint *pp = p + size * idx;
pp[n[idx]].x = x + bitmap.left + j;
pp[n[idx]].y = y - bitmap.top + i;
if (++(n[idx]) == size)
{
XDrawPoints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
idx == 6 ? gc_fore : gcs[idx], pp, size,
CoordModeOrigin);
n[idx] = 0;
}
}
}
}
if (flush)
{
for (i = 0; i < 6; i++)
if (n[i] > 0)
XDrawPoints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
gcs[i], p + 0x100 * i, n[i], CoordModeOrigin);
if (n[6] > 0)
XDrawPoints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
gc_fore, p + 0x600, n[6], CoordModeOrigin);
}
}
if (ftfont_driver.free_bitmap)
ftfont_driver.free_bitmap (font, &bitmap);
return bitmap.advance;
}
static void
ftxfont_draw_background (struct frame *f, struct font *font, GC gc, int x, int y,
int width)
{
XGCValues xgcv;
XGetGCValues (FRAME_X_DISPLAY (f), gc,
GCForeground | GCBackground, &xgcv);
XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.background);
XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
x, y - FONT_BASE (font), width, FONT_HEIGHT (font));
XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.foreground);
}
static Lisp_Object
ftxfont_list (struct frame *f, Lisp_Object spec)
{
Lisp_Object list = ftfont_driver.list (f, spec), tail;
for (tail = list; CONSP (tail); tail = XCDR (tail))
ASET (XCAR (tail), FONT_TYPE_INDEX, Qftx);
return list;
}
static Lisp_Object
ftxfont_match (struct frame *f, Lisp_Object spec)
{
Lisp_Object entity = ftfont_driver.match (f, spec);
if (VECTORP (entity))
ASET (entity, FONT_TYPE_INDEX, Qftx);
return entity;
}
static Lisp_Object
ftxfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
Lisp_Object font_object;
struct font *font;
font_object = ftfont_driver.open (f, entity, pixel_size);
if (NILP (font_object))
return Qnil;
font = XFONT_OBJECT (font_object);
font->driver = &ftxfont_driver;
return font_object;
}
static void
ftxfont_close (struct font *font)
{
ftfont_driver.close (font);
}
static int
ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y,
bool with_background)
{
struct frame *f = s->f;
struct face *face = s->face;
struct font *font = s->font;
XPoint p[0x700];
int n[7];
unsigned *code;
int len = to - from;
int i;
GC *gcs;
int xadvance;
n[0] = n[1] = n[2] = n[3] = n[4] = n[5] = n[6] = 0;
USE_SAFE_ALLOCA;
SAFE_NALLOCA (code, 1, len);
block_input ();
if (with_background)
ftxfont_draw_background (f, font, s->gc, x, y, s->width);
for (i = 0; i < len; i++)
code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
| XCHAR2B_BYTE2 (s->char2b + from + i));
if (face->gc == s->gc)
{
gcs = ftxfont_get_gcs (f, face->foreground, face->background);
}
else
{
XGCValues xgcv;
unsigned long mask = GCForeground | GCBackground;
XGetGCValues (FRAME_X_DISPLAY (f), s->gc, mask, &xgcv);
gcs = ftxfont_get_gcs (f, xgcv.foreground, xgcv.background);
}
if (gcs)
{
if (s->num_clips)
for (i = 0; i < 6; i++)
XSetClipRectangles (FRAME_X_DISPLAY (f), gcs[i], 0, 0,
s->clip, s->num_clips, Unsorted);
for (i = 0; i < len; i++)
{
xadvance = ftxfont_draw_bitmap (f, s->gc, gcs, font, code[i], x, y,
p, 0x100, n, i + 1 == len);
x += (s->padding_p ? 1 : xadvance);
}
if (s->num_clips)
for (i = 0; i < 6; i++)
XSetClipMask (FRAME_X_DISPLAY (f), gcs[i], None);
}
else
{
/* We can't draw with antialiasing.
s->gc should already have a proper clipping setting. */
for (i = 0; i < len; i++)
{
xadvance = ftxfont_draw_bitmap (f, s->gc, NULL, font, code[i], x, y,
p, 0x700, n, i + 1 == len);
x += (s->padding_p ? 1 : xadvance);
}
}
unblock_input ();
SAFE_FREE ();
return len;
}
static int
ftxfont_end_for_frame (struct frame *f)
{
struct ftxfont_frame_data *data = font_get_frame_data (f, Qftx);
block_input ();
while (data)
{
struct ftxfont_frame_data *next = data->next;
int i;
for (i = 0; i < 6; i++)
XFreeGC (FRAME_X_DISPLAY (f), data->gcs[i]);
xfree (data);
data = next;
}
unblock_input ();
font_put_frame_data (f, Qftx, NULL);
return 0;
}
void
syms_of_ftxfont (void)
{
DEFSYM (Qftx, "ftx");
ftxfont_driver = ftfont_driver;
ftxfont_driver.type = Qftx;
ftxfont_driver.list = ftxfont_list;
ftxfont_driver.match = ftxfont_match;
ftxfont_driver.open = ftxfont_open;
ftxfont_driver.close = ftxfont_close;
ftxfont_driver.draw = ftxfont_draw;
ftxfont_driver.end_for_frame = ftxfont_end_for_frame;
register_font_driver (&ftxfont_driver, NULL);
}