/* Anchor of the chain of MDisplayInfo objects. */
static MPlist *display_info_list;
+
+/* Color value and the corresponding GC. */
typedef struct
{
unsigned int rgb; /* (red << 16) | (green << 8) | blue */
GC gc;
-} MColorGC;
+} RGB_GC;
+
+enum face_gc
+ {
+ MFACE_GC_NORMAL,
+ MFACE_GC_INVERSE,
+ MFACE_GC_HLINE,
+ MFACE_GC_BOX_TOP,
+ MFACE_GC_BOX_BOTTOM,
+ MFACE_GC_BOX_LEFT,
+ MFACE_GC_BOX_RIGHT,
+ MFACE_GCS
+ };
+
+typedef struct
+{
+ int rgb_fore;
+ int rgb_back;
+ GC gc[MFACE_GCS + 8];
+} GCInfo;
struct MWDevice
{
Colormap cmap;
- GC gc_fore, gc_back, gc_scratch;
+ GCInfo gc_info;
/** List of pointers to realized faces on the frame. */
MPlist *realized_face_list;
#define FRAME_DISPLAY(frame) (frame->device->display_info->display)
#define FRAME_SCREEN(frame) (frame->device->screen_num)
-enum face_gc
- {
- MFACE_GC_NORMAL,
- MFACE_GC_INVERSE,
- MFACE_GC_HLINE,
- MFACE_GC_BOX_TOP,
- MFACE_GC_BOX_BOTTOM,
- MFACE_GC_BOX_LEFT,
- MFACE_GC_BOX_RIGHT,
- MFACE_GCS
- };
-
static void
free_display_info (void *object)
{
MPLIST_DO (plist, device->gc_list)
{
XFreeGC (device->display_info->display,
- ((MColorGC *) MPLIST_VAL (plist))->gc);
+ ((RGB_GC *) MPLIST_VAL (plist))->gc);
free (MPLIST_VAL (plist));
}
M17N_OBJECT_UNREF (device->gc_list);
{
unsigned long valuemask = GCForeground;
- XCopyGC (FRAME_DISPLAY (frame), gc, valuemask, frame->device->gc_scratch);
- XSetRegion (FRAME_DISPLAY (frame), frame->device->gc_scratch, region);
- return frame->device->gc_scratch;
+ XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
+ frame->device->gc_info.gc[MFACE_GCS]);
+ XSetRegion (FRAME_DISPLAY (frame), frame->device->gc_info.gc[MFACE_GCS],
+ region);
+ return frame->device->gc_info.gc[MFACE_GCS];
}
/* The X font driver function RENDER. */
MRealizedFace *rface = from->rface;
Display *display;
XChar2b *code;
- GC *gcs = rface->info;
- GC gc = gcs[reverse ? MFACE_GC_INVERSE : MFACE_GC_NORMAL];
+ GC gc = ((GCInfo *) rface->info)->gc[reverse ? MFACE_GC_INVERSE
+ : MFACE_GC_NORMAL];
MGlyph *g;
int i;
{
unsigned long valuemask = GCForeground;
XGCValues values;
+ XColor color;
M17N_OBJECT (device, free_device, MERROR_WIN);
device->display_info = disp_info;
device->realized_face_list = mplist ();
device->realized_fontset_list = mplist ();
values.foreground = BlackPixel (display, screen_num);
- device->gc_fore = XCreateGC (display, device->drawable,
- valuemask, &values);
- device->gc_scratch = XCreateGC (display, device->drawable,
- valuemask, &values);
+ color.pixel = values.foreground;
+ XQueryColor (display, cmap, &color);
+ device->gc_info.rgb_fore
+ = (((color.red >> 8) << 16) | ((color.green >> 8) << 8)
+ | (color.blue >> 8));
+ device->gc_info.gc[MFACE_GC_NORMAL]
+ = XCreateGC (display, device->drawable, valuemask, &values);
+ device->gc_info.gc[MFACE_GCS]
+ = XCreateGC (display, device->drawable, valuemask, &values);
values.foreground = WhitePixel (display, screen_num);
- device->gc_back = XCreateGC (display, device->drawable,
- valuemask, &values);
+ color.pixel = values.foreground;
+ XQueryColor (display, cmap, &color);
+ device->gc_info.rgb_back
+ = (((color.red >> 8) << 16) | ((color.green >> 8) << 8)
+ | (color.blue >> 8));
+ device->gc_info.gc[MFACE_GC_INVERSE]
+ = XCreateGC (display, device->drawable, valuemask, &values);
device->gc_list = mplist ();
}
static GC
-get_gc (MFrame *frame, MSymbol color, int for_foreground)
+get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret)
{
MWDevice *device = frame->device;
XColor xcolor;
unsigned long valuemask = GCForeground;
XGCValues values;
GC gc;
- MColorGC *color_gc;
- unsigned int rgb;
+ RGB_GC *rgb_gc;
+ int rgb;
+
+ if (color == Mnil)
+ {
+ if (for_foreground)
+ rgb = device->gc_info.rgb_fore,
+ gc = device->gc_info.gc[MFACE_GC_NORMAL];
+ else
+ rgb = device->gc_info.rgb_back,
+ gc = device->gc_info.gc[MFACE_GC_INVERSE];
+ if (rgb_ret)
+ *rgb_ret = rgb;
+ return gc;
+ }
if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
msymbol_name (color), &xcolor))
- return (for_foreground ? device->gc_fore : device->gc_back);
+ goto no_color;
rgb = (((xcolor.red >> 8) << 16) | ((xcolor.green >> 8) << 8)
| (xcolor.blue >> 8));
+ if (rgb_ret)
+ *rgb_ret = rgb;
MPLIST_DO (plist, device->gc_list)
{
- color_gc = MPLIST_VAL (plist);
+ rgb_gc = MPLIST_VAL (plist);
- if (color_gc->rgb == rgb)
- return color_gc->gc;
- if (color_gc->rgb > rgb)
+ if (rgb_gc->rgb == rgb)
+ return rgb_gc->gc;
+ if (rgb_gc->rgb > rgb)
break;
}
if (! XAllocColor (FRAME_DISPLAY (frame), device->cmap, &xcolor))
- return (for_foreground ? device->gc_fore : device->gc_back);
+ goto no_color;
values.foreground = xcolor.pixel;
gc = XCreateGC (FRAME_DISPLAY (frame), device->drawable, valuemask, &values);
- color_gc = malloc (sizeof (MColorGC));
- color_gc->rgb = rgb;
- color_gc->gc = gc;
- mplist_push (plist, Mt, color_gc);
+ rgb_gc = malloc (sizeof (RGB_GC));
+ rgb_gc->rgb = rgb;
+ rgb_gc->gc = gc;
+ mplist_push (plist, Mt, rgb_gc);
return gc;
+
+ no_color:
+ {
+ GCInfo *info = frame->rface ? frame->rface->info : &device->gc_info;
+
+ if (for_foreground)
+ {
+ if (rgb_ret)
+ *rgb_ret = info->rgb_fore;
+ gc = info->gc[MFACE_GC_NORMAL];
+ }
+ else
+ {
+ if (rgb_ret)
+ *rgb_ret = info->rgb_back;
+ gc = info->gc[MFACE_GC_INVERSE];
+ }
+ }
+ return (gc);
}
void
mwin__realize_face (MRealizedFace *rface)
{
- MFrame *frame = rface->frame;
- MSymbol foreground = rface->face.property[MFACE_FOREGROUND];
- MSymbol background = rface->face.property[MFACE_BACKGROUND];
- MFaceHLineProp *hline = rface->hline;
- MFaceBoxProp *box = rface->box;
- MFaceHookFunc func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC];
- GC *gcs;
-
- MTABLE_CALLOC (gcs, MFACE_GCS + 1, MERROR_WIN);
-
- gcs[MFACE_GC_NORMAL] = get_gc (frame, foreground, 1);
- gcs[MFACE_GC_INVERSE] = get_gc (frame, background, 0);
-
- if (rface->face.property[MFACE_VIDEOMODE] == Mreverse)
+ MFrame *frame;
+ MSymbol foreground, background;
+ MFaceHLineProp *hline;
+ MFaceBoxProp *box;
+ MFaceHookFunc func;
+ GCInfo *info;
+ XColor color;
+
+ if (rface != rface->ascii_rface)
{
- GC gc = gcs[MFACE_GC_NORMAL];
- gcs[MFACE_GC_NORMAL] = gcs[MFACE_GC_INVERSE];
- gcs[MFACE_GC_INVERSE] = gc;
+ rface->info = rface->ascii_rface->info;
+ return;
}
- if (rface == rface->ascii_rface)
- {
- /* This realized face is for ASCII. Setup GCs for hline and
- box. */
- if (hline && hline->color != foreground)
- gcs[MFACE_GC_HLINE] = get_gc (frame, hline->color, 1);
+ frame = rface->frame;
+ foreground = rface->face.property[MFACE_FOREGROUND];
+ background = rface->face.property[MFACE_BACKGROUND];
+ hline = rface->hline;
+ box = rface->box;
+ func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC];
- if (box)
- {
- if (box->color_top)
- gcs[MFACE_GC_BOX_TOP] = get_gc (frame, box->color_top, 1);
- else
- gcs[MFACE_GC_BOX_TOP] = gcs[MFACE_GC_NORMAL];
+ MSTRUCT_CALLOC (info, MERROR_WIN);
- if (box->color_left && box->color_left != box->color_top)
- gcs[MFACE_GC_BOX_LEFT] = get_gc (frame, box->color_left, 1);
- else
- gcs[MFACE_GC_BOX_LEFT] = gcs[MFACE_GC_BOX_TOP];
+ info->gc[MFACE_GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
+ info->gc[MFACE_GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
+ info->gc[MFACE_GCS] = info->gc[MFACE_GC_INVERSE];
+ info->gc[MFACE_GCS + 7] = info->gc[MFACE_GC_NORMAL];
- if (box->color_bottom && box->color_bottom != box->color_top)
- gcs[MFACE_GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1);
- else
- gcs[MFACE_GC_BOX_BOTTOM] = gcs[MFACE_GC_BOX_TOP];
+ if (hline && hline->color != foreground)
+ info->gc[MFACE_GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
- if (box->color_right && box->color_right != box->color_top)
- gcs[MFACE_GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1);
- else
- gcs[MFACE_GC_BOX_RIGHT] = gcs[MFACE_GC_BOX_BOTTOM];
- }
- }
- else
+ if (box)
{
- /* This realized face is not for ASCII. GCs for hline and box
- are shared with that of the corresponding ASCII face. */
- GC *ascii_gcs = rface->ascii_rface->info;
- int i;
+ if (box->color_top)
+ info->gc[MFACE_GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
+ else
+ info->gc[MFACE_GC_BOX_TOP] = info->gc[MFACE_GC_NORMAL];
+
+ if (box->color_left && box->color_left != box->color_top)
+ info->gc[MFACE_GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
+ else
+ info->gc[MFACE_GC_BOX_LEFT] = info->gc[MFACE_GC_BOX_TOP];
- for (i = MFACE_GC_HLINE; i < MFACE_GCS; i++)
- gcs[i] = ascii_gcs[i];
+ if (box->color_bottom && box->color_bottom != box->color_top)
+ info->gc[MFACE_GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
+ else
+ info->gc[MFACE_GC_BOX_BOTTOM] = info->gc[MFACE_GC_BOX_TOP];
+
+ if (box->color_right && box->color_right != box->color_top)
+ info->gc[MFACE_GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
+ else
+ info->gc[MFACE_GC_BOX_RIGHT] = info->gc[MFACE_GC_BOX_BOTTOM];
}
- rface->info = gcs;
+ rface->info = info;
if (func)
(func) (&(rface->face), rface->info, rface->face.property[MFACE_HOOK_ARG]);
}
int reverse,
int x, int y, int width, int height, MDrawRegion region)
{
- GC *gcs = rface->info;
- GC gc = gcs[reverse ? MFACE_GC_NORMAL : MFACE_GC_INVERSE];
+ GC gc = ((GCInfo *) rface->info)->gc[reverse ? MFACE_GC_INVERSE
+ : MFACE_GC_NORMAL];
if (region)
gc = set_region (frame, gc, region);
int x, int y, int width, MDrawRegion region)
{
enum MFaceHLineType type = rface->hline->type;
- GC *gcs = rface->info;
+ GCInfo *info = rface->info;
GC gc;
int i;
? y - ((gstring->ascent + gstring->descent) / 2)
: y - gstring->text_ascent);
if (reverse)
- gc = gcs[MFACE_GC_INVERSE];
- else if (gcs[MFACE_GC_HLINE])
- gc = gcs[MFACE_GC_HLINE];
+ gc = info->gc[MFACE_GC_INVERSE];
+ else if (info->gc[MFACE_GC_HLINE])
+ gc = info->gc[MFACE_GC_HLINE];
else
- gc = gcs[MFACE_GC_NORMAL];
+ gc = info->gc[MFACE_GC_NORMAL];
if (region)
gc = set_region (frame, gc, region);
Display *display = FRAME_DISPLAY (frame);
MRealizedFace *rface = g->rface;
MFaceBoxProp *box = rface->box;
- GC *gcs = rface->info;
+ GCInfo *info = rface->info;
GC gc_top, gc_left, gc_right, gc_btm;
int y0, y1;
int i;
y1 = y + (gstring->text_descent
+ rface->box->inner_vmargin + rface->box->width - 1);
- gc_top = gcs[MFACE_GC_BOX_TOP];
+ gc_top = info->gc[MFACE_GC_BOX_TOP];
if (! gc_top)
- gc_top = gcs[MFACE_GC_NORMAL];
+ gc_top = info->gc[MFACE_GC_NORMAL];
if (region)
gc_top = set_region (frame, gc_top, region);
- gc_btm = gcs[MFACE_GC_BOX_BOTTOM];
+ gc_btm = info->gc[MFACE_GC_BOX_BOTTOM];
if (! gc_btm)
gc_btm = gc_top;
if (g->left_padding > 0)
{
/* Draw the left side. */
- gc_left = gcs[MFACE_GC_BOX_LEFT];
+ gc_left = info->gc[MFACE_GC_BOX_LEFT];
if (! gc_left)
gc_left = gc_top;
else if (region)
else
{
/* Draw the right side. */
- gc_right = gcs[MFACE_GC_BOX_RIGHT];
+ gc_right = info->gc[MFACE_GC_BOX_RIGHT];
if (! gc_right)
gc_right = gc_top;
else if (region)
{
Display *display = FRAME_DISPLAY (frame);
int i, j;
- GC *gcs = rface->info;
- GC gc = gcs[reverse ? MFACE_GC_INVERSE : MFACE_GC_NORMAL];
+ GC gc = ((GCInfo *) rface->info)->gc[reverse ? MFACE_GC_INVERSE
+ : MFACE_GC_NORMAL];
if (region)
gc = set_region (frame, gc, region);
XDrawPoint (display, (Window) win, gc, x + j, y + i);
}
+
+static GC
+get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity)
+{
+ int rgb_fore = info->rgb_fore, rgb_back = info->rgb_back;
+ XColor color;
+
+ if (intensity == 0)
+ return info->gc[MFACE_GC_INVERSE];
+ if (intensity == 7)
+ return info->gc[MFACE_GC_NORMAL];
+
+ color.red = ((((rgb_fore & 0xFF0000) >> 16) * intensity
+ + ((rgb_back & 0xFF0000) >> 16) * (7 - intensity)) / 7) << 8;
+ color.green = ((((rgb_fore & 0xFF00) >> 8) * intensity
+ + ((rgb_back & 0xFF00) >> 8) * (7 - intensity)) / 7) << 8;
+ color.blue = (((rgb_fore & 0xFF) * intensity
+ + (rgb_back & 0xFF) * (7 - intensity)) / 7) << 8;
+ if (XAllocColor (device->display_info->display, device->cmap, &color))
+ {
+ unsigned long valuemask = GCForeground;
+ XGCValues values;
+
+ values.foreground = color.pixel;
+ return XCreateGC (device->display_info->display, device->drawable,
+ valuemask, &values);
+ }
+ return get_gc_for_anti_alias (device, info,
+ (intensity < 4 ? --intensity : ++ intensity));
+}
+
void
mwin__draw_pixmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
int reverse, int x, int y,
MDrawRegion region)
{
Display *display = FRAME_DISPLAY (frame);
+ GCInfo *info = rface->info;
int i, j;
- GC *gcs = rface->info;
GC gc;
- unsigned long valuemask = GCForeground | GCBackground;
- XGCValues values;
- XColor fore_color, back_color, color;
-
- XGetGCValues (FRAME_DISPLAY (frame), gc, valuemask, &values);
- fore_color.pixel = values.foreground;
- back_color.pixel = values.background;
- XQueryColor (FRAME_DISPLAY (frame), frame->device->cmap, &fore_color);
- XQueryColor (FRAME_DISPLAY (frame), frame->device->cmap, &back_color);
-
- if (! gcs[MFACE_GCS])
- {
- GC *new_gcs;
-
- MTABLE_CALLOC (new_gcs, MFACE_GCS + 6, MERROR_WIN);
- memcpy (new_gcs, gcs, sizeof (GC) * MFACE_GCS);
- for (i = 0; i < 6; i++)
- {
-
- }
-
- }
-
- if (region)
- gc = set_region (frame, gc, region);
-
-
for (i = 0; i < height; i++, pmp += row_bytes)
for (j = 0; j < width; j++)
if (pmp[j])
{
- int fore_ratio = pmp[j] >> 5, back_ratio = 7 - fore_ratio;
-
- color = fore_color;
- color.red = ((fore_color.red * fore_ratio) + (back_color.red * back_ratio)) / 7;
- color.green = ((fore_color.green * fore_ratio) + (back_color.green * back_ratio)) / 7;
- color.blue = ((fore_color.blue * fore_ratio) + (back_color.blue * back_ratio)) / 7;
- if (XAllocColor (FRAME_DISPLAY (frame), frame->device->cmap, &color)
- && fore_color.pixel != color.pixel)
- {
- XSetForeground (FRAME_DISPLAY (frame), gc, color.pixel);
- fore_color.pixel = color.pixel;
- }
+ int intensity = reverse ? (7 - (pmp[j] >> 5)) : (pmp[j] >> 5);
+ GC gc = info->gc[MFACE_GCS + intensity];
+
+ if (! gc)
+ gc = info->gc[MFACE_GCS + intensity]
+ = get_gc_for_anti_alias (frame->device, info, intensity);
+ if (region)
+ gc = set_region (frame, gc, region);
XDrawPoint (display, (Window) win, gc, x + j, y + i);
}
- if (fore_color.pixel != values.foreground)
- XSetForeground (FRAME_DISPLAY (frame), gc, values.foreground);
}
void
mwin__verify_region (MFrame *frame, MDrawRegion region)
{
- set_region (frame, ((GC *) frame->rface->info)[MFACE_GC_NORMAL], region);
+ set_region (frame, ((GCInfo *) frame->rface->info)->gc[MFACE_GC_NORMAL],
+ region);
}
MDrawWindow
unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
XGCValues values;
Display *display = FRAME_DISPLAY (frame);
- GC *gcs = rface->info;
+ GCInfo *info = rface->info;
int i;
for (i = 0; i <= MFACE_GC_INVERSE; i++)
{
- XGetGCValues (display, gcs[i], valuemask, &values);
+ XGetGCValues (display, info->gc[i], valuemask, &values);
fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
values.foreground, values.background);
fprintf (stderr, "\n");