diff options
| author | Jason Rumney | 2007-09-19 13:58:58 +0000 |
|---|---|---|
| committer | Jason Rumney | 2007-09-19 13:58:58 +0000 |
| commit | 78573c5715cd4034b090acf8097a54779ad9f40e (patch) | |
| tree | d2c30f2cbded05d204d07b25d40b2a23545e1b44 /src | |
| parent | ef5e1a96514126f8175a9409041ed1f8eeac9518 (diff) | |
| download | emacs-78573c5715cd4034b090acf8097a54779ad9f40e.tar.gz emacs-78573c5715cd4034b090acf8097a54779ad9f40e.zip | |
(w32font_text_extents): Calculate metrics for the whole string.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32font.c | 91 |
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. */ |
| 376 | static int | 376 | static int |
| 377 | w32font_text_extents (font, code, nglyphs, metrics) | 377 | w32font_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); |