X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fm17n-gd.c;h=99269e11c8af51c2c94a9f1143389de5fe45b355;hb=9d7ee19cc55a52fb74e149402f20a5c4c7b0650a;hp=3e1ce7a24cda5f04bccb04b63561ec31b035f627;hpb=78694746412ff04ee44865fab47793b9ea9d4bf8;p=m17n%2Fm17n-lib.git diff --git a/src/m17n-gd.c b/src/m17n-gd.c index 3e1ce7a..99269e1 100644 --- a/src/m17n-gd.c +++ b/src/m17n-gd.c @@ -1,5 +1,5 @@ /* m17n-gd.c -- implementation of the GUI API on GD Library. - Copyright (C) 2004 + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 National Institute of Advanced Industrial Science and Technology (AIST) Registration Number H15PRO112 @@ -17,7 +17,7 @@ You should have received a copy of the GNU Lesser General Public License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 02111-1307, USA. */ #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) @@ -67,13 +67,39 @@ static MSymbol M_rgb; static void read_rgb_txt () { - FILE *fp = fopen ("/usr/lib/X11/rgb.txt", "r"); - int r, g, b; + FILE *fp; + int r, g, b, i; + + /* At first, support HTML 4.0 color names. */ + msymbol_put (msymbol ("black"), M_rgb, (void *) 0x000000); + msymbol_put (msymbol ("silver"), M_rgb, (void *) 0xC0C0C0); + msymbol_put (msymbol ("gray"), M_rgb, (void *) 0x808080); + msymbol_put (msymbol ("white"), M_rgb, (void *) 0xFFFFFF); + msymbol_put (msymbol ("maroon"), M_rgb, (void *) 0x800000); + msymbol_put (msymbol ("red"), M_rgb, (void *) 0xFF0000); + msymbol_put (msymbol ("purple"), M_rgb, (void *) 0x800080); + msymbol_put (msymbol ("fuchsia"), M_rgb, (void *) 0xFF00FF); + msymbol_put (msymbol ("green"), M_rgb, (void *) 0x008000); + msymbol_put (msymbol ("lime"), M_rgb, (void *) 0x00FF00); + msymbol_put (msymbol ("olive"), M_rgb, (void *) 0x808000); + msymbol_put (msymbol ("yellow"), M_rgb, (void *) 0xFFFF00); + msymbol_put (msymbol ("navy"), M_rgb, (void *) 0x000080); + msymbol_put (msymbol ("blue"), M_rgb, (void *) 0x0000FF); + msymbol_put (msymbol ("teal"), M_rgb, (void *) 0x008080); + msymbol_put (msymbol ("aqua"), M_rgb, (void *) 0x00FFFF); - if (! fp) - fp = fopen ("/usr/X11R6/lib/X11/rgb.txt", "r"); - if (! fp) - return; + { + char *rgb_path[] + = {"/usr/lib/X11/rgb.txt", "/usr/X11R6/lib/X11/rgb.txt", + "/etc/X11/rgb.txt" }; + + fp = NULL; + for (i = 0; i < (sizeof rgb_path) / (sizeof rgb_path[0]); i++) + if ((fp = fopen ("/usr/lib/X11/rgb.txt", "r"))) + break; + if (! fp) + return; + } while (1) { char buf[256]; @@ -95,6 +121,8 @@ read_rgb_txt () buf[0] = c; fgets (buf + 1, 255, fp); len = strlen (buf); + for (i = 0; i < len; i++) + buf[i] = tolower (buf[i]); if (buf[len - 1] == '\n') buf[len - 1] = '\0'; b |= (r << 16) | (g << 8); @@ -223,6 +251,49 @@ intersect_rectangle (MDrawMetric *r1, MDrawMetric *r2, MDrawMetric *rect) gdImageColorResolve ((img), (color) >> 16, ((color) >> 8) & 0xFF, \ (color) & 0xFF) +static MRealizedFont *gd_font_open (MFrame *, MFont *, MFont *, + MRealizedFont *); +static void gd_render (MDrawWindow, int, int, MGlyphString *, + MGlyph *, MGlyph *, int, MDrawRegion); + +static MFontDriver gd_font_driver = + { NULL, gd_font_open, NULL, NULL, NULL, gd_render, NULL }; + +static MRealizedFont * +gd_font_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont) +{ + double size = font->size ? font->size : spec->size; + int reg = spec->property[MFONT_REGISTRY]; + MRealizedFont *new; + + if (rfont) + { + MRealizedFont *save = NULL; + + for (; rfont; rfont = rfont->next) + if (rfont->font == font + && (rfont->font->size ? rfont->font->size == size + : rfont->spec.size == size) + && rfont->spec.property[MFONT_REGISTRY] == reg) + { + if (! save) + save = rfont; + if (rfont->driver == &gd_font_driver) + return rfont; + } + rfont = save; + } + rfont = (mfont__ft_driver.open) (frame, font, spec, rfont); + if (! rfont) + return NULL; + M17N_OBJECT_REF (rfont->info); + MSTRUCT_CALLOC (new, MERROR_GD); + *new = *rfont; + new->driver = &gd_font_driver; + new->next = MPLIST_VAL (frame->realized_font_list); + MPLIST_VAL (frame->realized_font_list) = new; + return new; +} static void gd_render (MDrawWindow win, int x, int y, @@ -230,7 +301,6 @@ gd_render (MDrawWindow win, int x, int y, int reverse, MDrawRegion region) { gdImagePtr img = (gdImagePtr) win; - MFTInfo *ft_info; FT_Face ft_face; MRealizedFace *rface = from->rface; FT_Int32 load_flags = FT_LOAD_RENDER; @@ -238,15 +308,12 @@ gd_render (MDrawWindow win, int x, int y, int color, pixel; int r, g, b; - pixel = RESOLVE_COLOR (img, color); - if (from == to) return; /* It is assured that the all glyphs in the current range use the same realized face. */ - ft_info = (MFTInfo *) rface->rfont->info; - ft_face = ft_info->ft_face; + ft_face = rface->rfont->fontp; color = ((int *) rface->info)[reverse ? COLOR_INVERSE : COLOR_NORMAL]; pixel = RESOLVE_COLOR (img, color); @@ -261,14 +328,14 @@ gd_render (MDrawWindow win, int x, int y, #endif } - for (; from < to; x += from++->width) + for (; from < to; x += from++->g.xadv) { unsigned char *bmp; int xoff, yoff; int width, pitch; - FT_Load_Glyph (ft_face, (FT_UInt) from->code, load_flags); - yoff = y - ft_face->glyph->bitmap_top + from->yoff; + FT_Load_Glyph (ft_face, (FT_UInt) from->g.code, load_flags); + yoff = y - ft_face->glyph->bitmap_top + from->g.yoff; bmp = ft_face->glyph->bitmap.buffer; width = ft_face->glyph->bitmap.width; pitch = ft_face->glyph->bitmap.pitch; @@ -281,12 +348,18 @@ gd_render (MDrawWindow win, int x, int y, for (i = 0; i < ft_face->glyph->bitmap.rows; i++, bmp += ft_face->glyph->bitmap.pitch, yoff++) { - xoff = x + ft_face->glyph->bitmap_left + from->xoff; + xoff = x + ft_face->glyph->bitmap_left + from->g.xoff; for (j = 0; j < width; j++, xoff++) - if (bmp[j]) + if (bmp[j] > 0) { - int f = bmp[j] >> 5; int pixel1 = pixel; +#if HAVE_GD > 1 + int alpha = gdAlphaTransparent * (255 - bmp[j]) / 255; + + if (alpha > 0) + pixel1 = gdImageColorResolveAlpha (img, r, g, b, alpha); +#else + int f = bmp[j] >> 5; if (f < 7) { @@ -301,6 +374,7 @@ gd_render (MDrawWindow win, int x, int y, | ((b * f + b1 * (7 - f)) / 7)); pixel1 = RESOLVE_COLOR (img, color1); } +#endif gdImageSetPixel (img, xoff, yoff, pixel1); } } @@ -308,7 +382,7 @@ gd_render (MDrawWindow win, int x, int y, for (i = 0; i < ft_face->glyph->bitmap.rows; i++, bmp += ft_face->glyph->bitmap.pitch, yoff++) { - xoff = x + ft_face->glyph->bitmap_left + from->xoff; + xoff = x + ft_face->glyph->bitmap_left + from->g.xoff; for (j = 0; j < width; j++, xoff++) if (bmp[j / 8] & (1 << (7 - (j % 8)))) gdImageSetPixel (img, xoff, yoff, pixel); @@ -316,9 +390,6 @@ gd_render (MDrawWindow win, int x, int y, } } -static MFontDriver gd_font_driver = - { NULL, NULL, NULL, NULL, gd_render }; - static void gd_close (MFrame *frame) { @@ -443,15 +514,15 @@ gd_draw_empty_boxes (MDrawWindow win, int x, int y, y -= gstring->ascent - 1; height = gstring->ascent + gstring->descent - 2; if (! region) - for (; from < to; x += from++->width) - gdImageRectangle (img, x, y, x + from->width - 2, y + height - 1, color); + for (; from < to; x += from++->g.xadv) + gdImageRectangle (img, x, y, x + from->g.xadv - 2, y + height - 1, color); else { gdImagePtr cpy; MGlyph *g; int width, x1; - for (g = from, width = 0; g < to; width += g++->width); + for (g = from, width = 0; g < to; width += g++->g.xadv); cpy = get_scrach_image (img, width, height); MPLIST_DO (plist, region_list) { @@ -459,8 +530,8 @@ gd_draw_empty_boxes (MDrawWindow win, int x, int y, gdImageCopy (cpy, img, rect->x - x, rect->y - y, rect->x, rect->y, rect->x + rect->width, rect->y + rect->height); } - for (x1 = 0; from < to; x1 += from++->width) - gdImageRectangle (cpy, x1, 0, x1 + from->width - 2, height - 1, color); + for (x1 = 0; from < to; x1 += from++->g.xadv) + gdImageRectangle (cpy, x1, 0, x1 + from->g.xadv - 2, height - 1, color); MPLIST_DO (plist, region_list) { MDrawMetric *rect = MPLIST_VAL (plist); @@ -534,7 +605,7 @@ gd_draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring, gdImagePtr cpy; if (g->type == GLYPH_BOX) - width = g->width; + width = g->g.xadv; cpy = get_scrach_image (img, width, height); MPLIST_DO (plist, region_list) { @@ -557,9 +628,9 @@ gd_draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring, int x0, x1; if (g->left_padding) - x0 = x + box->outer_hmargin, x1 = x + g->width - 1; + x0 = x + box->outer_hmargin, x1 = x + g->g.xadv - 1; else - x0 = x, x1 = x + g->width - box->outer_hmargin - 1; + x0 = x, x1 = x + g->g.xadv - box->outer_hmargin - 1; /* Draw the top side. */ color = RESOLVE_COLOR (img, colors[COLOR_BOX_TOP]); @@ -740,9 +811,12 @@ device_init () scratch_images[0] = scratch_images[1] = NULL; gd_font_driver.select = mfont__ft_driver.select; - gd_font_driver.open = mfont__ft_driver.open; gd_font_driver.find_metric = mfont__ft_driver.find_metric; + gd_font_driver.has_char = mfont__ft_driver.has_char; gd_font_driver.encode_char = mfont__ft_driver.encode_char; + gd_font_driver.list = mfont__ft_driver.list; + gd_font_driver.check_otf = mfont__ft_driver.check_otf; + gd_font_driver.drive_otf = mfont__ft_driver.drive_otf; return 0; } @@ -766,8 +840,8 @@ device_fini () } M17N_OBJECT_UNREF (realized_face_list); - MPLIST_DO (plist, realized_font_list) - mfont__free_realized ((MRealizedFont *) MPLIST_VAL (plist)); + if (MPLIST_VAL (realized_font_list)) + mfont__free_realized (MPLIST_VAL (realized_font_list)); M17N_OBJECT_UNREF (realized_font_list); for (i = 0; i < 2; i++) @@ -783,6 +857,9 @@ device_open (MFrame *frame, MPlist *param) frame->device = NULL; frame->device_type = MDEVICE_SUPPORT_OUTPUT; + frame->dpi = (int) mplist_get (param, Mresolution); + if (frame->dpi == 0) + frame->dpi = 100; frame->driver = &gd_driver; frame->font_driver_list = mplist (); mplist_add (frame->font_driver_list, Mfreetype, &gd_font_driver); @@ -790,11 +867,17 @@ device_open (MFrame *frame, MPlist *param) frame->realized_face_list = realized_face_list; frame->realized_fontset_list = realized_fontset_list; face = mface_copy (mface__default); + mface_put_prop (face, Mfoundry, Mnil); + mface_put_prop (face, Mfamily, Mnil); mplist_push (param, Mface, face); M17N_OBJECT_UNREF (face); return 0; } +#else /* not HAVE_GD nor HAVE_FREETYPE */ + +int device_open () { return -1; } + #endif /* not HAVE_GD nor HAVE_FREETYPE */ /*** @} */