Opened 20 years ago
Last modified 15 years ago
#1243 new defect
[Performance] gdImageStringFT called multiple time in msDrawTextGD.
Reported by: | jlacroix | Owned by: | jlacroix |
---|---|---|---|
Priority: | high | Milestone: | 6.0 release |
Component: | MapServer C Library | Version: | unspecified |
Severity: | normal | Keywords: | |
Cc: | woodbri@…, aboudreault, tbonfort, jmckenna |
Description (last modified by )
In bug 1224, I found out that in msDrawTextGD, gdImageStringFT is called 7 times in a row to make the outline of the text. In 4.0 there were only three call to this function. I suppose it's for a better outlining of labels. This cause a problem, a performance lost. It depends on the mapfiles, but in the GMap demo (around 14 labels), it results in a 15% performance lost. With 4.0, for 50 call to gmap75.map: total: 6.18 sec. in gdImageStringFT: 1.66 sec. With 4.0: total: 7.56 in gdImageStringFT: 2.51 sec. Is there a way to reduce the cost of outlining? To reduce the number of call?
Attachments (4)
Change History (28)
comment:2 by , 20 years ago
I'm all for finding a better way but I've not had any luck. I've been playing with this off and on for years. Ideally the outlining would be implemented very close to the GD/FT interface (i.e. GD should offer the effects: shadows and outlines, not MapServer. The additional calls are indeed for better outlining. With glyph caching it should not be that expensive. Anyway, I'm open to suggestions... Steve
comment:3 by , 20 years ago
What is the original reason of the change from 3 to 7 calls? I did not check, but is it possible to do less than 7 calls?
comment:4 by , 20 years ago
Status: | new → assigned |
---|
The reason for the change was to get better text outlines. It actually went from 4 to 8 calls I think. The outline is created by offsetting the text each of the 8 directions, used to be just 4. However, for some fonts that left gaps in the outline, most notably 'i' and 'l' with arial. It would probably by faster to render the text in the outline color once in a temporary image, then paste that image into the main image subsequent times. Could also try running a convolution filter on the temp image to achieve an effect. Let me play with it. May take a couple of days though. Steve
comment:5 by , 19 years ago
Milestone: | → 4.6 release |
---|
I think we should aim 4.6 with, at least to see if it's possible to gain speed with the temporary image. I may have time to check it this week. I will assign it to me if it's the case.
comment:6 by , 19 years ago
I have been thinking about this. The problem with a temporary image is that antialiasing falls apart. I think the solution lies either: - in modifications to GD or Freetype to allow for text effects upon initial rendering - perhaps trying to use a different font size to lay down the outline color I've experimented with the latter before, but with older versions of Freetype, and found that simply scaling of labels did not work well. Steve
comment:7 by , 19 years ago
Cc: | added |
---|
comment:8 by , 19 years ago
Using a different font size won't work unfortunately. I searched for "halo" and freetype, and found the following post at http://lists.gnu.org/archive/html/freetype/2004-04/msg00016.html This is probably what we need: we could do the dilation (and antialias) in MapServer on a pixmap that contains the rendered font, and possibly submit a patch to boutell.com to integrate this in future versions of GD. Re: [Freetype] Halo(?) font/effect From: Peter Montgomery Subject: Re: [Freetype] Halo(?) font/effect Date: Tue, 13 Apr 2004 23:50:45 -0700 Ian, > The effect (Called a 'halo font' by the end user - Not sure if that is the correct > term or not) results in a ring (typically white) of a pixel or two being drawn > all the way around each character, almost as if the character was drawn on top > of a larger version of itself. <SNIP> > So, I'm wondering if FreeType has any support for this feature, or if anyone > has suggestions about how to achieve this? The best approach I've found so far > is to extract the curves of each character, draw them as (white) lines with a > thick lineweight, then proceed to draw the (black) character on top as per usual. You could also come at this from an image processing perspective. Once you have a bitmap of your string, perform a dilation of the image and then merge that with the bitmap from Freetype. I did a google search on the following terms: image dilation code Here's a couple of hits that looked interesting: This one has some source code: http://www.theimagingsource.com/prod/soft/adoculos/adoculos_textbook_sc_sourcecode.htm This one shows some images of dilation, erosion, etc: http://rsb.info.nih.gov/ij/docs/menus/process.html This is an open source image processing library that looked interesting and contained various morphological functions such as dilation: http://www.cs.rug.nl/~cosmin/tip/ Thanks, PeterM
comment:9 by , 19 years ago
While trying to test the code above I found two useful thread on the Freetype mailing list: [ft] Thick contours http://lists.gnu.org/archive/html/freetype/2005-03/msg00005.html [Freetype] using a Stroker to make a glyph border pixmap http://lists.gnu.org/archive/html/freetype/2004-07/msg00008.html I will give a try to the stroker stuff.
comment:10 by , 19 years ago
Cc: | added |
---|---|
Owner: | changed from | to
Status: | assigned → new |
reassign to me to try the stroker stuff.
comment:11 by , 19 years ago
Status: | new → assigned |
---|
comment:12 by , 19 years ago
Note that MapServer used to use the offset 4 times method described in the first thread, but found that insufficient, hence the 8 times now. Steve
by , 19 years ago
Attachment: | outlines.png added |
---|
comparison between freetype outlines with stroker and current mapserver outline
comment:13 by , 19 years ago
That's good news. Can you post some examples? Also, some clarification on what exactly you are adding? There may be other uses... Are you changing MapServer (by just removing stuff) adding to GD, using new Freetype functions or what? I had problems getting to the URLs you referenced, on intermittent success. Steve
comment:14 by , 19 years ago
Sorry, there's no other real example other than what I attached to the bug. What would you want, maybe I can quickly build an example. Here what I changed: Mapserver: Remove the outlining code. Since the outlining is done by GD, we do not need this code. Freetype: I updated my freetype version to use the development version (snapshot available on their website) instead of the last stable release (freetype 2.1.9). The stroker code is stable only in the development version. It was fixed in august 2004, and there is no official release with the fixes. GD: I modified the gdImageStringFTEx function in GD 2.0.33. This function is used to draw the text in GD. At some point in this function, the glyph are loaded from freetype. It's there, before the drawing, that we need to include the stroker code. This code simply load the outline of the glyph and make it thick. In short, after the line: /* load and transform glyph image */ FT_Get_Glyph (slot, &image); You include: FT_Glyph borderimg; FT_Stroker stroker; FT_Glyph_Copy(image, &borderimg); FT_Stroker_New (face->memory, &stroker); FT_Stroker_Set (stroker, 80, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 1); FT_Glyph_Stroke (&borderimg, stroker, 1); if (borderimg->format != ft_glyph_format_bitmap) { err = FT_Glyph_To_Bitmap (&borderimg, ft_render_mode_normal, 0, 1); if (err) { gdCacheDelete (tc_cache); gdMutexUnlock (gdFontCacheMutex); return "Problem rendering glyph"; } } bm = (FT_BitmapGlyph) borderimg; gdft_draw_bitmap (tc_cache, im, 2, bm->bitmap, x + (penf.x * cos_a + penf.y * sin_a)*hdpi/(METRIC_RES*64) + bm->left, y - (penf.x * sin_a - penf.y * cos_a)*vdpi/(METRIC_RES*64) - bm->top); FT_Done_Glyph (borderimg); This code load the stroker (thick outline of the glyph) and draw it with the color we want. In this example, it is hardcoded to second color in color index (the third argument in gdft_draw_bitmap). At the end, we draw the label 2 times.
comment:15 by , 19 years ago
It's not as good an outline as MapServer currently, but it ain't bad at all. I would support the changes once GD and Freetype have releases with this, but until then we can't yank outlining (nobody is complaining now). This can't happen by the 4.6 release, unless there's some conditional compilation added. Have you contacted John Ellson who handles the Freetype support for GD? Great fix though. I wonder what other effects this brings into play? Steve
comment:16 by , 19 years ago
Cc: | added |
---|---|
Milestone: | 4.6 release → FUTURE |
I agree that we should wait until Freetype and GD have been released with the required functions. I tried to find infos about the planned date for the release of Freetype 2.1.10 and found the following post saying that it was planned for end of December 2004: http://lists.kde.org/?l=freetype-devel&m=110349526107608&w=2 But then they had some server problems in January which may have caused some delays... the new lists are at http://savannah.nongnu.org/mail/?group=freetype but I am unable to connect to the list server to subscribe and ask for an ETA, so I give up.. they will release at some point I'm sure. We'll also need to submit a patch to GD. I looked at this with Julien and it should be possible to send a patch that integrates in the exsiting gdImageStringFTEx() by passing the outline args via the gdFTStringExtra struct. Julien will attach a patch to this bug and then we'll try to submit it to GD. Frank, Steve, did you guys not have a support agreement with Boutell.com? Would it be easier to submit the patch through you?
comment:18 by , 19 years ago
Status: | assigned → new |
---|
I atached the patch to use this technology. Feel free to test/use it. It require at least gd-2.0.33 freetype from september 2004 mapserver 4.5 The patch was built for GD on gd 2.0.33 and for mapserver with the 4.5 version as of 2005-05-06
comment:19 by , 16 years ago
Pierre, a libgd maintainer, has confirmed that a similar patch will be in GD 2.1.0. He has already investigated in that patch.
comment:20 by , 16 years ago
Cc: | added |
---|
comment:21 by , 16 years ago
Cc: | added |
---|---|
Description: | modified (diff) |
For "historical" reasons, the AGG code uses the same behavior for 1-pixel outlines. This should probably be changed too for consistency and performance.
comment:22 by , 16 years ago
AGG change committed in r8766. I'm seeing a couple of percent performance increase for heavily labelled maps.
comment:23 by , 16 years ago
Milestone: | FUTURE → 6.0 release |
---|
comment:24 by , 15 years ago
Cc: | added |
---|
Note:
See TracTickets
for help on using tickets.