/***en
@addtogroup m17nDraw
- @brief Drawing M-text on a window.
+ @brief Drawing M-texts on a window.
The m17n GUI API provides functions to draw M-texts.
/***ja
@addtogroup m17nDraw
- @brief M-text ɽ¼¨¤Î¤¿¤á¤Î m17n-gui API
+ @brief M-text ¤ò¥¦¥£¥ó¥É¥¦¤ËÉÁ²è¤¹¤ë.
- m17n-gui API ¤Ë¤Ï¡¢M-text ¤òɽ¼¨¤¹¤ë¤¿¤á¤Î´Ø¿ô¤¬ÍÑ°Õ¤µ¤ì¤Æ¤¤¤ë¡£É½
- ¼¨¤ËÍѤ¤¤é¤ì¤ë¥Õ¥©¥ó¥È¤Ï¡¢¥Õ¥ì¡¼¥à¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤È¥×¥í¥Ñ¥Æ¥£¤Ë´ð
- ¤Å¤¤¤Æ¼«Æ°Åª¤Ë·èÄꤵ¤ì¤ë¡£¤Þ¤¿¡¢¿§¤ä²¼Àþ¤Ê¤É¤Î°À¤â¥Õ¥ì¡¼¥à¤Ë¤è¤Ã
- ¤Æ·èÄꤵ¤ì¤ë¡£ */
+ m17n-gui API ¤Ë¤Ï¡¢M-text ¤òɽ¼¨¤¹¤ë¤¿¤á¤Î´Ø¿ô¤¬ÍÑ°Õ¤µ¤ì¤Æ¤¤¤ë¡£
+
+ ɽ¼¨¤ËÍѤ¤¤é¤ì¤ë¥Õ¥©¥ó¥È¤Ï¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤È face ¥×¥í¥Ñ¥Æ¥£¤Ë´ð¤Å
+ ¤¤¤Æ¼«Æ°Åª¤Ë·èÄꤵ¤ì¤ë¡£¤Þ¤¿¡¢¥Õ¥©¥ó¥È¤Î¥µ¥¤¥º¤ä¿§¤ä²¼Àþ¤Ê¤É¤Î¸«±É
+ ¤¨¤â face ¤Ë¤è¤Ã¤Æ·è¤Þ¤ë¡£
+
+ M-text ¤ÎÉÁ²è¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï¿ÍͤÊÊýË¡¤ÇÀ©¸æ¤Ç¤¤ë¤Î¤Ç¡¢¶¯ÎϤÊÆó¼¡
+ ¸µ¥ì¥¤¥¢¥¦¥Èµ¡Ç½¤¬¼Â¸½¤Ç¤¤ë¡£
+ */
/*=*/
static MSymbol M_glyph_string;
/* Special scripts */
-static MSymbol Mlatin, Minherited;
+static MSymbol Minherited;
/* Special categories */
static MSymbol McatCc, McatCf;
-static MSymbol Mdepth;
-
\f
/* Glyph-string composer. */
{
int len = gstring->used - 2;
MGlyph *glyphs;
- int *idx = alloca (sizeof (int) * len);
- int gidx;
int bidi_sensitive = gstring->control.orientation_reversed;
- int size = 0;
- MGlyph *g = MGLYPH (1);
+ MGlyph *g;
int i;
#ifdef HAVE_FRIBIDI
- FriBidiCharType base = (gstring->control.orientation_reversed
- ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR);
+ FriBidiCharType base = bidi_sensitive ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR;
FriBidiChar *logical = alloca (sizeof (FriBidiChar) * len);
FriBidiChar *visual;
FriBidiStrIndex *indices;
- FriBidiLevel *levels = alloca (sizeof (FriBidiLevel) * len);
+ FriBidiLevel *levels;
#else /* not HAVE_FRIBIDI */
int *logical = alloca (sizeof (int) * len);
int *indices;
char *levels = alloca (len);
#endif /* not HAVE_FRIBIDI */
- while (g->type != GLYPH_ANCHOR)
+ for (g = MGLYPH (1), i = 0; g->type != GLYPH_ANCHOR; g++, i++)
{
- MSymbol bidi = (MSymbol) mchar_get_prop (g->c, Mbidi_category);
-
- if (bidi == MbidiR || bidi == MbidiAL
- || bidi == MbidiRLE || bidi == MbidiRLO)
+ if (! bidi_sensitive
+#ifndef HAVE_FRIBIDI
+ || 1
+#endif /* not HAVE_FRIBIDI */
+ )
{
- bidi_sensitive = 1;
- levels[size] = 1;
+ MSymbol bidi = (MSymbol) mchar_get_prop (g->c, Mbidi_category);
+
+ if (bidi == MbidiR || bidi == MbidiAL
+ || bidi == MbidiRLE || bidi == MbidiRLO)
+ {
+ bidi_sensitive = 1;
+#ifndef HAVE_FRIBIDI
+ levels[i] = 1;
+#endif /* not HAVE_FRIBIDI */
+ }
}
- else
- levels[size] = 0;
- idx[size] = GLYPH_INDEX (g);
- logical[size++] = g++->c;
- while (g->type != GLYPH_ANCHOR && g->combining_code)
- g++;
+ logical[i] = g->c;
}
if (! bidi_sensitive)
return;
- glyphs = alloca (sizeof (MGlyph) * gstring->used);
- memcpy (glyphs, gstring->glyphs, (sizeof (MGlyph) * gstring->used));
+ glyphs = alloca (sizeof (MGlyph) * len);
+ memcpy (glyphs, gstring->glyphs + 1, sizeof (MGlyph) * len);
#ifdef HAVE_FRIBIDI
- visual = alloca (sizeof (FriBidiChar) * size);
- indices = alloca (sizeof (FriBidiStrIndex) * size);
+ visual = alloca (sizeof (FriBidiChar) * (len + 1));
+ indices = alloca (sizeof (FriBidiStrIndex) * (len + 1));
+ levels = alloca (sizeof (FriBidiLevel) * (len + 1));
- fribidi_log2vis (logical, size, &base, visual, NULL, indices, levels);
+ fribidi_log2vis (logical, len, &base, visual, indices, NULL, levels);
#else /* not HAVE_FRIBIDI */
- indices = alloca (sizeof (int) * size);
- for (i = 0; i < size; i++)
+ indices = alloca (sizeof (int) * len);
+ for (i = 0; i < len; i++)
{
if (levels[i])
{
int j, k;
- for (j = i + 1; j < size && levels[j]; j++);
+ for (j = i + 1; j < len && levels[j]; j++);
for (k = j--; i < k; i++, j--)
indices[i] = j;
i--;
}
#endif /* not HAVE_FRIBIDI */
- /* IDX are indices to gstring->glyphs[]. The glyphs for LOGICAL[N]
- starts from gstring->glyphs[IDX[N]].
-
- INDICES are indices to LOGICAL[]. The glyph for VISUAL[N] is
- originally at LOGICAL[INDICES[N]]. */
-
- for (i = 0, gidx = 1; i < size; i++)
+ for (i = 0; i < len;)
{
+ /* Index into gstring->glyphs plus 1 for GLYPHS[i]. */
int j = indices[i];
- int k = idx[j];
+ /* Length of grapheme-cluster */
+ int seglen;
- glyphs[k].bidi_level = levels[j];
+ g = glyphs + i;
#ifdef HAVE_FRIBIDI
- if (visual[i] != logical[j])
+ if (visual[j] != logical[i])
{
/* Mirrored. */
- glyphs[k].c = visual[i];
- if (glyphs[k].rface->rfont)
- glyphs[k].code = mfont__encode_char (glyphs[k].rface->rfont,
- glyphs[k].c);
+ g->c = visual[j];
+ if (g->rface->rfont)
+ g->code = mfont__encode_char (g->rface->rfont, g->c);
}
-#endif /* not HAVE_FRIBIDI */
- *(MGLYPH (gidx)) = glyphs[k];
- for (gidx++, k++;
- k < gstring->used - 1 && glyphs[k].combining_code;
- gidx++, k++)
+#endif /* HAVE_FRIBIDI */
+ g->bidi_level = levels[i];
+ for (seglen = 1, g++;
+ i + seglen < len && (glyphs[i].pos == glyphs[i + seglen].pos
+ || glyphs[i + seglen].combining_code);
+ seglen++, g++)
{
- glyphs[k].bidi_level = levels[j];
- *(MGLYPH (gidx)) = glyphs[k];
+ g->bidi_level = levels[i];
+ if (indices[i + seglen] < j)
+ j = indices[i + seglen];
}
+ memcpy (MGLYPH (j + 1), glyphs + i, sizeof (MGlyph) * seglen);
+ i += seglen;
}
}
MGlyph g_tmp, *g;
int pos;
MSymbol language = Mnil, script = Mnil, charset = Mnil;
+ MSymbol non_latin_script = Mnil;
MRealizedFace *rface = default_rface;
- int non_ascii_found;
int size = gstring->control.fixed_width;
- int i, limit;
+ int i;
int last;
MLIST_RESET (gstring);
stop = face_change = charset_change = language_change = pos = from;
last = 0;
- non_ascii_found = 0;
while (1)
{
int c;
c = mtext_ref_char (mt, pos);
else
c = '\n';
- g_tmp.category = Mnil;
+ g_tmp.category = mchar_get_prop (c, Mcategory);
if (c < 0x100)
{
- if (c == ' ' || c == '\n' || c == '\t')
- g_tmp.type = GLYPH_SPACE, this_script = Mnil;
- else
- g_tmp.type = GLYPH_CHAR, this_script = Mlatin;
+ /* Short cut for the obvious case. */
+ g_tmp.type = (c == ' ' || c == '\n' || c == '\t'
+ ? GLYPH_SPACE : GLYPH_CHAR);
+ this_script = Mlatin;
}
else
{
- g_tmp.category = mchar_get_prop (c, Mcategory);
g_tmp.type = GLYPH_CHAR;
this_script = (MSymbol) mchar_get_prop (c, Mscript);
- if (this_script == Minherited)
+ if (this_script == Minherited || this_script == Mnil)
this_script = script;
+ if (this_script == Mnil)
+ this_script = non_latin_script;
+ if (this_script == Mnil)
+ {
+ /* Search forward for a character that explicitly
+ specifies a non-latin script. */
+ int c1;
+ MSymbol sym;
+
+ for (i = pos + 1; i < to; i++)
+ if ((c1 = mtext_ref_char (mt, i)) >= 0x100
+ && (sym = mchar_get_prop (c1, Mscript)) != Mnil
+ && sym != Minherited)
+ {
+ this_script = sym;
+ break;
+ }
+ }
}
if (pos == stop || script != this_script
|| MGLYPH (last)->type != g_tmp.type)
{
g = MGLYPH (last);
- if (non_ascii_found && g->type == GLYPH_CHAR)
+ if (g->type != GLYPH_ANCHOR)
while (g < gstring->glyphs + gstring->used)
g = mface__for_chars (script, language, charset,
g, gstring->glyphs + gstring->used, size);
- last = gstring->used;
- non_ascii_found = 0;
- script = this_script;
if (pos == to)
break;
- if (pos < mtext_nchars (mt) && pos == language_change)
- {
- language = (MSymbol) mtext_get_prop (mt, pos, Mlanguage);
- mtext_prop_range (mt, Mlanguage, pos, NULL, &language_change, 0);
- }
- if (pos < mtext_nchars (mt) && pos == charset_change)
- {
- charset = (MSymbol) mtext_get_prop (mt, pos, Mcharset);
- mtext_prop_range (mt, Mcharset, pos, NULL, &charset_change, 0);
- }
- if (pos < mtext_nchars (mt) && pos == face_change)
+ last = gstring->used;
+ script = this_script;
+ if (script != Mnil && script != Mlatin)
+ non_latin_script = script;
+ if (pos == stop)
{
- MFace *faces[64];
- int num = mtext_get_prop_values (mt, pos, Mface,
- (void **) faces, 64);
-
- mtext_prop_range (mt, Mface, pos, NULL, &face_change, 1);
- rface = (num > 0
- ? mface__realize (frame, faces, num,
- language, charset, size)
- : default_rface);
+ if (pos < mtext_nchars (mt) && pos == language_change)
+ {
+ language = (MSymbol) mtext_get_prop (mt, pos, Mlanguage);
+ mtext_prop_range (mt, Mlanguage, pos, NULL,
+ &language_change, 0);
+ }
+ if (pos < mtext_nchars (mt) && pos == charset_change)
+ {
+ charset = (MSymbol) mtext_get_prop (mt, pos, Mcharset);
+ mtext_prop_range (mt, Mcharset, pos, NULL,
+ &charset_change, 0);
+ }
+ if (pos < mtext_nchars (mt) && pos == face_change)
+ {
+ MFace *faces[64];
+ int num = mtext_get_prop_values (mt, pos, Mface,
+ (void **) faces, 64);
+
+ mtext_prop_range (mt, Mface, pos, NULL, &face_change, 1);
+ rface = (num > 0
+ ? mface__realize (frame, faces, num,
+ language, charset, size)
+ : default_rface);
+ }
+ stop = to;
+ if (stop > language_change)
+ stop = language_change;
+ if (stop > charset_change)
+ stop = charset_change;
+ if (face_change < stop)
+ stop = face_change;
}
- stop = to;
- if (stop > language_change)
- stop = language_change;
- if (stop > charset_change)
- stop = charset_change;
- if (face_change < stop)
- stop = face_change;
}
- g_tmp.c = g_tmp.code = c;
+ g_tmp.c = c;
g_tmp.pos = pos++;
g_tmp.to = pos;
g_tmp.rface = rface;
- if (c >= 0x100)
- non_ascii_found = 1;
- else if (g_tmp.type == GLYPH_CHAR && (c <= 32 || c == 127))
+ if ((c <= 32 || c == 127) && g_tmp.type == GLYPH_CHAR)
{
- g_tmp.code = '^';
- APPEND_GLYPH (gstring, g_tmp);
- if (c < ' ')
- g_tmp.code = g_tmp.c + 0x40;
- else
- g_tmp.code = '?';
+ MGlyph ctrl[2];
+
+ ctrl[0] = ctrl[1] = g_tmp;
+ ctrl[0].c = '^';
+ ctrl[1].c = c < ' ' ? c + 0x40 : '?';
+ mface__for_chars (Mlatin, language, charset, ctrl, ctrl + 2, size);
+ APPEND_GLYPH (gstring, ctrl[0]);
+ APPEND_GLYPH (gstring, ctrl[1]);
}
- APPEND_GLYPH (gstring, g_tmp);
+ else
+ APPEND_GLYPH (gstring, g_tmp);
if (c == '\n'
&& gstring->control.two_dimensional)
break;
}
- limit = pos - from;
-
/* Append an anchor glyph. */
g_tmp.type = GLYPH_ANCHOR;
g_tmp.c = 0;
!= MCHAR_INVALID_CODE))));
i++, g++)
if (g->rface->rfont != this->rface->rfont)
- g->code = code;
+ {
+ g->rface->rfont = this->rface->rfont;
+ g->code = code;
+ }
i = mfont__flt_run (gstring, start, i, this->rface);
}
else
}
if (start + 1 < i)
reorder_combining_chars (gstring, start, i);
+ if (this->type == GLYPH_ANCHOR)
+ break;
}
g = MGLYPH (i);
}
}
+typedef struct {
+ int width, lbearing, rbearing;
+} MSubTextExtents;
+
static void
-layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to)
+layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to,
+ MSubTextExtents *extents)
{
int g_physical_ascent, g_physical_descent;
- int g_width, g_lbearing, g_rbearing;
MGlyph *g = MGLYPH (from);
MGlyph *last_g = MGLYPH (to);
+ int i;
g_physical_ascent = gstring->physical_ascent;
g_physical_descent = gstring->physical_descent;
- g_width = g_lbearing = g_rbearing = 0;
+ extents->width = extents->lbearing = extents->rbearing = 0;
+
+ for (i = from; i < to;)
+ {
+ if ( MGLYPH (i)->otf_encoded)
+ i++;
+ else
+ {
+ int j = i++;
- mfont__get_metric (gstring, from, to);
+ while (i < to && ! MGLYPH (i)->otf_encoded) i++;
+ mfont__get_metric (gstring, j, i);
+ }
+ }
+ g = MGLYPH (from);
while (g < last_g)
{
MGlyph *base = g++;
if (g == last_g || ! g->combining_code)
{
/* No combining. */
+ if (base->width == 0 && ! base->left_padding && ! base->right_padding
+ && GLYPH_INDEX (base) > from)
+ {
+ MGlyph *prev = base - 1;
+
+ if (base->pos < prev->pos)
+ prev->pos = base->pos;
+ else
+ base->pos = prev->pos;
+ if (base->to > prev->to)
+ prev->to = base->to;
+ else
+ base->to = prev->to;
+ }
+
if (base->left_padding && base->lbearing < 0)
{
base->xoff = - base->lbearing;
{
base->width = base->rbearing;
}
- lbearing = (base->lbearing < 0 ? base->lbearing : 0);
- rbearing = base->rbearing;
+ lbearing = (base->xoff + base->lbearing < 0
+ ? base->xoff + base->lbearing : 0);
+ rbearing = base->xoff + base->rbearing;
}
else
{
while (g != last_g && g->combining_code)
{
- int combining_code, base_x, base_y, add_x, add_y, off_x, off_y;
-
- combining_code = g->combining_code;
- if (COMBINING_BY_CLASS_P (combining_code))
- g->combining_code = combining_code
- = combining_code_from_class (COMBINING_CODE_CLASS
- (combining_code));
-
- rfont = g->rface->rfont;
- size = rfont->font.property[MFONT_SIZE];
- off_x = (size * (COMBINING_CODE_OFF_X (combining_code) - 128)
- / 1000);
- off_y = (size * (COMBINING_CODE_OFF_Y (combining_code) - 128)
- / 1000);
- base_x = COMBINING_CODE_BASE_X (combining_code);
- base_y = COMBINING_CODE_BASE_Y (combining_code);
- add_x = COMBINING_CODE_ADD_X (combining_code);
- add_y = COMBINING_CODE_ADD_Y (combining_code);
+ int combining_code = g->combining_code;
if (begin > g->pos)
begin = g->pos;
else if (end < g->to)
end = g->to;
- g->xoff = left + (width * base_x - g->width * add_x) / 2 + off_x;
- if (g->xoff < left)
- left = g->xoff;
- if (g->xoff + g->width > right)
- right = g->xoff + g->width;
- width = right - left;
+ if (! COMBINING_PRECOMPUTED_P (combining_code))
+ {
+ int base_x, base_y, add_x, add_y, off_x, off_y;
+
+ if (COMBINING_BY_CLASS_P (combining_code))
+ g->combining_code = combining_code
+ = combining_code_from_class (COMBINING_CODE_CLASS
+ (combining_code));
+
+ rfont = g->rface->rfont;
+ size = rfont->font.property[MFONT_SIZE];
+ off_x = (size * (COMBINING_CODE_OFF_X (combining_code) - 128)
+ / 1000);
+ off_y = (size * (COMBINING_CODE_OFF_Y (combining_code) - 128)
+ / 1000);
+ base_x = COMBINING_CODE_BASE_X (combining_code);
+ base_y = COMBINING_CODE_BASE_Y (combining_code);
+ add_x = COMBINING_CODE_ADD_X (combining_code);
+ add_y = COMBINING_CODE_ADD_Y (combining_code);
+
+ g->xoff = left + (width * base_x - g->width * add_x) / 2 + off_x;
+ if (g->xoff < left)
+ left = g->xoff;
+ if (g->xoff + g->width > right)
+ right = g->xoff + g->width;
+ width = right - left;
+
+ if (base_y < 3)
+ g->yoff = top + height * base_y / 2;
+ else
+ g->yoff = 0;
+ if (add_y < 3)
+ g->yoff -= (g->ascent + g->descent) * add_y / 2 - g->ascent;
+ g->yoff -= off_y;
+ }
+
if (g->xoff + g->lbearing < left + lbearing)
lbearing = g->xoff + g->lbearing - left;
if (g->xoff + g->rbearing > left + rbearing)
rbearing = g->xoff + g->rbearing - left;
-
- if (base_y < 3)
- g->yoff = top + height * base_y / 2;
- else
- g->yoff = 0;
- if (add_y < 3)
- g->yoff -= (g->ascent + g->descent) * add_y / 2 - g->ascent;
- g->yoff -= off_y;
if (g->yoff - g->ascent < top)
top = g->yoff - g->ascent;
if (g->yoff + g->descent > bottom)
g_physical_ascent = MAX (g_physical_ascent, base->ascent);
g_physical_descent = MAX (g_physical_descent, base->descent);
- g_lbearing = MIN (g_lbearing, g_width + lbearing);
- g_rbearing = MAX (g_rbearing, g_width + rbearing);
- g_width += base->width;
+ extents->lbearing = MIN (extents->lbearing, extents->width + lbearing);
+ extents->rbearing = MAX (extents->rbearing, extents->width + rbearing);
+ extents->width += base->width;
}
gstring->physical_ascent = g_physical_ascent;
gstring->physical_descent = g_physical_descent;
- gstring->sub_width = g_width;
- gstring->sub_lbearing = g_lbearing;
- gstring->sub_rbearing = g_rbearing;
}
{
int extra_width;
int to = GLYPH_INDEX (g);
+ MSubTextExtents extents;
- layout_glyphs (frame, gstring, from, to);
- extra_width = - gstring->sub_lbearing;
+ layout_glyphs (frame, gstring, from, to, &extents);
+ extra_width = - extents.lbearing;
if (extra_width > 0
- && (GLYPH_INDEX (g) > 1
- || control->align_head))
+ && ! control->disable_overlapping_adjustment
+ && (! control->orientation_reversed
+ ? ((to > 1 || control->align_head)
+ && g->type != GLYPH_ANCHOR)
+ : (((g->type && GLYPH_ANCHOR) || control->align_head)
+ && to > 1)))
{
g = MGLYPH (from);
pad = *g;
pad.xoff = 0;
pad.lbearing = 0;
pad.width = pad.rbearing = extra_width;
+ pad.left_padding = 1;
INSERT_GLYPH (gstring, from, pad);
to++;
- gstring->sub_lbearing = 0;
- gstring->sub_width += extra_width;
- gstring->sub_rbearing += extra_width;
+ extents.lbearing = 0;
+ extents.width += extra_width;
+ extents.rbearing += extra_width;
g = MGLYPH (from - 1);
if (g->type == GLYPH_SPACE)
}
else
{
- extra_width -= g->width - 2;
+ extra_width = g->width - 2;
g->width = 2;
}
gstring->width -= extra_width;
}
}
- extra_width = gstring->sub_rbearing - gstring->sub_width;
- if (extra_width > 0)
+ g = MGLYPH (to);
+ extra_width = extents.rbearing - extents.width;
+ if (extra_width > 0
+ && ! control->disable_overlapping_adjustment
+ && (GLYPH_INDEX (g) < gstring->used - 1
+ || (control->orientation_reversed && control->align_head)))
{
- g = MGLYPH (to);
if (g->type == GLYPH_SPACE && box == g->rface->box)
{
- g--;
- pad = *g;
+ pad = g[-1];
pad.type = GLYPH_PAD;
pad.xoff = 0;
pad.lbearing = 0;
pad.width = pad.rbearing = extra_width;
INSERT_GLYPH (gstring, to, pad);
to++;
+ g = MGLYPH (to);
}
else
g[-1].width += extra_width;
- gstring->sub_width += extra_width;
+ extents.width += extra_width;
}
- if (gstring->lbearing > gstring->width + gstring->sub_lbearing)
- gstring->lbearing = gstring->width + gstring->sub_lbearing;
- if (gstring->rbearing < gstring->width + gstring->sub_rbearing)
- gstring->rbearing = gstring->width + gstring->sub_rbearing;
- gstring->width += gstring->sub_width;
+ if (gstring->lbearing > gstring->width + extents.lbearing)
+ gstring->lbearing = gstring->width + extents.lbearing;
+ if (gstring->rbearing < gstring->width + extents.rbearing)
+ gstring->rbearing = gstring->width + extents.rbearing;
+ gstring->width += extents.width;
if (gstring->ascent < rface->ascent)
gstring->ascent = rface->ascent;
if (gstring->descent < rface->descent)
gstring->descent = rface->descent;
- g = MGLYPH (to);
}
else
{
if (gstring->from <= control->cursor_pos
&& gstring->to > control->cursor_pos)
cursor_pos = control->cursor_pos;
- if (cursor_bidi
+ if (cursor_pos >= 0
+ && cursor_bidi
&& gstring->from <= control->cursor_pos - 1
&& gstring->to > control->cursor_pos - 1)
prev_pos = control->cursor_pos - 1;
}
if (width > 0
&& (control->as_image
- || rface->face.property[MFACE_BACKGROUND] != Mnil
|| rface->face.property[MFACE_VIDEOMODE] == Mreverse))
{
int this_x = x, this_width = width;
this_x += fromg->width, this_width -= fromg->width;
if (g[-1].type == GLYPH_BOX)
this_width -= g[-1].width;
- mwin__fill_space (frame, win, rface, 0,
- this_x, y - gstring->text_ascent, this_width,
- gstring->text_ascent + gstring->text_descent,
- control->clip_region);
+ (frame->driver->fill_space)
+ (frame, win, rface, 0,
+ this_x, y - gstring->text_ascent, this_width,
+ gstring->text_ascent + gstring->text_descent,
+ control->clip_region);
}
if (cursor)
{
? control->cursor_width : cursor_width);
}
else
- {
- if (cursor->bidi_level % 2)
- rect.x += cursor_width - 1;
- rect.width = 1;
- }
- mwin__fill_space (frame, win, rface, 1,
- rect.x, rect.y, rect.width, rect.height,
- control->clip_region);
+ rect.width = 1;
+ if (cursor->bidi_level % 2)
+ rect.x += cursor_width - rect.width;
+ (*frame->driver->fill_space)
+ (frame, win, rface, 1, rect.x, rect.y, rect.width, rect.height,
+ control->clip_region);
if (! region)
- region = mwin__region_from_rect (&rect);
+ region = (*frame->driver->region_from_rect) (&rect);
else
- mwin__region_add_rect (region, &rect);
- mwin__verify_region (frame, region);
+ (*frame->driver->region_add_rect) (region, &rect);
if (cursor_bidi)
{
if (cursor->bidi_level % 2)
rect.x -= 3;
rect.height = 2;
rect.width = cursor_width < 4 ? cursor_width : 4;
- mwin__fill_space (frame, win, rface, 1,
- rect.x, rect.y, rect.width, rect.height,
- control->clip_region);
- mwin__region_add_rect (region, &rect);
- mwin__verify_region (frame, region);
+ (*frame->driver->fill_space)
+ (frame, win, rface, 1,
+ rect.x, rect.y, rect.width, rect.height,
+ control->clip_region);
+ (*frame->driver->region_add_rect) (region, &rect);
}
}
rect.y = y - gstring->text_ascent;
rect.height = gstring->text_ascent + gstring->text_descent;
rect.width = 1;
- mwin__fill_space (frame, win, rface, 1,
- rect.x, rect.y, rect.width, rect.height,
- control->clip_region);
+ (*frame->driver->fill_space)
+ (frame, win, rface, 1,
+ rect.x, rect.y, rect.width, rect.height,
+ control->clip_region);
if (! region)
- region = mwin__region_from_rect (&rect);
+ region = (*frame->driver->region_from_rect) (&rect);
else
- mwin__region_add_rect (region, &rect);
- mwin__verify_region (frame, region);
+ (*frame->driver->region_add_rect) (region, &rect);
rect.y += rect.height - 2;
rect.height = 2;
rect.width = cursor_width < 4 ? cursor_width : 4;
if (! (cursor->bidi_level % 2))
rect.x -= rect.width - 1;
- mwin__fill_space (frame, win, rface, 1,
+ (*frame->driver->fill_space) (frame, win, rface, 1,
rect.x, rect.y, rect.width, rect.height,
control->clip_region);
- mwin__region_add_rect (region, &rect);
- mwin__verify_region (frame, region);
+ (*frame->driver->region_add_rect) (region, &rect);
}
}
x += width;
{
MDrawMetric rect;
- mwin__region_to_rect (region, &rect);
+ (*frame->driver->region_to_rect) (region, &rect);
if (rect.x > x)
{
while (g != gend && x + g->rbearing <= rect.x)
while (g != gend
&& g->type == from_g->type
&& g->rface == rface
- && (g->code < 0) == (from_g->code < 0)
+ && ((g->code == MCHAR_INVALID_CODE)
+ == (from_g->code == MCHAR_INVALID_CODE))
&& g->enabled)
width += g++->width;
if (from_g->type == GLYPH_CHAR)
{
- MFontDriver *driver;
-
- if (rface->rfont && from_g->code >= 0)
- driver = rface->rfont->driver;
+ if (rface->rfont && from_g->code != MCHAR_INVALID_CODE)
+ (rface->rfont->driver->render) (win, x, y, gstring, from_g, g,
+ reverse, region);
else
- driver = mfont__driver_list[MFONT_TYPE_WIN];
- (driver->render) (win, x, y, gstring, from_g, g,
- reverse, region);
+ (*frame->driver->draw_empty_boxes) (win, x, y, gstring, from_g, g,
+ reverse, region);
}
else if (from_g->type == GLYPH_BOX)
{
/* Draw the left or right side of a box. If
from_g->lbearing is nonzero, this is the left side,
else this is the right side. */
- mwin__draw_box (frame, win, gstring, from_g, x, y, 0, region);
+ (*frame->driver->draw_box) (frame, win, gstring, from_g, x, y, 0, region);
}
if (from_g->type != GLYPH_BOX)
{
if (rface->hline)
- mwin__draw_hline (frame, win, gstring, rface, reverse,
+ (*frame->driver->draw_hline) (frame, win, gstring, rface, reverse,
x, y, width, region);
if (rface->box
&& ! reverse)
/* Draw the top and bottom side of a box. */
- mwin__draw_box (frame, win, gstring, from_g,
+ (*frame->driver->draw_box) (frame, win, gstring, from_g,
x, y, width, region);
}
x += width;
{
rect.y = y - gstring->line_ascent;
rect.height = gstring->height;
- clip_region = mwin__region_from_rect (&rect);
+ clip_region = (*frame->driver->region_from_rect) (&rect);
if (control->clip_region)
- mwin__intersect_region (clip_region, control->clip_region);
+ (*frame->driver->intersect_region) (clip_region, control->clip_region);
}
else
clip_region = control->clip_region;
if (cursor_region)
{
if (clip_region)
- mwin__intersect_region (cursor_region, clip_region);
+ (*frame->driver->intersect_region) (cursor_region, clip_region);
render_glyphs (frame, win, x, y, to_x - x, gstring, from_idx, to_idx,
1, cursor_region);
}
if (clip_region != control->clip_region)
- mwin__free_region (clip_region);
+ (*frame->driver->free_region) (clip_region);
if (cursor_region)
- mwin__free_region (cursor_region);
+ (*frame->driver->free_region) (cursor_region);
return;
}
gstring_num++;
}
+ gstring->frame = frame;
+ gstring->tick = frame->tick;
gstring->top = gstring;
- gstring->mt = mt;
gstring->control = *control;
gstring->indent = gstring->width_limit = 0;
if (control->format)
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;
}
int pos;
/* Setup the array POS_WIDTH so that POS_WIDTH[I - GSTRING->from] is
- a width of glyphs for the character at I of GSTRING->mt. If I is
- not a beginning of a grapheme cluster, the corresponding element
- is 0. */
+ a width of glyphs for the character at I of MT. If I is not a
+ beginning of a grapheme cluster, the corresponding element is
+ 0. */
MTABLE_ALLOCA (pos_width, gstring->to - gstring->from, MERROR_DRAW);
memset (pos_width, 0, sizeof (int) * (gstring->to - gstring->from));
for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++)
pos = gstring->from + i;
if (gstring->control.line_break)
{
- pos = (*gstring->control.line_break) (gstring->mt, gstring->from + i,
+ pos = (*gstring->control.line_break) (mt, gstring->from + i,
gstring->from, gstring->to, 0, 0);
- if (pos <= gstring->from || pos >= gstring->to)
- return;
+ if (pos <= gstring->from)
+ pos = gstring->from + 1;
+ else if (pos >= gstring->to)
+ pos = gstring->to;
}
+ else if (i == 0)
+ pos++;
compose_glyph_string (frame, mt, gstring->from, pos, gstring);
layout_glyph_string (frame, gstring);
}
if (prop)
{
gstring = prop->val;
- if (memcmp (control, &gstring->control,
- (char *) (&control->with_cursor)
- - (char *) (control)))
+ if (gstring->frame != frame
+ || gstring->tick != frame->tick
+ || memcmp (control, &gstring->control,
+ (char *) (&control->with_cursor)
+ - (char *) (control))
+ || control->cursor_width != gstring->control.cursor_width
+ || control->cursor_bidi != gstring->control.cursor_bidi)
{
mtext_detach_property (prop);
gstring = NULL;
int beg, end;
int line = 0, y = 0;
- if (control->two_dimensional)
- {
- beg = mtext_character (mt, pos, 0, '\n');
- if (beg < 0)
- beg = 0;
- else
- beg++;
- end = mtext_nchars (mt) + (control->cursor_width != 0);
- }
+ beg = mtext_character (mt, pos, 0, '\n');
+ if (beg < 0)
+ beg = 0;
else
- {
- beg = pos;
- end = to;
- }
+ beg++;
+ end = mtext_nchars (mt) + (control->cursor_width != 0);
+
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;
- if (control->two_dimensional
- && gstring->width_limit
+ if (gstring->width_limit
&& gstring->width > gstring->width_limit)
{
MGlyphString *gst = gstring;
memset (&scratch_gstring, 0, sizeof (scratch_gstring));
MLIST_INIT1 (&scratch_gstring, glyphs, 3);
- Mlatin = msymbol ("latin");
Minherited = msymbol ("inherited");
McatCc = msymbol ("Cc");
McatCf = msymbol ("Cf");
- Mdepth = msymbol ("depth");
MbidiR = msymbol ("R");
MbidiAL = msymbol ("AL");
<li> Search the text properties given to the character for the one
whose key is @c Mcharset; its value should be either a symbol
- specifying a charset or Mnil. If the value is Mnil, proceed
- to the next step.
+ specifying a charset or #Mnil. If the value is #Mnil,
+ proceed to the next step.
Otherwise, search the mapping table of the fontset for the
- charset. If no entry is found proceed to the next step. If
- an entry is found, use one of the fonts in the entry that has
- a glyph for the character and that matches best with the face
- properties. If no such font exists, proceed to the next
+ charset. If no entry is found proceed to the next step.
+
+ If an entry is found, use one of the fonts in the entry that
+ has a glyph for the character and that matches best with the
+ face properties. If no such font exists, proceed to the next
step.
- <li> Get the character-property script of the character. If it is
+ <li> Get the character property "script" of the character. If it is
inherited, get the script property from the previous
characters. If there is no previous character, or none of
them has the script property other than inherited, proceed to
Search the mapping table of the fontset for the combination
of the script and language. If no entry is found, proceed to
- the next step. If an entry is found, use one of the fonts in
- the entry that has a glyph for the character and that matches
- best with the face properties. If no such font exists,
- proceed to the next step.
+ the next step.
+
+ If an entry is found, use one of the fonts in the entry that
+ has a glyph for the character and that matches best with the
+ face properties. If no such font exists, proceed to the next
+ step.
<li> Search the fall-back table of the fontset for a font that has
a glyph of the character. If such a font is found, use that
@return
If the operation was successful, mdraw_text () returns 0. If an
error is detected, it returns -1 and assigns an error code to the
- external variable @c merror_code. */
-
+ external variable #merror_code. */
/***ja
- @brief ¥¦¥£¥ó¥É¥¦¤Ë M-text ¤òɽ¼¨¤¹¤ë
+ @brief ¥¦¥£¥ó¥É¥¦¤Ë M-text ¤òÉÁ²è¤¹¤ë.
´Ø¿ô mdraw_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤ÎºÂɸ
($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥¥¹¥È¤ò
- ɽ¼¨¤¹¤ë¡£
-
- ¥Ý¥¤¥ó¥¿ $RET_DESCENT ¤¬ @c NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢É½¼¨¤·¤¿¥Æ¥¥¹¥È¤Î¥Ç¥£¥»
- ¥ó¥È¤¬¤½¤³¤Ë³ÊǼ¤µ¤ì¤ë¡£
+ ÉÁ²è¤¹¤ë¡£
¥Æ¥¥¹¥È¤Î¸«±É¤¨¡Ê¥Õ¥©¥ó¥È¡¢¥¹¥¿¥¤¥ë¡¢¿§¤Ê¤É¡Ë¤Ï¡¢¥¡¼¤¬ @c Mface
¤Ç¤¢¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ÎÃͤˤè¤Ã¤Æ·è¤Þ¤ë¡£M-text ¤Î°ìÉô¤¢¤ë¤¤¤Ï
Á´Éô¤Ë¤½¤Î¤è¤¦¤Ê¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬ÉÕ¤¤¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢$FRAME
¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤¬ÍѤ¤¤é¤ì¤ë¡£
- M-text ¤Î³Æʸ»ú¤òɽ¼¨¤¹¤ë¥Õ¥©¥ó¥È¤Ï¡¢$FACE ¤Î fontset ¥×¥í¥Ñ¥Æ¥£¤Î
- Ãͤ«¤é°Ê²¼¤Î¥¢¥ë¥´¥ê¥º¥à¤ÇÁª¤Ð¤ì¤ë¡£
+ M-text ¤Î³Æʸ»ú¤òɽ¼¨¤¹¤ë¥Õ¥©¥ó¥È¤Ï¡¢¥Õ¥§¡¼¥¹¤Î fontset ¥×¥í¥Ñ¥Æ¥£
+ ¤ÎÃͤ«¤é°Ê²¼¤Î¥¢¥ë¥´¥ê¥º¥à¤ÇÁª¤Ð¤ì¤ë¡£
<ol>
- <li> ¤½¤Îʸ»ú¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥¡¼¤¬ @c Mlanguage ¤Ç¤¢
- ¤ë¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£¤³¤ÎÃͤϸÀ¸ì¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil ¤Î¤¤
- ¤º¤ì¤«¤Ç¤¢¤ë¡£¼¡¤Ë¥¡¼¤¬ @c Mscript ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£
- ¤³¤ÎÃͤϥ¹¥¯¥ê¥×¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil ¤Î¤É¤Á¤é¤«¤Ç¤¢¤ë¡£
-
- ¤É¤Á¤é¤â @c Mnil ¤Ê¤é¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
-
- ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤½¤Î¸À¸ì¤È¥¹¥¯¥ê¥×¥È¤ÎÁȤ߹ç¤ï¤»¤ò»È¤Ã
- ¤Æ¡¢¤½¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤ò¤Ò¤¯¡£¥Õ¥©¥ó¥È¤¬
- ¤ß¤Ä¤«¤ê¡¢¤«¤Ä¤½¤Î¥Õ¥©¥ó¥È¤Ç¸½ºß¤Îʸ»ú¤¬É½¼¨¤Ç¤¤ì¤Ð¡¢¤½¤Î¥Õ¥©
- ¥ó¥È¤ò»È¤¦¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
-
<li> ¤½¤Îʸ»ú¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥¡¼¤¬ @c Mcharset ¤Ç¤¢¤ë
- ¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£¤³¤ÎÃͤÏʸ»ú¥»¥Ã¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil
- ¤Î¤É¤Á¤é¤«¤Ç¤¢¤ë¡£@c Mnil ¤Ê¤é¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
-
- ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¸«¤Ä¤«¤Ã¤¿Ê¸»ú¥»¥Ã¥È»È¤Ã¤Æ¡¢¤½¤Î¥Õ¥©¥ó¥È¥»¥Ã
- ¥È¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤ò¤Ò¤¯¡£¥Õ¥©¥ó¥È¤¬¤ß¤Ä¤«¤ê¡¢¤«¤Ä¤½¤Î¥Õ¥©
- ¥ó¥È¤Ç¸½ºß¤Îʸ»ú¤¬É½¼¨¤Ç¤¤ì¤Ð¡¢¤½¤Î¥Õ¥©¥ó¥È¤ò»È¤¦¡£¤½¤¦¤Ç¤Ê
- ¤±¤ì¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
-
- <li> ¸½ºß¤Îʸ»ú¼«¿È¤ò»È¤Ã¤Æ¡¢¤½¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö
- ¥ë¤ò¤Ò¤¯¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤ì¤Ð¤½¤ì¤ò»È¤¦¡£
+ ¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£¤³¤ÎÃͤÏʸ»ú¥»¥Ã¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« #Mnil
+ ¤Î¤É¤Á¤é¤«¤Ç¤¢¤ë¡£#Mnil ¤Ê¤é¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£¤½¤¦¤Ç¤Ê
+ ¤±¤ì¤Ð¡¢¤½¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤«¤é¤½¤Îʸ»ú¥»¥Ã
+ ¥ÈÍѤΤâ¤Î¤òõ¤¹¡£¥Õ¥©¥ó¥È¤¬¤ß¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë
+ ¿Ê¤à¡£
+
+ ¤½¤Îʸ»ú¥»¥Ã¥ÈÍѤΥե©¥ó¥È¤¬¤ß¤Ä¤«¤ì¤Ð¡¢¤½¤ì¤é¤Î¤¦¤Á¸½ºß¤Îʸ
+ »úÍѤΥ°¥ê¥Õ¤ò»ý¤Á¡¢¥Õ¥§¡¼¥¹¤Î³Æ¥×¥í¥Ñ¥Æ¥£¤ËºÇ¤â¤è¤¯¹çÃפ·¤Æ
+ ¤¤¤ë¤â¤Î¤ò»È¤¦¡£¤½¤Î¤è¤¦¤Ê¥Õ¥©¥ó¥È¤¬Ìµ¤±¤ì¤Ð¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê
+ ¤à¡£
+
+ <li> ¤½¤Îʸ»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "script" ¡Ê¥¹¥¯¥ê¥×¥È¡Ë¤òÄ´¤Ù¤ë¡£·Ñ
+ ¾µ¤µ¤ì¤Æ¤¤¤ë¤Ê¤é¤Ð¤½¤ì°ÊÁ°¤Îʸ»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "script" ¤ò
+ Ä´¤Ù¤ë¡£Á°¤Îʸ»ú¤¬¤Ê¤«¤Ã¤¿¤ê¡¢¤½¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ã¤Æ¤¤¤Ê
+ ¤«¤Ã¤¿¾ì¹ç¤Ë¤Ï¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
+
+ ¤½¤Îʸ»ú¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥¡¼¤¬ @c Mlanguage ¤Ç¤¢
+ ¤ë¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£¤³¤ÎÃͤϸÀ¸ì¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil ¤Î
+ ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
+
+ ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤½¤Î¸À¸ì¤È¥¹¥¯¥ê¥×¥È¤ÎÁȤ߹ç¤ï¤»ÍѤΥե©¥ó¥È
+ ¥»¥Ã¥È¤ò¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤«¤éõ¤¹¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¼¡¤Î¥¹¥Æ¥Ã
+ ¥×¤Ë¿Ê¤à¡£
+
+ ¤½¤Î¤è¤¦¤Êʸ»ú¥»¥Ã¥ÈÍѤΥե©¥ó¥È¤¬¤ß¤Ä¤«¤ì¤Ð¡¢¤½¤ì¤é¤Î¤¦¤Á¸½
+ ºß¤Îʸ»úÍѤΥ°¥ê¥Õ¤ò»ý¤Á¡¢¥Õ¥§¡¼¥¹¤Î³Æ¥×¥í¥Ñ¥Æ¥£¤ËºÇ¤â¤è¤¯¹ç
+ Ãפ·¤Æ¤¤¤ë¤â¤Î¤ò»È¤¦¡£¤½¤Î¤è¤¦¤Ê¥Õ¥©¥ó¥È¤¬Ìµ¤±¤ì¤Ð¼¡¤Î¥¹¥Æ¥Ã
+ ¥×¤Ë¿Ê¤à¡£
+
+ <li> ¤½¤Îʸ»ú¤Î¥°¥ê¥Õ¤ò»ý¤Ä¥Õ¥©¥ó¥È¤ò¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Îfall-back¥Æ¡¼
+ ¥Ö¥ë¤«¤éõ¤¹¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤ì¤Ð¤½¤ì¤ò»È¤¦¡£
</ol>
°Ê¾å¤Î¥¢¥ë¥´¥ê¥º¥à¤Ç¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¤½¤Îʸ»ú
¤È¤·¤Æ¶õ¤Î»Í³Ñ·Á¤òɽ¼¨¤¹¤ë¡£
- ¤³¤Î´Ø¿ô¤¬ÉÁ²è¤¹¤ë¤Î¤Ï¥°¥ê¥Õ¤ÎÁ°·Ê¿§¤À¤±¤Ç¤¢¤ë¡£ÇØ·Ê¿§¤ò»ØÄꤹ¤ë¤Ë
- ¤Ï¡¢´Ø¿ô mdraw_image_text () ¤ò»È¤¦¤³¤È¡£
+ ¤³¤Î´Ø¿ô¤¬ÉÁ²è¤¹¤ë¤Î¤Ï¥°¥ê¥Õ¤ÎÁ°·Ê¤À¤±¤Ç¤¢¤ë¡£ÇØ·Ê¿§¤ò»ØÄꤹ¤ë¤Ë¤Ï¡¢
+ ´Ø¿ô mdraw_image_text () ¤«´Ø¿ô mdraw_text_with_control () ¤ò»È¤¦
+ ¤³¤È¡£
- ¤³¤Î´Ø¿ô¤Ï¡¢X ¥¦¥£¥ó¥É¥¦¤Ë¤ª¤±¤ë <tt>XDrawString ()</tt>,
+ ¤³¤Î´Ø¿ô¤Ï¡¢X ¥¦¥£¥ó¥É¥¦¤Ë¤ª¤±¤ë´Ø¿ô <tt>XDrawString ()</tt>,
<tt>XmbDrawString ()</tt>, <tt>XwcDrawString ()</tt> ¤ËÁêÅö¤¹¤ë¡£
@return
½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_text () ¤Ï 0 ÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì
- ¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
+ ¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
@latexonly \IPAlabel{mdraw_text} @endlatexonly */
{
MDrawControl control;
+ M_CHECK_WRITABLE (frame, MERROR_DRAW, -1);
memset (&control, 0, sizeof control);
control.as_image = 0;
return draw_text (frame, win, x, y, mt, from, to, &control);
/***en
- @brief Draw an M-text on a window as an image
+ @brief Draw an M-text on a window as an image.
The mdraw_image_text () function draws the text between $FROM and
$TO of M-text $MT as image on window $WIN of frame $FRAME at
@return
If the operation was successful, mdraw_image_text () returns 0.
If an error is detected, it returns -1 and assigns an error code
- to the external variable @c merror_code. */
+ to the external variable #merror_code. */
/***ja
- @brief ¥Ç¥£¥¹¥×¥ì¥¤¤ËM-text ¤ò²èÁü¤È¤·¤ÆÉÁ¤¯
-
+ @brief ¥Ç¥£¥¹¥×¥ì¥¤¤ËM-text ¤ò²èÁü¤È¤·¤ÆÉÁ¤¯.
+
´Ø¿ô mdraw_image_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤Î
ºÂɸ ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥¥¹¥È¤ò²è
Áü¤È¤·¤ÆÉÁ¤¯¡£
¥Æ¥¥¹¥È¤ÎÉÁ²èÊýË¡¤Ï mdraw_text () ¤È¤Û¤ÜƱ¤¸¤Ç¤¢¤ë¤¬¡¢¤³¤Î´Ø¿ô¤Ç
- ¤Ï $FACE ¤Ç»ØÄꤵ¤ì¤¿¿§¤ÇÇطʤâÉÁ¤¯ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£
+ ¤Ï¥Õ¥§¡¼¥¹¤Ç»ØÄꤵ¤ì¤¿¿§¤ÇÇطʤâÉÁ¤¯ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£
¤³¤Î´Ø¿ô¤Ï¡¢X ¥¦¥£¥ó¥É¥¦¤Ë¤ª¤±¤ë <tt>XDrawImageString ()</tt>,
<tt>XmbDrawImageString ()</tt>, <tt>XwcDrawImageString ()</tt> ¤Ë
@return
½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_image_text () ¤Ï 0 ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð
- ¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c m_errro ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ
+ ¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #m_errro ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ
¤ë¡£
@latexonly \IPAlabel{mdraw_image_text} @endlatexonly */
{
MDrawControl control;
+ M_CHECK_WRITABLE (frame, MERROR_DRAW, -1);
memset (&control, 0, sizeof control);
control.as_image = 1;
return draw_text (frame, win, x, y, mt, from, to, &control);
line. See the documentation of the structure @ MDrawControl for
more detail. */
+/***ja
+ @brief ¥Ç¥£¥¹¥×¥ì¥¤¤ËM-text ¤òÉÁ¤¯¡Ê¾ÜºÙ¤ÊÀ©¸æ¤Ä¤¡Ë.
+
+ ´Ø¿ô mdraw_text_with_control () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦
+ $WIN ¤ÎºÂɸ ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥¥¹
+ ¥È¤òÉÁ¤¯¡£
+
+ ¥Æ¥¥¹¥È¤ÎÉÁ²èÊýË¡¤Ï mdraw_text () ¤È¤Û¤ÜƱ¤¸¤Ç¤¢¤ë¤¬¡¢¤³¤Î´Ø¿ô¤Ï
+ ÉÁ²èÀ©¸æÍѤΥª¥Ö¥¸¥§¥¯¥È $CONTROL ¤Ç¤Î»Ø¼¨¤Ë¤â½¾¤¦ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£
+
+ ¤¿¤È¤¨¤Ð $CONTROL ¤Î <two_dimensional> ¤¬¥¼¥í¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô
+ ¤ÏM-text ¤ò2¼¡¸µÅª¤ËÉÁ¤¯¡£¤¹¤Ê¤ï¤Á M-text Ãæ¤Î²þ¹Ô¤Ç¹Ô¤ò²þ¤á¡¢Â³¤¯
+ ʸ»ú¤Ï¼¡¤Î¹Ô¤ËÉÁ¤¯¡£¾ÜºÙ¤Ï¹½Â¤ÂÎ @ MDrawControl ¤ÎÀâÌÀ¤ò»²¾È¤¹¤ë¤³
+ ¤È¡£*/
+
int
mdraw_text_with_control (MFrame *frame, MDrawWindow win, int x, int y,
MText *mt, int from, int to, MDrawControl *control)
{
+ M_CHECK_WRITABLE (frame, MERROR_DRAW, -1);
return draw_text (frame, win, x, y, mt, from, to, control);
}
max_line_descent of $CONTROL are all zero.
@return
-
This function returns the width of the text to be drawn in the
unit of pixels. If $CONTROL->two_dimensional is nonzero and the
text is drawn in multiple physical lines, it returns the width of
the widest line. If an error occurs, it returns -1 and assigns an
- error code to the external variable @c merror_code. */
+ error code to the external variable #merror_code. */
-/***ja
- @brief ¥Æ¥¥¹¥È¤ÎÉý¤ò·×»»¤¹¤ë
- ´Ø¿ô mdraw_text_extents () ¤Ï¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤ò
- ¥Õ¥ì¡¼¥à $FRAME ¤Ëɽ¼¨¤¹¤ëºÝ¤ËɬÍפȤʤëÉý¤òÊÖ¤¹¡£
+/***ja
+ @brief ¥Æ¥¥¹¥È¤ÎÉý¡Ê¥Ô¥¯¥»¥ëñ°Ì¡Ë¤ò·×»»¤¹¤ë.
- ¥Ý¥¤¥ó¥¿ $OVERALL_RETURN ¤¬ @c NULL °Ê³°¤Î¾ì¹ç¡¢¤³¤Î´Ø¿ô¤Ï¥Æ¥¥¹¥È
- Á´ÂΤÎɽ¼¨ÈϰϾðÊó¤â·×»»¤·¡¢$OVERALL_RETURN ¤¬»Ø¤¹¹½Â¤ÂΤΥá¥ó¥Ð¤Ë
- ¤½¤Î·ë²Ì¤òÀßÄꤹ¤ë¡£
+ ´Ø¿ô mdraw_text_extents () ¤Ï¡¢´Ø¿ô mdraw_text_with_control () ¤¬
+ ÉÁ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤¤Æ M-text $MT ¤Î $FROM ¤«¤é $TO
+ ¤Þ¤Ç¤ò¥Õ¥ì¡¼¥à $FRAME ¤Ëɽ¼¨¤¹¤ëºÝ¤ËɬÍפȤʤëÉý¤òÊÖ¤¹¡£
- @return
- ¤³¤Î´Ø¿ô¤Ïɽ¼¨¤ËɬÍפȤʤë¥Æ¥¥¹¥È¤ÎÉý¤ò¥Ô¥¯¥»¥ëñ°Ì¤ÇÊÖ¤¹¡£¥¨¥é¡¼
- ¤¬À¸¤¸¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤ò
- ÀßÄꤹ¤ë¡£
+ $OVERALL_INK_RETURN ¤¬ @c NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï M-text ¤Îʸ
+ »ú¤Î¥¤¥ó¥¯¤Î¥Ð¥¦¥ó¥Ç¥£¥ó¥°¥Ü¥Ã¥¯¥¹¤â·×»»¤·¡¢$OVERALL_INK_RETURN ¤¬
+ »Ø¤¹¹½Â¤ÂΤΥá¥ó¥Ð¤Ë¤½¤Î·ë²Ì¤òÀßÄꤹ¤ë¡£M-text ¤Ë°Ï¤ßÏÈ(surrounding box)
+ ¤ò»ØÄꤹ¤ë¥Õ¥§¡¼¥¹¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤â¥Ð¥¦¥ó¥Ç¥£¥ó¥°¥Ü¥Ã¥¯¥¹¤Ë´Þ¤à¡£
+
+ $OVERALL_LOGICAL_RETURN ¤¬ @c NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï M-text
+ ¤È¾¤Î graphical feature ¡Ê°Ï¤ßÏȤʤɡˤȤδ֤κǾ®¤Î¥¹¥Ú¡¼¥¹¤ò¼¨
+ ¤¹¥Ð¥¦¥ó¥Ç¥£¥ó¥°¥Ü¥Ã¥¯¥¹¤â·×»»¤·¡¢$OVERALL_LOGICAL_RETURN ¤¬»Ø¤¹¹½
+ ¤ÂΤΥá¥ó¥Ð¤Ë¤½¤Î·ë²Ì¤òÀßÄꤹ¤ë¡£
+
+ $OVERALL_LINE_RETURN ¤¬ @c NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¾¤Î M-text
+ ¤È¤Î´Ö¤ÎºÇ¾®¤Î¥¹¥Ú¡¼¥¹¤ò¼¨¤¹¥Ð¥¦¥ó¥Ç¥£¥ó¥°¥Ü¥Ã¥¯¥¹¤â·×»»¤·¡¢
+ $OVERALL_LINE_RETURN ¤¬»Ø¤¹¹½Â¤ÂΤΥá¥ó¥Ð¤Ë¤½¤Î·ë²Ì¤òÀßÄꤹ¤ë¡£¥ª
+ ¥Ö¥¸¥§¥¯¥È $CONTROL ¤Î¥á¥ó¥Ð min_line_ascent, min_line_descent,
+ max_line_ascent, max_line_descent ¤¬¤¹¤Ù¤Æ0¤Î»þ¤Ë¤Ï¡¢¤³¤ÎÃͤÏ
+ $OVERALL_INK_RETURN ¤È$OVERALL_LOGICAL_RETURN ¤ÎϤȤʤ롣
+
+ @return ¤³¤Î´Ø¿ô¤Ïɽ¼¨¤ËɬÍפʥƥ¥¹¥È¤ÎÉý¤ò¥Ô¥¯¥»¥ëñ°Ì¤ÇÊÖ¤¹¡£
+ $CONTROL->two_dimensional ¤¬0¤Ç¤Ê¤¯¡¢¥Æ¥¥¹¥È¤¬Ê£¿ô¤Î¹Ô¤ËÅϤäÆÉÁ
+ ¤«¤ì¤ë¾ì¹ç¤Ë¤Ï¡¢ºÇÂç¤ÎÉý¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬À¸¤¸¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°
+ ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
@latexonly \IPAlabel{mdraw_text_extents} @endlatexonly */
returns -1 and store the requested size in $NUM_CHARS_RETURN.
Otherwise, it returns zero.
- If pointer $OVERALL_INK_RETURN an $OVERALL_LOGICAL_RETURN are not
+ If pointer $OVERALL_INK_RETURN and $OVERALL_LOGICAL_RETURN are not
@c NULL, this function also computes the metrics of the overall
text and stores the results in the members of the structure
pointed to by $OVERALL_INK_RETURN and $OVERALL_LOGICAL_RETURN.
If $CONTROL->two_dimensional is nonzero, this function computes
only the metrics of characters in the first line. */
+/***ja
+ @brief M-text ¤Î³Æʸ»ú¤Îɽ¼¨ÈϰϤò·×»»¤¹¤ë.
+
+ ´Ø¿ô mdraw_text_per_char_extents () ¤Ï¡¢´Ø¿ô
+ mdraw_text_with_control () ¤¬ÉÁ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤
+ ¤Æ M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤ò¥Õ¥ì¡¼¥à $FRAME ¤Ëɽ¼¨¤¹¤ëºÝ
+ ¤Î³Æʸ»ú¤Î¥µ¥¤¥º¤ò·×»»¤¹¤ë¡£
+
+ $ARRAY_SIZE ¤Ë¤è¤Ã¤Æ $INK_ARRAY_RETURN ¤È$LOGICAL_ARRAY_RETURN ¤Î
+ ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¡£$INK_ARRAY_RETURN ¤È$LOGICAL_ARRAY_RETURN ¤Î³ÆÍ×
+ ÁǤϡ¢¤½¤ì¤¾¤ìʸ»ú¤ÎÉÁ²è¥¤¥ó¥¯¤ÈÏÀÍý¥µ¥¤¥º¡ÊM-text¤Îɽ¼¨¸¶ÅÀ¤«¤é¤Î
+ ÁêÂаÌÃ͡ˤˤè¤Ã¤Æ½ç¤ËËä¤á¤é¤ì¤ë¡£ÀßÄꤵ¤ì¤¿ $INK_ARRAY_RETURN ¤È
+ $LOGICAL_ARRAY_RETURN ¤ÎÍ×ÁǤοô¤Ï¡¢$NUM_CHARS_RETURN ¤ËÌᤵ¤ì¤ë¡£
+
+ $ARRAY_SIZE ¤¬¤¹¤Ù¤Æ¤ÎÀ£Ë¡¤òÌ᤻¤Ê¤¤¤Û¤É¾®¤µ¤¤¾ì¹ç¤Ë¤Ï¡¢´Ø¿ô¤Ï -1
+ ¤òÊÖ¤·¡¢É¬ÍפÊÂ礤µ¤ò $NUM_CHARS_RETURN ¤ËÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0
+ ¤òÊÖ¤¹¡£
+
+ ¥Ý¥¤¥ó¥¿ $OVERALL_INK_RETURN ¤È $OVERALL_LOGICAL_RETURN ¤¬@c NULL
+ ¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¥Æ¥¥¹¥ÈÁ´ÂΤΥµ¥¤¥º¤â·×»»¤·¡¢·ë²Ì¤ò
+ $OVERALL_INK_RETURN ¤È $OVERALL_LOGICAL_RETURN ¤Ç»Ø¤µ¤ì¤ë¹½Â¤¤Î¥á
+ ¥ó¥Ð¤ËÊݸ¤¹¤ë¡£
+
+ $CONTROL->two_dimensional ¤¬0¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤ÏºÇ½é¤Î¹Ô¤Îʸ»ú
+ ¤Î¥µ¥¤¥º¤À¤±¤ò·×»»¤¹¤ë¡£ */
int
mdraw_text_per_char_extents (MFrame *frame,
ASSURE_CONTROL (control);
*num_chars_return = to - from;
if (array_size < *num_chars_return)
- return 0;
+ MERROR (MERROR_DRAW, -1);
if (overall_logical_return)
memset (overall_logical_return, 0, sizeof (MDrawMetric));
if (overall_ink_return)
return 0;
}
- for (g = MGLYPH (1), x = 0; g->type != GLYPH_ANCHOR;)
+ for (g = MGLYPH (1), x = 0; g->type != GLYPH_ANCHOR; g++)
if (g->pos >= from && g->pos < to)
{
int start = g->pos;
int rbearing = g->rbearing;
int ascent = g->ascent;
int descent = g->descent;
- int logical_ascent = g->rface->rfont->ascent;
- int logical_descent = g->rface->rfont->descent;
+ int logical_ascent;
+ int logical_descent;
+ if (g->rface->rfont)
+ {
+ logical_ascent = g->rface->rfont->ascent;
+ logical_descent = g->rface->rfont->descent;
+ }
+ else
+ {
+ logical_ascent = g->rface->ascent;
+ logical_descent = g->rface->descent;
+ }
for (g++; g->type != GLYPH_ANCHOR && g->pos == start; g++)
{
if (lbearing < width + g->lbearing)
end = to;
while (start < end)
{
- ink_array_return[start - from].x = x + lbearing;
- ink_array_return[start - from].y = - ascent;
- ink_array_return[start - from].width = rbearing - lbearing;
- ink_array_return[start - from].height = ascent + descent;
- logical_array_return[start - from].x = x;
- logical_array_return[start - from].y = - logical_descent;
- logical_array_return[start - from].height
- = logical_ascent + logical_descent;
- logical_array_return[start - from].width = width;
+ if (ink_array_return)
+ {
+ ink_array_return[start - from].x = x + lbearing;
+ ink_array_return[start - from].y = - ascent;
+ ink_array_return[start - from].width = rbearing - lbearing;
+ ink_array_return[start - from].height = ascent + descent;
+ }
+ if (logical_array_return)
+ {
+ logical_array_return[start - from].x = x;
+ logical_array_return[start - from].y = - logical_descent;
+ logical_array_return[start - from].height
+ = logical_ascent + logical_descent;
+ logical_array_return[start - from].width = width;
+ }
start++;
}
x += width;
+ g--;
}
if (overall_ink_return)
}
M17N_OBJECT_UNREF (gstring->top);
- return 1;
+ return 0;
}
/*=*/
and $TO of M-text $MT is drawn at the coordinate (0, 0) using the
mdraw_text_with_control () function with the drawing control
object $CONTROL. Here, the character position means the number of
- characters that precede the character in question in $MT.
+ characters that precede the character in question in $MT, that is,
+ the character position of the first character is 0.
$FRAME is used only to get the default face information.
last character drawn on the line $Y. */
/***ja
- @brief »ØÄꤷ¤¿ºÂɸ¤Ë¤¢¤ëʸ»ú¤Î°ÌÃÖ¤òÆÀ¤ë
-
- ´Ø¿ô mdraw_coordinates_position () ¤Ï¡¢
-
- @li ´Ø¿ô mdraw_text () ¤ò»È¤Ã¤Æ
- @li M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤ò
- @li ºÂɸ (0, 0) ¤òµ¯ÅÀ¤È¤·¤Æ²¾¤ËÉÁ²è¤·¤¿¾ì¹ç
+ @brief »ØÄꤷ¤¿ºÂɸ¤ËºÇ¤â¶á¤¤Ê¸»ú¤Îʸ»ú°ÌÃÖ¤òÆÀ¤ë.
- ºÂɸ ($X, $Y) ¤ËÉÁ²è¤µ¤ì¤ë¥Ù¤Ê¸»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£¤³¤³¤Çʸ»ú°ÌÃÖ
- ¤È¤Ï¡¢Åö³º M-text Ãæ¤Ë¤ª¤¤¤Æ¤½¤Îʸ»ú¤¬ºÇ½é¤«¤é²¿ÈÖÌܤ«¤ò¼¨¤¹À°¿ô¤Ç
- ¤¢¤ë¡£¤¿¤À¤·ºÇ½é¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤Ï0¤È¤¹¤ë¡£
+ ´Ø¿ô mdraw_coordinates_position () ¤Ï¡¢´Ø¿ô
+ mdraw_text_with_control () ¤¬ÉÁ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤
+ ¤ÆM-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤òºÂɸ (0, 0) ¤òµ¯ÅÀ¤È¤·¤ÆÉÁ²è
+ ¤·¤¿¾ì¹ç¤Ë¡¢ºÂɸ ($X, $Y) ¤ËÉÁ²è¤µ¤ì¤ëʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£¤³¤³¤Ç
+ ʸ»ú°ÌÃ֤Ȥϡ¢Åö³º M-text Ãæ¤Ë¤ª¤¤¤Æ¤½¤Îʸ»ú¤¬ºÇ½é¤«¤é²¿ÈÖÌܤ«¤ò¼¨
+ ¤¹À°¿ô¤Ç¤¢¤ë¡£¤¿¤À¤·ºÇ½é¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤Ï0¤È¤¹¤ë¡£
- $FRAME ¤Ï¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤Î¾ðÊó¤òÆÀ¤ë¤¿¤á¤À¤±¤ËÍѤ¤¤é¤ì¤ë¡£
+ $FRAME ¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥§¡¼¥¹¤Î¾ðÊó¤òÆÀ¤ë¤¿¤á¤À¤±¤ËÍѤ¤¤é¤ì¤ë¡£
@return
ºÂɸ ($X, $Y) ¤¬¤¢¤ëʸ»ú¤Î¥°¥ê¥Õ¤Çʤ¤ï¤ì¤ë¾ì¹ç¡¢ ´Ø¿ô
if (! control->orientation_reversed)
{
width = gstring->indent;
- for (g = MGLYPH (1); g[1].type != GLYPH_ANCHOR; g++)
+ for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++)
if (g->pos >= from && g->pos < to)
{
width += g->width;
/***en
@brief Compute information about a glyph.
- The @c mdraw_glyph_info () function computes information about a
+ The mdraw_glyph_info () function computes information about a
glyph that covers a character at position $POS of the M-text $MT
assuming that the text is drawn from the character at $FROM of $MT
on a window of frame $FRAME using the mdraw_text_with_control ()
function with the drawing control object $CONTROL.
The information is stored in the members of $INFO. */
+/***ja
+ @brief ¥°¥ê¥Õ¤Ë´Ø¤¹¤ë¾ðÊó¤ò·×»»¤¹¤ë.
+
+ ´Ø¿ô mdraw_glyph_info () ¤Ï¡¢´Ø¿ô mdraw_text_with_control () ¤¬ÉÁ
+ ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤¤ÆM-text $MT ¤Î $FROM ¤«¤é $TO
+ ¤Þ¤Ç¤ò¥Õ¥ì¡¼¥à $FRAME ¤ËÉÁ²è¤·¤¿¾ì¹ç¡¢M-text ¤Îʸ»ú°ÌÃÖ $POS ¤Îʸ
+ »ú¤òʤ¤¦¥°¥ê¥Õ¤Ë´Ø¤¹¤ë¾ðÊó¤ò·×»»¤¹¤ë¡£
+
+ ¾ðÊó¤Ï$INFO ¤Î¥á¥ó¥Ð¤ËÊÝ»ý¤µ¤ì¤ë¡£ */
/***
@seealso
}
info->from = g->pos;
info->to = g->to;
- info->this.x = g->lbearing;
- info->this.y = - gstring->line_ascent;
- info->this.height = gstring->height;
+ info->metrics.x = g->lbearing;
+ info->metrics.y = - gstring->line_ascent;
+ info->metrics.height = gstring->height;
+ info->metrics.width = - g->lbearing + g->width;
if (g->rface->rfont)
info->font = &g->rface->rfont->font;
else
info->font = NULL;
- /* info->this.width is calculated later. */
+ /* info->logical_width is calculated later. */
if (info->from > info->line_from)
{
else
info->next_to = -1;
- for (info->this.width = (g++)->width;
+ for (info->logical_width = (g++)->width;
g->pos == pos && g->type != GLYPH_ANCHOR;
- info->this.width += (g++)->width);
+ info->metrics.width += g->width, info->logical_width += (g++)->width);
+ info->metrics.width += g[-1].rbearing - g[-1].width;
if (g->type != GLYPH_ANCHOR)
info->right_from = g->pos, info->right_to = g->to;
/*=*/
/***en
+ @brief Compute information about glyph sequence.
+
+ The mdraw_glyph_list () function computes information about glyphs
+ corresponding to the text between $FROM and $TO of M-text $MT when
+ it is drawn on a window of frame $FRAME using the
+ mdraw_text_with_control () function with the drawing control
+ object $CONTROL. $GLYPHS is an array of objects to store the
+ information, and $ARRAY_SIZE is the array size.
+
+ If $ARRAY_SIZE is large enough to cover all glyphs, it stores the
+ number of actually filled elements in the place pointed by
+ $NUM_GLYPHS_RETURN, and returns 0.
+
+ Otherwise, it stores the required array size in the place pointed
+ by $NUM_GLYPHS_RETURN, and returns -1. */
+
+/***ja
+ @brief ¥°¥ê¥ÕÎó¤Ë´Ø¤¹¤ë¾ðÊó¤ò·×»»¤¹¤ë.
+
+ ´Ø¿ô mdraw_glyph_list () ¤Ï¡¢´Ø¿ô mdraw_text_with_control () ¤¬ÉÁ²è
+ À©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤¤ÆM-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç
+ ¤ò¥Õ¥ì¡¼¥à $FRAME ¤ËÉÁ²è¤·¤¿¾ì¹ç¤Î¡¢³Æ¥°¥ê¥Õ¤Î¾ðÊó¤ò $GLYPHS ¤¬»Ø¤¹
+ ÇÛÎó¤Ë³ÊǼ¤¹¤ë¡£ $ARRAY_SIZE ¤Ï¤½¤ÎÇÛÎó¤Î¥µ¥¤¥º¤Ç¤¢¤ë¡£
+
+ ¤â¤· $ARRAY_SIZE ¤¬¤¹¤Ù¤Æ¤Î¥°¥ê¥Õ¤Ë¤Ä¤¤¤Æ¤Î¾ðÊó¤ò³ÊǼ¤¹¤ë¤Î¤Ë½½Ê¬¤Ç
+ ¤¢¤ì¤Ð¡¢ $NUM_GLYPHS_RETURN ¤¬»Ø¤¹¾ì½ê¤Ë¼ÂºÝ¤ËËä¤á¤¿Í×ÁǤοô¤òÀßÄê
+ ¤· 0 ¤òÊÖ¤¹¡£ */
+
+/***
+ @seealso
+ MDrawGlyph
+*/
+
+int
+mdraw_glyph_list (MFrame *frame, MText *mt, int from, int to,
+ MDrawControl *control, MDrawGlyph *glyphs,
+ int array_size, int *num_glyphs_return)
+{
+ MGlyphString *gstring;
+ MGlyph *g;
+ int n;
+ int pad_width = 0;
+
+ ASSURE_CONTROL (control);
+ *num_glyphs_return = 0;
+ M_CHECK_RANGE (mt, from, to, -1, 0);
+ gstring = get_gstring (frame, mt, from, to, control);
+ if (! gstring)
+ return -1;
+ for (g = MGLYPH (1), n = 0; g->type != GLYPH_ANCHOR; g++)
+ {
+ if (g->type == GLYPH_BOX
+ || g->pos < from || g->pos >= to)
+ continue;
+ if (g->type == GLYPH_PAD)
+ {
+ if (g->left_padding)
+ pad_width = g->width;
+ else if (n > 0)
+ {
+ pad_width = 0;
+ glyphs[-1].x_advance += g->width;
+ }
+ continue;
+ }
+ if (n < array_size)
+ {
+ glyphs->from = g->pos;
+ glyphs->to = g->to;
+ glyphs->glyph_code = g->code;
+ glyphs->x_off = g->xoff + pad_width;
+ glyphs->y_off = g->yoff;
+ glyphs->lbearing = g->lbearing;
+ glyphs->rbearing = g->rbearing;
+ glyphs->ascent = g->ascent;
+ glyphs->descent = g->descent;
+ glyphs->x_advance = g->width + pad_width;
+ glyphs->y_advance = 0;
+ if (g->rface->rfont)
+ {
+ glyphs->font = &g->rface->rfont->font;
+ glyphs->font_type = g->rface->rfont->type;
+ glyphs->fontp = g->rface->rfont->fontp;
+ }
+ else
+ {
+ glyphs->font = NULL;
+ glyphs->font_type = Mnil;
+ glyphs->fontp = NULL;
+ }
+ pad_width = 0;
+ glyphs++;
+ }
+ n++;
+ }
+ M17N_OBJECT_UNREF (gstring->top);
+
+ *num_glyphs_return = n;
+ return (n <= array_size ? 0 : -1);
+}
+
+/*=*/
+
+/***en
@brief Draw one or more textitems.
The mdraw_text_items () function draws one or more M-texts on
textimtems in the array. */
/***ja
- @brief textitem ¤òɽ¼¨¤¹¤ë
+ @brief textitem ¤òɽ¼¨¤¹¤ë.
´Ø¿ô mdraw_text_items () ¤Ï¡¢°ì¸Ä°Ê¾å¤Î¥Æ¥¥¹¥È¥¢¥¤¥Æ¥à¤ò¡¢¥Õ¥ì¡¼
¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤ÎºÂɸ ($X, $Y) ¤Ëɽ¼¨¤¹¤ë¡£$ITEMS ¤Ï
mdraw_text_items (MFrame *frame, MDrawWindow win, int x, int y,
MDrawTextItem *items, int nitems)
{
+ if (! (frame->device_type & MDEVICE_SUPPORT_OUTPUT))
+ return;
while (nitems-- > 0)
{
if (items->face)
}
/*=*/
+/***en
+ @brief calculate a line breaking position.
+
+ The function mdraw_default_line_break () calculates a line
+ breaking position based on the line number $LINE and the
+ coordinate $Y, when a line is too long to fit within the width
+ limit. $POS is the position of the character next to the last
+ one that fits within the limit. $FROM is the position of the
+ first character of the line, and TO is the position of the last
+ character displayed on the line if there were not width limit.
+ LINE and Y are reset to 0 when a line is broken by a newline
+ character, and incremented each time when a long line is broken
+ because of the width limit.
+
+ @return
+ This function returns a character position to break the
+ line.
+
+*/
+/***ja
+ @brief ²þ¹Ô°ÌÃÖ¤ò·×»»¤¹¤ë.
+
+ ´Ø¿ô mdraw_default_line_break () ¤Ï¡¢¹Ô¤¬ºÇÂçÉýÃæ¤Ë¼ý¤Þ¤é¤Ê¤¤¾ì
+ ¹ç¤Ë¹Ô¤ò²þ¤á¤ë°ÌÃÖ¤ò¡¢¹ÔÈÖ¹æ LINE ¤ÈºÂɸ Y ¤Ë´ð¤Å¤¤¤Æ·×»»¤¹¤ë¡£
+ $POS ¤ÏºÇÂçÉý¤Ë¼ý¤Þ¤ëºÇ¸å¤Îʸ»ú¤Î¼¡¤Îʸ»ú¤Î°ÌÃ֤Ǥ¢¤ë¡£$FROM ¤Ï
+ ¹Ô¤ÎºÇ½é¤Îʸ»ú¤Î°ÌÃÖ¡¢$TO ¤ÏºÇÂçÉý¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤½¤Î¹Ô¤Ë
+ ɽ¼¨¤µ¤ì¤ëºÇ¸å¤Îʸ»ú¤Î°ÌÃ֤Ǥ¢¤ë¡£ LINE ¤È Y ¤Ï²þ¹Ôʸ»ú¤Ë¤è¤Ã¤Æ
+ ¹Ô¤¬²þ¤Þ¤Ã¤¿ºÝ¤Ë¤Ï 0 ¤Ë¥ê¥»¥Ã¥È¤µ¤ì¡¢ºÇÂçÉý¤Ë¤è¤Ã¤Æ¹Ô¤¬²þ¤Þ¤Ã¤¿
+ ¾ì¹ç¤Ë¤Ï 1 ¤Å¤ÄÁý¤ä¤µ¤ì¤ë¡£
+
+ @return
+ ¤³¤Î´Ø¿ô¤Ï¹Ô¤ò²þ¤á¤ëʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£
+*/
int
mdraw_default_line_break (MText *mt, int pos,
If pointer $OVERALL_RETURN is not @c NULL, this function also
computes the extents of the overall text and stores the results in
- the members of the structure pointed to by $OVERALL_RETURN */
+ the members of the structure pointed to by $OVERALL_RETURN. */
/***ja
- @brief M-text ¤Îʸ»úËè¤Î¾ðÊó¤òÆÀ¤ë
+ @brief M-text ¤Îʸ»úËè¤Îɽ¼¨ÈϰϾðÊó¤òÆÀ¤ë.
´Ø¿ô mdraw_per_char_extents () ¤Ï¡¢M-text $MT Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈÏ°Ï
¤ò·×»»¤¹¤ë¡£¤³¤Î·×»»¤ËÍѤ¤¤ë¥Õ¥©¥ó¥È¤Ï¡¢$MT ¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ç
- »ØÄꤵ¤ì¤¿¥Õ¥§¡¼¥¹¤È¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤«¤é·èÄê
- ¤µ¤ì¤ë¡£$ARRAY_RETURN ¤Î³ÆÍ×ÁǤϡ¢Åö³º M-text Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈÏ°Ï
- ¾ðÊó¤Ë¤è¤Ã¤Æ½ç¤ËËä¤á¤é¤ì¤ë¡£¤³¤Îɽ¼¨ÈϰϾðÊó¤Ï¡¢M-text ¤Îɽ¼¨¸¶ÅÀ
- ¤«¤é¤ÎÁêÂаÌÃ֤Ǥ¢¤ë¡£$ARRAY_RETURN ¤ÎÍ×ÁÇ¿ô¤Ï¡¢M-text ¤Îʸ»ú¿ô°Ê
- ¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+ »ØÄꤵ¤ì¤¿¥Õ¥§¡¼¥¹¤Èa¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤Ë¤è¤Ã¤Æ
+ ·è¤Þ¤ë¡£$ARRAY_RETURN ¤Î³ÆÍ×ÁǤϡ¢Åö³º M-text Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈÏ°Ï
+ ¾ðÊó¤Ë¤è¤Ã¤Æ½ç¤ËËä¤á¤é¤ì¤ë¡£¤³¤Îɽ¼¨ÈϰϾðÊó¤Ï¡¢M-text ¤Îɽ¼¨¸¶ÅÀ¤«
+ ¤é¤ÎÁêÂаÌÃ֤Ǥ¢¤ë¡£$ARRAY_RETURN ¤ÎÍ×ÁÇ¿ô¤Ï¡¢M-text ¤Î°Ê¾å¤Ç¤Ê¤±¤ì
+ ¤Ð¤Ê¤é¤Ê¤¤¡£
- ¥Ý¥¤¥ó¥¿ $OVERALL_RETURN ¤¬ @c NULL ¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥Æ¥¥¹¥ÈÁ´ÂΤÎɽ¼¨
- ÈϰϾðÊó¤â·×»»¤·¡¢¤½¤Î·×»»¤ò $OVERALL_RETURN ¤Î»Ø¤¹Àè¤Ë³ÊǼ¤¹¤ë¡£
+ ¥Ý¥¤¥ó¥¿ $OVERALL_RETURN ¤¬ @c NULL ¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥Æ¥¥¹¥ÈÁ´ÂΤÎɽ
+ ¼¨ÈϰϾðÊó¤â·×»»¤·¡¢¤½¤Î·ë²Ì¤ò $OVERALL_RETURN ¤Î»Ø¤¹¹½Â¤ÂΤ˳ÊǼ
+ ¤¹¤ë¡£
@latexonly \IPAlabel{mdraw_per_char_extents} @endlatexonly */
void
mdraw_per_char_extents (MFrame *frame, MText *mt,
- MDrawMetric *array_return,
- MDrawMetric *overall_return)
+ MDrawMetric *array_return,
+ MDrawMetric *overall_return)
{
+ int n = mtext_nchars (mt);
+
+ mdraw_text_per_char_extents (frame, mt, 0, n, NULL, array_return, NULL,
+ n, &n, overall_return, NULL);
}
+/***en
+ @brief clear cached information.
+
+ The mdraw_clear_cache () function clear cached information
+ on M-text $MT that was attached by any of the drawing functions.
+ When the behaviour of `format' or `line_break'
+ member functions of MDrawControl is changed, the cache must be cleared.
+
+ @seealso
+ MDrawControl */
+/***ja
+ @brief ¥¥ã¥Ã¥·¥å¾ðÊó¤ò¾Ã¤¹.
+
+ ´Ø¿ô mdraw_clear_cache () ¤ÏÉÁ²è´Ø¿ô¤Ë¤è¤Ã¤Æ M-text $MT ¤ËÉÕ²Ã
+ ¤µ¤ì¤¿¥¥ã¥Ã¥·¥å¾ðÊó¤ò¤¹¤Ù¤Æ¾Ãµî¤¹¤ë¡£MDrawControl ¤Î `format' ¤¢
+ ¤ë¤¤¤Ï `line_break' ¥á¥ó¥Ð´Ø¿ô¤Î¿¶Éñ¤¤¤¬ÊѤï¤Ã¤¿¾ì¹ç¤Ë¤Ï¥¥ã¥Ã¥·¥å
+ ¤ò¾Ãµî¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+ @seealso
+ MDrawControl */
+
void
mdraw_clear_cache (MText *mt)
{