• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 723
  • Last Modified:

GetTextExtentPoint32() is slow

I have an app that takes a user batch and generates a dialog.  In building the display  GetTextExtentPoint32() is called to determine if the next item (button/text/combo box/custom control)will fit on the current line.  In one particularly long batch this is getting called 4043 times.  I ran MSDevStudio profiler, and it indicates that this call is the main slowdown for the display generation.

Is there a way to speed this up, or is there a more efficient way to determine the horizontal extent of a string?

I have forced the function inline with little improvement.
Thank You
0
marvinm
Asked:
marvinm
  • 3
  • 2
  • 2
  • +2
1 Solution
 
pjknibbsCommented:
GetTextExtentPoint32() does an awful lot of calculation to find the length of a string--it includes kerning between characters and other such esoteric items. Forcing it inline won't make the slightest difference because the function code is actually contained in the GDI and therefore can't physically be made inline, and it's the body of the function which is taking the time, not the call to it.

Unfortunately, your only way round this is to sacrifice the accuracy of GetTextExtentPoint32() and use an approximation. I had an application which had to format 200 pages of text; in order to make it do this quickly I wrote my own extent function which just added together all the widths of the characters making up the string: it built the character width table using GetTextExtentPoint32(), obviously, but once it had got them it worked out about 20 times faster! The small loss of accuracy wasn't noticeable for the fonts (Times, Arial, Courier) I was using for the app.
0
 
pjknibbsCommented:
Oh, BTW, for a monospaced font like Courier you can just use the width of a single character and multiply by the number of characters in the string, but I'm assuming you're using a variable font like Arial or Times.
0
 
NickRepinCommented:
Could you explain why do you use GetTextExtentPoint32 ?

May be, DrawText or clipping will be faster.
0
Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

 
ZoppoCommented:
Hi marvinm,

you can use GetCharWidth32() to recieve the width of each char of the font in an array which can later be used to simply calculate the length by yourself. This is much faster then GetTextExtentPoint32()

ZOPPO
0
 
nietodCommented:
The "problem" with pjknib's and Zoppo's idea of doing the math yourself is that it doesn't take care of kerning calculations.  (Actually you could get the kerning information and use it, but then you probably woudl be running at the speed of GetTextExtentPoint32().)   If the string is reasonabley short and you can survive small innacuracies, this might not matter.  

However, it is possible that an alternative approach would be better.  What are you trying to do that you need to use GetTextExtent() so many times?
0
 
marvinmAuthor Commented:
The user created batch generates a display with checkboxes, text, buttons, combo boxes, and some other custom controls.  The display fits within our app.  When I generate the display, I need to know if the next item will fit on the curront line, or if I need to start a new line.  I use GetTextExtentPoint32() to determine the width of the next item to be placed and whether or not it fits on the current line.  I also use to break up large blocks of text so that as much as possible fits on the current line.
I think that the small innaccuracy involed in pjknibbs' and Zoppo's suggestion will not be a problem.  I will be working with today to see for sure.
0
 
nietodCommented:
Does your algorithm perform GetTextExtent() repeatedly in sutuations where it might not have to?  Like does it repeatedly measure the current line.  (like it might measure the line, add onto it, measure the new line again etc)  you might be able to avoid some occurances by storing some of the results from GetTextExtent()  (Allthough because of kerning, you theoretically can't add the length of two strings to get the length of the resultant string, but again that small difference might not matter.)
0
 
marvinmAuthor Commented:
It only calls it for the next item to add to the display.  I keep track of the current position and the window width.  So far it looks like getting the individual char widths once, and then adding up in place of GetTextExtentPoint32() will work fine and provide a substantial speed increase.
Thank You
0
 
marvinmAuthor Commented:
Thanks to all.
0

Featured Post

Restore individual SQL databases with ease

Veeam Explorer for Microsoft SQL Server delivers an easy-to-use, wizard-driven interface for restoring your databases from a backup. No expert SQL background required. Web interface provides a complete view of all available SQL databases to simplify the recovery of lost database

  • 3
  • 2
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now