aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Rumney2007-09-19 13:58:58 +0000
committerJason Rumney2007-09-19 13:58:58 +0000
commit78573c5715cd4034b090acf8097a54779ad9f40e (patch)
treed2c30f2cbded05d204d07b25d40b2a23545e1b44 /src
parentef5e1a96514126f8175a9409041ed1f8eeac9518 (diff)
downloademacs-78573c5715cd4034b090acf8097a54779ad9f40e.tar.gz
emacs-78573c5715cd4034b090acf8097a54779ad9f40e.zip
(w32font_text_extents): Calculate metrics for the whole string.
Diffstat (limited to 'src')
-rw-r--r--src/w32font.c91
1 files changed, 45 insertions, 46 deletions
diff --git a/src/w32font.c b/src/w32font.c
index 061b253230a..16ae98f13bb 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -371,7 +371,7 @@ w32font_encode_char (font, c)
371/* w32 implementation of text_extents for font backend. 371/* w32 implementation of text_extents for font backend.
372 Perform the size computation of glyphs of FONT and fillin members 372 Perform the size computation of glyphs of FONT and fillin members
373 of METRICS. The glyphs are specified by their glyph codes in 373 of METRICS. The glyphs are specified by their glyph codes in
374 CODE (length NGLYPHS). Apparently medtrics can be NULL, in this 374 CODE (length NGLYPHS). Apparently metrics can be NULL, in this
375 case just return the overall width. */ 375 case just return the overall width. */
376static int 376static int
377w32font_text_extents (font, code, nglyphs, metrics) 377w32font_text_extents (font, code, nglyphs, metrics)
@@ -386,8 +386,6 @@ w32font_text_extents (font, code, nglyphs, metrics)
386 device context to measure against... */ 386 device context to measure against... */
387 HDC dc = GetDC (NULL); 387 HDC dc = GetDC (NULL);
388 int total_width = 0; 388 int total_width = 0;
389
390 /* TODO: Allow some extra room for surrogates. */
391 WORD *wcode = alloca(nglyphs * sizeof (WORD)); 389 WORD *wcode = alloca(nglyphs * sizeof (WORD));
392 SIZE size; 390 SIZE size;
393 391
@@ -397,66 +395,57 @@ w32font_text_extents (font, code, nglyphs, metrics)
397 { 395 {
398 GLYPHMETRICS gm; 396 GLYPHMETRICS gm;
399 MAT2 transform; 397 MAT2 transform;
400 int i, width;
401 UINT format = GGO_METRICS;
402 398
403 /* Set transform to the identity matrix. */ 399 /* Set transform to the identity matrix. */
404 bzero (&transform, sizeof (transform)); 400 bzero (&transform, sizeof (transform));
405 transform.eM11.value = 1; 401 transform.eM11.value = 1;
406 transform.eM22.value = 1; 402 transform.eM22.value = 1;
403 metrics->width = 0;
404 metrics->ascent = 0;
405 metrics->descent = 0;
407 406
408 for (i = 0; i < nglyphs; i++) 407 for (i = 0; i < nglyphs; i++)
409 { 408 {
410 if (code[i] < 0x10000) 409 if (GetGlyphOutlineW (dc, *(code + i), GGO_METRICS, &gm, 0,
411 wcode[i] = code[i];
412 else
413 {
414 /* TODO: Convert to surrogate, reallocating array if needed */
415 wcode[i] = 0xffff;
416 }
417
418 if (GetGlyphOutlineW (dc, *(code + i), format, &gm, 0,
419 NULL, &transform) != GDI_ERROR) 410 NULL, &transform) != GDI_ERROR)
420 { 411 {
421 metrics[i].lbearing = gm.gmptGlyphOrigin.x; 412 int new_val = metrics->width + gm.gmBlackBoxX
422 metrics[i].rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX; 413 + gm.gmptGlyphOrigin.x;
423 metrics[i].width = gm.gmCellIncX; 414
424 metrics[i].ascent = -gm.gmptGlyphOrigin.y; 415 metrics->rbearing = max (metrics->rbearing, new_val);
425 metrics[i].descent = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y; 416 metrics->width += gm.gmCellIncX;
426 } 417 new_val = -gm.gmptGlyphOrigin.y;
427 else if (GetTextExtentPoint32W (dc, wcode + i, 1, &size) 418 metrics->ascent = max (metrics->ascent, new_val);
428 != GDI_ERROR) 419 new_val = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
429 { 420 metrics->descent = max (metrics->descent, new_val);
430 metrics[i].lbearing = 0;
431 metrics[i].rbearing = size.cx
432 + ((struct w32font_info *) font)->metrics.tmOverhang;
433 metrics[i].width = size.cx;
434 metrics[i].ascent = font->ascent;
435 metrics[i].descent = font->descent;
436 } 421 }
437 else 422 else
438 { 423 {
439 metrics[i].lbearing = 0; 424 /* Rely on an estimate based on the overall font metrics. */
440 metrics[i].rbearing = font->font.size 425 break;
441 + ((struct w32font_info *) font)->metrics.tmOverhang;
442 metrics[i].width = font->font.size;
443 metrics[i].ascent = font->ascent;
444 metrics[i].descent = font->descent;
445 } 426 }
446 } 427 }
428
429 /* If we got through everything, return. */
430 if (i == nglyphs)
431 {
432 /* Restore state and release DC. */
433 SelectObject (dc, old_font);
434 ReleaseDC (NULL, dc);
435
436 return metrics->width;
437 }
447 } 438 }
448 else 439
440 for (i = 0; i < nglyphs; i++)
449 { 441 {
450 for (i = 0; i < nglyphs; i++) 442 if (code[i] < 0x10000)
451 { 443 wcode[i] = code[i];
452 if (code[i] < 0x10000) 444 else
453 wcode[i] = code[i]; 445 {
454 else 446 /* TODO: Convert to surrogate, reallocating array if needed */
455 { 447 wcode[i] = 0xffff;
456 /* TODO: Convert to surrogate, reallocating array if needed */ 448 }
457 wcode[i] = 0xffff;
458 }
459 }
460 } 449 }
461 450
462 if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size)) 451 if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size))
@@ -473,6 +462,16 @@ w32font_text_extents (font, code, nglyphs, metrics)
473 total_width = rect.right; 462 total_width = rect.right;
474 } 463 }
475 464
465 if (metrics)
466 {
467 metrics->width = total_width;
468 metrics->ascent = font->ascent;
469 metrics->descent = font->descent;
470 metrics->lbearing = 0;
471 metrics->rbearing = total_width
472 + ((struct w32font_info *) font)->metrics.tmOverhang;
473 }
474
476 /* Restore state and release DC. */ 475 /* Restore state and release DC. */
477 SelectObject (dc, old_font); 476 SelectObject (dc, old_font);
478 ReleaseDC (NULL, dc); 477 ReleaseDC (NULL, dc);