/***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.
appearance of M-texts, i.e. font size, color, underline, etc.
The drawing format of M-texts can be controlled in a variety of
- ways, which provides powerful 2-dimensional layouting
+ ways, which provides powerful 2-dimensional layout
facility. */
/***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 ¤ÎÉÁ²è¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï¿ÍͤÊÊýË¡¤ÇÀ©¸æ¤Ç¤¤ë¤Î¤Ç¡¢¶¯ÎϤÊÆ󼡸µ¥ì¥¤¥¢¥¦¥Èµ¡Ç½¤¬¼Â¸½¤Ç¤¤ë¡£
+ */
/*=*/
#include "m17n-misc.h"
#include "internal.h"
#include "symbol.h"
+#include "mtext.h"
#include "textprop.h"
#include "internal-gui.h"
#include "face.h"
static MSymbol M_glyph_string;
/* Special scripts */
-static MSymbol Mlatin, Minherited;
+static MSymbol Minherited;
/* Special categories */
static MSymbol McatCc, McatCf;
+static MCharTable *linebreak_table;
+static MSymbol M_break_at_space, M_break_at_word, M_break_at_any;
+static MSymbol M_kinsoku_bol, M_kinsoku_eol;
+
\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];
- int pos = glyphs[k].pos;
+ /* 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].pos == pos || 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;
}
}
/** Scan M-text MT from FROM to TO, and compose glyphs in GSTRING for
displaying them on FRAME.
- This function fills members <type>, <rface>, <c>, <pos>, <to>,
- <code> of glyphs. The other members are filled by
- layout_glyph_string. */
+ This function fills these members:
+ pos, to, c, code, rface, bidi_level, categories, type, combining_code
+ The other members are filled by layout_glyph_string. */
static void
compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
{
MRealizedFace *default_rface = frame->rface;
int stop, face_change, language_change, charset_change;
- MGlyph g_tmp, *g;
+ MGlyph g_tmp, *g, *last_g;
int pos;
MSymbol language = Mnil, script = Mnil, charset = Mnil;
+ MSymbol non_latin_script = Mnil;
MRealizedFace *rface = default_rface;
- int non_ascii_found;
+ MRealizedFont *rfont;
int size = gstring->control.fixed_width;
- int ignore_formatting_char = gstring->control.ignore_formatting_char;
- int i, limit;
+ int i;
MLIST_RESET (gstring);
gstring->from = from;
- /* At first generate glyphs while using the member <enabled> as a
- flag for rface re-checking. */
+ /* At first generate glyphs with <pos>, <to>, <c>, <type>,
+ <category> and <rface> members.*/
INIT_GLYPH (g_tmp);
/** Put anchor glyphs at the head and tail. */
g_tmp.type = GLYPH_ANCHOR;
g_tmp.pos = g_tmp.to = from;
- g_tmp.c = 0;
APPEND_GLYPH (gstring, g_tmp);
-
- stop = face_change = charset_change = language_change = pos = from;
- g = gstring->glyphs + gstring->used;
- non_ascii_found = 0;
+ stop = face_change = pos = from;
while (1)
{
int c;
- MSymbol this_script;
-
- if (pos < mtext_nchars (mt))
- c = mtext_ref_char (mt, pos);
- else
- c = '\n';
- g_tmp.category = Mnil;
- 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;
- }
- 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;
- }
- }
+ MSymbol category;
- if (pos == stop || script != this_script || g->type != g_tmp.type)
+ if (pos == stop)
{
- 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;
- non_ascii_found = 0;
- script = this_script;
if (pos == to)
break;
- if (pos < mtext_nchars (mt) && pos == language_change)
+ if (pos == face_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);
+ if (pos < mtext_nchars (mt))
+ {
+ 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);
+ if (face_change == mtext_nchars (mt))
+ face_change++;
+ rface = (num > 0 ? mface__realize (frame, faces, num, size)
+ : default_rface);
+ }
+ else
+ rface = default_rface;
}
- stop = language_change;
- if (stop > charset_change)
- stop = charset_change;
- if (face_change < stop)
+ stop = to;
+ if (stop > face_change)
stop = face_change;
}
- g_tmp.c = g_tmp.code = c;
+ if (pos < mtext_nchars (mt))
+ c = mtext_ref_char (mt, pos);
+ else
+ c = '\n';
+ g_tmp.type
+ = (c == ' ' || c == '\n' || c == '\t') ? GLYPH_SPACE : GLYPH_CHAR;
+ g_tmp.c = c;
g_tmp.pos = pos++;
g_tmp.to = pos;
g_tmp.rface = rface;
+ category = mchar_get_prop (c, Mcategory);
+ if (category == McatCf)
+ g_tmp.category = GLYPH_CATEGORY_FORMATTER;
+ else if (category != Mnil && MSYMBOL_NAME (category)[0] == 'M')
+ g_tmp.category = GLYPH_CATEGORY_MODIFIER;
+ else
+ g_tmp.category = GLYPH_CATEGORY_NORMAL;
- if (c >= 0x100)
- non_ascii_found = 1;
- else if (g_tmp.type == GLYPH_CHAR && (c <= 32 || c == 127))
+ if ((c <= ' ' || c == 127) && g_tmp.type == GLYPH_CHAR)
{
- g_tmp.c = '^';
- APPEND_GLYPH (gstring, g_tmp);
- if (c < ' ')
- g_tmp.c += 0x40;
- else
- g_tmp.c = '?';
+ MGlyph ctrl[2];
+
+ ctrl[0] = ctrl[1] = g_tmp;
+ ctrl[0].c = '^';
+ ctrl[1].c = c < ' ' ? c + 0x40 : '?';
+ APPEND_GLYPH (gstring, ctrl[0]);
+ APPEND_GLYPH (gstring, ctrl[1]);
}
- APPEND_GLYPH (gstring, g_tmp);
- if (c == '\n'
- && gstring->control.two_dimensional)
+ else
+ APPEND_GLYPH (gstring, g_tmp);
+ if (c == '\n' && gstring->control.two_dimensional)
break;
}
-
- limit = pos - from;
-
/* Append an anchor glyph. */
+ INIT_GLYPH (g_tmp);
g_tmp.type = GLYPH_ANCHOR;
- g_tmp.c = 0;
- g_tmp.code = MCHAR_INVALID_CODE;
g_tmp.pos = g_tmp.to = pos;
- g_tmp.rface = NULL;
APPEND_GLYPH (gstring, g_tmp);
-
gstring->to = pos;
- /* Next, run FLT if necessary. */
- for (i = 1, g = MGLYPH (i); g->type != GLYPH_ANCHOR;)
+ /* The next loop is to change each <rface> member for non-ASCII
+ characters if necessary. */
+ stop = charset_change = language_change = from;
+ rfont = default_rface->rfont;
+ for (last_g = g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++)
+ {
+ int c = g->c;
+ MSymbol this_script;
+
+ if (c < 0x100)
+ /* Short cut for the obvious case. */
+ this_script = Mlatin;
+ else
+ {
+ this_script = (MSymbol) mchar_get_prop (c, Mscript);
+ 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. */
+ MSymbol sym;
+ MGlyph *g1;
+
+ for (g1 = g + 1; g1->type != GLYPH_ANCHOR; g1++)
+ if (g1->c >= 0x100
+ && (sym = mchar_get_prop (g1->c, Mscript)) != Mnil
+ && sym != Minherited)
+ {
+ this_script = sym;
+ break;
+ }
+ }
+ }
+
+ pos = g->pos;
+ if (pos == stop || script != this_script || g->rface->rfont != rfont)
+ {
+ while (last_g < g)
+ last_g = mface__for_chars (script, language, charset,
+ last_g, g, size);
+ script = this_script;
+ if (script != Mnil && script != Mlatin)
+ non_latin_script = script;
+ rfont = g->rface->ascii_rface->rfont;
+ if (pos == stop)
+ {
+ 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);
+ }
+ stop = to;
+ if (stop > language_change)
+ stop = language_change;
+ if (stop > charset_change)
+ stop = charset_change;
+ }
+ }
+ }
+ while (last_g < g)
+ last_g = mface__for_chars (script, language, charset, last_g, g, size);
+
+ /* The next loop is to run FLT or perform the default combining if
+ necessary. */
+ for (i = 1, g = MGLYPH (1); g->type != GLYPH_ANCHOR;)
{
MGlyph *this = g;
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 == GLYPH_CATEGORY_FORMATTER
+ && (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 == GLYPH_CATEGORY_FORMATTER
+ && ((code = mfont__encode_char (this->rface->rfont,
+ g->c))
+ != MCHAR_INVALID_CODE))));
+ i++, g++)
+ if (g->rface->rfont != this->rface->rfont)
+ {
+ g->rface->rfont = this->rface->rfont;
+ g->code = code;
+ }
+ i = mfont__flt_run (gstring, start, i, this->rface);
}
else
{
while (this->type == GLYPH_CHAR
&& this->c >= 0x100
- && this->category
- && MSYMBOL_NAME (this->category)[0] == 'M'
+ && this->category == GLYPH_CATEGORY_MODIFIER
&& this->rface->rfont
&& this->rface->rfont->layouter == Mnil)
{
}
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++;
+
+ while (i < to && ! MGLYPH (i)->otf_encoded) i++;
+ mfont__get_metric (gstring, j, i);
+ }
+ }
+
+ g = MGLYPH (from);
while (g < last_g)
{
MGlyph *base = g++;
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. */
+ 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;
- 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;
- 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)
base->ascent = - top;
base->descent = bottom;
+ base->lbearing = lbearing;
+ base->rbearing = rbearing;
if (left < - base->width)
{
base->xoff = - base->width - left;
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 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;
}
}
+ if (g->category == GLYPH_CATEGORY_FORMATTER && ignore_formatting_char)
+ g->type = GLYPH_SPACE;
+
if (g->type == GLYPH_CHAR)
{
MRealizedFace *rface = g->rface;
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 == GLYPH_CATEGORY_FORMATTER
+ && ignore_formatting_char))
break;
if (rfont && fromg->code != MCHAR_INVALID_CODE)
{
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)
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)
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;
}
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;
if (pos == mt->nchars)
{
+ MGlyph *g;
+
gstring = &scratch_gstring;
+ if (gstring->size == 0)
+ {
+ MGlyph g_tmp;
+
+ INIT_GLYPH (g_tmp);
+ g_tmp.type = GLYPH_ANCHOR;
+ APPEND_GLYPH (gstring, g_tmp);
+ APPEND_GLYPH (gstring, g_tmp);
+ APPEND_GLYPH (gstring, g_tmp);
+ gstring->glyphs[1].type = GLYPH_SPACE;
+ gstring->glyphs[1].c = '\n';
+ gstring->glyphs[1].code = '\n';
+ }
+ gstring->from = pos;
+ g = MGLYPH (0);
+ g->rface = frame->rface;
+ g->pos = g->to = pos;
+ g++;
+ g->rface = frame->rface;
+ g->pos = pos++, g->to = pos;
+ g++;
+ g->rface = frame->rface;
+ g->pos = g->to = pos;
+ gstring->to = pos;
}
else
{
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)
(*control->format) (line, y, &(gstring->indent), &(gstring->width_limit));
else
gstring->width_limit = control->max_line_width;
+ gstring->anti_alias = control->anti_alias;
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,
- gstring->from, gstring->to, 0, 0);
- if (pos <= gstring->from || pos >= gstring->to)
- return;
+ pos = (*gstring->control.line_break) (mt, gstring->from + i,
+ gstring->from, gstring->from + i, 0, 0);
+ 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)
+ if (pos < mtext_nchars (mt))
{
beg = mtext_character (mt, pos, 0, '\n');
if (beg < 0)
beg = 0;
else
beg++;
- end = mtext_nchars (mt) + (control->cursor_width != 0);
}
else
- {
- beg = pos;
- end = to;
- }
- gstring = alloc_gstring (mt, beg, control, line, y);
- compose_glyph_string (frame, mt, beg, end, gstring);
+ beg = pos;
+ end = mtext_nchars (mt) + (control->cursor_width != 0);
+ gstring = alloc_gstring (frame, mt, beg, control, line, y);
+ if (beg < mtext_nchars (mt))
+ 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;
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;
return g;
}
+#define GET_LB_TYPE(MT, POS, LB_TYPE) \
+ do { \
+ int c = mtext_ref_char ((MT), (POS)); \
+ (LB_TYPE) = ((c == ' ' || c == '\t' || c == '\n') ? M_kinsoku_bol \
+ : mchartable_lookup (linebreak_table, c)); \
+ } while (0)
+
+static int
+find_break_backward (MText *mt, int pos, int limit)
+{
+ MSymbol lb_type;
+
+ if (pos <= limit)
+ return limit;
+
+ GET_LB_TYPE (mt, pos, lb_type);
+ if (lb_type == M_kinsoku_bol)
+ return find_break_backward (mt, pos - 1, limit);
+ if (lb_type == Mnil)
+ {
+ while (pos > limit)
+ {
+ GET_LB_TYPE (mt, pos - 1, lb_type);
+ if (lb_type != Mnil)
+ break;
+ pos--;
+ }
+ }
+ else if (lb_type == M_break_at_word)
+ {
+ int beg = limit, end = mtext_nchars (mt);
+ int in_word = mtext__word_segment (mt, pos, &beg, &end);
+
+ if (in_word)
+ pos = beg;
+ else if (beg > limit)
+ {
+ end = beg;
+ beg = limit;
+ mtext__word_segment (mt, beg - 1, &beg, &end);
+ pos = beg;
+ }
+ }
+ while (pos > limit)
+ {
+ GET_LB_TYPE (mt, pos - 1, lb_type);
+ if (lb_type != M_kinsoku_eol)
+ return pos;
+ pos--;
+ }
+ return limit;
+}
+
+static int
+find_break_forward (MText *mt, int pos, int limit)
+{
+ MSymbol lb_type;
+
+ GET_LB_TYPE (mt, pos, lb_type);
+ if (lb_type == Mnil)
+ {
+ while (pos < limit)
+ {
+ pos++;
+ GET_LB_TYPE (mt, pos, lb_type);
+ }
+ }
+ else if (lb_type == M_break_at_word)
+ {
+ int beg = 0, end = mtext_nchars (mt);
+ int in_word = mtext__word_segment (mt, pos, &beg, &end);
+
+ if (! in_word)
+ pos = end;
+ else if (end < limit)
+ {
+ beg = end;
+ pos = end = mtext_nchars (mt);
+ mtext__word_segment (mt, pos, &beg, &end);
+ pos = end;
+ }
+ }
+ else if (lb_type == M_kinsoku_bol)
+ pos++;
+ while (pos < limit)
+ {
+ GET_LB_TYPE (mt, pos, lb_type);
+ if (lb_type != M_kinsoku_bol)
+ return pos;
+ pos++;
+ }
+ return limit;
+}
+
\f
/* for debugging... */
char work[16];
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);
memset (&scratch_gstring, 0, sizeof (scratch_gstring));
MLIST_INIT1 (&scratch_gstring, glyphs, 3);
- Mlatin = msymbol ("latin");
Minherited = msymbol ("inherited");
McatCc = msymbol ("Cc");
fribidi_set_mirroring (TRUE);
#endif
+ M_break_at_space = msymbol ("bs");
+ M_break_at_word = msymbol ("bw");
+ M_break_at_any = msymbol ("ba");
+ M_kinsoku_bol = msymbol ("kb");
+ M_kinsoku_eol = msymbol ("ke");
+
return 0;
}
mdraw__fini ()
{
MLIST_FREE1 (&scratch_gstring, glyphs);
+ M17N_OBJECT_UNREF (linebreak_table);
+ linebreak_table = NULL;
}
/*** @} */
<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 ¤Ç¤Ê¤±¤ì¤Ð¡¢É½¼¨¤·¤¿¥Æ¥¥¹¥È¤Î¥Ç¥£¥»
- ¥ó¥È¤¬¤½¤³¤Ë³ÊǼ¤µ¤ì¤ë¡£
+ ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥¥¹¥È¤òÉÁ²è¤¹¤ë¡£
¥Æ¥¥¹¥È¤Î¸«±É¤¨¡Ê¥Õ¥©¥ó¥È¡¢¥¹¥¿¥¤¥ë¡¢¿§¤Ê¤É¡Ë¤Ï¡¢¥¡¼¤¬ @c Mface
- ¤Ç¤¢¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ÎÃͤˤè¤Ã¤Æ·è¤Þ¤ë¡£M-text ¤Î°ìÉô¤¢¤ë¤¤¤Ï
- Á´Éô¤Ë¤½¤Î¤è¤¦¤Ê¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬ÉÕ¤¤¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢$FRAME
- ¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤¬ÍѤ¤¤é¤ì¤ë¡£
+ ¤Ç¤¢¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ÎÃͤˤè¤Ã¤Æ·è¤Þ¤ë¡£M-text
+ ¤Î°ìÉô¤¢¤ë¤¤¤ÏÁ´Éô¤Ë¤½¤Î¤è¤¦¤Ê¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬ÉÕ¤¤¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢$FRAME
+ ¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤òÂå¤ï¤ê¤ËÍѤ¤¤ë¡£
- M-text ¤Î³Æʸ»ú¤òɽ¼¨¤¹¤ë¥Õ¥©¥ó¥È¤Ï¡¢$FACE ¤Î fontset ¥×¥í¥Ñ¥Æ¥£¤Î
- Ãͤ«¤é°Ê²¼¤Î¥¢¥ë¥´¥ê¥º¥à¤ÇÁª¤Ð¤ì¤ë¡£
+ M-text ¤Î³Æʸ»ú¤òɽ¼¨¤¹¤ë¥Õ¥©¥ó¥È¤Ï¡¢¥Õ¥§¡¼¥¹¤Î fontset
+ ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤΤ¦¤Á¤«¤é¡¢°Ê²¼¤Î¥¢¥ë¥´¥ê¥º¥à¤ÇÁª¤Ð¤ì¤ë¡£
<ol>
- <li> ¤½¤Îʸ»ú¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥¡¼¤¬ @c Mlanguage ¤Ç¤¢
- ¤ë¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£¤³¤ÎÃͤϸÀ¸ì¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil ¤Î¤¤
- ¤º¤ì¤«¤Ç¤¢¤ë¡£¼¡¤Ë¥¡¼¤¬ @c Mscript ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£
- ¤³¤ÎÃͤϥ¹¥¯¥ê¥×¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil ¤Î¤É¤Á¤é¤«¤Ç¤¢¤ë¡£
+ <li> ¤½¤Îʸ»ú¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥¡¼¤¬ @c Mcharset
+ ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£¤³¤ÎÃͤÏʸ»ú¥»¥Ã¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« #Mnil
+ ¤Î¤É¤Á¤é¤«¤Ç¤¢¤ë¡£#Mnil ¤Ê¤é¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
+ ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢fontset
+ ¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤Ë¤½¤Îʸ»ú¥»¥Ã¥ÈÍѤΥե©¥ó¥È¤¬¤¢¤ë¤«¤É¤¦¤«¤òÄ´¤Ù¤ë¡£
+ ̵¤±¤ì¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
+
+ ¤½¤Îʸ»ú¥»¥Ã¥ÈÍѤΥե©¥ó¥È¤¬¤ß¤Ä¤«¤ì¤Ð¡¢¤½¤ì¤é¤Î¤¦¤Á¸½ºß¤Îʸ»úÍѤΥ°¥ê¥Õ¤ò»ý¤Á¡¢¥Õ¥§¡¼¥¹¤Î³Æ¥×¥í¥Ñ¥Æ¥£¤ËºÇ¤â¤è¤¯¹çÃפ¹¤ë¤â¤Î¤ò»È¤¦¡£
+ ¤½¤Î¤è¤¦¤Ê¥Õ¥©¥ó¥È¤¬Ìµ¤±¤ì¤Ð¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
- ¤É¤Á¤é¤â @c Mnil ¤Ê¤é¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
+ <li> ¤½¤Îʸ»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "script" ¡Ê¥¹¥¯¥ê¥×¥È¡Ë¤òÄ´¤Ù¤ë¡£
+ ¤½¤Î¥×¥í¥Ñ¥Æ¥£¤¬·Ñ¾µ¤µ¤ì¤Æ¤¤¤ë¤Ê¤é¤Ð¤½¤ì°ÊÁ°¤Îʸ»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "script"
+ ¤òÄ´¤Ù¤ë¡£Á°¤Îʸ»ú¤¬¤Ê¤«¤Ã¤¿¤ê¡¢¤½¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ã¤Æ¤¤¤Ê¤«¤Ã¤¿¾ì¹ç¤Ë¤Ï¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
- ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤½¤Î¸À¸ì¤È¥¹¥¯¥ê¥×¥È¤ÎÁȤ߹ç¤ï¤»¤ò»È¤Ã
- ¤Æ¡¢¤½¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤ò¤Ò¤¯¡£¥Õ¥©¥ó¥È¤¬
- ¤ß¤Ä¤«¤ê¡¢¤«¤Ä¤½¤Î¥Õ¥©¥ó¥È¤Ç¸½ºß¤Îʸ»ú¤¬É½¼¨¤Ç¤¤ì¤Ð¡¢¤½¤Î¥Õ¥©
- ¥ó¥È¤ò»È¤¦¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
+ ¤½¤Îʸ»ú¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥¡¼¤¬ @c Mlanguage ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£
+ ¤³¤ÎÃͤϸÀ¸ì¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
- <li> ¤½¤Îʸ»ú¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥¡¼¤¬ @c Mcharset ¤Ç¤¢¤ë
- ¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£¤³¤ÎÃͤÏʸ»ú¥»¥Ã¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil
- ¤Î¤É¤Á¤é¤«¤Ç¤¢¤ë¡£@c Mnil ¤Ê¤é¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
+ ¤½¤Î¸À¸ì¤È¥¹¥¯¥ê¥×¥È¤ÎÁȤ߹ç¤ï¤»¤¬ fontset
+ ¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤Ë¤¢¤ë¤«¤É¤¦¤«¤òÄ´¤Ù¤ë¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
- ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¸«¤Ä¤«¤Ã¤¿Ê¸»ú¥»¥Ã¥È»È¤Ã¤Æ¡¢¤½¤Î¥Õ¥©¥ó¥È¥»¥Ã
- ¥È¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤ò¤Ò¤¯¡£¥Õ¥©¥ó¥È¤¬¤ß¤Ä¤«¤ê¡¢¤«¤Ä¤½¤Î¥Õ¥©
- ¥ó¥È¤Ç¸½ºß¤Îʸ»ú¤¬É½¼¨¤Ç¤¤ì¤Ð¡¢¤½¤Î¥Õ¥©¥ó¥È¤ò»È¤¦¡£¤½¤¦¤Ç¤Ê
- ¤±¤ì¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
+ ¸«¤Ä¤«¤Ã¤¿¤Ð¤¢¤¤¤Ë¤Ï¡¢¤½¤ì¤é¤Î¥Õ¥©¥ó¥È¤Î¤¦¤Á¸½ºß¤Îʸ»úÍѤΥ°¥ê¥Õ¤ò»ý¤Á¡¢¥Õ¥§¡¼¥¹¤Î³Æ¥×¥í¥Ñ¥Æ¥£¤ËºÇ¤â¤è¤¯¹çÃפ·¤Æ¤¤¤ë¤â¤Î¤ò»È¤¦¡£
+ ¤½¤Î¤è¤¦¤Ê¥Õ¥©¥ó¥È¤¬Ìµ¤±¤ì¤Ð¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
- <li> ¸½ºß¤Îʸ»ú¼«¿È¤ò»È¤Ã¤Æ¡¢¤½¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö
- ¥ë¤ò¤Ò¤¯¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤ì¤Ð¤½¤ì¤ò»È¤¦¡£
+ <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 ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
+ ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_text () ¤Ï 0 ÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï
+ -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 ¤ò²èÁü¤È¤·¤ÆÉÁ¤¯
-
- ´Ø¿ô mdraw_image_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤Î
- ºÂɸ ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥¥¹¥È¤ò²è
- Áü¤È¤·¤ÆÉÁ¤¯¡£
+ @brief ¥Ç¥£¥¹¥×¥ì¥¤¤ËM-text ¤ò²èÁü¤È¤·¤ÆÉÁ¤¯.
+
+ ´Ø¿ô mdraw_image_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN
+ ¤ÎºÂɸ ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO
+ ¤Þ¤Ç¤Î¥Æ¥¥¹¥È¤ò²èÁü¤È¤·¤ÆÉÁ¤¯¡£
- ¥Æ¥¥¹¥È¤ÎÉÁ²èÊýË¡¤Ï mdraw_text () ¤È¤Û¤ÜƱ¤¸¤Ç¤¢¤ë¤¬¡¢¤³¤Î´Ø¿ô¤Ç
- ¤Ï $FACE ¤Ç»ØÄꤵ¤ì¤¿¿§¤ÇÇطʤâÉÁ¤¯ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£
+ ¥Æ¥¥¹¥È¤ÎÉÁ²èÊýË¡¤Ï mdraw_text ()
+ ¤È¤Û¤ÜƱ¤¸¤Ç¤¢¤ë¤¬¡¢¤³¤Î´Ø¿ô¤Ç¤Ï¥Õ¥§¡¼¥¹¤Ç»ØÄꤵ¤ì¤¿¿§¤ÇÇطʤâÉÁ¤¯ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£
¤³¤Î´Ø¿ô¤Ï¡¢X ¥¦¥£¥ó¥É¥¦¤Ë¤ª¤±¤ë <tt>XDrawImageString ()</tt>,
- <tt>XmbDrawImageString ()</tt>, <tt>XwcDrawImageString ()</tt> ¤Ë
- ÁêÅö¤¹¤ë¡£
+ <tt>XmbDrawImageString ()</tt>, <tt>XwcDrawImageString ()</tt>
+ ¤ËÁêÅö¤¹¤ë¡£
@return
- ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_image_text () ¤Ï 0 ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð
- ¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c m_errro ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ
- ¤ë¡£
+ ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_image_text () ¤Ï 0
+ ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï -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);
}
surrounding box, the box is included in the bounding box.
If $OVERALL_LOGICAL_RETURN is not @c NULL, this function also
- computes the bounding box that provides mininum spacing to other
+ computes the bounding box that provides minimum spacing to other
graphical features (such as surrounding box) for the M-text, and
stores the results in the members of the structure pointed to by
$OVERALL_LOGICAL_RETURN.
If $OVERALL_LINE_RETURN is not @c NULL, this function also
- computes the bounding box that provides mininum spacing to the
+ computes the bounding box that provides minimum spacing to the
other M-text drawn, and stores the results in the members of the
structure pointed to by $OVERALL_LINE_RETURN. This is a union of
$OVERALL_INK_RETURN and $OVERALL_LOGICAL_RETURN if the members
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.
mdraw_coordinates_position () returns the character position of
that character.\n\n
If $Y is less than the minimum Y-coordinate of the drawn area, it
- returns $FROM.\n\n\n
+ returns $FROM.\n\n
If $Y is greater than the maximum Y-coordinate of the drawn area,
- it returns $TO.\n\n\n
+ it returns $TO.\n\n
If $Y fits in with the drawn area but $X is less than the minimum
X-coordinate, it returns the character position of the first
- character drawn on the line $Y.\n\n\n
+ character drawn on the line $Y.\n\n
If $Y fits in with the drawn area but $X is greater than the
maximum X-coordinate, it returns the character position of the
last character drawn on the line $Y. */
/***ja
- @brief »ØÄꤷ¤¿ºÂɸ¤Ë¤¢¤ëʸ»ú¤Î°ÌÃÖ¤òÆÀ¤ë
-
- ´Ø¿ô mdraw_coordinates_position () ¤Ï¡¢
+ @brief »ØÄꤷ¤¿ºÂɸ¤ËºÇ¤â¶á¤¤Ê¸»ú¤Îʸ»ú°ÌÃÖ¤òÆÀ¤ë.
- @li ´Ø¿ô mdraw_text () ¤ò»È¤Ã¤Æ
- @li M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤ò
- @li ºÂɸ (0, 0) ¤òµ¯ÅÀ¤È¤·¤Æ²¾¤ËÉÁ²è¤·¤¿¾ì¹ç
+ ´Ø¿ô mdraw_coordinates_position () ¤Ï¡¢´Ø¿ô
+ mdraw_text_with_control () ¤¬ÉÁ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤¤Æ¡¢
+ M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤òºÂɸ (0, 0)
+ ¤òµ¯ÅÀ¤È¤·¤ÆÉÁ²è¤¹¤ëºÝ¤Ë¡¢ºÂɸ ($X, $Y)
+ ¤ËÉÁ²è¤µ¤ì¤ëʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£¤³¤³¤Çʸ»ú°ÌÃ֤Ȥϡ¢Åö³º
+ M-text Ãæ¤Ë¤ª¤¤¤Æ¤½¤Îʸ»ú¤¬ºÇ½é¤«¤é²¿ÈÖÌܤ«¤ò¼¨¤¹À°¿ô¤Ç¤¢¤ë¡£¤¿¤À¤·ºÇ½é¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤Ï0¤È¤¹¤ë¡£
- ºÂɸ ($X, $Y) ¤ËÉÁ²è¤µ¤ì¤ë¥Ù¤Ê¸»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£¤³¤³¤Çʸ»ú°ÌÃÖ
- ¤È¤Ï¡¢Åö³º M-text Ãæ¤Ë¤ª¤¤¤Æ¤½¤Îʸ»ú¤¬ºÇ½é¤«¤é²¿ÈÖÌܤ«¤ò¼¨¤¹À°¿ô¤Ç
- ¤¢¤ë¡£¤¿¤À¤·ºÇ½é¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤Ï0¤È¤¹¤ë¡£
-
- $FRAME ¤Ï¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤Î¾ðÊó¤òÆÀ¤ë¤¿¤á¤À¤±¤ËÍѤ¤¤é¤ì¤ë¡£
+ $FRAME ¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥§¡¼¥¹¤Î¾ðÊó¤òÆÀ¤ë¤¿¤á¤À¤±¤ËÍѤ¤¤é¤ì¤ë¡£
@return
ºÂɸ ($X, $Y) ¤¬¤¢¤ëʸ»ú¤Î¥°¥ê¥Õ¤Çʤ¤ï¤ì¤ë¾ì¹ç¡¢ ´Ø¿ô
- mdraw_coordinates_position () ¤Ï¤½¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£
-
- ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤ÎºÇ¾®YºÂɸ¤è¤ê¤â¾®¤µ¤¤¤Ê¤é¤Ð $FROM ¤òÊÖ¤¹¡£
-
- ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤ÎºÇÂçYºÂɸ¤è¤ê¤âÂ礤¤¤Ê¤é¤Ð $TO ¤òÊÖ¤¹¡£
-
+ mdraw_coordinates_position () ¤Ï¤½¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£\n\n
+ ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤ÎºÇ¾®YºÂɸ¤è¤ê¤â¾®¤µ¤¤¤Ê¤é¤Ð $FROM ¤òÊÖ¤¹¡£\n\n
+ ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤ÎºÇÂçYºÂɸ¤è¤ê¤âÂ礤¤¤Ê¤é¤Ð $TO ¤òÊÖ¤¹¡£\n\n
¤â¤· $Y ¤¬ÉÁ²èÎΰè¤Ë¾è¤Ã¤Æ¤¤¤Æ¤«¤Ä $X ¤¬ÉÁ²èÎΰè¤ÎºÇ¾®XºÂɸ¤è¤ê¤â
- ¾®¤µ¤¤¾ì¹ç¤Ï¡¢Ä¾Àþ y = $Y ¾å¤ËÉÁ²è¤µ¤ì¤ëºÇ½é¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£
-
+ ¾®¤µ¤¤¾ì¹ç¤Ï¡¢Ä¾Àþ y = $Y ¾å¤ËÉÁ²è¤µ¤ì¤ëºÇ½é¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£\n\n
¤â¤· $Y ¤¬ÉÁ²èÎΰè¤Ë¾è¤Ã¤Æ¤¤¤Æ¤«¤Ä $X ¤¬ÉÁ²èÎΰè¤ÎºÇÂçXºÂɸ¤è¤ê¤â
Â礤¤¾ì¹ç¤Ï¡¢Ä¾Àþ y = $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;
break;
}
}
+ if (g->type == GLYPH_ANCHOR
+ && control->two_dimensional
+ && g[-1].c == '\n')
+ g--;
from = g->pos;
M17N_OBJECT_UNREF (gstring->top);
/***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 ¤òÊÖ¤¹¡£
+
+
+ ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢$NUM_GLYPHS_RETURN ¤¬»Ø¤¹¾ì½ê¤ËɬÍפÊÇÛÎó¤Î¥µ¥¤¥º¤òÀßÄꤷ¡¢
+ -1 ¤òÊÖ¤¹¡£
+ */
+
+/***
+ @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
- window $WIN of $FRAME at coordinate ($X, $Y). $ITEMS is an array
+ window $WIN of frame $FRAME at coordinate ($X, $Y). $ITEMS is an array
of the textitems to be drawn and $NITEMS is the number of
- textimtems in the array. */
+ textitems in the array. */
/***ja
- @brief textitem ¤òɽ¼¨¤¹¤ë
+ @brief textitem ¤òɽ¼¨¤¹¤ë.
- ´Ø¿ô mdraw_text_items () ¤Ï¡¢°ì¸Ä°Ê¾å¤Î¥Æ¥¥¹¥È¥¢¥¤¥Æ¥à¤ò¡¢¥Õ¥ì¡¼
- ¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤ÎºÂɸ ($X, $Y) ¤Ëɽ¼¨¤¹¤ë¡£$ITEMS ¤Ï
- ɽ¼¨¤¹¤Ù¤¥Æ¥¥¹¥È¥¢¥¤¥Æ¥à¤ÎÇÛÎó¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ê¡¢$NITEMS ¤Ï¤½¤Î
- ¸Ä¿ô¤Ç¤¢¤ë¡£
+ ´Ø¿ô mdraw_text_items () ¤Ï¡¢°ì¸Ä°Ê¾å¤Î¥Æ¥¥¹¥È¥¢¥¤¥Æ¥à¤ò¡¢¥Õ¥ì¡¼¥à
+ $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤ÎºÂɸ ($X, $Y) ¤Ëɽ¼¨¤¹¤ë¡£$ITEMS
+ ¤Ïɽ¼¨¤¹¤Ù¤¥Æ¥¥¹¥È¥¢¥¤¥Æ¥à¤ÎÇÛÎó¤Ç¤¢¤ê¡¢$NITEMS ¤Ï¤½¤Î¸Ä¿ô¤Ç¤¢¤ë¡£
@latexonly \IPAlabel{mdraw_text_items} @endlatexonly */
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,
int from, int to, int line, int y)
{
- int c = mtext_ref_char (mt, pos);
- int orig_pos = pos;
+ int p;
- if (c == ' ' || c == '\t')
+ if (! linebreak_table)
{
- pos++;
- while (pos < to
- && ((c = mtext_ref_char (mt, pos)) == ' ' || c == '\t'))
- pos++;
+ MDatabase *mdb = mdatabase_find (Mchar_table, Msymbol,
+ msymbol ("linebreak"), Mnil);
+
+ if (mdb)
+ linebreak_table = mdatabase_load (mdb);
+ if (! linebreak_table)
+ linebreak_table = mchartable (Msymbol, Mnil);
}
- else
+
+ if (pos > from)
{
- while (pos > from)
- {
- if (c == ' ' || c == '\t')
- break;
- pos--;
- c = mtext_ref_char (mt, pos);
- }
- if (pos == from)
- pos = orig_pos;
- else
- pos++;
+ p = find_break_backward (mt, pos, from);
+ if (p > from)
+ return p;
+ }
+ if (pos < to)
+ {
+ p = find_break_forward (mt, pos, to);
+ if (p < to)
+ return p;
}
- return pos;
+ return to;
}
/*=*/
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 ¤Îʸ»ú¿ô°Ê
- ¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+ ´Ø¿ô mdraw_per_char_extents () ¤Ï¡¢M-text $MT
+ Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈϰϤò·×»»¤¹¤ë¡£¤³¤Î·×»»¤ËÍѤ¤¤ë¥Õ¥©¥ó¥È¤Ï¡¢
+ $MT ¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ç»ØÄꤵ¤ì¤¿¥Õ¥§¡¼¥¹¤È¡¢¥Õ¥ì¡¼¥à $FRAME
+ ¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤Ë¤è¤Ã¤Æ·è¤Þ¤ë¡£$ARRAY_RETURN ¤Î³ÆÍ×ÁǤϡ¢$MT
+ Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈϰϾðÊó¤Ë¤è¤Ã¤Æ½ç¤ËËä¤á¤é¤ì¤ë¡£É½¼¨ÈϰϾðÊó¤È¤Ï¡¢
+ ɽ¼¨¸¶ÅÀ¤«¤é¤ÎÁêÂаÌÃ֤ȳÆʸ»ú¤ÎÀê¤á¤ëĹÊý·Á¤Ç¤¢¤ë¡£$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 behavior 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)
{