comparison src/w32font.c @ 92151:664a09af03dc

(w32font_text_extents): Avoid getting HDC and selecting a font into it unless we have to.
author Jason Rumney <jasonr@gnu.org>
date Sun, 24 Feb 2008 15:07:46 +0000
parents 3081b8f848bc
children b7277e09e943
comparison
equal deleted inserted replaced
92150:1c088baa9d2d 92151:664a09af03dc
288 unsigned *code; 288 unsigned *code;
289 int nglyphs; 289 int nglyphs;
290 struct font_metrics *metrics; 290 struct font_metrics *metrics;
291 { 291 {
292 int i; 292 int i;
293 HFONT old_font; 293 HFONT old_font = NULL;
294 HDC dc; 294 HDC dc = NULL;
295 struct frame * f; 295 struct frame * f;
296 int total_width = 0; 296 int total_width = 0;
297 WORD *wcode = alloca(nglyphs * sizeof (WORD)); 297 WORD *wcode = alloca(nglyphs * sizeof (WORD));
298 SIZE size; 298 SIZE size;
299 299
300 /* TODO: Frames can come and go, and their fonts outlive them. So we 300 /* TODO: Frames can come and go, and their fonts outlive them. So we
301 can't cache the frame in the font structure. Use selected_frame 301 can't cache the frame in the font structure. Use selected_frame
302 until the API is updated to pass in a frame. */ 302 until the API is updated to pass in a frame. */
303 f = XFRAME (selected_frame); 303 f = XFRAME (selected_frame);
304
305 dc = get_frame_dc (f);
306 old_font = SelectObject (dc, ((W32FontStruct *)(font->font.font))->hfont);
307 304
308 if (metrics) 305 if (metrics)
309 { 306 {
310 GLYPHMETRICS gm; 307 GLYPHMETRICS gm;
311 MAT2 transform; 308 MAT2 transform;
337 metrics->width + char_metric->rbearing); 334 metrics->width + char_metric->rbearing);
338 metrics->width += char_metric->width; 335 metrics->width += char_metric->width;
339 metrics->ascent = max (metrics->ascent, char_metric->ascent); 336 metrics->ascent = max (metrics->ascent, char_metric->ascent);
340 metrics->descent = max (metrics->descent, char_metric->descent); 337 metrics->descent = max (metrics->descent, char_metric->descent);
341 } 338 }
342 else if (GetGlyphOutlineW (dc, *(code + i), GGO_METRICS, &gm, 0,
343 NULL, &transform) != GDI_ERROR)
344 {
345 int new_val = metrics->width + gm.gmBlackBoxX
346 + gm.gmptGlyphOrigin.x;
347 metrics->rbearing = max (metrics->rbearing, new_val);
348 new_val = -gm.gmptGlyphOrigin.x - metrics->width;
349 metrics->lbearing = max (metrics->lbearing, new_val);
350 metrics->width += gm.gmCellIncX;
351 new_val = -gm.gmptGlyphOrigin.y;
352 metrics->ascent = max (metrics->ascent, new_val);
353 new_val = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
354 metrics->descent = max (metrics->descent, new_val);
355 }
356 else 339 else
357 { 340 {
358 /* Rely on an estimate based on the overall font metrics. */ 341 if (dc == NULL)
359 break; 342 {
343 dc = get_frame_dc (f);
344 old_font = SelectObject (dc, ((W32FontStruct *)
345 (font->font.font))->hfont);
346 }
347 if (GetGlyphOutlineW (dc, *(code + i), GGO_METRICS, &gm, 0,
348 NULL, &transform) != GDI_ERROR)
349 {
350 int new_val = metrics->width + gm.gmBlackBoxX
351 + gm.gmptGlyphOrigin.x;
352 metrics->rbearing = max (metrics->rbearing, new_val);
353 new_val = -gm.gmptGlyphOrigin.x - metrics->width;
354 metrics->lbearing = max (metrics->lbearing, new_val);
355 metrics->width += gm.gmCellIncX;
356 new_val = -gm.gmptGlyphOrigin.y;
357 metrics->ascent = max (metrics->ascent, new_val);
358 new_val = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
359 metrics->descent = max (metrics->descent, new_val);
360 }
361 else
362 {
363 /* Rely on an estimate based on the overall font metrics. */
364 break;
365 }
360 } 366 }
361 } 367 }
362 368
363 /* If we got through everything, return. */ 369 /* If we got through everything, return. */
364 if (i == nglyphs) 370 if (i == nglyphs)
365 { 371 {
366 /* Restore state and release DC. */ 372 if (dc != NULL)
367 SelectObject (dc, old_font); 373 {
368 release_frame_dc (f, dc); 374 /* Restore state and release DC. */
375 SelectObject (dc, old_font);
376 release_frame_dc (f, dc);
377 }
369 378
370 return metrics->width; 379 return metrics->width;
371 } 380 }
372 } 381 }
373 382
378 else 387 else
379 { 388 {
380 /* TODO: Convert to surrogate, reallocating array if needed */ 389 /* TODO: Convert to surrogate, reallocating array if needed */
381 wcode[i] = 0xffff; 390 wcode[i] = 0xffff;
382 } 391 }
392 }
393
394 if (dc == NULL)
395 {
396 dc = get_frame_dc (f);
397 old_font = SelectObject (dc, ((W32FontStruct *)
398 (font->font.font))->hfont);
383 } 399 }
384 400
385 if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size)) 401 if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size))
386 { 402 {
387 total_width = size.cx; 403 total_width = size.cx;