aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Innes2000-10-21 13:26:41 +0000
committerAndrew Innes2000-10-21 13:26:41 +0000
commit82f9d56522a44d7f32a092873d55b5d1cfb3e4ad (patch)
tree14257dc98238a702e2dde865793ffc9f9c896ebb /src
parentaa2ee344e3f206a0964d35212c194178358bd2a5 (diff)
downloademacs-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.c212
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
82enum 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
190extern int w32_codepage_for_font (char *fontname); 181extern int w32_codepage_for_font (char *fontname);
191 182
183extern glyph_metric *w32_BDF_TextMetric(bdffont *fontp,
184 unsigned char *text, int dim);
192extern Lisp_Object Vwindow_system; 185extern 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 *));
1102static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int, 1095static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
1103 int, wchar_t *, int)); 1096 int, wchar_t *, int));
1104static XCharStruct *w32_per_char_metric P_ ((HDC hdc, XFontStruct *, 1097static 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));
1107static enum w32_char_font_type 1100static 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
1133static XCharStruct * 1126static int
1134w32_bdf_per_char_metric (font, char2b, dim) 1127w32_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
1171static XCharStruct * 1161static int
1172w32_per_char_metric (hdc, font, char2b, font_type) 1162w32_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
1238static XCharStruct *
1239w32_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
1273void
1274w32_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}