diff options
| author | Jason Rumney | 2008-02-24 15:08:06 +0000 |
|---|---|---|
| committer | Jason Rumney | 2008-02-24 15:08:06 +0000 |
| commit | 2a36efcfc245388b81913d2b192ee9ca74cb4a04 (patch) | |
| tree | ce477e4b8505e5e9ee056f651d7abe1b01506b7c | |
| parent | a2bc5bdd7db3f708b7489d91919336e775c3e6ca (diff) | |
| download | emacs-2a36efcfc245388b81913d2b192ee9ca74cb4a04.tar.gz emacs-2a36efcfc245388b81913d2b192ee9ca74cb4a04.zip | |
(w32font_text_extents): Avoid getting HDC and selecting
a font into it unless we have to.
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/w32font.c | 64 |
2 files changed, 45 insertions, 24 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 29a4e7ba636..afddcca381b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2008-02-24 Jason Rumney <jasonr@gnu.org> | ||
| 2 | |||
| 3 | * w32font.c (w32font_text_extents): Avoid getting HDC and selecting | ||
| 4 | a font into it unless we have to. | ||
| 5 | |||
| 1 | 2008-02-19 Stefan Monnier <monnier@iro.umontreal.ca> | 6 | 2008-02-19 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 7 | ||
| 3 | * intervals.h (INT_LISPLIKE): Remove. It may misfire. | 8 | * intervals.h (INT_LISPLIKE): Remove. It may misfire. |
diff --git a/src/w32font.c b/src/w32font.c index 5776c95d0a7..d0cbe508d4f 100644 --- a/src/w32font.c +++ b/src/w32font.c | |||
| @@ -290,8 +290,8 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 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)); |
| @@ -302,9 +302,6 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 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 | 304 | ||
| 305 | dc = get_frame_dc (f); | ||
| 306 | old_font = SelectObject (dc, ((W32FontStruct *)(font->font.font))->hfont); | ||
| 307 | |||
| 308 | if (metrics) | 305 | if (metrics) |
| 309 | { | 306 | { |
| 310 | GLYPHMETRICS gm; | 307 | GLYPHMETRICS gm; |
| @@ -339,33 +336,45 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 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 | } |
| @@ -382,6 +391,13 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 382 | } | 391 | } |
| 383 | } | 392 | } |
| 384 | 393 | ||
| 394 | if (dc == NULL) | ||
| 395 | { | ||
| 396 | dc = get_frame_dc (f); | ||
| 397 | old_font = SelectObject (dc, ((W32FontStruct *) | ||
| 398 | (font->font.font))->hfont); | ||
| 399 | } | ||
| 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; |