| 388 | #define CAIROLINESPACE 1.33 |
| 389 | |
| 390 | int getTruetypeTextBBoxCairo(rendererVTableObj *renderer, char *font, double size, char *text, rectObj *rect, double **advances) { |
| 391 | |
| 392 | |
| 393 | cairoCacheData *cache = MS_RENDERER_CACHE(renderer); |
| 394 | faceCacheObj *face = getFontFace(cache,font); |
| 395 | |
| 396 | char *utfptr=text; |
| 397 | int i,has_kerning,unicode; |
| 398 | unsigned long previdx=0; |
| 399 | int numglyphs = msGetNumGlyphs(text); |
| 400 | cairo_glyph_t glyph; |
| 401 | cairo_text_extents_t extents; |
| 402 | double px=0,py=0; |
| 403 | |
| 404 | if(face == NULL) { |
| 405 | return MS_FAILURE; |
| 406 | } |
| 407 | |
| 408 | cairo_set_font_face(cache->dummycr,face->face); |
| 409 | cairo_set_font_size(cache->dummycr,size*96/72.0); |
| 410 | |
| 411 | has_kerning = FT_HAS_KERNING((face->ftface)); |
| 412 | |
| 413 | if(advances != NULL) { |
| 414 | *advances = (double*)malloc(numglyphs*sizeof(double)); |
| 415 | } |
| 416 | |
| 417 | for(i=0;i<numglyphs;i++) { |
| 418 | utfptr+=msUTF8ToUniChar(utfptr, &unicode); |
| 419 | glyph.x=px; |
| 420 | glyph.y=py; |
| 421 | if(unicode=='\n') { |
| 422 | py += ceil(size*CAIROLINESPACE); |
| 423 | px = 0; |
| 424 | previdx=0; |
| 425 | continue; |
| 426 | } |
| 427 | glyph.index = FT_Get_Char_Index(face->ftface, unicode); |
| 428 | if( has_kerning && previdx ) { |
| 429 | FT_Vector delta; |
| 430 | FT_Get_Kerning( face->ftface, previdx, glyph.index, FT_KERNING_DEFAULT, &delta ); |
| 431 | px += delta.x / 64.; |
| 432 | } |
| 433 | cairo_glyph_extents(cache->dummycr,&glyph,1,&extents); |
| 434 | |
| 435 | if(i==0) { |
| 436 | rect->minx = px+extents.x_bearing; |
| 437 | rect->miny = py+extents.y_bearing; |
| 438 | rect->maxx = px+extents.x_bearing+extents.width; |
| 439 | rect->maxy = py+extents.y_bearing+extents.height; |
| 440 | } else { |
| 441 | rect->minx = MS_MIN(rect->minx,px+extents.x_bearing); |
| 442 | rect->miny = MS_MIN(rect->miny,py+extents.y_bearing); |
| 443 | rect->maxy = MS_MAX(rect->maxy,py+extents.y_bearing+extents.height); |
| 444 | rect->maxx = MS_MAX(rect->maxx,px+extents.x_bearing+extents.width); |
| 445 | } |
| 446 | if(advances!=NULL) |
| 447 | (*advances)[i]=extents.x_advance; |
nothing calls this directly
no test coverage detected