/* draw.c -- drawing module.
- Copyright (C) 2003, 2004
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H15PRO112
You should have received a copy of the GNU Lesser General Public
License along with the m17n library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
02111-1307, USA. */
/***en
#include "mtext.h"
#include "textprop.h"
#include "internal-gui.h"
+#include "internal-flt.h"
#include "face.h"
#include "font.h"
static MSymbol M_glyph_string;
/* Special scripts */
-static MSymbol Minherited, Mcommon;
+static MSymbol Mcommon;
/* Special categories */
static MSymbol McatCc, McatCf;
static MSymbol MbidiRLO;
static MSymbol MbidiBN;
static MSymbol MbidiS;
+static MSymbol MbidiNSM;
-static void
-visual_order (MGlyphString *gstring)
+static int
+analyse_bidi_level (MGlyphString *gstring)
{
int len = gstring->used - 2;
- MGlyph *glyphs;
int bidi_sensitive = gstring->control.orientation_reversed;
+ int max_level;
MGlyph *g;
int i;
#ifdef HAVE_FRIBIDI
FriBidiCharType base = bidi_sensitive ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR;
FriBidiChar *logical = alloca (sizeof (FriBidiChar) * len);
- FriBidiChar *visual;
- FriBidiStrIndex *indices;
FriBidiLevel *levels;
+ FriBidiStrIndex *indices;
#else /* not HAVE_FRIBIDI */
int *logical = alloca (sizeof (int) * len);
- int *indices;
char *levels = alloca (len);
+
+ memset (levels, 0, sizeof (int) * len);
#endif /* not HAVE_FRIBIDI */
for (g = MGLYPH (1), i = 0; g->type != GLYPH_ANCHOR; g++, i++)
#endif /* not HAVE_FRIBIDI */
)
{
- MSymbol bidi = (MSymbol) mchar_get_prop (g->c, Mbidi_category);
+ MSymbol bidi = (MSymbol) mchar_get_prop (g->g.c, Mbidi_category);
if (bidi == MbidiR || bidi == MbidiAL
|| bidi == MbidiRLE || bidi == MbidiRLO)
levels[i] = 1;
#endif /* not HAVE_FRIBIDI */
}
+#ifndef HAVE_FRIBIDI
+ else if (bidi == MbidiNSM && i > 0 && levels[i - 1])
+ levels[i] = 1;
+#endif /* not HAVE_FRIBIDI */
}
- logical[i] = g->c;
+ logical[i] = g->g.c;
}
if (! bidi_sensitive)
- return;
+ return 0;
- glyphs = alloca (sizeof (MGlyph) * len);
- memcpy (glyphs, gstring->glyphs + 1, sizeof (MGlyph) * len);
#ifdef HAVE_FRIBIDI
- visual = alloca (sizeof (FriBidiChar) * (len + 1));
- indices = alloca (sizeof (FriBidiStrIndex) * (len + 1));
levels = alloca (sizeof (FriBidiLevel) * (len + 1));
+ indices = alloca (sizeof (FriBidiStrIndex) * (len + 1));
- fribidi_log2vis (logical, len, &base, visual, indices, NULL, levels);
-#else /* not HAVE_FRIBIDI */
- indices = alloca (sizeof (int) * len);
- for (i = 0; i < len; i++)
+ fribidi_log2vis (logical, len, &base, NULL, NULL, indices, levels);
+#endif /* not HAVE_FRIBIDI */
+
+ MGLYPH (0)->bidi_level = 0;
+ max_level = 0;
+ for (g = MGLYPH (1), i = 0; i < len; g++, i++)
{
- if (levels[i])
+ g->bidi_level = levels[i];
+ if (max_level < g->bidi_level)
+ max_level = g->bidi_level;
+ }
+ MGLYPH (i)->bidi_level = 0;
+ return max_level;
+}
+
+static void
+visual_order (MGlyphString *gstring)
+{
+ MGlyph *glyphs = alloca (sizeof (MGlyph) * gstring->used);
+ int i, j, gidx;
+
+ memcpy (glyphs, gstring->glyphs, sizeof (MGlyph) * gstring->used);
+
+ for (i = gidx = 0; i < gstring->used - 1; gidx++)
+ {
+ int level = glyphs[i].bidi_level;
+
+ gstring->glyphs[gidx] = glyphs[i];
+ glyphs[i].rface = NULL;
+
+ if (level % 2)
{
- int j, k;
+ int prev_level = glyphs[i - 1].bidi_level;
- for (j = i + 1; j < len && levels[j]; j++);
- for (k = j--; i < k; i++, j--)
- indices[i] = j;
- i--;
+ if (prev_level == level)
+ i--;
+ else if (prev_level > level)
+ {
+ for (; glyphs[i - 1].bidi_level > level; i--);
+ if (glyphs[i].bidi_level % 2)
+ for (level = glyphs[i].bidi_level;
+ glyphs[i + 1].bidi_level == level; i++);
+ }
+ else
+ for (i++; ! glyphs[i].rface; i++);
}
else
- indices[i] = i;
- }
-#endif /* not HAVE_FRIBIDI */
+ {
+ int next_level = glyphs[i + 1].bidi_level;
- for (i = 0; i < len;)
- {
- /* Index into gstring->glyphs plus 1 for GLYPHS[i]. */
- int j = indices[i];
- /* Length of grapheme-cluster */
- int seglen;
+ if (next_level == level)
+ i++;
+ else if (next_level > level)
+ {
+ for (; glyphs[i + 1].bidi_level > level; i++);
+ if ((glyphs[i].bidi_level % 2) == 0)
+ for (level = glyphs[i].bidi_level;
+ glyphs[i - 1].bidi_level == level; i--);
+ }
+ else
+ {
+ int save = i + 1;
- g = glyphs + i;
-#ifdef HAVE_FRIBIDI
- if (visual[j] != logical[i])
- {
- /* Mirrored. */
- g->c = visual[j];
- if (g->rface->rfont)
- g->code = mfont__encode_char (NULL, (MFont *) g->rface->rfont,
- NULL, g->c);
+ for (i--; glyphs[i].bidi_level >= level; i--);
+ if (! glyphs[i].rface)
+ for (i = save; ! glyphs[i].rface; i++);
+ }
}
-#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++)
+ }
+ for (i = 1; i < gstring->used - 1; i++)
+ {
+ MGlyph *g = gstring->glyphs + i;
+
+ for (j = i; g->g.from == gstring->glyphs[j + 1].g.from; j++);
+ if (j > i)
{
- g->bidi_level = levels[i];
- if (indices[i + seglen] < j)
- j = indices[i + seglen];
+ memcpy (glyphs + i, gstring->glyphs + i,
+ sizeof (MGlyph) * (j - i + 1));
+ for (; i <= j; i++)
+ g[j - i] = glyphs[i];
+ i--;
}
- memcpy (MGLYPH (j + 1), glyphs + i, sizeof (MGlyph) * seglen);
- i += seglen;
}
}
-static void
-reorder_combining_chars (MGlyphString *gstring, int from, int to)
+static MSymbol
+font_id (MFLTFont *font)
{
- MGlyph *g, *gbeg = MGLYPH (from + 1), *gend = MGLYPH (to), temp;
- int reordered = 1;
-
- while (reordered)
+ return ((MFLTFontForRealized *) font)->rfont->id;
+}
+
+static int
+run_flt (MGlyphString *gstring, int from, int to, MRealizedFace *rface)
+{
+ MRealizedFont *rfont = rface->rfont;
+ MSymbol layouter = rface->layouter;
+ MFLTGlyphString flt_gstr;
+ MFLTFontForRealized font;
+ MFLT *flt;
+ int from_pos = MGLYPH (from)->g.from;
+ int len = to - from;
+ int catcode;
+ int i;
+
+ flt = mflt_get (layouter);
+ flt_gstr.glyph_size = sizeof (MGlyph);
+ flt_gstr.glyphs = (MFLTGlyph *) (gstring->glyphs);
+ flt_gstr.used = gstring->used;
+ flt_gstr.allocated = gstring->size;
+ flt_gstr.r2l = 0;
+ font.font.family = mfont_get_prop (rfont->font, Mfamily);
+ font.font.x_ppem = rfont->x_ppem;
+ font.font.y_ppem = rfont->y_ppem;
+ font.font.get_glyph_id = mfont__get_glyph_id;
+ font.font.get_metrics = mfont__get_metrics;
+ font.font.check_otf = rfont->driver->check_otf;
+ font.font.drive_otf = rfont->driver->drive_otf;
+ font.font.internal = NULL;
+ font.rfont = rfont;
+ mflt_font_id = font_id;
+ mflt_iterate_otf_feature = rfont->driver->iterate_otf_feature;
+ mflt_try_otf = rfont->driver->try_otf;
+ for (i = 0; i < 3; i++)
{
- reordered = 0;
- for (g = gbeg; g != gend; g++)
- if (COMBINING_CODE_CLASS (g->combining_code) > 0
- && (COMBINING_CODE_CLASS (g[-1].combining_code)
- > COMBINING_CODE_CLASS (g->combining_code)))
- {
- reordered = 1;
- temp = *g;
- *g = g[-1];
- g[-1] = temp;
- }
+ to = mflt_run (&flt_gstr, from, to, &font.font, flt);
+ if (to != -2)
+ break;
+ APPEND_GLYPH (gstring, *MGLYPH (0));
+ APPEND_GLYPH (gstring, *MGLYPH (0));
+ gstring->used -= 2;
}
-}
+ if (from + len != to)
+ gstring->used += to - (from + len);
+ for (i = from, catcode = -1; i < to; i++)
+ {
+ MGlyph *g = MGLYPH (i);
+
+ g->g.from += from_pos - from;
+ g->g.to += from_pos - from + 1;
+ g->g.xadv >>= 6;
+ g->g.yadv >>= 6;
+ g->g.ascent >>= 6;
+ g->g.descent >>= 6;
+ g->g.lbearing >>= 6;
+ g->g.rbearing >>= 6;
+ g->g.xoff >>= 6;
+ g->g.yoff >>= 6;
+ g->rface = rface;
+ if (catcode < 0 || g->g.from != g[-1].g.from)
+ {
+ MSymbol category = mchar_get_prop (g->g.c, Mcategory);
+ catcode = (category == McatCf
+ ? GLYPH_CATEGORY_FORMATTER
+ : category != Mnil && MSYMBOL_NAME (category)[0] == 'M'
+ ? GLYPH_CATEGORY_MODIFIER
+ : GLYPH_CATEGORY_NORMAL);
+ }
+ g->category = catcode;
+ }
+ return to;
+}
/** Scan M-text MT from FROM to TO, and compose glyphs in GSTRING for
displaying them on FRAME.
MRealizedFace *rface = default_rface;
MRealizedFont *rfont;
int size = gstring->control.fixed_width;
+ int max_bidi_level = 0;
int i;
MLIST_RESET (gstring);
/** Put anchor glyphs at the head and tail. */
g_tmp.type = GLYPH_ANCHOR;
- g_tmp.pos = g_tmp.to = from;
+ g_tmp.g.from = g_tmp.g.to = from;
APPEND_GLYPH (gstring, g_tmp);
stop = face_change = font_change = pos = from;
while (1)
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.g.c = c;
+ g_tmp.g.from = pos++;
+ g_tmp.g.to = pos;
g_tmp.rface = rface;
category = mchar_get_prop (c, Mcategory);
if (category == McatCf)
MGlyph ctrl[2];
ctrl[0] = ctrl[1] = g_tmp;
- ctrl[0].c = '^';
- ctrl[1].c = c < ' ' ? c + 0x40 : '?';
+ ctrl[0].g.c = '^';
+ ctrl[1].g.c = c < ' ' ? c + 0x40 : '?';
APPEND_GLYPH (gstring, ctrl[0]);
APPEND_GLYPH (gstring, ctrl[1]);
}
/* Append an anchor glyph. */
INIT_GLYPH (g_tmp);
g_tmp.type = GLYPH_ANCHOR;
- g_tmp.pos = g_tmp.to = pos;
+ g_tmp.g.from = g_tmp.g.to = pos;
APPEND_GLYPH (gstring, g_tmp);
gstring->to = pos;
+ if (gstring->control.enable_bidi)
+ max_bidi_level = analyse_bidi_level (gstring);
+
/* 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;
+ int c = g->g.c;
MSymbol this_script;
if (c < 0x100)
{
this_script = (MSymbol) mchar_get_prop (c, Mscript);
if (this_script == Minherited || this_script == Mcommon)
- this_script = script;
- if (this_script == Mcommon)
+ {
+ if (g > MGLYPH (1))
+ {
+ MSymbol category = mchar_get_prop (g[-1].g.c, Mcategory);
+
+ if (category != Mnil && MSYMBOL_NAME (category)[0] != 'Z')
+ this_script = script;
+ }
+ }
+ if (this_script == Mcommon && non_latin_script)
this_script = non_latin_script;
if (this_script == Mcommon)
{
MGlyph *g1;
for (g1 = g + 1; g1->type != GLYPH_ANCHOR; g1++)
- if (g1->c >= 0x100
- && (sym = mchar_get_prop (g1->c, Mscript)) != Mcommon
+ if (g1->g.c >= 0x100
+ && (sym = mchar_get_prop (g1->g.c, Mscript)) != Mcommon
&& sym != Minherited)
{
this_script = sym;
}
}
- pos = g->pos;
+ pos = g->g.from;
if (pos == stop || script != this_script || g->rface->rfont != rfont)
{
while (last_g < g)
if (this->rface->layouter != Mnil)
{
- MGlyph *prev;
- unsigned code;
-
- for (prev = MGLYPH (start - 1);
- (prev->type == GLYPH_CHAR
- && prev->category == GLYPH_CATEGORY_FORMATTER
- && (code = mfont__encode_char (NULL,
- (MFont *) this->rface->rfont,
- NULL, prev->c)
- != MCHAR_INVALID_CODE));
- start--, prev--)
- prev->code = code;
+ MGlyph *prev = MGLYPH (start - 1);
+
+ while (prev->type == GLYPH_CHAR
+ && prev->category == GLYPH_CATEGORY_FORMATTER
+ && (mfont__encode_char (NULL, (MFont *) this->rface->rfont,
+ NULL, prev->g.c)
+ != MCHAR_INVALID_CODE))
+ {
+ prev->rface->rfont = this->rface->rfont;
+ start--, prev--;
+ }
for (g++;
(g->type == GLYPH_CHAR
+ && g->g.from != gstring->control.cursor_pos
&& g->rface->layouter == this->rface->layouter
&& (g->rface->rfont == this->rface->rfont
|| (g->category == GLYPH_CATEGORY_FORMATTER
- && ((code = mfont__encode_char (NULL,
- (MFont *) this->rface->rfont,
- NULL,
- g->c))
+ && (mfont__encode_char (NULL,
+ (MFont *) this->rface->rfont,
+ NULL, g->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);
+ g->rface->rfont = this->rface->rfont;
+ i = run_flt (gstring, start, i, this->rface);
}
else
{
- while (this->type == GLYPH_CHAR
- && this->c >= 0x100
- && this->category == GLYPH_CATEGORY_MODIFIER
- && this->rface->rfont
- && this->rface->rfont->layouter == Mnil)
+ g++;
+ while (g->type == GLYPH_CHAR
+ && g->g.c >= 0x100
+ && g->category == GLYPH_CATEGORY_MODIFIER
+ && g->rface->rfont
+ && g->rface->layouter == Mnil)
+ i++, g++;
+ if (start + 1 < i)
{
- int class = (int) mchar_get_prop (this->c,
- Mcombining_class);
- this->combining_code
- = MAKE_COMBINING_CODE_BY_CLASS (class);
- i++, this++;
+ this->rface->layouter = Mcombining;
+ run_flt (gstring, start, i, this->rface);
}
- if (start + 1 < i)
- reorder_combining_chars (gstring, start, i);
- if (this->type == GLYPH_ANCHOR)
- break;
+ else
+ mfont__get_metric (gstring, start, i);
}
g = MGLYPH (i);
}
}
/* At last, reorder glyphs visually if necessary. */
- if (gstring->control.enable_bidi)
+ if (max_bidi_level > 0)
visual_order (gstring);
}
-
-static int
-combining_code_from_class (int class)
-{
- int code;
-
- if (class < 200)
- code = MAKE_COMBINING_CODE (3, 1, 3, 1, 128, 128);
- else if (class == 200) /* below left attached */
- code = MAKE_COMBINING_CODE (2, 0, 0, 1, 128, 128);
- else if (class == 202) /* below attached*/
- code = MAKE_COMBINING_CODE (2, 1, 0, 1, 128, 128);
- else if (class == 204) /* below right attached */
- code = MAKE_COMBINING_CODE (2, 2, 0, 1, 128, 128);
- else if (class == 208) /* left attached */
- code = MAKE_COMBINING_CODE (3, 0, 3, 2, 128, 128);
- else if (class == 210) /* right attached */
- code = MAKE_COMBINING_CODE (3, 2, 3, 0, 128, 128);
- else if (class == 212) /* above left attached */
- code = MAKE_COMBINING_CODE (0, 0, 2, 1, 128, 128);
- else if (class == 214) /* above attached */
- code = MAKE_COMBINING_CODE (0, 1, 2, 1, 128, 128);
- else if (class == 216) /* above right attached */
- code = MAKE_COMBINING_CODE (0, 2, 2, 1, 128, 128);
- else if (class == 218) /* below left */
- code = MAKE_COMBINING_CODE (2, 0, 0, 1, 122, 128);
- else if (class == 220) /* below */
- code = MAKE_COMBINING_CODE (2, 1, 0, 1, 122, 128);
- else if (class == 222) /* below right */
- code = MAKE_COMBINING_CODE (2, 2, 0, 1, 122, 128);
- else if (class == 224) /* left */
- code = MAKE_COMBINING_CODE (3, 0, 3, 2, 128, 122);
- else if (class == 226) /* right */
- code = MAKE_COMBINING_CODE (3, 2, 3, 0, 128, 133);
- else if (class == 228) /* above left */
- code = MAKE_COMBINING_CODE (0, 0, 2, 1, 133, 128);
- else if (class == 230) /* above */
- code = MAKE_COMBINING_CODE (0, 1, 2, 1, 133, 128);
- else if (class == 232) /* above right */
- code = MAKE_COMBINING_CODE (0, 2, 2, 1, 133, 128);
- else if (class == 233) /* double below */
- code = MAKE_COMBINING_CODE (2, 2, 0, 2, 122, 128);
- else if (class == 234) /* double above */
- code = MAKE_COMBINING_CODE (0, 2, 2, 2, 133, 128);
- else if (class == 240) /* iota subscript */
- code = MAKE_COMBINING_CODE (2, 1, 0, 1, 122, 128);
- else /* unknown */
- code = MAKE_COMBINING_CODE (3, 1, 3, 1, 128, 128);
- return code;
-}
-
-
typedef struct {
int width, lbearing, rbearing;
} MSubTextExtents;
int g_physical_ascent, g_physical_descent;
MGlyph *g = MGLYPH (from);
MGlyph *last_g = MGLYPH (to);
- int i;
g_physical_ascent = gstring->physical_ascent;
g_physical_descent = gstring->physical_descent;
extents->width = extents->lbearing = extents->rbearing = 0;
- for (i = from; i < to;)
+ for (g = MGLYPH (from); g < last_g; g++)
{
- 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++;
- MRealizedFont *rfont = base->rface->rfont;
- int size = rfont->spec.size;
- int width, lbearing, rbearing;
-
- 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->xoff;
- base->rbearing += base->xoff;
- base->lbearing = 0;
- }
- if (base->right_padding && base->rbearing > base->width)
- {
- base->width = base->rbearing;
- }
- lbearing = (base->xoff + base->lbearing < 0
- ? base->xoff + base->lbearing : 0);
- rbearing = base->xoff + base->rbearing;
- }
- else
- {
- /* With combining glyphs. */
- int left = -base->width;
- int right = 0;
- int top = - base->ascent;
- int bottom = base->descent;
- int height = bottom - top;
- int begin = base->pos;
- int end = base->to;
- int i;
-
- width = base->width;
- lbearing = (base->lbearing < 0 ? base->lbearing : 0);
- rbearing = base->rbearing;
-
- while (g != last_g && g->combining_code)
- {
- int combining_code = g->combining_code;
-
- if (begin > g->pos)
- begin = g->pos;
- else if (end < g->to)
- end = g->to;
-
- 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->spec.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 (g->yoff - g->ascent < top)
- top = g->yoff - g->ascent;
- if (g->yoff + g->descent > bottom)
- bottom = g->yoff + g->descent;
- height = bottom - top;
-
- g->width = 0;
- g++;
- }
-
- base->ascent = - top;
- base->descent = bottom;
- base->lbearing = lbearing;
- base->rbearing = rbearing;
- if (left < - base->width)
- {
- base->xoff = - base->width - left;
- base->width += base->xoff;
- base->rbearing += base->xoff;
- base->lbearing += base->xoff;
- }
- if (right > 0)
- {
- base->width += right;
- base->rbearing += right;
- base->right_padding = 1;
- for (i = 1; base + i != g; i++)
- base[i].xoff -= right;
- }
-
- for (i = 0; base + i != g; i++)
- {
- base[i].pos = begin;
- base[i].to = end;
- }
- }
-
- g_physical_ascent = MAX (g_physical_ascent, base->ascent);
- g_physical_descent = MAX (g_physical_descent, base->descent);
- extents->lbearing = MIN (extents->lbearing, extents->width + lbearing);
- extents->rbearing = MAX (extents->rbearing, extents->width + rbearing);
- extents->width += base->width;
+ g_physical_ascent = MAX (g_physical_ascent, g->g.ascent);
+ g_physical_descent = MAX (g_physical_descent, g->g.descent);
+ extents->lbearing = MIN (extents->lbearing,
+ extents->width + g->g.lbearing);
+ extents->rbearing = MAX (extents->rbearing,
+ extents->width + g->g.rbearing);
+ extents->width += g->g.xadv;
}
gstring->physical_ascent = g_physical_ascent;
MGlyph box_glyph = g[-1];
box_glyph.type = GLYPH_BOX;
- box_glyph.width
+ box_glyph.g.xadv
= (control->fixed_width
? frame->space_width
: box->inner_hmargin + box->width + box->outer_hmargin);
- box_glyph.lbearing = 0;
- box_glyph.rbearing = box_glyph.width;
- box_glyph.xoff = 0;
+ box_glyph.g.lbearing = 0;
+ box_glyph.g.rbearing = box_glyph.g.xadv;
+ box_glyph.g.xoff = 0;
box_glyph.right_padding = 1;
- gstring->width += box_glyph.width;
- gstring->rbearing += box_glyph.width;
+ gstring->width += box_glyph.g.xadv;
+ gstring->rbearing += box_glyph.g.xadv;
INSERT_GLYPH (gstring, gidx, box_glyph);
gidx++;
g = MGLYPH (gidx);
if (box_line_height < box_height)
box_line_height = box_height;
box_glyph.type = GLYPH_BOX;
- box_glyph.width
+ box_glyph.g.xadv
= (control->fixed_width
? frame->space_width
: box->inner_hmargin + box->width + box->outer_hmargin);
- box_glyph.lbearing = 0;
- box_glyph.rbearing = box_glyph.width;
- box_glyph.xoff = 0;
+ box_glyph.g.lbearing = 0;
+ box_glyph.g.rbearing = box_glyph.g.xadv;
+ box_glyph.g.xoff = 0;
box_glyph.left_padding = 1;
- gstring->width += box_glyph.width;
- gstring->rbearing += box_glyph.width;
+ gstring->width += box_glyph.g.xadv;
+ gstring->rbearing += box_glyph.g.xadv;
INSERT_GLYPH (gstring, gidx, box_glyph);
gidx++;
g = MGLYPH (gidx);
for (g++; g->type == GLYPH_CHAR; g++)
if (! rfont != ! g->rface->rfont
|| box != g->rface->box
- || ((fromg->code == MCHAR_INVALID_CODE)
- != (g->code == MCHAR_INVALID_CODE))
+ || ((fromg->g.code == MCHAR_INVALID_CODE)
+ != (g->g.code == MCHAR_INVALID_CODE))
|| (g->category == GLYPH_CATEGORY_FORMATTER
&& ignore_formatting_char))
break;
- if (rfont && fromg->code != MCHAR_INVALID_CODE)
+ if (rfont && fromg->g.code != MCHAR_INVALID_CODE)
{
int extra_width;
int to = GLYPH_INDEX (g);
g = MGLYPH (from);
pad = *g;
pad.type = GLYPH_PAD;
- pad.xoff = 0;
- pad.lbearing = 0;
- pad.width = pad.rbearing = extra_width;
+ pad.g.xoff = 0;
+ pad.g.lbearing = 0;
+ pad.g.xadv = pad.g.rbearing = extra_width;
pad.left_padding = 1;
INSERT_GLYPH (gstring, from, pad);
to++;
face, or a default value of the current
frame, which is, however, not yet
implemented. */
- if (extra_width + 2 < g->width)
+ if (extra_width + 2 < g->g.xadv)
{
- g->width -= extra_width;
+ g->g.xadv -= extra_width;
}
else
{
- extra_width = g->width - 2;
- g->width = 2;
+ extra_width = g->g.xadv - 2;
+ g->g.xadv = 2;
}
gstring->width -= extra_width;
gstring->rbearing -= extra_width;
{
pad = g[-1];
pad.type = GLYPH_PAD;
- pad.xoff = 0;
- pad.lbearing = 0;
- pad.width = pad.rbearing = extra_width;
+ pad.g.xoff = 0;
+ pad.g.lbearing = 0;
+ pad.g.xadv = pad.g.rbearing = extra_width;
INSERT_GLYPH (gstring, to, pad);
to++;
g = MGLYPH (to);
}
else
- g[-1].width += extra_width;
+ g[-1].g.xadv += extra_width;
extents.width += extra_width;
}
{
for (; fromg < g; fromg++)
{
- if ((fromg->c >= 0x200B && fromg->c <= 0x200F)
- || (fromg->c >= 0x202A && fromg->c <= 0x202E))
- fromg->width = fromg->rbearing = 1;
+ if ((fromg->g.c >= 0x200B && fromg->g.c <= 0x200F)
+ || (fromg->g.c >= 0x202A && fromg->g.c <= 0x202E))
+ fromg->g.xadv = fromg->g.rbearing = 1;
else
- fromg->width = fromg->rbearing = rface->space_width;
- fromg->xoff = fromg->lbearing = 0;
- fromg->ascent = fromg->descent = 0;
- gstring->width += fromg->width;
- gstring->rbearing += fromg->width;
+ fromg->g.xadv = fromg->g.rbearing = rface->space_width;
+ fromg->g.xoff = fromg->g.lbearing = 0;
+ fromg->g.ascent = fromg->g.descent = 0;
+ gstring->width += fromg->g.xadv;
+ gstring->rbearing += fromg->g.xadv;
}
if (gstring->ascent < frame->rface->ascent)
gstring->ascent = frame->rface->ascent;
}
else if (g->type == GLYPH_SPACE)
{
- if (g->c == ' ')
- g->width = g->rface->space_width;
- else if (g->c == '\n')
+ if (g->g.c == ' ')
+ g->g.xadv = g->rface->space_width;
+ else if (g->g.c == '\n')
{
- g->width = control->cursor_width;
- if (g->width)
+ g->g.xadv = control->cursor_width;
+ if (g->g.xadv)
{
if (control->cursor_bidi)
- g->width = 3;
- else if (g->width < 0)
- g->width = g->rface->space_width;
+ g->g.xadv = 3;
+ else if (g->g.xadv < 0)
+ g->g.xadv = g->rface->space_width;
}
}
- else if (g->c == '\t')
+ else if (g->g.c == '\t')
{
- g->width = tab_width - ((gstring->indent + gstring->width)
- % tab_width);
+ g->g.xadv = tab_width - ((gstring->indent + gstring->width)
+ % tab_width);
tab_found = 1;
}
else
- g->width = 1;
+ g->g.xadv = 1;
if (g[-1].type == GLYPH_PAD)
{
/* This space glyph absorbs (maybe partially) the
previous padding glyph. */
- g->width -= g[-1].width;
- if (g->width < 1)
+ g->g.xadv -= g[-1].g.xadv;
+ if (g->g.xadv < 1)
/* But, keep at least some space width. For the
moment, we use the arbitrary width 2-pixel. */
- g->width = 2;
+ g->g.xadv = 2;
}
- g->rbearing = g->width;
- gstring->width += g->width;
- gstring->rbearing += g->width;
+ g->g.rbearing = g->g.xadv;
+ gstring->width += g->g.xadv;
+ gstring->rbearing += g->g.xadv;
if (g->rface->rfont)
{
if (gstring->ascent < g->rface->ascent)
}
else
{
- gstring->width += g->width;
- gstring->rbearing += g->width;
+ gstring->width += g->g.xadv;
+ gstring->rbearing += g->g.xadv;
g++;
}
}
MGlyph box_glyph = g[-1];
box_glyph.type = GLYPH_BOX;
- box_glyph.width
+ box_glyph.g.xadv
= (control->fixed_width
? frame->space_width
: box->inner_hmargin + box->width + box->outer_hmargin);
- box_glyph.lbearing = 0;
- box_glyph.rbearing = box_glyph.width;
- box_glyph.xoff = 0;
+ box_glyph.g.lbearing = 0;
+ box_glyph.g.rbearing = box_glyph.g.xadv;
+ box_glyph.g.xoff = 0;
box_glyph.right_padding = 1;
- gstring->width += box_glyph.width;
- gstring->rbearing += box_glyph.width;
+ gstring->width += box_glyph.g.xadv;
+ gstring->rbearing += box_glyph.g.xadv;
INSERT_GLYPH (gstring, gidx, box_glyph);
}
for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--)
{
- if (g->type == GLYPH_CHAR && g->c == '\t')
+ if (g->type == GLYPH_CHAR && g->g.c == '\t')
{
int this_width = tab_width - (width % tab_width);
if (g[1].type == GLYPH_PAD)
- this_width -= g[1].width;
+ this_width -= g[1].g.xadv;
if (g[-1].type == GLYPH_PAD)
- this_width -= g[-1].width;
+ this_width -= g[-1].g.xadv;
if (this_width < 2)
this_width = 2;
- gstring->width += this_width - g->width;
- gstring->rbearing += this_width - g->width;
- g->width = this_width;
+ gstring->width += this_width - g->g.xadv;
+ gstring->rbearing += this_width - g->g.xadv;
+ g->g.xadv = this_width;
width += this_width;
}
else
- width += g->width;
+ width += g->g.xadv;
}
}
}
}
*from_idx = *to_idx = 0;
+ *to_x = x;
while (g->type != GLYPH_ANCHOR)
{
- if (g->pos >= from && g->pos < to)
+ if (g->g.from >= from && g->g.from < to)
{
MGlyph *fromg = g, *cursor = NULL;
MRealizedFace *rface = g->rface;
if (! *from_idx)
*from_idx = GLYPH_INDEX (g);
- while (g->pos >= from && g->pos < to
+ while (g->g.from >= from && g->g.from < to
&& g->rface == rface)
{
g->enabled = 1;
if (g->type != GLYPH_BOX
- && g->pos <= cursor_pos && g->to > cursor_pos)
+ && g->g.from <= cursor_pos && g->g.to > cursor_pos)
{
if (! cursor)
cursor = g, cursor_x = x + width;
- cursor_width += g->width;
+ cursor_width += g->g.xadv;
}
- width += g++->width;
+ width += g++->g.xadv;
}
if (width > 0
&& (control->as_image
int this_x = x, this_width = width;
if (fromg->type == GLYPH_BOX)
- this_x += fromg->width, this_width -= fromg->width;
+ this_x += fromg->g.xadv, this_width -= fromg->g.xadv;
if (g[-1].type == GLYPH_BOX)
- this_width -= g[-1].width;
+ this_width -= g[-1].g.xadv;
(frame->driver->fill_space)
(frame, win, rface, 0,
this_x, y - gstring->text_ascent, this_width,
while (fromg < g)
{
if (fromg->type != GLYPH_BOX
- && fromg->pos <= prev_pos && fromg->to > prev_pos)
+ && fromg->g.from <= prev_pos && fromg->g.to > prev_pos)
{
if (! cursor)
cursor = fromg, cursor_x = x + temp_width;
- cursor_width += fromg->width;
+ cursor_width += fromg->g.xadv;
}
- temp_width += fromg++->width;
+ temp_width += fromg++->g.xadv;
}
if (cursor)
{
(*frame->driver->region_to_rect) (region, &rect);
if (rect.x > x)
{
- while (g != gend && x + g->rbearing <= rect.x)
+ while (g != gend && x + g->g.rbearing <= rect.x)
{
- x += g->width;
- width -= g++->width;
+ x += g->g.xadv;
+ width -= g++->g.xadv;
while (! g->enabled && g != gend)
g++;
}
if (rect.x < x + width)
{
while (g != gend
- && (x + width - gend[-1].width + gend[-1].lbearing >= rect.x))
+ && (x + width - gend[-1].g.xadv + gend[-1].g.lbearing >= rect.x))
{
- width -= (--gend)->width;
+ width -= (--gend)->g.xadv;
while (! gend->enabled && g != gend)
gend--;
}
if (g != gend)
- while (gend->type != GLYPH_ANCHOR && gend[-1].to == gend->to)
+ while (gend->type != GLYPH_ANCHOR && gend[-1].g.to == gend->g.to)
gend++;
}
}
if (g->enabled)
{
MRealizedFace *rface = g->rface;
- int width = g->width;
+ int width = g->g.xadv;
MGlyph *from_g = g++;
/* Handle the glyphs of the same type/face at once. */
while (g != gend
&& g->type == from_g->type
&& g->rface == rface
- && ((g->code == MCHAR_INVALID_CODE)
- == (from_g->code == MCHAR_INVALID_CODE))
+ && ((g->g.code == MCHAR_INVALID_CODE)
+ == (from_g->g.code == MCHAR_INVALID_CODE))
&& g->enabled)
- width += g++->width;
+ width += g++->g.xadv;
if (from_g->type == GLYPH_CHAR)
{
- if (rface->rfont && from_g->code != MCHAR_INVALID_CODE)
+ if (rface->rfont && from_g->g.code != MCHAR_INVALID_CODE)
(rface->rfont->driver->render) (win, x, y, gstring, from_g, g,
reverse, region);
else
for (g = MGLYPH (*left) - 1, x = 0; g->type != GLYPH_ANCHOR; g--)
{
- x -= g->width;
- if (x + g->rbearing > 0)
+ x -= g->g.xadv;
+ if (x + g->g.rbearing > 0)
{
- while (g[-1].pos == g->pos && g[-1].type != GLYPH_ANCHOR)
- x -= (--g)->width;
+ while (g[-1].g.from == g->g.from && g[-1].type != GLYPH_ANCHOR)
+ x -= (--g)->g.xadv;
left_idx = GLYPH_INDEX (g);
left_x = x;
}
for (g = MGLYPH (*right), x = 0; g->type != GLYPH_ANCHOR; g++)
{
- x += g->width;
- if (x - g->width + g->lbearing < 0)
+ x += g->g.xadv;
+ if (x - g->g.xadv + g->g.lbearing < 0)
{
- while (g->pos == g[1].pos && g[1].type != GLYPH_ANCHOR)
- x += (++g)->width;
+ while (g->g.from == g[1].g.from && g[1].type != GLYPH_ANCHOR)
+ x += (++g)->g.xadv;
right_idx = GLYPH_INDEX (g) + 1;
right_x = x;
}
static int
-gstring_width (MGlyphString *gstring, int from, int to, int *rbearing)
+gstring_width (MGlyphString *gstring, int from, int to,
+ int *lbearing, int *rbearing)
{
MGlyph *g;
int width;
if (from <= gstring->from && to >= gstring->to)
{
+ if (lbearing)
+ *lbearing = gstring->lbearing;
if (rbearing)
*rbearing = gstring->rbearing;
return gstring->width;
}
+ if (lbearing)
+ *lbearing = 0;
if (rbearing)
*rbearing = 0;
for (g = MGLYPH (1), width = 0; g->type != GLYPH_ANCHOR; g++)
- if (g->pos >= from && g->pos < to)
+ if (g->g.from >= from && g->g.from < to)
{
- if (rbearing && width + g->rbearing > *rbearing)
- *rbearing = width + g->rbearing;
- width += g->width;
+ if (lbearing && width + g->g.lbearing < *lbearing)
+ *lbearing = width + g->g.lbearing;
+ if (rbearing && width + g->g.rbearing > *rbearing)
+ *rbearing = width + g->g.rbearing;
+ width += g->g.xadv;
}
return width;
}
int from_idx, to_idx;
int to_x;
+ if (from == to)
+ return;
if (control->orientation_reversed)
- x -= gstring->indent + gstring_width (gstring, from, to, NULL);
+ x -= gstring->indent + gstring_width (gstring, from, to, NULL, NULL);
else
x += gstring->indent;
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->glyphs[1].g.c = '\n';
+ gstring->glyphs[1].g.code = '\n';
}
gstring->from = pos;
g = MGLYPH (0);
g->rface = frame->rface;
- g->pos = g->to = pos;
+ g->g.from = g->g.to = pos;
g++;
g->rface = frame->rface;
- g->pos = pos++, g->to = pos;
+ g->g.from = pos++, g->g.to = pos;
g++;
g->rface = frame->rface;
- g->pos = g->to = pos;
+ g->g.from = g->g.to = pos;
gstring->to = pos;
}
else
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_width[g->pos - gstring->from] += g->width;
+ pos_width[g->g.from - gstring->from] += g->g.xadv;
for (i = 0, width = 0; i < gstring->to - gstring->from; i++)
{
if (pos_width[i] > 0)
if (pos <= gstring->from)
{
g = find_glyph_in_gstring (gstring, gstring->from, 1);
- pos = g->to;
+ pos = g->g.to;
}
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);
+ {
+ g = find_glyph_in_gstring (gstring, gstring->from, 1);
+ pos = g->g.to;
+ }
+ if (pos < gstring->to)
+ {
+ compose_glyph_string (frame, mt, gstring->from, pos, gstring);
+ layout_glyph_string (frame, gstring);
+ }
}
|| memcmp (control, &gstring->control,
(char *) (&control->with_cursor)
- (char *) (control))
+ || control->cursor_pos != gstring->control.cursor_pos
|| control->cursor_width != gstring->control.cursor_width
|| control->cursor_bidi != gstring->control.cursor_bidi)
{
gst->to += offset;
for (i = 0; i < gst->used; i++)
{
- gst->glyphs[i].pos += offset;
- gst->glyphs[i].to += offset;
+ gst->glyphs[i].g.from += offset;
+ gst->glyphs[i].g.to += offset;
}
}
M17N_OBJECT_REF (gstring);
if (forwardp)
{
for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++)
- if (g->pos <= pos && g->to > pos)
+ if (g->g.from <= pos && g->g.to > pos)
break;
}
else
{
for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--)
- if (g->pos <= pos && g->to > pos)
+ if (g->g.from <= pos && g->g.to > pos)
break;
}
return g;
/* for debugging... */
char work[16];
-char *
-dump_combining_code (int code)
-{
- char *vallign = "tcbB";
- char *hallign = "lcr";
- char *p;
- int off_x, off_y;
-
- if (! code)
- return "none";
- if (COMBINING_BY_CLASS_P (code))
- code = combining_code_from_class (COMBINING_CODE_CLASS (code));
- work[0] = vallign[COMBINING_CODE_BASE_Y (code)];
- work[1] = hallign[COMBINING_CODE_BASE_X (code)];
- off_y = COMBINING_CODE_OFF_Y (code) - 128;
- off_x = COMBINING_CODE_OFF_X (code) - 128;
- if (off_y > 0)
- sprintf (work + 2, "+%d", off_y);
- else if (off_y < 0)
- sprintf (work + 2, "%d", off_y);
- else if (off_x == 0)
- sprintf (work + 2, ".");
- p = work + strlen (work);
- if (off_x > 0)
- sprintf (p, ">%d", off_x);
- else if (off_x < 0)
- sprintf (p, "<%d", -off_x);
- p += strlen (p);
- p[0] = vallign[COMBINING_CODE_ADD_Y (code)];
- p[1] = hallign[COMBINING_CODE_ADD_X (code)];
- p[2] = '\0';
- return work;
-}
-
void
-dump_gstring (MGlyphString *gstring, int indent)
+dump_gstring (MGlyphString *gstring, int indent, int type)
{
char *prefix = (char *) alloca (indent + 1);
- MGlyph *g, *last_g = gstring->glyphs + gstring->used;
+ MGlyph *g, *first_g, *last_g;
memset (prefix, 32, indent);
prefix[indent] = 0;
fprintf (stderr, "(glyph-string");
- for (g = MGLYPH (0); g < last_g; g++)
- fprintf (stderr,
- "\n%s (%02d %s pos:%d-%d c:%04X code:%04X face:%x cmb:%s w:%02d bidi:%d)",
- prefix,
- g - gstring->glyphs,
- (g->type == GLYPH_SPACE ? "SPC": g->type == GLYPH_PAD ? "PAD"
- : g->type == GLYPH_ANCHOR ? "ANC"
- : g->type == GLYPH_BOX ? "BOX" : "CHR"),
- g->pos, g->to, g->c, g->code, (unsigned) g->rface,
- dump_combining_code (g->combining_code),
- g->width, g->bidi_level);
+ if (type == 0)
+ {
+ first_g = MGLYPH (0);
+ last_g = first_g + gstring->used;
+ }
+ else
+ {
+ first_g = (MGlyph *) ((MFLTGlyphString *) gstring)->glyphs;
+ last_g = first_g + ((MFLTGlyphString *) gstring)->used;
+ }
+
+ for (g = first_g; g < last_g; g++)
+ {
+ fprintf (stderr,
+ "\n%s (%02d %s pos:%d-%d c:%04X code:%04X face:%x w:%02d bidi:%d",
+ prefix,
+ g - first_g,
+ (g->type == GLYPH_SPACE ? "SPC": g->type == GLYPH_PAD ? "PAD"
+ : g->type == GLYPH_ANCHOR ? "ANC"
+ : g->type == GLYPH_BOX ? "BOX" : "CHR"),
+ g->g.from, g->g.to, g->g.c, g->g.code, (unsigned) g->rface,
+ g->g.xadv, g->bidi_level);
+ if (g->g.xoff || g->g.yoff)
+ fprintf (stderr, " off:%d,%d", g->g.xoff, g->g.yoff);
+ fprintf (stderr, ")");
+ }
fprintf (stderr, ")");
}
\f
memset (&scratch_gstring, 0, sizeof (scratch_gstring));
MLIST_INIT1 (&scratch_gstring, glyphs, 3);
- Minherited = msymbol ("inherited");
Mcommon = msymbol ("common");
McatCc = msymbol ("Cc");
MbidiRLO = msymbol ("RLO");
MbidiBN = msymbol ("BN");
MbidiS = msymbol ("S");
+ MbidiNSM = msymbol ("NSM");
#ifdef HAVE_FRIBIDI
+#if FRIBIDI_INTERFACE_VERSION < 3
fribidi_set_mirroring (TRUE);
+#else
+ fribidi_set_mirroring (1);
+#endif
#endif
M_break_at_space = msymbol ("bs");
M_kinsoku_bol = msymbol ("kb");
M_kinsoku_eol = msymbol ("ke");
+ mflt_enable_new_feature = 1;
+
return 0;
}
@return
½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_image_text () ¤Ï 0
- ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #m_errro ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
+ ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
@latexonly \IPAlabel{mdraw_image_text} @endlatexonly */
this function also follows what specified in the drawing control
object $CONTROL.
- For instance, if <two_dimensional> of $CONTROL is nonzero, this
+ For instance, if \<two_dimensional\> of $CONTROL is nonzero, this
function draw an M-text 2-dimensionally, i.e., newlines in M-text
breaks lines and the following characters are drawn in the next
line. See the documentation of the structure @ MDrawControl for
¥Æ¥¥¹¥È¤ÎÉÁ²èÊýË¡¤Ï mdraw_text () ¤È¤Û¤ÜƱ¤¸¤Ç¤¢¤ë¤¬¡¢¤³¤Î´Ø¿ô¤ÏÉÁ²èÀ©¸æÍѤΥª¥Ö¥¸¥§¥¯¥È
$CONTROL ¤Î»Ø¼¨¤Ë¤â½¾¤¦ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£
- ¤¿¤È¤¨¤Ð $CONTROL ¤Î <two_dimensional> ¤¬¥¼¥í¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï
+ ¤¿¤È¤¨¤Ð $CONTROL ¤Î \<two_dimensional\> ¤¬¥¼¥í¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï
M-text ¤ò2¼¡¸µÅª¤ËÉÁ¤¯¡£¤¹¤Ê¤ï¤Á M-text Ãæ¤Î²þ¹Ô¤Ç¹Ô¤ò²þ¤á¡¢Â³¤¯Ê¸»ú¤Ï¼¡¤Î¹Ô¤ËÉÁ¤¯¡£¾ÜºÙ¤Ï¹½Â¤ÂÎ
@ MDrawControl ¤ÎÀâÌÀ¤ò»²¾È¤¹¤ë¤³¤È¡£*/
{
MGlyphString *gstring;
int y = 0;
- int width, rbearing;
+ int width, lbearing, rbearing;
ASSURE_CONTROL (control);
M_CHECK_POS_X (mt, from, -1);
gstring = get_gstring (frame, mt, from, to, control);
if (! gstring)
MERROR (MERROR_DRAW, -1);
- width = gstring_width (gstring, from, to, &rbearing);
+ width = gstring_width (gstring, from, to, &lbearing, &rbearing);
if (overall_ink_return)
- {
- overall_ink_return->y = - gstring->physical_ascent;
- overall_ink_return->x = gstring->lbearing;
- }
+ overall_ink_return->y = - gstring->physical_ascent;
if (overall_logical_return)
- {
- overall_logical_return->y = - gstring->ascent;
- overall_logical_return->x = 0;
- }
+ overall_logical_return->y = - gstring->ascent;
if (overall_line_return)
- {
- overall_line_return->y = - gstring->line_ascent;
- overall_line_return->x = gstring->lbearing;
- }
+ overall_line_return->y = - gstring->line_ascent;
for (from = gstring->to; from < to; from = gstring->to)
{
- int this_width, this_rbearing;
+ int this_width, this_lbearing, this_rbearing;
y += gstring->line_descent;
M17N_OBJECT_UNREF (gstring->top);
gstring = get_gstring (frame, mt, from, to, control);
- this_width = gstring_width (gstring, from, to, &this_rbearing);
+ this_width = gstring_width (gstring, from, to,
+ &this_lbearing, &this_rbearing);
y += gstring->line_ascent;
if (width < this_width)
width = this_width;
if (rbearing < this_rbearing)
rbearing = this_rbearing;
+ if (lbearing > this_lbearing)
+ lbearing = this_lbearing;
}
if (overall_ink_return)
{
- overall_ink_return->width = rbearing;
+ overall_ink_return->x = lbearing;
+ overall_ink_return->width = rbearing - lbearing;
overall_ink_return->height
= y + gstring->physical_descent - overall_ink_return->y;
}
if (overall_logical_return)
{
+ overall_logical_return->x = 0;
overall_logical_return->width = width;
overall_logical_return->height
= y + gstring->descent - overall_logical_return->y;
}
if (overall_line_return)
{
- overall_line_return->width = MAX (width, rbearing);
+ overall_line_return->x = lbearing;
+ overall_line_return->width = MAX (width, rbearing - lbearing);
overall_line_return->height
= y + gstring->line_descent - overall_line_return->y;
}
}
for (g = MGLYPH (1), x = 0; g->type != GLYPH_ANCHOR; g++)
- if (g->pos >= from && g->pos < to)
+ if (g->g.from >= from && g->g.from < to)
{
- int start = g->pos;
- int end = g->to;
- int width = g->width;
- int lbearing = g->lbearing;
- int rbearing = g->rbearing;
- int ascent = g->ascent;
- int descent = g->descent;
+ int start = g->g.from;
+ int end = g->g.to;
+ int width = g->g.xadv;
+ int lbearing = g->g.lbearing;
+ int rbearing = g->g.rbearing;
+ int ascent = g->g.ascent;
+ int descent = g->g.descent;
int logical_ascent;
int logical_descent;
logical_ascent = g->rface->ascent;
logical_descent = g->rface->descent;
}
- for (g++; g->type != GLYPH_ANCHOR && g->pos == start; g++)
+ for (g++; g->type != GLYPH_ANCHOR && g->g.from == start; g++)
{
- if (lbearing < width + g->lbearing)
- lbearing = width + g->lbearing;
- if (rbearing < width + g->rbearing)
- rbearing = width + g->rbearing;
- width += g->width;
- if (ascent < g->ascent)
- ascent = g->ascent;
- if (descent < g->descent)
- descent = g->descent;
+ if (lbearing < width + g->g.lbearing)
+ lbearing = width + g->g.lbearing;
+ if (rbearing < width + g->g.rbearing)
+ rbearing = width + g->g.rbearing;
+ width += g->g.xadv;
+ if (ascent < g->g.ascent)
+ ascent = g->g.ascent;
+ if (descent < g->g.descent)
+ descent = g->g.descent;
}
if (end > to)
{
width = gstring->indent;
for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++)
- if (g->pos >= from && g->pos < to)
+ if (g->g.from >= from && g->g.from < to)
{
- width += g->width;
+ width += g->g.xadv;
if (width > x_offset)
break;
}
{
width = - gstring->indent;
for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--)
- if (g->pos >= from && g->pos < to)
+ if (g->g.from >= from && g->g.from < to)
{
- width -= g->width;
+ width -= g->g.xadv;
if (width < x_offset)
break;
}
}
if (g->type == GLYPH_ANCHOR
&& control->two_dimensional
- && g[-1].c == '\n')
+ && g[-1].g.c == '\n')
g--;
- from = g->pos;
+ from = g->g.from;
M17N_OBJECT_UNREF (gstring->top);
return from;
if (! control->orientation_reversed)
{
info->x = gstring->indent;
- for (g = MGLYPH (1); g->pos > pos || g->to <= pos; g++)
- info->x += g->width;
+ for (g = MGLYPH (1); g->g.from > pos || g->g.to <= pos; g++)
+ info->x += g->g.xadv;
}
else
{
info->x = - gstring->indent;
- for (g = MGLYPH (gstring->used - 2); g->pos > pos || g->to <= pos; g--)
- info->x -= g->width;
- while (g[-1].to == g->to)
+ for (g = MGLYPH (gstring->used - 2); g->g.from > pos || g->g.to <= pos; g--)
+ info->x -= g->g.xadv;
+ while (g[-1].g.to == g->g.to)
g--;
}
- info->from = g->pos;
- info->to = g->to;
- info->metrics.x = g->lbearing;
+ info->from = g->g.from;
+ info->to = g->g.to;
+ info->metrics.x = g->g.lbearing;
info->metrics.y = - gstring->line_ascent;
info->metrics.height = gstring->height;
- info->metrics.width = - g->lbearing + g->width;
+ info->metrics.width = - g->g.lbearing + g->g.xadv;
if (g->rface->rfont)
info->font = (MFont *) g->rface->rfont;
else
/* The logically previous glyph is on this line. */
MGlyph *g_tmp = find_glyph_in_gstring (gstring, info->from - 1, 1);
- info->prev_from = g_tmp->pos;
+ info->prev_from = g_tmp->g.from;
}
else if (info->line_from > 0
&& gstring->from > 0)
gstring->from, control);
MGlyph *g_tmp = find_glyph_in_gstring (gst, info->from - 1, 1);
- info->prev_from = g_tmp->pos;
+ info->prev_from = g_tmp->g.from;
M17N_OBJECT_UNREF (gst->top);
}
else
info->prev_from = -1;
if (GLYPH_INDEX (g) > 1)
- info->left_from = g[-1].pos, info->left_to = g[-1].to;
+ info->left_from = g[-1].g.from, info->left_to = g[-1].g.to;
else if (! control->orientation_reversed)
{
if (info->line_from > 0)
gst = get_gstring (frame, mt, p, gstring->from, control);
g_tmp = gst->glyphs + (gst->used - 2);
- info->left_from = g_tmp->pos, info->left_to = g_tmp->to;
+ info->left_from = g_tmp->g.from, info->left_to = g_tmp->g.to;
M17N_OBJECT_UNREF (gst->top);
}
else
gst = get_gstring (frame, mt, p, p + 1, control);
g_tmp = gst->glyphs + (gst->used - 2);
- info->left_from = g_tmp->pos, info->left_to = g_tmp->to;
+ info->left_from = g_tmp->g.from, info->left_to = g_tmp->g.to;
M17N_OBJECT_UNREF (gst->top);
}
else
/* The logically next glyph is on this line. */
MGlyph *g_tmp = find_glyph_in_gstring (gstring, info->to, 0);
- info->next_to = g_tmp->to;
+ info->next_to = g_tmp->g.to;
}
else if (info->to + (control->cursor_width == 0) <= mtext_nchars (mt))
{
MGlyphString *gst = get_gstring (frame, mt, p, p + 1, control);
MGlyph *g_tmp = find_glyph_in_gstring (gst, p, 0);
- info->next_to = g_tmp->to;
+ info->next_to = g_tmp->g.to;
M17N_OBJECT_UNREF (gst->top);
}
else
info->next_to = -1;
- for (info->logical_width = (g++)->width;
- g->pos == pos && g->type != GLYPH_ANCHOR;
- info->metrics.width += g->width, info->logical_width += (g++)->width);
- info->metrics.width += g[-1].rbearing - g[-1].width;
+ for (info->logical_width = (g++)->g.xadv;
+ g->g.from == pos && g->type != GLYPH_ANCHOR;
+ info->metrics.width += g->g.xadv, info->logical_width += (g++)->g.xadv);
+ info->metrics.width += g[-1].g.rbearing - g[-1].g.xadv;
if (g->type != GLYPH_ANCHOR)
- info->right_from = g->pos, info->right_to = g->to;
+ info->right_from = g->g.from, info->right_to = g->g.to;
else if (! control->orientation_reversed)
{
if (gstring->to + (control->cursor_width == 0) <= mtext_nchars (mt))
M17N_OBJECT_UNREF (gstring->top);
gstring = get_gstring (frame, mt, pos, pos + 1, control);
g = MGLYPH (1);
- info->right_from = g->pos, info->right_to = g->to;
+ info->right_from = g->g.from, info->right_to = g->g.to;
}
else
info->right_from = info->right_to = -1;
M17N_OBJECT_UNREF (gstring->top);
gstring = get_gstring (frame, mt, pos, pos + 1, control);
g = MGLYPH (1);
- info->right_from = g->pos, info->right_to = g->to;
+ info->right_from = g->g.from, info->right_to = g->g.to;
}
else
info->right_from = info->right_to = -1;
for (g = MGLYPH (1), n = 0; g->type != GLYPH_ANCHOR; g++)
{
if (g->type == GLYPH_BOX
- || g->pos < from || g->pos >= to)
+ || g->g.from < from || g->g.from >= to)
continue;
if (g->type == GLYPH_PAD)
{
if (g->left_padding)
- pad_width = g->width;
+ pad_width = g->g.xadv;
else if (n > 0)
{
pad_width = 0;
- glyphs[-1].x_advance += g->width;
+ glyphs[-1].x_advance += g->g.xadv;
}
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->from = g->g.from;
+ glyphs->to = g->g.to;
+ glyphs->glyph_code = g->g.code;
+ glyphs->x_off = g->g.xoff + pad_width;
+ glyphs->y_off = g->g.yoff;
+ glyphs->lbearing = g->g.lbearing;
+ glyphs->rbearing = g->g.rbearing;
+ glyphs->ascent = g->g.ascent;
+ glyphs->descent = g->g.descent;
+ glyphs->x_advance = g->g.xadv + pad_width;
glyphs->y_advance = 0;
if (g->rface->rfont)
{
glyphs->font = (MFont *) g->rface->rfont;
+#ifdef HAVE_FREETYPE
glyphs->font_type
= (glyphs->font->source == MFONT_SOURCE_X ? Mx
: g->rface->rfont->driver == &mfont__ft_driver ? Mfreetype
: Mxft);
+#else /* not HAVE_FREETYPE */
+ glyphs->font_type = Mx;
+#endif /* not HAVE_FREETYPE */
glyphs->fontp = g->rface->rfont->fontp;
}
else
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
+ @return
+ This function returns a character position to break the
line.
*/