X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fface.c;h=983228c13a07ca71fe264902f677502e3d08bfdc;hb=d68a1ef5c7dc1dd24430bfb11dac9a9035c11428;hp=d3e793740c6f00a3945b82afa6c1514b77e73a75;hpb=41163570c82fe4f3fcf377ad493d5a2c07473214;p=m17n%2Fm17n-lib.git diff --git a/src/face.c b/src/face.c index d3e7937..983228c 100644 --- a/src/face.c +++ b/src/face.c @@ -17,7 +17,7 @@ You should have received a copy of the GNU Lesser General Public License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 02111-1307, USA. */ /***en @@ -243,7 +243,7 @@ serialize_face (void *val) MSymbol *key; MSymbol *type; MPlist *(*func) (MPlist *plist, void *val); - } serializer[MFACE_PROPERTY_MAX] + } serializer[MFACE_RATIO + 1] = { { &Mfoundry, &Msymbol }, { &Mfamily, &Msymbol }, { &Mweight, &Msymbol }, @@ -257,11 +257,9 @@ serialize_face (void *val) { &Mhline, NULL }, { &Mbox, NULL }, { &Mvideomode, &Msymbol }, - { NULL, NULL}, /* MFACE_HOOK_FUNC */ - { NULL, NULL}, /* MFACE_HOOK_ARG */ { &Mratio, &Minteger } }; - for (i = 0; i < MFACE_PROPERTY_MAX; i++) + for (i = 0; i <= MFACE_RATIO; i++) if (face->property[i] && serializer[i].key) { pl = mplist_add (pl, Msymbol, *serializer[i].key); @@ -363,7 +361,7 @@ deserialize_face (MPlist *plist) plist = MPLIST_NEXT (plist); if (MPLIST_TAIL_P (plist)) break; - if (index < 0 || index >= MFACE_PROPERTY_MAX) + if (index < 0 || index > MFACE_RATIO) continue; if (key == Mfoundry || key == Mfamily || key == Mweight || key == Mstyle || key == Mstretch || key == Madstyle @@ -419,8 +417,10 @@ mface__init () M17N_OBJECT_ADD_ARRAY (face_table, "Face"); Mface = msymbol_as_managing_key ("face"); - msymbol_put (Mface, Mtext_prop_serializer, (void *) serialize_face); - msymbol_put (Mface, Mtext_prop_deserializer, (void *) deserialize_face); + msymbol_put_func (Mface, Mtext_prop_serializer, + M17N_FUNC (serialize_face)); + msymbol_put_func (Mface, Mtext_prop_deserializer, + M17N_FUNC (deserialize_face)); Mforeground = msymbol ("foreground"); Mbackground = msymbol ("background"); @@ -442,7 +442,7 @@ mface__init () MSymbol *key; /* Index (enum face_property) of the face property. */ int index; - } mface_prop_data[MFACE_PROPERTY_MAX] = + } mface_prop_data[MFACE_HOOK_ARG + 1] = { { &Mfoundry, MFACE_FOUNDRY }, { &Mfamily, MFACE_FAMILY }, { &Mweight, MFACE_WEIGHT }, @@ -456,10 +456,8 @@ mface__init () { &Mhline, MFACE_HLINE }, { &Mbox, MFACE_BOX }, { &Mvideomode, MFACE_VIDEOMODE }, - { &Mhook_func, MFACE_HOOK_FUNC }, - { &Mhook_arg, MFACE_HOOK_ARG }, { &Mratio, MFACE_RATIO }, - }; + { &Mhook_arg, MFACE_HOOK_ARG } }; for (i = 0; i < MFACE_PROPERTY_MAX; i++) /* We add one to distinguish it from no-property. */ @@ -488,7 +486,7 @@ mface__init () mface__default->property[MFACE_HLINE] = hline; mface__default->property[MFACE_BOX] = box; mface__default->property[MFACE_VIDEOMODE] = Mnormal; - mface__default->property[MFACE_HOOK_FUNC] = (void *) noop_hook; + mface__default->hook = noop_hook; mface_normal_video = mface (); mface_normal_video->property[MFACE_VIDEOMODE] = (void *) Mnormal; @@ -634,9 +632,12 @@ mface__realize (MFrame *frame, MFace **faces, int num, int size, MFont *font) merged_face.property[i] = FONT_PROPERTY (font, i); if (font->size) { + int font_size; + if (font->size < 0) font->size = ((double) (- font->size)) * frame->dpi / 72.27 + 0.5; - merged_face.property[MFACE_SIZE] = (void *) font->size; + font_size = font->size; + merged_face.property[MFACE_SIZE] = (void *) font_size; merged_face.property[MFACE_RATIO] = (void *) 0; } } @@ -701,15 +702,15 @@ mface__realize (MFrame *frame, MFace **faces, int num, int size, MFont *font) font); rfont = NULL; mfont__set_spec_from_face (&spec, &merged_face); - mfont_put_prop (&spec, Mregistry, Miso8859_1); - spec.source = MFONT_SOURCE_X; + mfont_put_prop (&spec, Mregistry, Municode_bmp); + spec.source = MFONT_SOURCE_FT; font = mfont__select (frame, &spec, 0); if (font) rfont = mfont__open (frame, font, &spec); if (! rfont) { - mfont_put_prop (&spec, Mregistry, Municode_bmp); - spec.source = MFONT_SOURCE_FT; + mfont_put_prop (&spec, Mregistry, Miso8859_1); + spec.source = MFONT_SOURCE_X; font = mfont__select (frame, &spec, 0); if (font) rfont = mfont__open (frame, font, &spec); @@ -728,29 +729,32 @@ mface__realize (MFrame *frame, MFace **faces, int num, int size, MFont *font) rface->layouter = rfont->layouter; rfont->layouter = Mnil; work_gstring.glyphs[0].rface = rface; - work_gstring.glyphs[0].code = MCHAR_INVALID_CODE; + work_gstring.glyphs[0].g.code = MCHAR_INVALID_CODE; + work_gstring.glyphs[0].g.measured = 0; mfont__get_metric (&work_gstring, 0, 1); - rface->ascent = work_gstring.glyphs[0].ascent; - rface->descent = work_gstring.glyphs[0].descent; - work_gstring.glyphs[0].code + rface->ascent = work_gstring.glyphs[0].g.ascent; + rface->descent = work_gstring.glyphs[0].g.descent; + work_gstring.glyphs[0].g.code = mfont__encode_char (frame, (MFont *) rfont, NULL, ' '); - if (work_gstring.glyphs[0].code != MCHAR_INVALID_CODE) + if (work_gstring.glyphs[0].g.code != MCHAR_INVALID_CODE) { + work_gstring.glyphs[0].g.measured = 0; mfont__get_metric (&work_gstring, 0, 1); - rface->space_width = work_gstring.glyphs[0].width; + rface->space_width = work_gstring.glyphs[0].g.xadv; } else rface->space_width = rfont->spec.size / 10; if (rfont->average_width) - rface->average_width = rfont->average_width; + rface->average_width = rfont->average_width >> 6; else { - work_gstring.glyphs[0].code + work_gstring.glyphs[0].g.code = mfont__encode_char (frame, (MFont *) rfont, NULL, 'x'); - if (work_gstring.glyphs[0].code != MCHAR_INVALID_CODE) + if (work_gstring.glyphs[0].g.code != MCHAR_INVALID_CODE) { + work_gstring.glyphs[0].g.measured = 0; mfont__get_metric (&work_gstring, 0, 1); - rface->average_width = work_gstring.glyphs[0].width; + rface->average_width = work_gstring.glyphs[0].g.xadv; } else rface->average_width = rface->space_width; @@ -771,7 +775,7 @@ mface__realize (MFrame *frame, MFace **faces, int num, int size, MFont *font) rface->ascii_rface = rface; (*frame->driver->realize_face) (rface); - func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC]; + func = rface->face.hook; if (func && func != noop_hook) (func) (&(rface->face), rface->info, rface->face.property[MFACE_HOOK_ARG]); @@ -817,7 +821,7 @@ mface__for_chars (MSymbol script, MSymbol language, MSymbol charset, if (! rfont) { for (; from_g < to_g && from_g->rface->font; from_g++) - from_g->code = MCHAR_INVALID_CODE; + from_g->g.code = MCHAR_INVALID_CODE; } else { @@ -832,28 +836,33 @@ mface__for_chars (MSymbol script, MSymbol language, MSymbol charset, new->layouter = rfont->layouter; rfont->layouter = Mnil; new->non_ascii_list = NULL; - new->ascent = rfont->ascent; - new->descent = rfont->descent; + new->ascent = rfont->ascent >> 6; + new->descent = rfont->descent >> 6; } for (; from_g < to_g && from_g->rface->font; from_g++) { from_g->rface = new; if (new->layouter) { - from_g->code = mfont__flt_encode_char (new->layouter, - from_g->c); - if (from_g->code == MCHAR_INVALID_CODE) + MFLT *flt = mflt_get (new->layouter); + MCharTable *coverage; + + if (! flt + || ((coverage = mflt_coverage (flt)) + && ! (from_g->g.code + = (unsigned) mchartable_lookup (coverage, + from_g->g.c)))) { from_g->rface = rface; - from_g->code = mfont__encode_char (rfont->frame, - (MFont *) rfont, - NULL, from_g->c); + from_g->g.code = mfont__encode_char (rfont->frame, + (MFont *) rfont, + NULL, from_g->g.c); } } else - from_g->code = mfont__encode_char (rfont->frame, - (MFont *) rfont, - NULL, from_g->c); + from_g->g.code = mfont__encode_char (rfont->frame, + (MFont *) rfont, + NULL, from_g->g.c); } } return from_g; @@ -864,10 +873,10 @@ mface__for_chars (MSymbol script, MSymbol language, MSymbol charset, for (i = 0; i < num; i++) { unsigned code = mfont__encode_char (rfont->frame, (MFont *) rfont, - NULL, from_g[i].c); + NULL, from_g[i].g.c); if (code == MCHAR_INVALID_CODE) break; - from_g[i].code = code; + from_g[i].g.code = code; } if (i == num || from_g[i].rface->font) return from_g + i; @@ -882,7 +891,7 @@ mface__for_chars (MSymbol script, MSymbol language, MSymbol charset, } else { - from_g->code = MCHAR_INVALID_CODE; + from_g->g.code = MCHAR_INVALID_CODE; num = 1; rfont = NULL; layouter = Mnil; @@ -918,8 +927,8 @@ mface__for_chars (MSymbol script, MSymbol language, MSymbol charset, new->non_ascii_list = NULL; if (rfont) { - new->ascent = rfont->ascent; - new->descent = rfont->descent; + new->ascent = rfont->ascent >> 6; + new->descent = rfont->descent >> 6; } } while (g < from_g) @@ -1820,7 +1829,7 @@ mface_from_font (MFont *font) #Mforeground, #Mbackground, #Mvideomode, #Mhline, #Mbox, #Mfoundry, #Mfamily, #Mweight, #Mstyle, #Mstretch, #Madstyle, - #Msize, #Mfontset, #Mratio, #Mhook_func, #Mhook_arg + #Msize, #Mfontset, #Mratio, #Mhook_arg @return Ìá¤êÃͤη¿¤Ï $KEY ¤Ë°Í¸¤¹¤ë¡£¾åµ­¤Î¥­¡¼¤ÎÀâÌÀ¤ò»²¾È¤¹¤ë¤³¤È¡£ @@ -1829,7 +1838,7 @@ mface_from_font (MFont *font) /*** @seealso - mface_put_prop () + mface_put_prop (), mface_put_hook () @errors @c MERROR_FACE */ @@ -1840,13 +1849,37 @@ mface_get_prop (MFace *face, MSymbol key) int index = (int) msymbol_get (key, M_face_prop_index) - 1; if (index < 0) - MERROR (MERROR_FACE, NULL); + { + if (key == Mhook_func) + /* This unsafe code is for backward compatiblity. */ + return *(void **) &face->hook; + MERROR (MERROR_FACE, NULL); + } return face->property[index]; } /*=*/ /***en + @brief Get the hook function of a face. + + The mface_get_hook () function returns the hook function of face + $FACE. */ + +/***ja + @brief ¥Õ¥§¡¼¥¹¤Î¥Õ¥Ã¥¯´Ø¿ô¤òÆÀ¤ë. + + ´Ø¿ô mface_get_hook () ¤Ï¥Õ¥§¡¼¥¹ $FACE ¤Î¥Õ¥Ã¥¯´Ø¿ô¤òÊÖ¤¹¡£ */ + +MFaceHookFunc +mface_get_hook (MFace *face) +{ + return face->hook; +} + +/*=*/ + +/***en @brief Set a value of a face property. The mface_put_prop () function assigns $VAL to the property whose @@ -1901,22 +1934,32 @@ mface_put_prop (MFace *face, MSymbol key, void *val) int index = (int) msymbol_get (key, M_face_prop_index) - 1; MPlist *plist; - if (index < 0) - MERROR (MERROR_FACE, -1); - if (key == Mfontset) + if (key == Mhook_func) { - if (face->property[index]) - M17N_OBJECT_UNREF (face->property[index]); - M17N_OBJECT_REF (val); + /* This unsafe code is for backward compatiblity. */ + if (*(void **) &face->hook == val) + return 0; + *(void **) &face->hook = val; } - else if (key == Mhline) - val = get_hline_create (val); - else if (key == Mbox) - val = get_box_create (val); + else + { + if (index < 0) + MERROR (MERROR_FACE, -1); + if (key == Mfontset) + { + if (face->property[index]) + M17N_OBJECT_UNREF (face->property[index]); + M17N_OBJECT_REF (val); + } + else if (key == Mhline) + val = get_hline_create (val); + else if (key == Mbox) + val = get_box_create (val); - if (face->property[index] == val) - return 0; - face->property[index] = val; + if (face->property[index] == val) + return 0; + face->property[index] = val; + } MPLIST_DO (plist, face->frame_list) { @@ -1933,6 +1976,40 @@ mface_put_prop (MFace *face, MSymbol key, void *val) /*=*/ /***en + @brief Set a hook function to a face. + + The mface_set_hook () function sets the hook function of face + $FACE to $FUNC. */ + +/***ja + @brief ¥Õ¥§¡¼¥¹¤Î¥Õ¥Ã¥¯´Ø¿ô¤òÀßÄꤹ¤ë. + + ´Ø¿ô mface_set_hook () ¤Ï¡¢¥Õ¥§¡¼¥¹ $FACE ¤Î¥Õ¥Ã¥¯´Ø¿ô¤ò$FUNC ¤ËÀß + Äꤹ¤ë¡£ */ + +int +mface_put_hook (MFace *face, MFaceHookFunc func) +{ + if (face->hook != func) + { + MPlist *plist; + face->hook = func; + + MPLIST_DO (plist, face->frame_list) + { + MFrame *frame = MPLIST_VAL (plist); + + frame->tick++; + if (face == frame->face) + mface__update_frame_face (frame); + } + } + return 0; +} + +/*=*/ + +/***en @brief Update a face. The mface_update () function update face $FACE on frame $FRAME by @@ -1947,7 +2024,7 @@ mface_put_prop (MFace *face, MSymbol key, void *val) void mface_update (MFrame *frame, MFace *face) { - MFaceHookFunc func = (MFaceHookFunc) face->property[MFACE_HOOK_FUNC]; + MFaceHookFunc func = face->hook; MPlist *rface_list; MRealizedFace *rface; @@ -1956,7 +2033,7 @@ mface_update (MFrame *frame, MFace *face) MPLIST_DO (rface_list, frame->realized_face_list) { rface = MPLIST_VAL (rface_list); - if ((MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC] == func) + if (rface->face.hook == func) (func) (&(rface->face), rface->face.property[MFACE_HOOK_ARG], rface->info); }