helper functions */
| 733 | |
| 734 | /* helper functions */ |
| 735 | int agg2GetTruetypeTextBBox(rendererVTableObj *renderer, char *font, double size, char *string, |
| 736 | rectObj *rect, double **advances) { |
| 737 | |
| 738 | aggRendererCache *cache = (aggRendererCache*)MS_RENDERER_CACHE(renderer); |
| 739 | if (!cache->m_feng.load_font(font, 0, mapserver::glyph_ren_outline)) { |
| 740 | msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2GetTruetypeTextBBox()", font); |
| 741 | return MS_FAILURE; |
| 742 | } |
| 743 | cache->m_feng.hinting(true); |
| 744 | cache->m_feng.height(size); |
| 745 | cache->m_feng.resolution(96); |
| 746 | cache->m_feng.flip_y(true); |
| 747 | int unicode, curGlyph = 1, numglyphs = 0; |
| 748 | if (advances) { |
| 749 | numglyphs = msGetNumGlyphs(string); |
| 750 | } |
| 751 | const mapserver::glyph_cache* glyph; |
| 752 | string += msUTF8ToUniChar(string, &unicode); |
| 753 | glyph = cache->m_fman.glyph(unicode); |
| 754 | if (glyph) { |
| 755 | rect->minx = glyph->bounds.x1; |
| 756 | rect->maxx = glyph->bounds.x2; |
| 757 | rect->miny = glyph->bounds.y1; |
| 758 | rect->maxy = glyph->bounds.y2; |
| 759 | } else |
| 760 | return MS_FAILURE; |
| 761 | if (advances) { |
| 762 | *advances = (double*) malloc(numglyphs * sizeof (double)); |
| 763 | MS_CHECK_ALLOC(*advances, numglyphs * sizeof (double), MS_FAILURE); |
| 764 | (*advances)[0] = glyph->advance_x; |
| 765 | } |
| 766 | double fx = glyph->advance_x, fy = glyph->advance_y; |
| 767 | while (*string) { |
| 768 | if (advances) { |
| 769 | if (*string == '\r' || *string == '\n') |
| 770 | (*advances)[curGlyph++] = -fx; |
| 771 | } |
| 772 | if (*string == '\r') { |
| 773 | fx = 0; |
| 774 | string++; |
| 775 | continue; |
| 776 | } |
| 777 | if (*string == '\n') { |
| 778 | fx = 0; |
| 779 | fy += ceil(size * AGG_LINESPACE); |
| 780 | string++; |
| 781 | continue; |
| 782 | } |
| 783 | string += msUTF8ToUniChar(string, &unicode); |
| 784 | glyph = cache->m_fman.glyph(unicode); |
| 785 | if (glyph) { |
| 786 | rect->minx = MS_MIN(rect->minx, fx+glyph->bounds.x1); |
| 787 | rect->miny = MS_MIN(rect->miny, fy+glyph->bounds.y1); |
| 788 | rect->maxx = MS_MAX(rect->maxx, fx+glyph->bounds.x2); |
| 789 | rect->maxy = MS_MAX(rect->maxy, fy+glyph->bounds.y2); |
| 790 | |
| 791 | fx += glyph->advance_x; |
| 792 | fy += glyph->advance_y; |
nothing calls this directly
no test coverage detected