From: handa Date: Sun, 14 Mar 2004 23:54:56 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=58b9b8a4f78dfd6993a63f070f8eb31a37e138b2;p=m17n%2Fm17n-lib.git *** empty log message *** --- diff --git a/src/m17n-X.c b/src/m17n-X.c index 2a33689..e357b06 100644 --- a/src/m17n-X.c +++ b/src/m17n-X.c @@ -84,11 +84,32 @@ typedef struct /* 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 { @@ -105,7 +126,7 @@ 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; @@ -124,18 +145,6 @@ static MSymbol M_iso8859_1, M_iso10646_1; #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) { @@ -205,7 +214,7 @@ free_device (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); @@ -732,9 +741,11 @@ set_region (MFrame *frame, GC gc, MDrawRegion region) { 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. */ @@ -746,8 +757,8 @@ xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring, 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; @@ -1264,6 +1275,7 @@ mwin__open_device (MFrame *frame, MPlist *param) { unsigned long valuemask = GCForeground; XGCValues values; + XColor color; M17N_OBJECT (device, free_device, MERROR_WIN); device->display_info = disp_info; @@ -1277,13 +1289,23 @@ mwin__open_device (MFrame *frame, MPlist *param) 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 (); } @@ -1387,7 +1409,7 @@ struct { 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; @@ -1395,101 +1417,128 @@ get_gc (MFrame *frame, MSymbol color, int for_foreground) 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]); } @@ -1507,8 +1556,8 @@ mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface, 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); @@ -1524,7 +1573,7 @@ mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring, 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; @@ -1536,11 +1585,11 @@ mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring, ? 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); @@ -1558,7 +1607,7 @@ mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring, 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; @@ -1568,12 +1617,12 @@ mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring, 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; @@ -1599,7 +1648,7 @@ mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring, 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) @@ -1611,7 +1660,7 @@ mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring, 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) @@ -1646,8 +1695,8 @@ mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface, { 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); @@ -1658,6 +1707,37 @@ mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface, 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, @@ -1665,57 +1745,24 @@ mwin__draw_pixmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface, 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); } @@ -1804,7 +1851,8 @@ mwin__dump_region (MDrawRegion region) 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 @@ -2052,12 +2100,12 @@ mwin__dump_gc (MFrame *frame, MRealizedFace *rface) 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");