diff options
| author | Jason Rumney | 2008-02-06 22:35:30 +0000 |
|---|---|---|
| committer | Jason Rumney | 2008-02-06 22:35:30 +0000 |
| commit | 46a923ac725b5ce93bfb7ef8d56055bdc167df22 (patch) | |
| tree | a078f4388ea36ce673445991cc2494de053d3bdf /src | |
| parent | 06c0751a07882220836c83256c12b87e723f5877 (diff) | |
| download | emacs-46a923ac725b5ce93bfb7ef8d56055bdc167df22.tar.gz emacs-46a923ac725b5ce93bfb7ef8d56055bdc167df22.zip | |
* w32font.c (w32font_text_extents): Fill in lbearing metric.
Use cached metrics for ASCII characters.
(w32font_open_internal): Don't set font's owning_frame. Cache
metrics for ASCII characters.
* w32font.h (struct w32font_info): Add ascii_metrics.
Remove owning_frame.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/w32font.c | 62 | ||||
| -rw-r--r-- | src/w32font.h | 2 |
3 files changed, 63 insertions, 11 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index dcdd9a855c6..637c15e0628 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2008-02-06 Jason Rumney <jasonr@gnu.org> | ||
| 2 | |||
| 3 | * w32font.c (w32font_text_extents): Fill in lbearing metric. | ||
| 4 | Use cached metrics for ASCII characters. | ||
| 5 | (w32font_open_internal): Don't set font's owning_frame. Cache | ||
| 6 | metrics for ASCII characters. | ||
| 7 | |||
| 8 | * w32font.h (struct w32font_info): Add ascii_metrics. | ||
| 9 | Remove owning_frame. | ||
| 10 | |||
| 1 | 2008-02-06 Kenichi Handa <handa@ni.aist.go.jp> | 11 | 2008-02-06 Kenichi Handa <handa@ni.aist.go.jp> |
| 2 | 12 | ||
| 3 | * xdisp.c (x_produce_glyphs): Don't set it->ascent and it->descent | 13 | * xdisp.c (x_produce_glyphs): Don't set it->ascent and it->descent |
diff --git a/src/w32font.c b/src/w32font.c index ddb2f43eb57..5776c95d0a7 100644 --- a/src/w32font.c +++ b/src/w32font.c | |||
| @@ -297,13 +297,10 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 297 | WORD *wcode = alloca(nglyphs * sizeof (WORD)); | 297 | WORD *wcode = alloca(nglyphs * sizeof (WORD)); |
| 298 | SIZE size; | 298 | SIZE size; |
| 299 | 299 | ||
| 300 | #if 0 | 300 | /* TODO: Frames can come and go, and their fonts outlive them. So we |
| 301 | /* Frames can come and go, and their fonts outlive them. This is | 301 | can't cache the frame in the font structure. Use selected_frame |
| 302 | particularly troublesome with tooltip frames, and causes crashes. */ | 302 | until the API is updated to pass in a frame. */ |
| 303 | f = ((struct w32font_info *)font)->owning_frame; | ||
| 304 | #else | ||
| 305 | f = XFRAME (selected_frame); | 303 | f = XFRAME (selected_frame); |
| 306 | #endif | ||
| 307 | 304 | ||
| 308 | dc = get_frame_dc (f); | 305 | dc = get_frame_dc (f); |
| 309 | old_font = SelectObject (dc, ((W32FontStruct *)(font->font.font))->hfont); | 306 | old_font = SelectObject (dc, ((W32FontStruct *)(font->font.font))->hfont); |
| @@ -320,16 +317,36 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 320 | metrics->width = 0; | 317 | metrics->width = 0; |
| 321 | metrics->ascent = 0; | 318 | metrics->ascent = 0; |
| 322 | metrics->descent = 0; | 319 | metrics->descent = 0; |
| 320 | metrics->lbearing = 0; | ||
| 323 | 321 | ||
| 324 | for (i = 0; i < nglyphs; i++) | 322 | for (i = 0; i < nglyphs; i++) |
| 325 | { | 323 | { |
| 326 | if (GetGlyphOutlineW (dc, *(code + i), GGO_METRICS, &gm, 0, | 324 | if (*(code + i) < 128 && *(code + i) > 32) |
| 325 | { | ||
| 326 | /* Use cached metrics for ASCII. */ | ||
| 327 | struct font_metrics *char_metric | ||
| 328 | = &((struct w32font_info *)font)->ascii_metrics[*(code+i)-32]; | ||
| 329 | |||
| 330 | /* If we couldn't get metrics when caching, use fallback. */ | ||
| 331 | if (char_metric->width == 0) | ||
| 332 | break; | ||
| 333 | |||
| 334 | metrics->lbearing = max (metrics->lbearing, | ||
| 335 | char_metric->lbearing - metrics->width); | ||
| 336 | metrics->rbearing = max (metrics->rbearing, | ||
| 337 | metrics->width + char_metric->rbearing); | ||
| 338 | metrics->width += char_metric->width; | ||
| 339 | metrics->ascent = max (metrics->ascent, char_metric->ascent); | ||
| 340 | metrics->descent = max (metrics->descent, char_metric->descent); | ||
| 341 | } | ||
| 342 | else if (GetGlyphOutlineW (dc, *(code + i), GGO_METRICS, &gm, 0, | ||
| 327 | NULL, &transform) != GDI_ERROR) | 343 | NULL, &transform) != GDI_ERROR) |
| 328 | { | 344 | { |
| 329 | int new_val = metrics->width + gm.gmBlackBoxX | 345 | int new_val = metrics->width + gm.gmBlackBoxX |
| 330 | + gm.gmptGlyphOrigin.x; | 346 | + gm.gmptGlyphOrigin.x; |
| 331 | |||
| 332 | metrics->rbearing = max (metrics->rbearing, new_val); | 347 | metrics->rbearing = max (metrics->rbearing, new_val); |
| 348 | new_val = -gm.gmptGlyphOrigin.x - metrics->width; | ||
| 349 | metrics->lbearing = max (metrics->lbearing, new_val); | ||
| 333 | metrics->width += gm.gmCellIncX; | 350 | metrics->width += gm.gmCellIncX; |
| 334 | new_val = -gm.gmptGlyphOrigin.y; | 351 | new_val = -gm.gmptGlyphOrigin.y; |
| 335 | metrics->ascent = max (metrics->ascent, new_val); | 352 | metrics->ascent = max (metrics->ascent, new_val); |
| @@ -658,14 +675,39 @@ w32font_open_internal (f, font_entity, pixel_size, w32_font) | |||
| 658 | if (hfont == NULL) | 675 | if (hfont == NULL) |
| 659 | return 0; | 676 | return 0; |
| 660 | 677 | ||
| 661 | w32_font->owning_frame = f; | ||
| 662 | |||
| 663 | /* Get the metrics for this font. */ | 678 | /* Get the metrics for this font. */ |
| 664 | dc = get_frame_dc (f); | 679 | dc = get_frame_dc (f); |
| 665 | old_font = SelectObject (dc, hfont); | 680 | old_font = SelectObject (dc, hfont); |
| 666 | 681 | ||
| 667 | GetTextMetrics (dc, &w32_font->metrics); | 682 | GetTextMetrics (dc, &w32_font->metrics); |
| 668 | 683 | ||
| 684 | /* Cache ASCII metrics. */ | ||
| 685 | { | ||
| 686 | GLYPHMETRICS gm; | ||
| 687 | MAT2 transform; | ||
| 688 | int i; | ||
| 689 | |||
| 690 | bzero (&transform, sizeof (transform)); | ||
| 691 | transform.eM11.value = 1; | ||
| 692 | transform.eM22.value = 1; | ||
| 693 | |||
| 694 | for (i = 0; i < 96; i++) | ||
| 695 | { | ||
| 696 | struct font_metrics* char_metric = &w32_font->ascii_metrics[i]; | ||
| 697 | |||
| 698 | if (GetGlyphOutlineW (dc, i + 32, GGO_METRICS, &gm, 0, | ||
| 699 | NULL, &transform) != GDI_ERROR) | ||
| 700 | { | ||
| 701 | char_metric->lbearing = -gm.gmptGlyphOrigin.x; | ||
| 702 | char_metric->rbearing = gm.gmBlackBoxX + gm.gmptGlyphOrigin.x; | ||
| 703 | char_metric->width = gm.gmCellIncX; | ||
| 704 | char_metric->ascent = -gm.gmptGlyphOrigin.y; | ||
| 705 | char_metric->descent = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y; | ||
| 706 | } | ||
| 707 | else | ||
| 708 | char_metric->width = 0; | ||
| 709 | } | ||
| 710 | } | ||
| 669 | SelectObject (dc, old_font); | 711 | SelectObject (dc, old_font); |
| 670 | release_frame_dc (f, dc); | 712 | release_frame_dc (f, dc); |
| 671 | /* W32FontStruct - we should get rid of this, and use the w32font_info | 713 | /* W32FontStruct - we should get rid of this, and use the w32font_info |
diff --git a/src/w32font.h b/src/w32font.h index dd71405bf0a..ba8af67fa5a 100644 --- a/src/w32font.h +++ b/src/w32font.h | |||
| @@ -32,7 +32,7 @@ struct w32font_info | |||
| 32 | { | 32 | { |
| 33 | struct font font; | 33 | struct font font; |
| 34 | TEXTMETRIC metrics; | 34 | TEXTMETRIC metrics; |
| 35 | struct frame *owning_frame; | 35 | struct font_metrics ascii_metrics[96]; |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | Lisp_Object w32font_get_cache P_ ((FRAME_PTR fe)); | 38 | Lisp_Object w32font_get_cache P_ ((FRAME_PTR fe)); |