static cairo_status_t glyph_array_add_text(glyph_array_t *glyphs, cairo_t *cr, const char *s, double spacing) { cairo_scaled_font_t *scaled_font; cairo_status_t status; FT_Face face; unsigned long charcode; unsigned int index; cairo_text_extents_t extents; const char *p; FT_Vector kerning; double kern_x; int first = TRUE; scaled_font = cairo_get_scaled_font (cr); status = cairo_scaled_font_status (scaled_font); if (status) return status; face = cairo_ft_scaled_font_lock_face (scaled_font); if (face == NULL) return CAIRO_STATUS_FONT_TYPE_MISMATCH; p = s; while (*p) { charcode = *p; index = FT_Get_Char_Index (face, charcode); glyphs->glyph_list[glyphs->num_glyphs].index = index; if (first) { first = FALSE; glyphs->glyph_list[glyphs->num_glyphs].x = glyphs->x; glyphs->glyph_list[glyphs->num_glyphs].y = glyphs->y; } else { cairo_glyph_extents (cr, &glyphs->glyph_list[glyphs->num_glyphs - 1], 1, &extents); FT_Get_Kerning (face, glyphs->glyph_list[glyphs->num_glyphs - 1].index, glyphs->glyph_list[glyphs->num_glyphs].index, FT_KERNING_UNSCALED, &kerning); kern_x = DOUBLE_FROM_26_6(kerning.x); glyphs->glyph_list[glyphs->num_glyphs].x = glyphs->glyph_list[glyphs->num_glyphs - 1].x + extents.x_advance + kern_x + spacing; glyphs->glyph_list[glyphs->num_glyphs].y = glyphs->glyph_list[glyphs->num_glyphs - 1].y + extents.y_advance; } cairo_glyph_extents (cr, &glyphs->glyph_list[glyphs->num_glyphs], 1, &extents); glyphs->x = glyphs->glyph_list[glyphs->num_glyphs].x + extents.x_advance + spacing; glyphs->y = glyphs->glyph_list[glyphs->num_glyphs].y + extents.y_advance; p++; glyphs->num_glyphs++; } cairo_ft_scaled_font_unlock_face (scaled_font); return CAIRO_STATUS_SUCCESS; }
void ilG_gui_textlayout_getExtents(ilG_gui_textlayout *self, unsigned *rx, unsigned *ry, int *bx, int *by, int *ax, int *ay) { if (!self->have_size) { self->have_size = 1; cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0); cairo_t *cr = cairo_create(surface); il_return_on_fail(self->cairo_glyphs); cairo_set_font_face(cr, self->cairo_ft_face); cairo_set_font_size(cr, self->pt); cairo_glyph_extents(cr, self->cairo_glyphs, self->glyph_count, &self->extents); cairo_surface_destroy(surface); cairo_destroy(cr); } if (rx) { *rx = self->extents.width; } if (ry) { *ry = self->extents.height + 1; // TODO: ???? } if (bx) { *bx = self->extents.x_bearing; } if (by) { *by = self->extents.y_bearing; } if (ax) { *ax = self->extents.x_advance; } if (ay) { *ay = self->extents.y_advance; } }
int renderTruetypeSymbolCairo(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *s) { int unicode; cairo_glyph_t glyph; cairo_text_extents_t extents; cairo_matrix_t trans; double ox,oy; cairoCacheData *cache = MS_IMAGE_RENDERER_CACHE(img); cairo_renderer *r = CAIRO_RENDERER(img); faceCacheObj *face = getFontFace(cache,symbol->full_font_path); if(!face) return MS_FAILURE; cairo_save(r->cr); cairo_set_font_face(r->cr,face->face); cairo_set_font_size(r->cr,s->scale*96/72.0); msUTF8ToUniChar(symbol->character, &unicode); if (face->ftface->charmap && face->ftface->charmap->encoding == FT_ENCODING_MS_SYMBOL) unicode |= 0xf000; glyph.index = FT_Get_Char_Index(face->ftface, unicode); glyph.x=0; glyph.y=0; cairo_glyph_extents(r->cr,&glyph,1,&extents); ox=extents.x_bearing+extents.width/2.; oy=extents.y_bearing+extents.height/2.; cairo_matrix_init_rotate(&trans,-s->rotation); cairo_matrix_transform_point(&trans,&ox,&oy); /* cairo_translate(cr,-extents.width/2,-extents.height/2); */ cairo_translate(r->cr,x-ox,y-oy); cairo_rotate(r->cr, -s->rotation); cairo_glyph_path(r->cr,&glyph,1); if (s->outlinewidth) { msCairoSetSourceColor(r->cr, s->outlinecolor); cairo_set_line_width(r->cr, s->outlinewidth + 1); cairo_stroke_preserve(r->cr); } if(s->color) { msCairoSetSourceColor(r->cr, s->color); cairo_fill_preserve(r->cr); } cairo_new_path(r->cr); cairo_restore(r->cr); return MS_SUCCESS; }
static void text_extents (cairo_t *cr, const char *text, cairo_text_extents_t *extents) { cairo_glyph_t *glyphs; gint num_glyphs; text_to_glyphs (cr, text, &glyphs, &num_glyphs); cairo_glyph_extents (cr, glyphs, num_glyphs, extents); g_free (glyphs); }
static VALUE cr_glyph_extents (VALUE self, VALUE rb_glyphs) { cairo_text_extents_t extents; cairo_glyph_t *glyphs; int length; RB_CAIRO__GLYPHS_TO_ARRAY (rb_glyphs, glyphs, length); cairo_glyph_extents (_SELF, glyphs, length, &extents); cr_check_status (_SELF); return CRTEXTEXTENTS2RVAL (&extents); }
CAMLprim value ml_cairo_glyph_extents (value v_cr, value v_glyphs) { int num_glyphs; cairo_glyph_t *c_glyphs; cairo_text_extents_t c_extents; c_glyphs = ml_convert_cairo_glypth_in (v_glyphs, &num_glyphs); cairo_glyph_extents (cairo_t_val (v_cr), c_glyphs, num_glyphs, &c_extents); caml_stat_free (c_glyphs); check_cairo_status (v_cr); return Val_cairo_text_extents (&c_extents); }
static int cr_glyph_extents (lua_State *L) { cairo_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_CONTEXT); cairo_glyph_t *glyphs; int num_glyphs; cairo_text_extents_t extents; from_lua_glyph_array(L, &glyphs, &num_glyphs, 2); cairo_glyph_extents(*obj, glyphs, num_glyphs, &extents); if (glyphs) GLYPHS_FREE(glyphs); create_lua_text_extents(L, &extents); return 1; }
/* adapted from gnome-utils:font-viewer/font-view.c * * Copyright (C) 2002-2003 James Henstridge <*****@*****.**> * Copyright (C) 2010 Cosimo Cecchi <*****@*****.**> * * License: GPLv2+ */ static void draw_string (SushiFontWidget *self, cairo_t *cr, GtkBorder padding, const gchar *text, gint *pos_y) { cairo_font_extents_t font_extents; cairo_text_extents_t extents; cairo_glyph_t *glyphs; GtkTextDirection text_dir; gint pos_x; gint num_glyphs; gint i; text_dir = gtk_widget_get_direction (GTK_WIDGET (self)); text_to_glyphs (cr, text, &glyphs, &num_glyphs); cairo_font_extents (cr, &font_extents); cairo_glyph_extents (cr, glyphs, num_glyphs, &extents); if (pos_y != NULL) *pos_y += font_extents.ascent + font_extents.descent + extents.y_advance + LINE_SPACING / 2; if (text_dir == GTK_TEXT_DIR_LTR) pos_x = padding.left; else { pos_x = gtk_widget_get_allocated_width (GTK_WIDGET (self)) - extents.x_advance - padding.right; } for (i = 0; i < num_glyphs; i++) { glyphs[i].x += pos_x; glyphs[i].y += *pos_y; } cairo_move_to (cr, pos_x, *pos_y); cairo_show_glyphs (cr, glyphs, num_glyphs); g_free (glyphs); *pos_y += LINE_SPACING / 2; }
static cairo_status_t test_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *extents) { cairo_glyph_t cairo_glyph; cairo_glyph.index = glyph; cairo_glyph.x = 0; cairo_glyph.y = 0; cairo_set_font_face (cr, cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), &fallback_font_key)); cairo_show_glyphs (cr, &cairo_glyph, 1); cairo_glyph_extents (cr, &cairo_glyph, 1, extents); return CAIRO_STATUS_SUCCESS; }
static PyObject * pycairo_glyph_extents (PycairoContext *o, PyObject *args) { int num_glyphs = -1; cairo_glyph_t *glyphs; cairo_text_extents_t extents; PyObject *py_object; if (!PyArg_ParseTuple (args, "O|i:Context.glyph_extents", &py_object, &num_glyphs)) return NULL; glyphs = _PyGlyphs_AsGlyphs (py_object, &num_glyphs); if (glyphs == NULL) return NULL; cairo_glyph_extents (o->ctx, glyphs, num_glyphs, &extents); PyMem_Free (glyphs); RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); return Py_BuildValue("(dddddd)", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { const cairo_test_context_t *ctx = cairo_test_get_context (cr); cairo_text_extents_t extents, nil_extents; cairo_font_extents_t font_extents, nil_font_extents; cairo_scaled_font_t *scaled_font; cairo_select_font_face (cr, "Bitstream Vera Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (cr, 16); cairo_move_to (cr, 10, 25); cairo_show_text (cr, NULL); cairo_show_text (cr, ""); cairo_show_glyphs (cr, NULL, 0); cairo_show_glyphs (cr, (void*)8, 0); cairo_move_to (cr, 10, 55); cairo_text_path (cr, NULL); cairo_text_path (cr, ""); cairo_glyph_path (cr, (void*)8, 0); cairo_fill (cr); memset (&nil_extents, 0, sizeof (cairo_text_extents_t)); memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_text_extents (cr, "", &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_text_extents(\"\"); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_text_extents (cr, NULL, &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_text_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_glyph_extents (cr, (void*)8, 0, &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_glyph_extents(); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } scaled_font = cairo_get_scaled_font (cr); memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_scaled_font_text_extents (scaled_font, "", &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_scaled_font_text_extents(\"\"); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_scaled_font_text_extents (scaled_font, NULL, &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_scaled_font_text_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_scaled_font_glyph_extents (scaled_font, (void*)8, 0, &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_scaled_font_glyph_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } /* Lets also try font size 0 while here */ cairo_set_font_size (cr, 0); memset (&extents, 0xff, sizeof (cairo_text_extents_t)); cairo_text_extents (cr, "test", &extents); if (! text_extents_equal (&extents, &nil_extents)) { cairo_test_log (ctx, "Error: cairo_set_font_size(0); cairo_text_extents(\"test\"); extents (%g, %g, %g, %g, %g, %g)\n", extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); return CAIRO_TEST_FAILURE; } memset (&nil_font_extents, 0, sizeof (cairo_font_extents_t)); memset (&font_extents, 0xff, sizeof (cairo_font_extents_t)); cairo_font_extents (cr, &font_extents); if (! font_extents_equal (&font_extents, &nil_font_extents)) { cairo_test_log (ctx, "Error: cairo_set_font_size(0); cairo_font_extents(); extents (%g, %g, %g, %g, %g)\n", font_extents.ascent, font_extents.descent, font_extents.height, font_extents.max_x_advance, font_extents.max_y_advance); return CAIRO_TEST_FAILURE; } scaled_font = cairo_get_scaled_font (cr); memset (&font_extents, 0xff, sizeof (cairo_font_extents_t)); cairo_scaled_font_extents (scaled_font, &font_extents); if (! font_extents_equal (&font_extents, &nil_font_extents)) { cairo_test_log (ctx, "Error: cairo_set_font_size(0); cairo_scaled_font_extents(); extents (%g, %g, %g, %g, %g)\n", font_extents.ascent, font_extents.descent, font_extents.height, font_extents.max_x_advance, font_extents.max_y_advance); return CAIRO_TEST_FAILURE; } return CAIRO_TEST_SUCCESS; }
int renderGlyphsCairo(imageObj *img,double x, double y, labelStyleObj *style, char *text) { cairo_renderer *r = CAIRO_RENDERER(img); cairoCacheData *cache = MS_IMAGE_RENDERER_CACHE(img); faceCacheObj *face = getFontFace(cache,style->font); char *utfptr=text; int i,has_kerning,unicode; unsigned long previdx=0; int numglyphs = msGetNumGlyphs(text); cairo_glyph_t glyph; cairo_text_extents_t extents; double px=0,py=0; if(face == NULL) { return MS_FAILURE; } cairo_set_font_face(r->cr,face->face); cairo_set_font_size(r->cr,style->size*96/72.0); cairo_save(r->cr); cairo_translate(r->cr,MS_NINT(x),MS_NINT(y)); if(style->rotation != 0.0) cairo_rotate(r->cr, -style->rotation); has_kerning = FT_HAS_KERNING((face->ftface)); for(i=0;i<numglyphs;i++) { utfptr+=msUTF8ToUniChar(utfptr, &unicode); glyph.x=px; glyph.y=py; if(unicode=='\n') { py += ceil(style->size*CAIROLINESPACE); px = 0; previdx=0; continue; } glyph.index = FT_Get_Char_Index(face->ftface, unicode); if( has_kerning && previdx ) { FT_Vector delta; FT_Get_Kerning( face->ftface, previdx, glyph.index, FT_KERNING_DEFAULT, &delta ); px += delta.x / 64.; } cairo_glyph_extents(r->cr,&glyph,1,&extents); cairo_glyph_path(r->cr,&glyph,1); px += extents.x_advance; previdx=glyph.index; } if (style->outlinewidth > 0) { cairo_save(r->cr); msCairoSetSourceColor(r->cr, style->outlinecolor); cairo_set_line_width(r->cr, style->outlinewidth + 1); cairo_stroke_preserve(r->cr); cairo_restore(r->cr); } if(style->color) { msCairoSetSourceColor(r->cr, style->color); cairo_fill(r->cr); } cairo_new_path(r->cr); cairo_restore(r->cr); return MS_SUCCESS; }
int getTruetypeTextBBoxCairo(rendererVTableObj *renderer, char *font, double size, char *text, rectObj *rect, double **advances) { cairoCacheData *cache = MS_RENDERER_CACHE(renderer); faceCacheObj *face = getFontFace(cache,font); char *utfptr=text; int i,has_kerning,unicode; unsigned long previdx=0; int numglyphs = msGetNumGlyphs(text); cairo_glyph_t glyph; cairo_text_extents_t extents; double px=0,py=0; if(face == NULL) { return MS_FAILURE; } cairo_set_font_face(cache->dummycr,face->face); cairo_set_font_size(cache->dummycr,size*96/72.0); has_kerning = FT_HAS_KERNING((face->ftface)); if(advances != NULL) { *advances = (double*)malloc(numglyphs*sizeof(double)); } for(i=0;i<numglyphs;i++) { utfptr+=msUTF8ToUniChar(utfptr, &unicode); glyph.x=px; glyph.y=py; if(unicode=='\n') { py += ceil(size*CAIROLINESPACE); px = 0; previdx=0; continue; } glyph.index = FT_Get_Char_Index(face->ftface, unicode); if( has_kerning && previdx ) { FT_Vector delta; FT_Get_Kerning( face->ftface, previdx, glyph.index, FT_KERNING_DEFAULT, &delta ); px += delta.x / 64.; } cairo_glyph_extents(cache->dummycr,&glyph,1,&extents); if(i==0) { rect->minx = px+extents.x_bearing; rect->miny = py+extents.y_bearing; rect->maxx = px+extents.x_bearing+extents.width; rect->maxy = py+extents.y_bearing+extents.height; } else { rect->minx = MS_MIN(rect->minx,px+extents.x_bearing); rect->miny = MS_MIN(rect->miny,py+extents.y_bearing); rect->maxy = MS_MAX(rect->maxy,py+extents.y_bearing+extents.height); rect->maxx = MS_MAX(rect->maxx,px+extents.x_bearing+extents.width); } if(advances!=NULL) (*advances)[i]=extents.x_advance; px += extents.x_advance; previdx=glyph.index; } /* rect->minx = 0; rect->miny = 0; rect->maxx = 1; rect->maxy = 1; */ return MS_SUCCESS; }
int getTruetypeTextBBoxCairo(rendererVTableObj *renderer, char **fonts, int numfonts, double size, char *text, rectObj *rect, double **advances, int bAdjustBaseline) { cairoCacheData *cache = MS_RENDERER_CACHE(renderer); faceCacheObj* face = getFontFace(cache,fonts[0]); int curfontidx = 0; char *utfptr=text; int i,unicode; unsigned long previdx=0; faceCacheObj* prevface = face; int numglyphs = msGetNumGlyphs(text); cairo_glyph_t glyph; cairo_text_extents_t extents; double px=0,py=0; if(face == NULL) { return MS_FAILURE; } cairo_set_font_face(cache->dummycr,face->face); cairo_set_font_size(cache->dummycr,size*96/72.0); if(advances != NULL) { *advances = (double*)malloc(numglyphs*sizeof(double)); } for(i=0; i<numglyphs; i++) { utfptr+=msUTF8ToUniChar(utfptr, &unicode); glyph.x=px; glyph.y=py; if(unicode=='\n') { py += ceil(size*CAIROLINESPACE); px = 0; previdx=0; continue; } if (curfontidx != 0) { face = getFontFace(cache, fonts[0]); cairo_set_font_face(cache->dummycr, face->face); curfontidx = 0; } if (face->ftface->charmap && face->ftface->charmap->encoding == FT_ENCODING_MS_SYMBOL) unicode |= 0xf000; glyph.index = FT_Get_Char_Index(face->ftface, unicode); if (glyph.index == 0) { int j; for (j = 1; j < numfonts; j++) { curfontidx = j; face = getFontFace(cache, fonts[j]); glyph.index = FT_Get_Char_Index(face->ftface, unicode); if (glyph.index != 0) { cairo_set_font_face(cache->dummycr, face->face); break; } } } if( FT_HAS_KERNING((prevface->ftface)) && previdx ) { FT_Vector delta; FT_Get_Kerning( prevface->ftface, previdx, glyph.index, FT_KERNING_DEFAULT, &delta ); px += delta.x / 64.; } cairo_glyph_extents(cache->dummycr,&glyph,1,&extents); if(i==0) { rect->minx = px+extents.x_bearing; rect->miny = py+extents.y_bearing; rect->maxx = px+extents.x_bearing+extents.width; rect->maxy = py+(bAdjustBaseline?1:(extents.y_bearing+extents.height)); } else { rect->minx = MS_MIN(rect->minx,px+extents.x_bearing); rect->miny = MS_MIN(rect->miny,py+extents.y_bearing); rect->maxy = MS_MAX(rect->maxy,py+(bAdjustBaseline?1:(extents.y_bearing+extents.height))); rect->maxx = MS_MAX(rect->maxx,px+extents.x_bearing+extents.width); } if(advances!=NULL) (*advances)[i]=extents.x_advance; px += extents.x_advance; previdx=glyph.index; prevface = face; } return MS_SUCCESS; }