diff options
| author | Andrew Innes | 2000-10-21 13:26:41 +0000 |
|---|---|---|
| committer | Andrew Innes | 2000-10-21 13:26:41 +0000 |
| commit | 82f9d56522a44d7f32a092873d55b5d1cfb3e4ad (patch) | |
| tree | 14257dc98238a702e2dde865793ffc9f9c896ebb /src | |
| parent | aa2ee344e3f206a0964d35212c194178358bd2a5 (diff) | |
| download | emacs-82f9d56522a44d7f32a092873d55b5d1cfb3e4ad.tar.gz emacs-82f9d56522a44d7f32a092873d55b5d1cfb3e4ad.zip | |
(w32_per_char_metric): Remove HDC argument. Use
cached information in emulated XFontStruct to handle common cases
quickly. Do not allocate XCharStruct for return.
(w32_native_per_char_metric): New function.
(w32_bdf_per_char_metric): Fill in supplied XCharStruct instead of
allocating one.
(x_produce_glyphs): Don't get an HDC. Change calls to
w32_per_char_metric to match arg change above. Remove calls to
free results.
(w32_get_glyph_overhangs): Ditto.
(w32_cache_char_metrics): New function.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32term.c | 212 |
1 files changed, 120 insertions, 92 deletions
diff --git a/src/w32term.c b/src/w32term.c index 950d5525d59..c20e470037a 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -79,15 +79,6 @@ enum bitmap_type | |||
| 79 | ZV_LINE_BITMAP | 79 | ZV_LINE_BITMAP |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | enum w32_char_font_type | ||
| 83 | { | ||
| 84 | UNKNOWN_FONT, | ||
| 85 | ANSI_FONT, | ||
| 86 | UNICODE_FONT, | ||
| 87 | BDF_1D_FONT, | ||
| 88 | BDF_2D_FONT | ||
| 89 | }; | ||
| 90 | |||
| 91 | /* Bitmaps are all unsigned short, as Windows requires bitmap data to | 82 | /* Bitmaps are all unsigned short, as Windows requires bitmap data to |
| 92 | be Word aligned. For some reason they are horizontally reflected | 83 | be Word aligned. For some reason they are horizontally reflected |
| 93 | compared to how they appear on X, so changes in xterm.c should be | 84 | compared to how they appear on X, so changes in xterm.c should be |
| @@ -189,6 +180,8 @@ extern void w32_menu_display_help (HMENU menu, UINT menu_item, UINT flags); | |||
| 189 | 180 | ||
| 190 | extern int w32_codepage_for_font (char *fontname); | 181 | extern int w32_codepage_for_font (char *fontname); |
| 191 | 182 | ||
| 183 | extern glyph_metric *w32_BDF_TextMetric(bdffont *fontp, | ||
| 184 | unsigned char *text, int dim); | ||
| 192 | extern Lisp_Object Vwindow_system; | 185 | extern Lisp_Object Vwindow_system; |
| 193 | 186 | ||
| 194 | #define x_any_window_to_frame x_window_to_frame | 187 | #define x_any_window_to_frame x_window_to_frame |
| @@ -1101,7 +1094,7 @@ static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *, | |||
| 1101 | int *)); | 1094 | int *)); |
| 1102 | static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int, | 1095 | static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int, |
| 1103 | int, wchar_t *, int)); | 1096 | int, wchar_t *, int)); |
| 1104 | static XCharStruct *w32_per_char_metric P_ ((HDC hdc, XFontStruct *, | 1097 | static XCharStruct *w32_per_char_metric P_ ((XFontStruct *, |
| 1105 | wchar_t *, | 1098 | wchar_t *, |
| 1106 | enum w32_char_font_type)); | 1099 | enum w32_char_font_type)); |
| 1107 | static enum w32_char_font_type | 1100 | static enum w32_char_font_type |
| @@ -1130,15 +1123,15 @@ static void x_produce_image_glyph P_ ((struct it *it)); | |||
| 1130 | If CHAR2B is not contained in FONT, the font's default character | 1123 | If CHAR2B is not contained in FONT, the font's default character |
| 1131 | metric is returned. */ | 1124 | metric is returned. */ |
| 1132 | 1125 | ||
| 1133 | static XCharStruct * | 1126 | static int |
| 1134 | w32_bdf_per_char_metric (font, char2b, dim) | 1127 | w32_bdf_per_char_metric (font, char2b, dim, pcm) |
| 1135 | XFontStruct *font; | 1128 | XFontStruct *font; |
| 1136 | wchar_t *char2b; | 1129 | wchar_t *char2b; |
| 1137 | int dim; | 1130 | int dim; |
| 1131 | XCharStruct * pcm; | ||
| 1138 | { | 1132 | { |
| 1139 | glyph_metric * bdf_metric; | 1133 | glyph_metric * bdf_metric; |
| 1140 | char buf[2]; | 1134 | char buf[2]; |
| 1141 | XCharStruct * pcm = (XCharStruct *) xmalloc (sizeof (XCharStruct)); | ||
| 1142 | 1135 | ||
| 1143 | if (dim == 1) | 1136 | if (dim == 1) |
| 1144 | buf[0] = (char)char2b; | 1137 | buf[0] = (char)char2b; |
| @@ -1158,42 +1151,32 @@ w32_bdf_per_char_metric (font, char2b, dim) | |||
| 1158 | - (bdf_metric->bbox + bdf_metric->bbw); | 1151 | - (bdf_metric->bbox + bdf_metric->bbw); |
| 1159 | pcm->ascent = bdf_metric->bboy + bdf_metric->bbh; | 1152 | pcm->ascent = bdf_metric->bboy + bdf_metric->bbh; |
| 1160 | pcm->descent = bdf_metric->bboy; | 1153 | pcm->descent = bdf_metric->bboy; |
| 1154 | |||
| 1155 | return 1; | ||
| 1161 | } | 1156 | } |
| 1162 | else | 1157 | return 0; |
| 1163 | { | ||
| 1164 | xfree (pcm); | ||
| 1165 | return NULL; | ||
| 1166 | } | ||
| 1167 | return pcm; | ||
| 1168 | } | 1158 | } |
| 1169 | 1159 | ||
| 1170 | 1160 | ||
| 1171 | static XCharStruct * | 1161 | static int |
| 1172 | w32_per_char_metric (hdc, font, char2b, font_type) | 1162 | w32_native_per_char_metric (font, char2b, font_type, pcm) |
| 1173 | HDC hdc; | ||
| 1174 | XFontStruct *font; | 1163 | XFontStruct *font; |
| 1175 | wchar_t *char2b; | 1164 | wchar_t *char2b; |
| 1176 | enum w32_char_font_type font_type; | 1165 | enum w32_char_font_type font_type; |
| 1166 | XCharStruct * pcm; | ||
| 1177 | { | 1167 | { |
| 1178 | /* NTEMACS_TODO: Use GetGlyphOutline where possible (no Unicode | 1168 | /* NTEMACS_TODO: Use GetGlyphOutline where possible (no Unicode |
| 1179 | version on W9x) */ | 1169 | version on W9x) */ |
| 1180 | 1170 | ||
| 1181 | /* The result metric information. */ | 1171 | HDC hdc = GetDC (NULL); |
| 1182 | XCharStruct *pcm; | 1172 | HFONT old_font; |
| 1183 | BOOL retval; | 1173 | BOOL retval = FALSE; |
| 1184 | 1174 | ||
| 1185 | xassert (font && char2b); | 1175 | xassert (font && char2b); |
| 1186 | xassert (font_type != UNKNOWN_FONT); | 1176 | xassert (font->hfont); |
| 1177 | xassert (font_type == UNICODE_FONT || font_type == ANSI_FONT); | ||
| 1187 | 1178 | ||
| 1188 | if (font_type == BDF_1D_FONT) | 1179 | old_font = SelectObject (hdc, font->hfont); |
| 1189 | return w32_bdf_per_char_metric (font, char2b, 1); | ||
| 1190 | else if (font_type == BDF_2D_FONT) | ||
| 1191 | return w32_bdf_per_char_metric (font, char2b, 2); | ||
| 1192 | |||
| 1193 | pcm = (XCharStruct *) xmalloc (sizeof (XCharStruct)); | ||
| 1194 | |||
| 1195 | if (font->hfont) | ||
| 1196 | SelectObject (hdc, font->hfont); | ||
| 1197 | 1180 | ||
| 1198 | if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0) | 1181 | if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0) |
| 1199 | { | 1182 | { |
| @@ -1201,7 +1184,7 @@ w32_per_char_metric (hdc, font, char2b, font_type) | |||
| 1201 | 1184 | ||
| 1202 | if (font_type == UNICODE_FONT) | 1185 | if (font_type == UNICODE_FONT) |
| 1203 | retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths); | 1186 | retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths); |
| 1204 | else if (font_type == ANSI_FONT) | 1187 | else |
| 1205 | retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths); | 1188 | retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths); |
| 1206 | 1189 | ||
| 1207 | if (retval) | 1190 | if (retval) |
| @@ -1209,61 +1192,119 @@ w32_per_char_metric (hdc, font, char2b, font_type) | |||
| 1209 | pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC; | 1192 | pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC; |
| 1210 | pcm->lbearing = char_widths.abcA; | 1193 | pcm->lbearing = char_widths.abcA; |
| 1211 | pcm->rbearing = pcm->width - char_widths.abcC; | 1194 | pcm->rbearing = pcm->width - char_widths.abcC; |
| 1212 | } | 1195 | pcm->ascent = FONT_BASE (font); |
| 1213 | else | 1196 | pcm->descent = FONT_DESCENT (font); |
| 1214 | { | ||
| 1215 | /* Windows 9x does not implement GetCharABCWidthsW, so if that | ||
| 1216 | failed, try GetTextExtentPoint32W, which is implemented and | ||
| 1217 | at least gives us some of the info we are after (total | ||
| 1218 | character width). */ | ||
| 1219 | SIZE sz; | ||
| 1220 | |||
| 1221 | if (font_type == UNICODE_FONT) | ||
| 1222 | retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz); | ||
| 1223 | |||
| 1224 | if (retval) | ||
| 1225 | { | ||
| 1226 | pcm->width = sz.cx; | ||
| 1227 | pcm->rbearing = sz.cx; | ||
| 1228 | pcm->lbearing = 0; | ||
| 1229 | } | ||
| 1230 | else | ||
| 1231 | { | ||
| 1232 | xfree (pcm); | ||
| 1233 | return NULL; | ||
| 1234 | } | ||
| 1235 | } | 1197 | } |
| 1236 | } | 1198 | } |
| 1237 | else | 1199 | |
| 1200 | if (!retval) | ||
| 1238 | { | 1201 | { |
| 1239 | /* Do our best to deduce the desired metrics data for non-Truetype | 1202 | /* Either font is not a True-type font, or GetCharABCWidthsW |
| 1240 | fonts (generally, raster fonts). */ | 1203 | failed (it is not supported on Windows 9x for instance), so we |
| 1241 | INT char_width; | 1204 | can't determine the full info we would like. All is not lost |
| 1205 | though - we can call GetTextExtentPoint32 to get rbearing and | ||
| 1206 | deduce width based on the font's per-string overhang. lbearing | ||
| 1207 | is assumed to be zero. */ | ||
| 1208 | SIZE sz; | ||
| 1209 | |||
| 1210 | if (font_type == UNICODE_FONT) | ||
| 1211 | retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz); | ||
| 1212 | else | ||
| 1213 | retval = GetTextExtentPoint32A (hdc, (char*)char2b, 1, &sz); | ||
| 1242 | 1214 | ||
| 1243 | retval = GetCharWidth (hdc, *char2b, *char2b, &char_width); | ||
| 1244 | if (retval) | 1215 | if (retval) |
| 1245 | { | 1216 | { |
| 1246 | pcm->width = char_width; | 1217 | pcm->width = sz.cx - font->tm.tmOverhang; |
| 1247 | pcm->rbearing = char_width; | 1218 | pcm->rbearing = sz.cx; |
| 1248 | pcm->lbearing = 0; | 1219 | pcm->lbearing = 0; |
| 1249 | } | 1220 | pcm->ascent = FONT_BASE (font); |
| 1250 | else | 1221 | pcm->descent = FONT_DESCENT (font); |
| 1251 | { | ||
| 1252 | xfree (pcm); | ||
| 1253 | return NULL; | ||
| 1254 | } | 1222 | } |
| 1255 | } | 1223 | } |
| 1256 | 1224 | ||
| 1257 | pcm->ascent = FONT_BASE (font); | ||
| 1258 | pcm->descent = FONT_DESCENT (font); | ||
| 1259 | 1225 | ||
| 1260 | if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0) | 1226 | if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0) |
| 1261 | { | 1227 | { |
| 1262 | xfree (pcm); | 1228 | retval = FALSE; |
| 1263 | return NULL; | 1229 | } |
| 1230 | |||
| 1231 | SelectObject (hdc, old_font); | ||
| 1232 | ReleaseDC (NULL, hdc); | ||
| 1233 | |||
| 1234 | return retval; | ||
| 1235 | } | ||
| 1236 | |||
| 1237 | |||
| 1238 | static XCharStruct * | ||
| 1239 | w32_per_char_metric (font, char2b, font_type) | ||
| 1240 | XFontStruct *font; | ||
| 1241 | wchar_t *char2b; | ||
| 1242 | enum w32_char_font_type font_type; | ||
| 1243 | { | ||
| 1244 | /* The result metric information. */ | ||
| 1245 | XCharStruct *pcm; | ||
| 1246 | BOOL retval; | ||
| 1247 | |||
| 1248 | xassert (font && char2b); | ||
| 1249 | xassert (font_type != UNKNOWN_FONT); | ||
| 1250 | |||
| 1251 | /* Handle the common cases quickly. */ | ||
| 1252 | if (font->per_char == NULL) | ||
| 1253 | /* TODO: determine whether char2b exists in font? */ | ||
| 1254 | return &font->max_bounds; | ||
| 1255 | else if (*char2b < 128) | ||
| 1256 | return &font->per_char[*char2b]; | ||
| 1257 | |||
| 1258 | pcm = &font->scratch; | ||
| 1259 | |||
| 1260 | if (font_type == BDF_1D_FONT) | ||
| 1261 | retval = w32_bdf_per_char_metric (font, char2b, 1, pcm); | ||
| 1262 | else if (font_type == BDF_2D_FONT) | ||
| 1263 | retval = w32_bdf_per_char_metric (font, char2b, 2, pcm); | ||
| 1264 | else | ||
| 1265 | retval = w32_native_per_char_metric (font, char2b, font_type, pcm); | ||
| 1266 | |||
| 1267 | if (retval) | ||
| 1268 | return pcm; | ||
| 1269 | |||
| 1270 | return NULL; | ||
| 1271 | } | ||
| 1272 | |||
| 1273 | void | ||
| 1274 | w32_cache_char_metrics (font) | ||
| 1275 | XFontStruct *font; | ||
| 1276 | { | ||
| 1277 | wchar_t char2b = L'x'; | ||
| 1278 | |||
| 1279 | /* Cache char metrics for the common cases. */ | ||
| 1280 | if (font->bdf) | ||
| 1281 | { | ||
| 1282 | /* TODO: determine whether font is fixed-pitch. */ | ||
| 1283 | w32_bdf_per_char_metric (font, &char2b, 1, &font->max_bounds); | ||
| 1264 | } | 1284 | } |
| 1285 | else | ||
| 1286 | { | ||
| 1287 | if ((font->tm.tmPitchAndFamily & TMPF_FIXED_PITCH) != 0) | ||
| 1288 | { | ||
| 1289 | /* Font is not fixed pitch, so cache per_char info for the | ||
| 1290 | ASCII characters. It would be much more work, and probably | ||
| 1291 | not worth it, to cache other chars, since we may change | ||
| 1292 | between using Unicode and ANSI text drawing functions at | ||
| 1293 | run-time. */ | ||
| 1294 | int i; | ||
| 1265 | 1295 | ||
| 1266 | return pcm; | 1296 | font->per_char = xmalloc (128 * sizeof(XCharStruct)); |
| 1297 | for (i = 0; i < 128; i++) | ||
| 1298 | { | ||
| 1299 | char2b = i; | ||
| 1300 | w32_native_per_char_metric (font, &char2b, ANSI_FONT, | ||
| 1301 | &font->per_char[i]); | ||
| 1302 | } | ||
| 1303 | } | ||
| 1304 | else | ||
| 1305 | w32_native_per_char_metric (font, &char2b, ANSI_FONT, | ||
| 1306 | &font->max_bounds); | ||
| 1307 | } | ||
| 1267 | } | 1308 | } |
| 1268 | 1309 | ||
| 1269 | 1310 | ||
| @@ -1893,7 +1934,6 @@ x_produce_glyphs (it) | |||
| 1893 | int font_not_found_p; | 1934 | int font_not_found_p; |
| 1894 | struct font_info *font_info; | 1935 | struct font_info *font_info; |
| 1895 | int boff; /* baseline offset */ | 1936 | int boff; /* baseline offset */ |
| 1896 | HDC hdc; | ||
| 1897 | /* We may change it->multibyte_p upon unibyte<->multibyte | 1937 | /* We may change it->multibyte_p upon unibyte<->multibyte |
| 1898 | conversion. So, save the current value now and restore it | 1938 | conversion. So, save the current value now and restore it |
| 1899 | later. | 1939 | later. |
| @@ -1906,8 +1946,6 @@ x_produce_glyphs (it) | |||
| 1906 | */ | 1946 | */ |
| 1907 | int saved_multibyte_p = it->multibyte_p; | 1947 | int saved_multibyte_p = it->multibyte_p; |
| 1908 | 1948 | ||
| 1909 | hdc = get_frame_dc (it->f); | ||
| 1910 | |||
| 1911 | /* Maybe translate single-byte characters to multibyte, or the | 1949 | /* Maybe translate single-byte characters to multibyte, or the |
| 1912 | other way. */ | 1950 | other way. */ |
| 1913 | it->char_to_display = it->c; | 1951 | it->char_to_display = it->c; |
| @@ -1955,9 +1993,6 @@ x_produce_glyphs (it) | |||
| 1955 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | 1993 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; |
| 1956 | } | 1994 | } |
| 1957 | 1995 | ||
| 1958 | if (font->hfont) | ||
| 1959 | SelectObject (hdc, font->hfont); | ||
| 1960 | |||
| 1961 | if (it->char_to_display >= ' ' | 1996 | if (it->char_to_display >= ' ' |
| 1962 | && (!it->multibyte_p || it->char_to_display < 128)) | 1997 | && (!it->multibyte_p || it->char_to_display < 128)) |
| 1963 | { | 1998 | { |
| @@ -1966,7 +2001,7 @@ x_produce_glyphs (it) | |||
| 1966 | 2001 | ||
| 1967 | it->nglyphs = 1; | 2002 | it->nglyphs = 1; |
| 1968 | 2003 | ||
| 1969 | pcm = w32_per_char_metric (hdc, font, &char2b, | 2004 | pcm = w32_per_char_metric (font, &char2b, |
| 1970 | font->bdf ? BDF_1D_FONT : ANSI_FONT); | 2005 | font->bdf ? BDF_1D_FONT : ANSI_FONT); |
| 1971 | it->ascent = FONT_BASE (font) + boff; | 2006 | it->ascent = FONT_BASE (font) + boff; |
| 1972 | it->descent = FONT_DESCENT (font) - boff; | 2007 | it->descent = FONT_DESCENT (font) - boff; |
| @@ -2034,8 +2069,6 @@ x_produce_glyphs (it) | |||
| 2034 | glyph row. This is used to optimize X output code. */ | 2069 | glyph row. This is used to optimize X output code. */ |
| 2035 | if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width)) | 2070 | if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width)) |
| 2036 | it->glyph_row->contains_overlapping_glyphs_p = 1; | 2071 | it->glyph_row->contains_overlapping_glyphs_p = 1; |
| 2037 | if (pcm) | ||
| 2038 | xfree (pcm); | ||
| 2039 | } | 2072 | } |
| 2040 | } | 2073 | } |
| 2041 | else if (it->char_to_display == '\n') | 2074 | else if (it->char_to_display == '\n') |
| @@ -2094,7 +2127,7 @@ x_produce_glyphs (it) | |||
| 2094 | else | 2127 | else |
| 2095 | type = UNICODE_FONT; | 2128 | type = UNICODE_FONT; |
| 2096 | 2129 | ||
| 2097 | pcm = w32_per_char_metric (hdc, font, &char2b, type); | 2130 | pcm = w32_per_char_metric (font, &char2b, type); |
| 2098 | 2131 | ||
| 2099 | if (font_not_found_p || !pcm) | 2132 | if (font_not_found_p || !pcm) |
| 2100 | { | 2133 | { |
| @@ -2141,11 +2174,7 @@ x_produce_glyphs (it) | |||
| 2141 | 2174 | ||
| 2142 | if (it->glyph_row) | 2175 | if (it->glyph_row) |
| 2143 | x_append_glyph (it); | 2176 | x_append_glyph (it); |
| 2144 | |||
| 2145 | if (pcm) | ||
| 2146 | xfree (pcm); | ||
| 2147 | } | 2177 | } |
| 2148 | release_frame_dc (it->f, hdc); | ||
| 2149 | it->multibyte_p = saved_multibyte_p; | 2178 | it->multibyte_p = saved_multibyte_p; |
| 2150 | } | 2179 | } |
| 2151 | else if (it->what == IT_COMPOSITION) | 2180 | else if (it->what == IT_COMPOSITION) |
| @@ -2798,14 +2827,13 @@ w32_get_glyph_overhangs (hdc, glyph, f, left, right) | |||
| 2798 | font = face->font; | 2827 | font = face->font; |
| 2799 | 2828 | ||
| 2800 | if (font | 2829 | if (font |
| 2801 | && (pcm = w32_per_char_metric (hdc, font, &char2b, | 2830 | && (pcm = w32_per_char_metric (font, &char2b, |
| 2802 | glyph->w32_font_type))) | 2831 | glyph->w32_font_type))) |
| 2803 | { | 2832 | { |
| 2804 | if (pcm->rbearing > pcm->width) | 2833 | if (pcm->rbearing > pcm->width) |
| 2805 | *right = pcm->rbearing - pcm->width; | 2834 | *right = pcm->rbearing - pcm->width; |
| 2806 | if (pcm->lbearing < 0) | 2835 | if (pcm->lbearing < 0) |
| 2807 | *left = -pcm->lbearing; | 2836 | *left = -pcm->lbearing; |
| 2808 | xfree (pcm); | ||
| 2809 | } | 2837 | } |
| 2810 | } | 2838 | } |
| 2811 | } | 2839 | } |