X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fdraw.c;h=033b69e28a7425dce5d78458e5a877e0f59021a6;hb=83ab367a9fa9629f58ba02dbb84b59d1e37019da;hp=c97c8c1d71b60a9dfe832f0ac8231068dd35bc9a;hpb=ad58cb889c537b38b6b9e6ce853c2e956abed259;p=m17n%2Fm17n-lib.git diff --git a/src/draw.c b/src/draw.c index c97c8c1..033b69e 100644 --- a/src/draw.c +++ b/src/draw.c @@ -34,7 +34,7 @@ ways, which provides powerful 2-dimensional layouting facility. */ -/***ja +/***oldja @addtogroup m17nDraw @brief M-text ɽ¼¨¤Î¤¿¤á¤Î m17n-gui API @@ -79,6 +79,8 @@ static MSymbol Mlatin, Minherited; /* Special categories */ static MSymbol McatCc, McatCf; +static MSymbol Mdepth; + /* Glyph-string composer. */ @@ -127,8 +129,7 @@ visual_order (MGlyphString *gstring) levels[size] = 0; idx[size] = GLYPH_INDEX (g); logical[size++] = g++->c; - while (g->type != GLYPH_ANCHOR - && g->combining_code) + while (g->type != GLYPH_ANCHOR && g->combining_code) g++; } @@ -170,7 +171,6 @@ visual_order (MGlyphString *gstring) { int j = indices[i]; int k = idx[j]; - int pos = glyphs[k].pos; glyphs[k].bidi_level = levels[j]; #ifdef HAVE_FRIBIDI @@ -185,8 +185,7 @@ visual_order (MGlyphString *gstring) #endif /* not HAVE_FRIBIDI */ *(MGLYPH (gidx)) = glyphs[k]; for (gidx++, k++; - (k < gstring->used - 1 - && (glyphs[k].pos == pos || glyphs[k].combining_code)); + k < gstring->used - 1 && glyphs[k].combining_code; gidx++, k++) { glyphs[k].bidi_level = levels[j]; @@ -237,8 +236,8 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, MRealizedFace *rface = default_rface; int non_ascii_found; int size = gstring->control.fixed_width; - int ignore_formatting_char = gstring->control.ignore_formatting_char; int i, limit; + int last; MLIST_RESET (gstring); gstring->from = from; @@ -254,7 +253,7 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, APPEND_GLYPH (gstring, g_tmp); stop = face_change = charset_change = language_change = pos = from; - g = gstring->glyphs + gstring->used; + last = 0; non_ascii_found = 0; while (1) { @@ -276,24 +275,21 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, else { g_tmp.category = mchar_get_prop (c, Mcategory); - if (ignore_formatting_char && g_tmp.category == McatCf) - g_tmp.type = GLYPH_SPACE, this_script = Mnil; - else - { - g_tmp.type = GLYPH_CHAR; - this_script = (MSymbol) mchar_get_prop (c, Mscript); - if (this_script == Minherited) - this_script = script; - } + g_tmp.type = GLYPH_CHAR; + this_script = (MSymbol) mchar_get_prop (c, Mscript); + if (this_script == Minherited) + this_script = script; } - if (pos == stop || script != this_script || g->type != g_tmp.type) + if (pos == stop || script != this_script + || MGLYPH (last)->type != g_tmp.type) { + g = MGLYPH (last); if (non_ascii_found && g->type == GLYPH_CHAR) while (g < gstring->glyphs + gstring->used) g = mface__for_chars (script, language, charset, g, gstring->glyphs + gstring->used, size); - g = gstring->glyphs + gstring->used; + last = gstring->used; non_ascii_found = 0; script = this_script; if (pos == to) @@ -320,7 +316,9 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, language, charset, size) : default_rface); } - stop = language_change; + stop = to; + if (stop > language_change) + stop = language_change; if (stop > charset_change) stop = charset_change; if (face_change < stop) @@ -336,12 +334,12 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, non_ascii_found = 1; else if (g_tmp.type == GLYPH_CHAR && (c <= 32 || c == 127)) { - g_tmp.c = '^'; + g_tmp.code = '^'; APPEND_GLYPH (gstring, g_tmp); if (c < ' ') - g_tmp.c += 0x40; + g_tmp.code = g_tmp.c + 0x40; else - g_tmp.c = '?'; + g_tmp.code = '?'; } APPEND_GLYPH (gstring, g_tmp); if (c == '\n' @@ -369,17 +367,31 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, if (this->type == GLYPH_CHAR && this->rface->rfont) { int start = i++; - MGlyph *tmp = gstring->glyphs + i; if (this->rface->rfont->layouter != Mnil) { - while ((tmp->type == GLYPH_CHAR || tmp->type == GLYPH_SPACE) - && tmp->rface->rfont == this->rface->rfont - && tmp->code != MCHAR_INVALID_CODE) - i++, tmp++; - i = mfont__flt_run (gstring, start, i, - this->rface->rfont->layouter, - this->rface->ascii_rface); + MGlyph *prev; + unsigned code; + + for (prev = MGLYPH (start - 1); + (prev->type == GLYPH_CHAR + && prev->category == McatCf + && (code = mfont__encode_char (this->rface->rfont, prev->c) + != MCHAR_INVALID_CODE)); + start--, prev--) + prev->code = code; + + for (g++; + (g->type == GLYPH_CHAR + && (g->rface->rfont == this->rface->rfont + || (g->category == McatCf + && ((code = mfont__encode_char (this->rface->rfont, + g->c)) + != MCHAR_INVALID_CODE)))); + i++, g++) + if (g->rface->rfont != this->rface->rfont) + g->code = code; + i = mfont__flt_run (gstring, start, i, this->rface); } else { @@ -474,6 +486,8 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to) g_physical_descent = gstring->physical_descent; g_width = g_lbearing = g_rbearing = 0; + mfont__get_metric (gstring, from, to); + while (g < last_g) { MGlyph *base = g++; @@ -481,7 +495,6 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to) int size = rfont->font.property[MFONT_SIZE]; int width, lbearing, rbearing; - mfont__get_metric (rfont, base); if (g == last_g || ! g->combining_code) { /* No combining. */ @@ -541,7 +554,6 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to) else if (end < g->to) end = g->to; - mfont__get_metric (rfont, g); g->xoff = left + (width * base_x - g->width * add_x) / 2 + off_x; if (g->xoff < left) left = g->xoff; @@ -572,6 +584,8 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to) base->ascent = - top; base->descent = bottom; + base->lbearing = lbearing; + base->rbearing = rbearing; if (left < - base->width) { base->xoff = - base->width - left; @@ -629,6 +643,7 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) int width; MFaceBoxProp *box; int box_line_height = 0; + int ignore_formatting_char = control->ignore_formatting_char; gstring->ascent = gstring->descent = 0; gstring->physical_ascent = gstring->physical_descent = 0; @@ -691,6 +706,9 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) } } + if (g->category == McatCf && ignore_formatting_char) + g->type = GLYPH_SPACE; + if (g->type == GLYPH_CHAR) { MRealizedFace *rface = g->rface; @@ -702,7 +720,8 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) if (! rfont != ! g->rface->rfont || box != g->rface->box || ((fromg->code == MCHAR_INVALID_CODE) - != (g->code == MCHAR_INVALID_CODE))) + != (g->code == MCHAR_INVALID_CODE)) + || (g->category == McatCf && ignore_formatting_char)) break; if (rfont && fromg->code != MCHAR_INVALID_CODE) { @@ -1125,7 +1144,8 @@ render_glyphs (MFrame *frame, MDrawWindow win, int x, int y, int width, rect.x += rect.width; if (rect.x < x + width) { - while (g != gend && x + width - gend[-1].width >= rect.x) + while (g != gend + && (x + width - gend[-1].width + gend[-1].lbearing >= rect.x)) { width -= (--gend)->width; while (! gend->enabled && g != gend) @@ -1341,7 +1361,8 @@ free_gstring (void *object) static MGlyphString scratch_gstring; static MGlyphString * -alloc_gstring (MText *mt, int pos, MDrawControl *control, int line, int y) +alloc_gstring (MFrame *frame, MText *mt, int pos, MDrawControl *control, + int line, int y) { MGlyphString *gstring; @@ -1364,6 +1385,10 @@ alloc_gstring (MText *mt, int pos, MDrawControl *control, int line, int y) (*control->format) (line, y, &(gstring->indent), &(gstring->width_limit)); else gstring->width_limit = control->max_line_width; + gstring->anti_alias = control->anti_alias; + if (gstring->anti_alias + && (unsigned) mwin__device_get_prop (frame->device, Mdepth) < 8) + gstring->anti_alias = 0; return gstring; } @@ -1489,7 +1514,7 @@ get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control) beg = pos; end = to; } - gstring = alloc_gstring (mt, beg, control, line, y); + gstring = alloc_gstring (frame, mt, beg, control, line, y); compose_glyph_string (frame, mt, beg, end, gstring); layout_glyph_string (frame, gstring); end = gstring->to; @@ -1503,7 +1528,8 @@ get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control) while (gst->to < end) { line++, y += gst->height; - gst->next = alloc_gstring (mt, gst->from, control, line, y); + gst->next = alloc_gstring (frame, mt, gst->from, control, + line, y); gst->next->top = gstring; compose_glyph_string (frame, mt, gst->to, end, gst->next); gst = gst->next; @@ -1625,7 +1651,7 @@ dump_combining_code (int code) else if (off_y < 0) sprintf (work + 2, "%d", off_y); else if (off_x == 0) - sprintf (work + 2, "-"); + sprintf (work + 2, "."); p = work + strlen (work); if (off_x > 0) sprintf (p, ">%d", off_x); @@ -1679,6 +1705,7 @@ mdraw__init () McatCc = msymbol ("Cc"); McatCf = msymbol ("Cf"); + Mdepth = msymbol ("depth"); MbidiR = msymbol ("R"); MbidiAL = msymbol ("AL"); @@ -1776,7 +1803,7 @@ mdraw__fini () error is detected, it returns -1 and assigns an error code to the external variable @c merror_code. */ -/***ja +/***oldja @brief ¥¦¥£¥ó¥É¥¦¤Ë M-text ¤òɽ¼¨¤¹¤ë ´Ø¿ô mdraw_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤ÎºÂɸ @@ -1878,7 +1905,7 @@ mdraw_text (MFrame *frame, MDrawWindow win, int x, int y, If an error is detected, it returns -1 and assigns an error code to the external variable @c merror_code. */ -/***ja +/***oldja @brief ¥Ç¥£¥¹¥×¥ì¥¤¤ËM-text ¤ò²èÁü¤È¤·¤ÆÉÁ¤¯ ´Ø¿ô mdraw_image_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤Î @@ -1981,7 +2008,7 @@ mdraw_text_with_control (MFrame *frame, MDrawWindow win, int x, int y, the widest line. If an error occurs, it returns -1 and assigns an error code to the external variable @c merror_code. */ -/***ja +/***oldja @brief ¥Æ¥­¥¹¥È¤ÎÉý¤ò·×»»¤¹¤ë ´Ø¿ô mdraw_text_extents () ¤Ï¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤ò @@ -2232,7 +2259,7 @@ mdraw_text_per_char_extents (MFrame *frame, maximum X-coordinate, it returns the character position of the last character drawn on the line $Y. */ -/***ja +/***oldja @brief »ØÄꤷ¤¿ºÂɸ¤Ë¤¢¤ëʸ»ú¤Î°ÌÃÖ¤òÆÀ¤ë ´Ø¿ô mdraw_coordinates_position () ¤Ï¡¢ @@ -2511,7 +2538,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos, of the textitems to be drawn and $NITEMS is the number of textimtems in the array. */ -/***ja +/***oldja @brief textitem ¤òɽ¼¨¤¹¤ë ´Ø¿ô mdraw_text_items () ¤Ï¡¢°ì¸Ä°Ê¾å¤Î¥Æ¥­¥¹¥È¥¢¥¤¥Æ¥à¤ò¡¢¥Õ¥ì¡¼ @@ -2597,7 +2624,7 @@ mdraw_default_line_break (MText *mt, int pos, computes the extents of the overall text and stores the results in the members of the structure pointed to by $OVERALL_RETURN */ -/***ja +/***oldja @brief M-text ¤Îʸ»úËè¤Î¾ðÊó¤òÆÀ¤ë ´Ø¿ô mdraw_per_char_extents () ¤Ï¡¢M-text $MT Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈÏ°Ï