static void dump_font_sizes (PangoContext *context, FILE *f, guint flags) { PangoFont *font; PangoFontDescription *pfd; int nf; real height; fprintf (f, "height/cm"); for (nf = 0; test_families[nf] != NULL; ++nf) fprintf (f, "\t%s", test_families[nf]); fprintf (f, "\n"); for (height = 0.1; height <= 10.0; height += 0.1) { fprintf (f, "%g", height); for (nf = 0; test_families[nf] != NULL; ++nf) { pfd = pango_font_description_new (); pango_font_description_set_family (pfd, test_families[nf]); //pango_font_description_set_size (pfd, height * pixels_per_cm * PANGO_SCALE); if (flags & DUMP_ABSOLUTE) pango_font_description_set_absolute_size (pfd, height * pixels_per_cm * PANGO_SCALE); else pango_font_description_set_size (pfd, height * pixels_per_cm * PANGO_SCALE); font = pango_context_load_font (context, pfd); if (font) { PangoFontMetrics *metrics = pango_font_get_metrics (font, NULL); /* now make a font-size where the font/line-height matches the given pixel size */ real total = ((double)pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics)) / PANGO_SCALE; real factor = height*pixels_per_cm/total; real line_height; if (flags & DUMP_ABSOLUTE) pango_font_description_set_absolute_size (pfd, factor * height * pixels_per_cm * PANGO_SCALE); else pango_font_description_set_size (pfd, factor * height * pixels_per_cm * PANGO_SCALE); pango_font_metrics_unref (metrics); g_object_unref (font); font = pango_context_load_font (context, pfd); metrics = pango_font_get_metrics (font, NULL); line_height = ((double)pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics)) / PANGO_SCALE; fprintf (f, "\t%.3g", flags & DUMP_FACTORS ? factor : line_height); g_object_unref (font); } pango_font_description_free (pfd); } fprintf (f, "\n"); } }
static struct font_engine_font_t *do_font_load(const char *name) { struct font_engine_font_t *fef = NULL; PangoFontDescription *desc; if( (name) && (desc = pango_font_description_from_string(name)) ) { fef = calloc_2(1, sizeof(struct font_engine_font_t)); fef->desc = desc; fef->font = pango_font_map_load_font( pango_cairo_font_map_get_default(), GLOBALS->fonts_context, fef->desc); fef->metrics=pango_font_get_metrics(fef->font, NULL /*pango_language_get_default()*/ ); fef->ascent = pango_font_metrics_get_ascent(fef->metrics) / 1000; fef->descent = pango_font_metrics_get_descent(fef->metrics) / 1000; fef->is_pango = 1; if(!strncmp(name, "Monospace", 9)) { int i_width = font_engine_string_measure(fef, "i"); fef->mono_width = font_engine_string_measure(fef, "O"); fef->is_mono = (i_width == fef->mono_width); } } return(fef); }
static bool pango_load (Lisp_Font *f) { PangoLanguage *language; PangoFontDescription *fontdesc; PangoFont *font; PangoFontMetrics *metrics; if (pango_context) { language = pango_context_get_language (pango_context); } else { char *langname, *p; #ifdef HAVE_PANGO_XFT pango_context = pango_xft_get_context (dpy, screen_num); #endif langname = g_strdup (setlocale (LC_CTYPE, NULL)); p = strchr (langname, '.'); if (p) *p = 0; p = strchr (langname, '@'); if (p) *p = 0; language = pango_language_from_string (langname); pango_context_set_language (pango_context, language); g_free (langname); } fontdesc = pango_font_description_from_string (rep_STR (f->name)); if (!pango_font_description_get_family (fontdesc)) pango_font_description_set_family (fontdesc, "Sans"); if (pango_font_description_get_size (fontdesc) <= 0) pango_font_description_set_size (fontdesc, 12 * PANGO_SCALE); pango_context_set_font_description (pango_context, fontdesc); font = pango_context_load_font (pango_context, fontdesc); if (!font) { pango_font_description_free(fontdesc); return FALSE; } metrics = pango_font_get_metrics (font, language); f->ascent = metrics->ascent / PANGO_SCALE; f->descent = metrics->descent / PANGO_SCALE; pango_font_metrics_unref (metrics); f->font = fontdesc; /* We save the font description, not the font itself! That's because it seems we can't recover it perfectly later, and the layout routines want a description */ return TRUE; }
void gtk_glwidget_create_font (GtkWidget *widget) { PangoFontDescription *font_desc; PangoFont *font; PangoFontMetrics *font_metrics; font_list_base = qglGenLists (256); font_desc = pango_font_description_from_string (font_string); font = gdk_gl_font_use_pango_font (font_desc, 0, 256, font_list_base); if(font != NULL) { font_metrics = pango_font_get_metrics (font, NULL); font_height = pango_font_metrics_get_ascent (font_metrics) + pango_font_metrics_get_descent (font_metrics); font_height = PANGO_PIXELS (font_height); pango_font_metrics_unref (font_metrics); } pango_font_description_free (font_desc); }
WFontMetrics FontSupport::fontMetrics(const WFont& font) { PANGO_LOCK; enabledFontFormats = enabledFontFormats_; PangoFont *pangoFont = matchFont(font).pangoFont(); PangoFontMetrics *metrics = pango_font_get_metrics(pangoFont, nullptr); double ascent = pangoUnitsToDouble(pango_font_metrics_get_ascent(metrics)); double descent = pangoUnitsToDouble(pango_font_metrics_get_descent(metrics)); double leading = (ascent + descent) - font.sizeLength(12).toPixels(); // ascent < leading is an odd thing. it happens with a font like // Cursive. if (ascent > leading) ascent -= leading; else leading = 0; WFontMetrics result(font, leading, ascent, descent); pango_font_metrics_unref(metrics); return result; }
/*---------------------------------------------------------------------------------------------- Get Font Ascent and Descent in one go more efficent that making two calls. ----------------------------------------------------------------------------------------------*/ bool VwGraphicsCairo::FontAscentAndDescent(int * ascent, int * descent) { // cache the PangoFont and PangoFontMetricsfont to the m_pangoFontDescription if (m_ascent == -1 && m_descent == -1) { if (m_fontMapForFontContext == NULL) m_fontMapForFontContext = pango_cairo_font_map_get_default(); if (m_fontContext == NULL) m_fontContext = pango_font_map_create_context (m_fontMapForFontContext); PangoFont * font = pango_context_load_font(m_fontContext, m_pangoFontDescription); // TODO-Linux: should we specify a language - for the font? PangoFontMetrics * metrics = pango_font_get_metrics (font, NULL); m_ascent = pango_font_metrics_get_ascent (metrics) / PANGO_SCALE; m_descent = pango_font_metrics_get_descent (metrics) / PANGO_SCALE; pango_font_metrics_unref(metrics); g_object_unref(font); } if (ascent != NULL) *ascent = m_ascent; if (descent != NULL) *descent = m_descent; return true; }
PP_Bool ppb_browser_font_trusted_draw_text_at(PP_Resource font, PP_Resource image_data, const struct PP_BrowserFont_Trusted_TextRun *text, const struct PP_Point *position, uint32_t color, const struct PP_Rect *clip, PP_Bool image_data_is_opaque) { (void)image_data_is_opaque; // TODO: is it worth implementing? struct pp_browser_font_s *bf = pp_resource_acquire(font, PP_RESOURCE_BROWSER_FONT); if (!bf) return PP_FALSE; struct pp_image_data_s *id = pp_resource_acquire(image_data, PP_RESOURCE_IMAGE_DATA); if (!id) { pp_resource_release(font); return PP_FALSE; } cairo_t *cr = cairo_create(id->cairo_surf); if (clip) { cairo_rectangle(cr, clip->point.x, clip->point.y, clip->size.width, clip->size.height); cairo_clip(cr); } PangoFontMetrics *m = pango_font_get_metrics(bf->font, NULL); int32_t ascent = pango_font_metrics_get_ascent(m) / PANGO_SCALE; cairo_surface_mark_dirty(id->cairo_surf); if (position) cairo_move_to(cr, position->x, position->y - ascent); else cairo_move_to(cr, 0, 0); pango_font_metrics_unref(m); cairo_set_source_rgba(cr, ((color >> 16) & 0xffu) / 255.0, ((color >> 8) & 0xffu) / 255.0, ((color >> 0) & 0xffu) / 255.0, ((color >> 24) & 0xffu) / 255.0); PangoLayout *layout = pango_cairo_create_layout(cr); uint32_t len = 0; const char *s = ""; if (text->text.type == PP_VARTYPE_STRING) s = ppb_var_var_to_utf8(text->text, &len); // TODO: factor into rtl direction pango_layout_set_font_description(layout, bf->font_desc); pango_layout_set_text(layout, s, len); pango_cairo_layout_path(cr, layout); cairo_fill(cr); g_object_unref(layout); cairo_surface_flush(id->cairo_surf); cairo_destroy(cr); pp_resource_release(font); pp_resource_release(image_data); return PP_FALSE; }
static VALUE rg_metrics(int argc, VALUE *argv, VALUE self) { VALUE language; PangoLanguage* lang = NULL; rb_scan_args(argc, argv, "01", &language); if (!NIL_P(language)) lang = RVAL2PANGOLANGUAGE(language); return PANGOFONTMETRICS2RVAL(pango_font_get_metrics(_SELF(self), lang)); }
void ZLGtkPaintContext::setFont(const std::string &family, int size, bool bold, bool italic) { bool fontChanged = false; if (myFontDescription == 0) { myFontDescription = pango_font_description_new(); fontChanged = true; } const char *oldFamily = pango_font_description_get_family(myFontDescription); if ((oldFamily == 0) || (family != oldFamily)) { pango_font_description_set_family(myFontDescription, family.c_str()); fontChanged = true; } int newSize = size * PANGO_SCALE; if (pango_font_description_get_size(myFontDescription) != newSize) { pango_font_description_set_size(myFontDescription, newSize); fontChanged = true; } PangoWeight newWeight = bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL; if (pango_font_description_get_weight(myFontDescription) != newWeight) { pango_font_description_set_weight(myFontDescription, newWeight); fontChanged = true; } PangoStyle newStyle = italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL; if (pango_font_description_get_style(myFontDescription) != newStyle) { pango_font_description_set_style(myFontDescription, newStyle); fontChanged = true; } if (fontChanged) { if (myContext != 0) { myAnalysis.font = pango_context_load_font(myContext, myFontDescription); myAnalysis.shape_engine = pango_font_find_shaper(myAnalysis.font, 0, 0); PangoFontMetrics *metrics = pango_font_get_metrics(myAnalysis.font, myAnalysis.language); myDescent = pango_font_metrics_get_descent(metrics) / PANGO_SCALE; } myStringHeight = -1; mySpaceWidth = -1; } }
/*! * In Dia a font is usually referred to by it's (line-) height, not it's size. * * This methods "calculates" the latter from the former. This used to be some magic factor of 0.7 which did not * solve the resolution dependencance of the former calculation. In fact there is new magic factor now because * really calculating the font size from the height would involve two font loads which seem to be two expensive. */ static void _dia_font_adjust_size (DiaFont *font, real height, gboolean recalc_alwways) { if (font->height != height || !font->metrics || recalc_alwways) { PangoFont *loaded; dia_pfd_set_height (font->pfd, height); /* need to load a font to get it's metrics */ loaded = font->loaded; font->loaded = pango_context_load_font(dia_font_get_context(), font->pfd); if (loaded) /* drop old reference */ g_object_unref (loaded); if (font->metrics) pango_font_metrics_unref (font->metrics); /* caching metrics */ font->metrics = pango_font_get_metrics (font->loaded, NULL); font->height = height; } }
PP_Bool ppb_browser_font_trusted_describe(PP_Resource font, struct PP_BrowserFont_Trusted_Description *description, struct PP_BrowserFont_Trusted_Metrics *metrics) { struct pp_browser_font_s *bf = pp_resource_acquire(font, PP_RESOURCE_BROWSER_FONT); if (!bf) return PP_FALSE; memset(description, 0, sizeof(*description)); memset(metrics, 0, sizeof(*metrics)); const char *s_family = pango_font_description_get_family(bf->font_desc); description->face = PP_MakeString(s_family); description->family = bf->family >= 0 ? bf->family : 0; description->size = pango_font_description_get_size(bf->font_desc) / PANGO_SCALE; description->weight = pango_font_description_get_weight(bf->font_desc)/100 - 1; description->italic = (pango_font_description_get_style(bf->font_desc) != PANGO_STYLE_NORMAL); description->small_caps = (pango_font_description_get_variant(bf->font_desc) == PANGO_VARIANT_SMALL_CAPS); description->letter_spacing = bf->letter_spacing; description->word_spacing = bf->word_spacing; PangoFontMetrics *m = pango_font_get_metrics(bf->font, NULL); // TODO: use fontconfig-specific structures in pango to determine height and x-height metrics->ascent = pango_font_metrics_get_ascent(m) / PANGO_SCALE; metrics->descent = pango_font_metrics_get_descent(m) / PANGO_SCALE; metrics->height = (pango_font_metrics_get_ascent(m) + pango_font_metrics_get_descent(m)) / PANGO_SCALE; metrics->line_spacing = 1; // TODO: get actual line spacing metrics->x_height = metrics->height; // TODO: find out actual x-height pango_font_metrics_unref(m); pp_resource_release(font); return PP_TRUE; }
void ZLGtkPaintContext::updatePixmap(GtkWidget *area, int w, int h) { if ((myPixmap != 0) && ((myWidth != w) || (myHeight != h))) { if (myTextGC != 0) { gdk_gc_unref(myTextGC); gdk_gc_unref(myFillGC); gdk_gc_unref(myBackGC); myTextGC = 0; myFillGC = 0; myBackGC = 0; } gdk_pixmap_unref(myPixmap); myPixmap = 0; } if (myPixmap == 0) { myWidth = w; myHeight = h; myPixmap = gdk_pixmap_new(area->window, myWidth, myHeight, gdk_drawable_get_depth(area->window)); } if (myTextGC == 0) { myTextGC = gdk_gc_new(myPixmap); myFillGC = gdk_gc_new(myPixmap); myBackGC = gdk_gc_new(myPixmap); } if (myContext == 0) { myContext = gtk_widget_get_pango_context(area); if (myFontDescription != 0) { myAnalysis.font = pango_context_load_font(myContext, myFontDescription); myAnalysis.shape_engine = pango_font_find_shaper(myAnalysis.font, 0, 0); PangoFontMetrics *metrics = pango_font_get_metrics(myAnalysis.font, myAnalysis.language); myDescent = pango_font_metrics_get_descent(metrics) / PANGO_SCALE; } } }
int main(int argc, const char* argv[]) { size_t tex_side =(argc>1)? std::atoi(argv[1]) : 512; const char* font_desc_str = (argc>2)? argv[2] : "Sans 18"; unsigned plane = (argc>3)? std::atoi(argv[3]) : 0; cairo_surface_t *surface = cairo_image_surface_create( CAIRO_FORMAT_A8, tex_side, tex_side ); cairo_t *cr = cairo_create(surface); PangoFontDescription *font_desc = pango_font_description_from_string( font_desc_str ); PangoFontMap* font_map = pango_cairo_font_map_get_default(); PangoContext* context = pango_font_map_create_context(font_map); PangoFont* font = pango_font_map_load_font( font_map, context, font_desc ); PangoFontMetrics* font_metrics = pango_font_get_metrics(font, nullptr); // The Bitmap Glyph Metrics file std::ofstream bgm((argc>5) ? argv[5] : "out.bgm"); unsigned step = tex_side / 16; for(unsigned y=0; y!=16; ++y) { for(unsigned x=0; x!=16; ++x) { render_glyph( cr, font_desc, font, 256*plane + y*16 + x, x, y, step, tex_side, pango_font_metrics_get_ascent(font_metrics), pango_font_metrics_get_descent(font_metrics), bgm ); } } bgm.close(); pango_font_metrics_unref(font_metrics); pango_font_description_free(font_desc); g_object_unref(context); cairo_destroy(cr); cairo_status_t status = cairo_surface_write_to_png( surface, (argc>4) ? argv[4] : "out.png" ); cairo_surface_destroy(surface); return 0; }
static void CreateErrorWindow(void) { GtkWidget *hbox5; GtkWidget *view; GtkWidget *vscrollbar2; GdkPixbuf *Warning_icon_pixbuf; PangoContext *context; PangoFont *font; PangoFontMetrics *fm; int as, ds; GtkRequisition desired; errdata.gw = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_name (errdata.gw, "Warnings"); gtk_widget_set_events (errdata.gw, GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_PROPERTY_CHANGE_MASK); gtk_window_set_title (GTK_WINDOW (errdata.gw), _("Warnings")); Warning_icon_pixbuf = create_pixbuf ("fontview2.xbm"); if (Warning_icon_pixbuf) { gtk_window_set_icon (GTK_WINDOW (errdata.gw), Warning_icon_pixbuf); gdk_pixbuf_unref (Warning_icon_pixbuf); } hbox5 = gtk_hbox_new (FALSE, 0); gtk_widget_set_name (hbox5, "hbox5"); gtk_widget_show (hbox5); gtk_container_add (GTK_CONTAINER (errdata.gw), hbox5); view = gtk_drawing_area_new (); gtk_widget_set_name (view, "view"); gtk_widget_show (view); gtk_box_pack_start (GTK_BOX (hbox5), view, TRUE, TRUE, 0); gtk_widget_set_size_request (view, 16*24+1, 4*24+1); vscrollbar2 = gtk_vscrollbar_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 0, 0, 0, 0))); gtk_widget_set_name (vscrollbar2, "vscrollbar2"); gtk_widget_show (vscrollbar2); gtk_box_pack_start (GTK_BOX (hbox5), vscrollbar2, FALSE, TRUE, 0); g_signal_connect ((gpointer) errdata.gw, "delete_event", G_CALLBACK (Warning_Hide), NULL); g_signal_connect ((gpointer) vscrollbar2, "value_changed", G_CALLBACK (Warning_VScroll), NULL); g_signal_connect ((gpointer) view, "configure_event", G_CALLBACK (Warning_Resize), NULL); g_signal_connect ((gpointer) view, "expose_event", G_CALLBACK (Warning_Expose), NULL); errdata.v = view; errdata.vsb = vscrollbar2; errdata.layout = gtk_widget_create_pango_layout( view, NULL ); pango_layout_set_width(errdata.layout, -1); /* Don't wrap long lines */ context = gtk_widget_get_pango_context( view ); font = pango_context_load_font( context, pango_context_get_font_description(context)); fm = pango_font_get_metrics(font,NULL); as = pango_font_metrics_get_ascent(fm); ds = pango_font_metrics_get_descent(fm); errdata.as = as / PANGO_SCALE; errdata.fh = (as+ds) / PANGO_SCALE; gtk_widget_set_size_request(view, 40*errdata.fh, 5*errdata.fh ); gtk_widget_size_request(errdata.gw,&desired); /* This function is deprecated, but I can find no other way to position */ /* a window in the bottom right corner (or at all). So I use it */ gtk_widget_set_uposition(errdata.gw, gdk_screen_get_width(gdk_screen_get_default())-desired.width-5, gdk_screen_get_height(gdk_screen_get_default())-desired.height-errdata.fh-5); errdata.linecnt = 5; gtk_widget_show(errdata.gw); }
void ttext::recalculate(const bool force) const { if(calculation_dirty_ || force) { assert(layout_); calculation_dirty_ = false; surface_dirty_ = true; tfont font(get_font_families(font_class_), font_size_, font_style_); pango_layout_set_font_description(layout_, font.get()); if(font_style_ & ttext::STYLE_UNDERLINE) { PangoAttrList *attribute_list = pango_attr_list_new(); pango_attr_list_insert(attribute_list , pango_attr_underline_new(PANGO_UNDERLINE_SINGLE)); pango_layout_set_attributes (layout_, attribute_list); pango_attr_list_unref(attribute_list); } int maximum_width = 0; if(characters_per_line_ != 0) { PangoFont* f = pango_font_map_load_font( pango_cairo_font_map_get_default() , context_ , font.get()); PangoFontMetrics* m = pango_font_get_metrics(f, nullptr); int w = pango_font_metrics_get_approximate_char_width(m); w *= characters_per_line_; maximum_width = ceil(pango_units_to_double(w)); } else { maximum_width = maximum_width_; } if(maximum_width_ != -1) { maximum_width = std::min(maximum_width, maximum_width_); } /* * See set_maximum_width for some more background info as well. * In order to fix the problem first set a width which seems to render * correctly then lower it to fit. For the campaigns the 4 does "the * right thing" for the terrain labels it should use the value 0 to set * the ellipse properly. Need to see whether this is a bug in pango or * a bug in my understanding of the pango api. */ int hack = 4; do { pango_layout_set_width(layout_, maximum_width == -1 ? -1 : (maximum_width + hack) * PANGO_SCALE); pango_layout_get_pixel_extents(layout_, nullptr, &rect_); DBG_GUI_L << "ttext::" << __func__ << " text '" << gui2::debug_truncate(text_) << "' maximum_width " << maximum_width << " hack " << hack << " width " << rect_.x + rect_.width << ".\n"; --hack; } while(maximum_width != -1 && hack >= 0 && rect_.x + rect_.width > maximum_width); DBG_GUI_L << "ttext::" << __func__ << " text '" << gui2::debug_truncate(text_) << "' font_size " << font_size_ << " markedup_text " << markedup_text_ << " font_style " << std::hex << font_style_ << std::dec << " maximum_width " << maximum_width << " maximum_height " << maximum_height_ << " result " << rect_ << ".\n"; if(maximum_width != -1 && rect_.x + rect_.width > maximum_width) { DBG_GUI_L << "ttext::" << __func__ << " text '" << gui2::debug_truncate(text_) << " ' width " << rect_.x + rect_.width << " greater as the wanted maximum of " << maximum_width << ".\n"; } } }
void FontSupport::drawText(const WFont& font, const WRectF& rect, const WTransform& transform, Bitmap& bitmap, WFlags<AlignmentFlag> flags, const WString& text) { PANGO_LOCK; enabledFontFormats = enabledFontFormats_; PangoMatrix matrix; matrix.xx = transform.m11(); matrix.xy = transform.m21(); matrix.yx = transform.m12(); matrix.yy = transform.m22(); matrix.x0 = transform.dx(); matrix.y0 = transform.dy(); std::string utf8 = text.toUTF8(); std::vector<PangoGlyphString *> glyphs; int width; pango_context_set_matrix(context_, &matrix); /* * Oh my god, somebody explain me why we need to do this... */ WFont f = font; f.setSize(font.sizeLength().toPixels() / pango_matrix_get_font_scale_factor(&matrix)); GList *items = layoutText(f, utf8, glyphs, width); pango_context_set_matrix(context_, nullptr); AlignmentFlag hAlign = flags & AlignHorizontalMask; /* FIXME handle bidi ! */ double x; switch (hAlign) { case AlignmentFlag::Left: x = rect.left(); break; case AlignmentFlag::Right: x = rect.right() - pangoUnitsToDouble(width); break; case AlignmentFlag::Center: x = rect.center().x() - pangoUnitsToDouble(width/2); break; default: x = 0; } AlignmentFlag vAlign = flags & AlignVerticalMask; PangoFont *pangoFont = matchFont(font).pangoFont(); PangoFontMetrics *metrics = pango_font_get_metrics(pangoFont, nullptr); double ascent = pangoUnitsToDouble(pango_font_metrics_get_ascent(metrics)); double descent = pangoUnitsToDouble(pango_font_metrics_get_descent(metrics)); pango_font_metrics_unref(metrics); double baseline = ascent; double height = ascent + descent; double y; switch (vAlign) { case AlignmentFlag::Top: y = rect.top() + baseline; break; case AlignmentFlag::Middle: y = rect.center().y() - height / 2 + baseline; break; case AlignmentFlag::Bottom: y = rect.bottom() - height + baseline; break; default: y = 0; } FT_Bitmap bmp; bmp.buffer = bitmap.buffer(); bmp.width = bitmap.width(); bmp.rows = bitmap.height(); bmp.pitch = bitmap.pitch(); bmp.pixel_mode = FT_PIXEL_MODE_GRAY; bmp.num_grays = 16; // ??? GList *elem; unsigned i = 0; for (elem = items; elem; elem = elem->next) { PangoItem *item = (PangoItem *)elem->data; PangoAnalysis *analysis = &item->analysis; PangoGlyphString *gl = glyphs[i++]; pango_ft2_render_transformed(&bmp, &matrix, analysis->font, gl, pangoUnitsFromDouble(x), pangoUnitsFromDouble(y)); x += pangoUnitsToDouble(pango_glyph_string_get_width(gl)); pango_glyph_string_free(gl); pango_item_free(item); } g_list_free(items); }
void cb_glext2d_realize(GtkWidget *widget, gpointer user_data) { PangoFont *font; PangoFontMetrics *font_metrics; PangoFontDescription *font_desc; GdkGLContext *glcontext = gtk_widget_get_gl_context(widget); GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget); if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) { return; } glShadeModel(GL_FLAT); glDisable(GL_DITHER); // generate display list for our square base glNewList(GREY_2D_SQUARE_CALL_LIST, GL_COMPILE); glBegin(GL_QUAD_STRIP); glColor3ub(100, 100, 100); glVertex2f(-1, -1); glVertex2f(-1, 1); glVertex2f(1, -1); glVertex2f(1, 1); glEnd(); glEndList(); glNewList(WHITE_2D_SQUARE_CALL_LIST, GL_COMPILE); glBegin(GL_QUAD_STRIP); glColor3ub(255, 255, 255); glVertex2f(-1, -1); glVertex2f(-1, 1); glVertex2f(1, -1); glVertex2f(1, 1); glEnd(); glEndList(); // generate display lists for our font const char *font_string = gtk_entry_get_text(GTK_ENTRY(viz->prefs_label_font)); viz->font_list_2d = glGenLists(128); font_desc = pango_font_description_from_string(font_string); font = gdk_gl_font_use_pango_font(font_desc, 0, 128, viz->font_list_2d); if (font == NULL) { g_warning("cannot load font '%s', falling back to '%s'", font_string, DEFAULT_LABEL_FONT); font_desc = pango_font_description_from_string(DEFAULT_LABEL_FONT); font = gdk_gl_font_use_pango_font(font_desc, 0, 128, viz->font_list_3d); } // use pango to determine dimensions of font font_metrics = pango_font_get_metrics(font, NULL); viz->font_height_2d = pango_font_metrics_get_ascent(font_metrics) + pango_font_metrics_get_descent(font_metrics); viz->font_height_2d = PANGO_PIXELS(viz->font_height_2d); pango_font_description_free(font_desc); pango_font_metrics_unref(font_metrics); // define display lists for our as labels glNewList(LABELS_2D_AS_CALL_LIST, GL_COMPILE); // output our labels glColor3f(1.0, 1.0, 1.0); // 0 label glRasterPos2f(-1.0, -1.0); glListBase(viz->font_list_2d); glCallLists(strlen(" 0"), GL_UNSIGNED_BYTE, " 0"); // 65535 label glRasterPos2f(1.0, 1.0); glListBase(viz->font_list_2d); glCallLists(strlen(" 65535"), GL_UNSIGNED_BYTE, " 65535"); glEndList(); // enable the use of glDrawArrays with vertices and normals glEnableClientState(GL_VERTEX_ARRAY); gdk_gl_drawable_gl_end(gldrawable); }
guac_terminal_display* guac_terminal_display_alloc(guac_client* client, const char* font_name, int font_size, int dpi, int foreground, int background) { PangoFontMap* font_map; PangoFont* font; PangoFontMetrics* metrics; PangoContext* context; /* Allocate display */ guac_terminal_display* display = malloc(sizeof(guac_terminal_display)); display->client = client; /* Create default surface */ display->display_layer = guac_client_alloc_layer(client); display->select_layer = guac_client_alloc_layer(client); display->display_surface = guac_common_surface_alloc(client, client->socket, display->display_layer, 0, 0); /* Select layer is a child of the display layer */ guac_protocol_send_move(client->socket, display->select_layer, display->display_layer, 0, 0, 0); /* Get font */ display->font_desc = pango_font_description_new(); pango_font_description_set_family(display->font_desc, font_name); pango_font_description_set_weight(display->font_desc, PANGO_WEIGHT_NORMAL); pango_font_description_set_size(display->font_desc, font_size * PANGO_SCALE * dpi / 96); font_map = pango_cairo_font_map_get_default(); context = pango_font_map_create_context(font_map); font = pango_font_map_load_font(font_map, context, display->font_desc); if (font == NULL) { guac_client_abort(display->client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to get font \"%s\"", font_name); return NULL; } metrics = pango_font_get_metrics(font, NULL); if (metrics == NULL) { guac_client_abort(display->client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to get font metrics for font \"%s\"", font_name); return NULL; } display->default_foreground = display->glyph_foreground = foreground; display->default_background = display->glyph_background = background; /* Calculate character dimensions */ display->char_width = pango_font_metrics_get_approximate_digit_width(metrics) / PANGO_SCALE; display->char_height = (pango_font_metrics_get_descent(metrics) + pango_font_metrics_get_ascent(metrics)) / PANGO_SCALE; /* Initially empty */ display->width = 0; display->height = 0; display->operations = NULL; /* Initially nothing selected */ display->text_selected = display->selection_committed = false; return display; }
static void print_pango_layout_line (GnomePrintContext *gpc, PangoLayoutLine *line) { GSList *tmp_list = line->runs; PangoRectangle overall_rect; PangoRectangle logical_rect; PangoRectangle ink_rect; gint x_off = 0; gnome_print_gsave (gpc); current_point_to_origin (gpc); pango_layout_line_get_extents (line, NULL, &overall_rect); while (tmp_list) { ItemProperties properties; PangoLayoutRun *run = tmp_list->data; tmp_list = tmp_list->next; get_item_properties (run->item, &properties); if (properties.shape_logical_rect) { x_off += properties.shape_logical_rect->width; continue; } gnome_print_gsave (gpc); translate (gpc, x_off, properties.rise); gnome_print_moveto (gpc, 0, 0); if (properties.uline == PANGO_UNDERLINE_NONE && !properties.strikethrough) pango_glyph_string_extents (run->glyphs, run->item->analysis.font, NULL, &logical_rect); else pango_glyph_string_extents (run->glyphs, run->item->analysis.font, &ink_rect, &logical_rect); if (properties.bg_color) { gnome_print_gsave (gpc); gnome_print_setrgbcolor (gpc, (gdouble) properties.bg_color->red / 0xFFFF, (gdouble) properties.bg_color->green / 0xFFFF, (gdouble) properties.bg_color->blue / 0xFFFF); rect_filled (gpc, logical_rect.x, - overall_rect.y - overall_rect.height, logical_rect.width, overall_rect.height); gnome_print_grestore (gpc); } if (properties.fg_color) { gnome_print_setrgbcolor (gpc, (gdouble) properties.fg_color->red / 0xFFFF, (gdouble) properties.fg_color->green / 0xFFFF, (gdouble) properties.fg_color->blue / 0xFFFF); } gnome_print_pango_glyph_string (gpc, run->item->analysis.font, run->glyphs); if (properties.uline != PANGO_UNDERLINE_NONE || properties.strikethrough) { PangoFontMetrics *metrics = pango_font_get_metrics (run->item->analysis.font, run->item->analysis.language); if (properties.uline != PANGO_UNDERLINE_NONE) draw_underline (gpc, metrics, properties.uline, ink_rect.x, ink_rect.width, ink_rect.y + ink_rect.height); if (properties.strikethrough) draw_strikethrough (gpc, metrics, ink_rect.x, ink_rect.width); pango_font_metrics_unref (metrics); } gnome_print_grestore (gpc); x_off += logical_rect.width; } gnome_print_grestore (gpc); }