예제 #1
0
TextAsset::Size
TextAsset::computeSizeOfText(cairo_t* cairoContext,
                             const std::string textString,
                             int bounds,
                             PangoFontDescription* font,
                             Rect* tight,
                             float* lineHeightOut)
{
    PangoLayout* layout = pango_cairo_create_layout(cairoContext);

    // Kerning
    PangoAttrList* attr_list = pango_attr_list_new();
    PangoAttribute* spacing_attr = pango_attr_letter_spacing_new(pango_units_from_double(_kern));
    pango_attr_list_insert(attr_list, spacing_attr);
    pango_layout_set_attributes(layout, attr_list);

    pango_cairo_context_set_resolution(pango_layout_get_context(layout), DISPLAY_RESOLUTION);
    pango_layout_set_text(layout, textString.c_str(), (int)textString.length());
    pango_layout_set_alignment(layout, _alignment);
    pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);

    const Size maxTextureSize(bounds, 1024);
    pango_layout_set_width(layout, pango_units_from_double(maxTextureSize.width));
    pango_layout_set_height(layout, pango_units_from_double(maxTextureSize.height));
    pango_layout_set_font_description(layout, font);
    applyLeading(cairoContext, layout, font);

    PangoRectangle estimateSize;
    PangoRectangle ink;
    pango_layout_get_pixel_extents(layout, &ink, &estimateSize);

    // If the text is right or center aligned the offsets will contain all the
    // leading space.  We ignore that for the size because drawText will draw
    // in the larger box.  The tight box below will get the offsets so we know
    // where to draw so the text lands in the same tight box.
    Size res(estimateSize.width, estimateSize.height);

    if (tight != NULL) {
        float lineHeight;
        float xHeight = charHeight(cairoContext, font, 'x', &lineHeight);
        if (lineHeightOut != NULL) {
            *lineHeightOut = lineHeight;
        }
        const float capHeight = charHeight(cairoContext, font, 'Y');
        const float ascender = pango_units_to_double(pango_layout_get_baseline(layout));
        const float topSpace = ascender - capHeight;
        const float bottomSpace = MAX(lineHeight - ascender - (capHeight - xHeight), 0);
        if (res.height > topSpace + bottomSpace) {
            *tight = Rect(estimateSize.x,
                          estimateSize.y + topSpace,
                          res.width,
                          res.height - topSpace - bottomSpace);
        } else {
            *tight = Rect(0, 0, res.width, res.height);
        }
    }
    g_object_unref(layout);

    return res;
}
예제 #2
0
ttext::ttext() :
#if PANGO_VERSION_CHECK(1,22,0)
	context_(pango_font_map_create_context(pango_cairo_font_map_get_default())),
#else
	context_(pango_cairo_font_map_create_context((
		reinterpret_cast<PangoCairoFontMap*>(pango_cairo_font_map_get_default())))),
#endif
	layout_(pango_layout_new(context_)),
	rect_(),
	surface_(),
#ifdef SDL_GPU
	texture_(),
#endif
	text_(),
	markedup_text_(false),
	link_aware_(false),
	link_color_(),
	font_class_(font::FONT_SANS_SERIF),
	font_size_(14),
	font_style_(STYLE_NORMAL),
	foreground_color_(0xFFFFFFFF), // solid white
	maximum_width_(-1),
	characters_per_line_(0),
	maximum_height_(-1),
	ellipse_mode_(PANGO_ELLIPSIZE_END),
	alignment_(PANGO_ALIGN_LEFT),
	maximum_length_(std::string::npos),
	calculation_dirty_(true),
	length_(0),
	surface_dirty_(true),
	surface_buffer_(nullptr)
{
	// With 72 dpi the sizes are the same as with SDL_TTF so hardcoded.
	pango_cairo_context_set_resolution(context_, 72.0);

	pango_layout_set_ellipsize(layout_, ellipse_mode_);
	pango_layout_set_alignment(layout_, alignment_);
	pango_layout_set_wrap(layout_, PANGO_WRAP_WORD_CHAR);

	/*
	 * Set the pango spacing a bit bigger since the default is deemed to small
	 * http://www.wesnoth.org/forum/viewtopic.php?p=358832#p358832
	 */
	pango_layout_set_spacing(layout_, 2 * PANGO_SCALE);

	cairo_font_options_t *fo = cairo_font_options_create();
	cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
	cairo_font_options_set_hint_metrics(fo, CAIRO_HINT_METRICS_ON);
#ifdef _WIN32
	// Cairo on Windows (at least the latest available version from gtk.org
	// as of 2014-02-22, version 1.10.2) has issues with ClearType resulting
	// in glitchy anti-aliasing with CAIRO_ANTIALIAS_SUBPIXEL or
	// CAIRO_ANTIALIAS_DEFAULT, but not CAIRO_ANTIALIAS_GRAY, so we use that
	// as a workaround until the Windows package is updated to use a newer
	// version of Cairo (see Wesnoth bug #21648).
	cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY);
#endif
	pango_cairo_context_set_font_options(context_, fo);
	cairo_font_options_destroy(fo);
}
예제 #3
0
static void _tristatebutton_size_request(GtkWidget *widget, GtkRequisition *requisition)
{
  g_return_if_fail(widget != NULL);
  g_return_if_fail(DTGTK_IS_TRISTATEBUTTON(widget));
  g_return_if_fail(requisition != NULL);

  /* create pango text settings if label exists */
  PangoLayout *layout = NULL;
  int pw = 0, ph = 0;
  const gchar *text = gtk_button_get_label(GTK_BUTTON(widget));
  if(text)
  {
    layout = gtk_widget_create_pango_layout(widget, NULL);
    pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc);
    pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi);
    pango_layout_set_text(layout, text, -1);
    pango_layout_get_pixel_size(layout, &pw, &ph);
    g_object_unref(layout);

    requisition->width = pw + DT_PIXEL_APPLY_DPI(4);
    requisition->height = ph + DT_PIXEL_APPLY_DPI(4);
  }
  else
  {
    requisition->width = requisition->height = DT_PIXEL_APPLY_DPI(24);
  }
}
예제 #4
0
파일: cawc.c 프로젝트: Roger/caw
static PyObject *
_pango_cairo_layout_set_resolution(PyObject *self, PyObject *args)
{
    PangoLayout *layout;
    double res;

    if (!PyArg_ParseTuple(args, "ld", &layout, &res))
        return NULL;

    pango_cairo_context_set_resolution(pango_layout_get_context(layout), res);

    Py_RETURN_NONE;
}
예제 #5
0
ttext::ttext() :
#if PANGO_VERSION_CHECK(1,22,0)
	context_(pango_font_map_create_context(pango_cairo_font_map_get_default())),
#else
	context_(pango_cairo_font_map_create_context((
		reinterpret_cast<PangoCairoFontMap*>(pango_cairo_font_map_get_default())))),
#endif
	layout_(pango_layout_new(context_)),
	rect_(),
	surface_(),
	text_(),
	markedup_text_(false),
	link_aware_(false),
	link_color_(),
	font_class_(font::FONT_SANS_SERIF),
	font_size_(14),
	font_style_(STYLE_NORMAL),
	foreground_color_(0xFFFFFFFF), // solid white
	maximum_width_(-1),
	characters_per_line_(0),
	maximum_height_(-1),
	ellipse_mode_(PANGO_ELLIPSIZE_END),
	alignment_(PANGO_ALIGN_LEFT),
	maximum_length_(std::string::npos),
	calculation_dirty_(true),
	length_(0),
	surface_dirty_(true),
	surface_buffer_(nullptr)
{
	// With 72 dpi the sizes are the same as with SDL_TTF so hardcoded.
	pango_cairo_context_set_resolution(context_, 72.0);

	pango_layout_set_ellipsize(layout_, ellipse_mode_);
	pango_layout_set_alignment(layout_, alignment_);
	pango_layout_set_wrap(layout_, PANGO_WRAP_WORD_CHAR);

	/*
	 * Set the pango spacing a bit bigger since the default is deemed to small
	 * http://www.wesnoth.org/forum/viewtopic.php?p=358832#p358832
	 */
	pango_layout_set_spacing(layout_, 4 * PANGO_SCALE);

	cairo_font_options_t *fo = cairo_font_options_create();
	cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
	cairo_font_options_set_hint_metrics(fo, CAIRO_HINT_METRICS_ON);
	cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_DEFAULT);

	pango_cairo_context_set_font_options(context_, fo);
	cairo_font_options_destroy(fo);
}
예제 #6
0
static void
lsm_dom_view_set_cairo_context (LsmDomView *view, cairo_t *cairo)
{
	PangoContext *context;
	cairo_font_options_t *font_options;
	const cairo_font_options_t *current_font_options;
	cairo_surface_t *surface;
	cairo_surface_type_t type;

	g_return_if_fail (LSM_IS_DOM_VIEW (view));

	if (view->cairo == cairo)
		return;

	if (view->cairo != NULL) {
		cairo_destroy (view->cairo);
		g_object_unref (view->pango_layout);
	}

	if (cairo == NULL) {
		view->cairo = NULL;
		view->pango_layout = NULL;

		return;
	}

	cairo_reference (cairo);
	view->cairo = cairo;
	view->pango_layout = pango_cairo_create_layout (cairo);

	surface = cairo_get_target (cairo);

	type = cairo_surface_get_type (surface);

	view->is_vector = (type == CAIRO_SURFACE_TYPE_SVG ||
			   type == CAIRO_SURFACE_TYPE_PDF ||
			   type == CAIRO_SURFACE_TYPE_PS);

	context = pango_layout_get_context (view->pango_layout);
	pango_cairo_context_set_resolution (context, 72);

	current_font_options = pango_cairo_context_get_font_options (context);
	if (current_font_options == NULL)
		font_options = cairo_font_options_create ();
	else
		font_options = cairo_font_options_copy (current_font_options);
	cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
	pango_cairo_context_set_font_options (context, font_options);
	cairo_font_options_destroy (font_options);
}
예제 #7
0
// Returns the PangoFont structure corresponding to the closest available font
// in the font map. Note that if the font is wholly missing, this could
// correspond to a completely different font family and face.
PangoFont* PangoFontInfo::ToPangoFont() const {
  InitFontconfig();
  PangoFontMap* font_map = pango_cairo_font_map_get_default();
  PangoContext* context = pango_context_new();
  pango_cairo_context_set_resolution(context, resolution_);
  pango_context_set_font_map(context, font_map);
  PangoFont* font = NULL;
  {
    DISABLE_HEAP_LEAK_CHECK;
    font = pango_font_map_load_font(font_map, context, desc_);
  }
  g_object_unref(context);
  return font;
}
예제 #8
0
void
TextAsset::drawText(cairo_t* cairoContext,
                    const std::string& textString,
                    const Rect& rect,
                    PangoFontDescription* inFontDescription,
                    bool outlineEnabled)
{
    cairo_move_to(cairoContext, rect.x, rect.y);

    PangoLayout* layout = pango_cairo_create_layout(cairoContext);

    // Kerning
    PangoAttrList* attr_list = pango_attr_list_new();
    PangoAttribute* spacing_attr = pango_attr_letter_spacing_new(pango_units_from_double(_kern));
    pango_attr_list_insert(attr_list, spacing_attr);
    pango_layout_set_attributes(layout, attr_list);

    pango_cairo_context_set_resolution(pango_layout_get_context(layout), DISPLAY_RESOLUTION);
    pango_layout_set_text(layout, textString.c_str(), textString.length());
    pango_layout_set_font_description(layout, inFontDescription);
    pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
    pango_layout_set_width(layout, pango_units_from_double(rect.size.width + WIDTH_PADDING));
    pango_layout_set_height(layout, pango_units_from_double(rect.size.height + HEIGHT_PADDING));
    pango_layout_set_alignment(layout, _alignment);
    applyLeading(cairoContext, layout, inFontDescription);

    pango_cairo_show_layout(cairoContext, layout);

    // Core Text defines positive outline width values as stroke only
    if (_outlineThickness <= 0.0f) {
        cairo_fill_preserve(cairoContext);
    }

    // Outline
    if (outlineEnabled && _outlineThickness != 0.0f) {
        const float outlineThickness = (fabsf(_outlineThickness) / 100.0f) * _fontSize * CLIENT_TO_SERVER_SCALE;
        cairo_set_source_rgba(cairoContext,
                              _outlineColor.red,
                              _outlineColor.green,
                              _outlineColor.blue,
                              _outlineColor.alpha);
        pango_cairo_layout_path(cairoContext, layout);
        cairo_set_line_width(cairoContext, outlineThickness);
        cairo_stroke(cairoContext);
    } else {
        cairo_new_path(cairoContext);
    }

    g_object_unref(layout);
}
예제 #9
0
PangoLayout* TextView::initPango(cairo_t* cr, Text* t)
{
	PangoLayout* layout = pango_cairo_create_layout(cr);

	// Additional Feature: add autowrap and text field size for
	// the next xournal release (with new fileformat...)
	// pango_layout_set_wrap

	pango_cairo_context_set_resolution(pango_layout_get_context(layout), textDpi);
	pango_cairo_update_layout(cr, layout);

	pango_context_set_matrix(pango_layout_get_context(layout), NULL);
	updatePangoFont(layout, t);
	return layout;
}
예제 #10
0
파일: cairostuff.c 프로젝트: eguopt/fcitx
int
FontHeightWithContextReal(cairo_t* c, PangoFontDescription* fontDesc, int dpi)
{
    int height;

    PangoContext* pc = pango_cairo_create_context(c);
    pango_cairo_context_set_resolution(pc, dpi);
    PangoLayout *layout = pango_layout_new(pc);
    pango_layout_set_text(layout, "Ayg中", -1);
    pango_layout_set_font_description(layout, fontDesc);
    pango_layout_get_pixel_size(layout, NULL, &height);
    g_object_unref(layout);
    g_object_unref(pc);

    return height;
}
예제 #11
0
파일: cairostuff.c 프로젝트: eguopt/fcitx
void StringSizeStrict(const char* str, const char* font, int fontSize, int dpi, int* w, int* h)
{
    if (!str || str[0] == 0) {
        if (w) *w = 0;
        if (h) *h = 0;
        return;
    }
    if (!fcitx_utf8_check_string(str)) {
        if (w) *w = 0;
        if (h) *h = 0;

        return;
    }
    cairo_surface_t *surface =
        cairo_image_surface_create(CAIRO_FORMAT_RGB24, 10, 10);
    cairo_t        *c = cairo_create(surface);

    SetFontContext(c, font, fontSize, dpi);
#ifdef _ENABLE_PANGO
    PangoRectangle rect;
    PangoContext* pc = pango_cairo_create_context(c);
    pango_cairo_context_set_resolution(pc, dpi);
    PangoLayout *layout = pango_layout_new(pc);
    pango_layout_set_text(layout, str, -1);
    pango_layout_set_font_description(layout, fontDesc);
    pango_layout_get_pixel_extents(layout, &rect, NULL);
    if (w)
        *w = rect.width;
    if (h)
        *h = rect.height;
    g_object_unref(layout);
#else
    cairo_text_extents_t extents;
    cairo_text_extents(c, str, &extents);
    if (w)
        *w = extents.width;
    if (h)
        *h = extents.height;
#endif
    ResetFontContext();

    cairo_destroy(c);
    cairo_surface_destroy(surface);
}
예제 #12
0
파일: frames.c 프로젝트: micove/compiz
static void
style_updated (GtkWidget *widget,
               void      *user_data)
{
    GdkDisplay *gdkdisplay;
    GdkScreen  *gdkscreen;
    WnckScreen *screen;

    PangoContext *context = (PangoContext *) user_data;

    gdkdisplay = gdk_display_get_default ();
    gdkscreen  = gdk_display_get_default_screen (gdkdisplay);
    screen     = wnck_screen_get_default ();

    update_style (widget);

    pango_cairo_context_set_resolution (context, gdk_screen_get_resolution (gdkscreen));

    decorations_changed (screen);
}
예제 #13
0
static void
lsm_dom_view_init (LsmDomView *view)
{
	PangoFontMap *font_map;
	PangoContext *pango_context;
	cairo_font_options_t *font_options;

	view->resolution_ppi = LSM_DOM_VIEW_DEFAULT_RESOLUTION;
	view->viewport_pt.x = 0;
	view->viewport_pt.y = 0;
	view->viewport_pt.width  = LSM_DOM_VIEW_DEFAULT_VIEWBOX_WIDTH;
	view->viewport_pt.height = LSM_DOM_VIEW_DEFAULT_VIEWBOX_HEIGHT;

	view->font_description = pango_font_description_new ();

	font_map = pango_cairo_font_map_get_default ();

#if PANGO_VERSION_CHECK(1,22,0)
	pango_context = pango_font_map_create_context (font_map);
#else
	pango_context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (font_map));
#endif
	pango_cairo_context_set_resolution (pango_context, 72.0);

	view->measure_pango_layout = pango_layout_new (pango_context);

	font_options = cairo_font_options_create ();

	cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
	cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);

	pango_cairo_context_set_font_options (pango_context, font_options);

	cairo_font_options_destroy (font_options);

	g_object_unref (pango_context);

	view->pango_layout = NULL;
	view->cairo = NULL;
	view->is_vector = FALSE;
}
예제 #14
0
/**
 * gdk_pango_context_get_for_screen:
 * @screen: the #GdkScreen for which the context is to be created.
 * 
 * Creates a #PangoContext for @screen.
 *
 * The context must be freed when you're finished with it.
 * 
 * When using GTK+, normally you should use gtk_widget_get_pango_context()
 * instead of this function, to get the appropriate context for
 * the widget you intend to render text onto.
 * 
 * The newly created context will have the default font options
 * (see #cairo_font_options_t) for the screen; if these options
 * change it will not be updated. Using gtk_widget_get_pango_context()
 * is more convenient if you want to keep a context around and track
 * changes to the screen's font rendering settings.
 * 
 * Return value: (transfer full): a new #PangoContext for @screen
 *
 * Since: 2.2
 **/
PangoContext *
gdk_pango_context_get_for_screen (GdkScreen *screen)
{
  PangoFontMap *fontmap;
  PangoContext *context;
  const cairo_font_options_t *options;
  double dpi;

  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);

  fontmap = pango_cairo_font_map_get_default ();
  context = pango_font_map_create_context (fontmap);

  options = gdk_screen_get_font_options (screen);
  pango_cairo_context_set_font_options (context, options);

  dpi = gdk_screen_get_resolution (screen);
  pango_cairo_context_set_resolution (context, dpi);

  return context;
}
예제 #15
0
파일: cairostuff.c 프로젝트: eguopt/fcitx
void
OutputStringWithContextReal(cairo_t * c, PangoFontDescription* desc, int dpi, const char *str, int x, int y)
{
    if (!str || str[0] == 0)
        return;
    if (!fcitx_utf8_check_string(str))
        return;
    cairo_save(c);

    PangoContext *pc = pango_cairo_create_context(c);
    pango_cairo_context_set_resolution(pc, dpi);
    PangoLayout *layout = pango_layout_new(pc);
    pango_layout_set_text(layout, str, -1);
    pango_layout_set_font_description(layout, desc);
    cairo_move_to(c, x, y);
    pango_cairo_show_layout(c, layout);

    cairo_restore(c);
    g_object_unref(layout);
    g_object_unref(pc);
}
예제 #16
0
파일: cairostuff.c 프로젝트: eguopt/fcitx
void
StringSizeWithContextReal(cairo_t * c, PangoFontDescription* fontDesc, int dpi, const char *str, int* w, int* h)
{
    if (!str || str[0] == 0) {
        if (w) *w = 0;
        if (h) *h = 0;
        return;
    }
    if (!fcitx_utf8_check_string(str)) {
        if (w) *w = 0;
        if (h) *h = 0;

        return;
    }

    PangoContext *pc = pango_cairo_create_context(c);
    pango_cairo_context_set_resolution(pc, dpi);
    PangoLayout *layout = pango_layout_new(pc);
    pango_layout_set_text(layout, str, -1);
    pango_layout_set_font_description(layout, fontDesc);
    pango_layout_get_pixel_size(layout, w, h);
    g_object_unref(layout);
    g_object_unref(pc);
}
예제 #17
0
static void
schgui_cairo_drafter_draw_text(SchGUICairoDrafter *drafter, const struct _SchText *text)
{
    if (text != NULL)
    {
        int visible;

        sch_text_get_visible(text, &visible);

        if (visible)
        {

    SchGUICairoDrafterPrivate *privat = SCHGUI_CAIRO_DRAFTER_GET_PRIVATE(drafter);

    if (privat->cairo != NULL)
    {
        PangoLayout *layout;
        SchMultiline *multiline = sch_text_get_multiline(text);
        int point_size = sch_text_get_size(text);
        float height;
        int alignment;
        cairo_font_options_t *options;
        PangoContext *context;
        int baseline;
        PangoLayoutIter *iter;
        int index;
        int show;
        SchGUIDrawingCfgColor color;
        int          enabled;

        sch_text_get_color(text, &index);

        enabled = schgui_drawing_cfg_get_color(privat->config, index, &color);

        if (enabled)
        {
            if (0) /* show ink rect */
            {
                GeomBounds bounds;
                int        success;

                success = schgui_cairo_drafter_text_bounds(drafter, text, &bounds);

                if (success)
                {
                    cairo_set_source_rgb(privat->cairo, 1.0, 0, 0);
                
                    cairo_move_to(privat->cairo, bounds.min_x, bounds.min_y);
                    cairo_line_to(privat->cairo, bounds.max_x, bounds.min_y);
                
                    cairo_stroke(privat->cairo);

                    cairo_set_source_rgb(privat->cairo, 0.75, 0, 0);
                
                    cairo_move_to(privat->cairo, bounds.max_x, bounds.min_y);
                    cairo_line_to(privat->cairo, bounds.max_x, bounds.max_y);
                    cairo_line_to(privat->cairo, bounds.min_x, bounds.max_y);
                    cairo_line_to(privat->cairo, bounds.min_x, bounds.min_y);
                    //cairo_close_path(privat->cairo);

                    cairo_stroke(privat->cairo);
                
                    cairo_set_source_rgb(privat->cairo, 0, 0, 0);
                }

                cairo_set_source_rgb(privat->cairo, 0, 0, 1.0);
                cairo_new_sub_path(privat->cairo);
                cairo_arc(privat->cairo, sch_text_get_x(text), sch_text_get_y(text), 10, 0, 2 * M_PI);
                cairo_stroke(privat->cairo);
                cairo_set_source_rgb(privat->cairo, 0, 0, 0);
            }

            cairo_save(privat->cairo);
   
            height = 1000 * point_size / 72;

            layout = pango_cairo_create_layout(privat->cairo);
            pango_cairo_context_set_resolution(pango_layout_get_context(layout), 936);

//  context = pango_layout_get_context(layout);
//  options = cairo_font_options_create ();
//  cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
//  cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_MEDIUM);
//  pango_cairo_context_set_font_options (context, options);
//  cairo_font_options_destroy (options);


            cairo_set_source_rgb(privat->cairo, color.red, color.green, color.blue);


            pango_font_description_set_size(privat->desc, point_size * PANGO_SCALE );
            pango_layout_set_spacing(layout, 40000);
        
            pango_layout_set_font_description(layout, privat->desc);

            sch_text_get_show(text, &show);
            pango_layout_set_markup(layout, sch_multiline_peek_markup(multiline, show), -1);


            PangoFontMetrics *metrics = pango_context_get_metrics(
                pango_layout_get_context(layout),
                privat->desc,
                NULL
                );

        
            cairo_move_to(privat->cairo, sch_text_get_x(text), sch_text_get_y(text));
        
            cairo_rotate(privat->cairo, M_PI * sch_text_get_angle(text) / 180);

            cairo_scale(privat->cairo, 1, -1);

            baseline = pango_layout_get_baseline(layout); 

            alignment = sch_text_get_alignment(text);
#if 1
            switch (alignment)
            {
                case 2:
                case 5:
                case 8: 
                /* upper */
                //cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_ascent(metrics)/(privat->zoom * PANGO_SCALE));
                //cairo_rel_move_to(privat->cairo, 0, height);
                break;

                case 1:
                case 4:
                case 7:
                    /* center */
                    cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_ascent(metrics)/(privat->zoom * PANGO_SCALE));
                    cairo_rel_move_to(privat->cairo, 0, height);
                    cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_ascent(metrics) * sch_multiline_lines(multiline)/(2 * privat->zoom * PANGO_SCALE));
                    cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_descent(metrics) * (sch_multiline_lines(multiline) - 1)/(2 * privat->zoom * PANGO_SCALE));
                    break;

                case 0:
                case 3:
                case 6:
                default:
                    /* lower */
                    //cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_ascent(metrics) * sch_multiline_lines(multiline)/(privat->zoom * PANGO_SCALE));
                    //cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_descent(metrics) * (sch_multiline_lines(multiline)-1)/(privat->zoom * PANGO_SCALE));
                    //cairo_rel_move_to(privat->cairo, 0, -pango_layout_get_spacing(layout) * (sch_multiline_lines(multiline)-1)/ PANGO_SCALE);
                    iter = pango_layout_get_iter(layout);
                    while (!pango_layout_iter_at_last_line(iter))
                    {
                        pango_layout_iter_next_line(iter);
                    }
                    cairo_rel_move_to(privat->cairo, 0, -pango_layout_iter_get_baseline(iter) / PANGO_SCALE);
                    pango_layout_iter_free(iter);
            }
#endif

            //g_debug("Ascent:    %d", pango_font_metrics_get_ascent(metrics));
            //g_debug("Descent:   %d", pango_font_metrics_get_descent(metrics));
            //g_debug("Spacing:   %d", pango_layout_get_spacing(layout));
            //g_debug("Font size: %d", pango_font_description_get_size(privat->desc));
            //g_debug("Baseline   %d", pango_layout_get_baseline(layout));            

            pango_font_metrics_unref(metrics);

            pango_cairo_show_layout(privat->cairo, layout);

            cairo_restore(privat->cairo);

            g_object_unref(layout);
        }
    }
}
}
 
}
예제 #18
0
static void
schgui_cairo_text_draw(SchGUICairoDrawItem *item, cairo_t *cairo)
{
    if (cairo != NULL)
    {
        SchGUICairoTextPrivate *privat = SCHGUI_CAIRO_TEXT_GET_PRIVATE(item);

        if (privat != NULL)
        {
            PangoLayout *layout = pango_cairo_create_layout(cairo);

            if (layout != NULL)
            {
                PangoLayoutIter *iter;
                int width;

                cairo_save(cairo);

                cairo_set_source_rgba(cairo, privat->red, privat->green, privat->blue, privat->alpha);


                pango_cairo_context_set_resolution(pango_layout_get_context(layout), 936);
                pango_layout_set_spacing(layout, 40000);
                pango_layout_set_font_description(layout, privat->font_desc);

                pango_layout_set_markup(layout, privat->markup, -1);

                cairo_move_to(cairo, privat->x, privat->y);
                cairo_rotate(cairo, privat->angle);
                cairo_scale(cairo, 1, -1);

                switch (privat->alignment)
                {
                    case 2:
                    case 5:
                    case 8: 
                        /* upper */
                        break;

                    case 1:
                    case 4:
                    case 7:
                        /* center */
                        iter = pango_layout_get_iter(layout);
                        while (!pango_layout_iter_at_last_line(iter))
                        {
                            pango_layout_iter_next_line(iter);
                        }
                        cairo_rel_move_to(cairo, 0, -pango_layout_iter_get_baseline(iter) / PANGO_SCALE / 2);
                        pango_layout_iter_free(iter);
                        break;

                    case 0:
                    case 3:
                    case 6:
                    default:
                        /* lower */
                        iter = pango_layout_get_iter(layout);
                        while (!pango_layout_iter_at_last_line(iter))
                        {
                            pango_layout_iter_next_line(iter);
                        }
                        cairo_rel_move_to(cairo, 0, -pango_layout_iter_get_baseline(iter) / PANGO_SCALE);
                        pango_layout_iter_free(iter);
                }

                switch (privat->alignment)
                {

                    case 3:
                    case 4:
                    case 5:
                        /* center */
                        pango_layout_get_size(layout, &width, NULL);
                        cairo_rel_move_to(cairo, -width / PANGO_SCALE / 2, 0);
                        break;

                    case 6:
                    case 7:
                    case 8:
                        pango_layout_get_size(layout, &width, NULL);
                        cairo_rel_move_to(cairo, -width / PANGO_SCALE, 0);
                        /* right */
                        break;

                    case 0:
                    case 1:
                    case 2:
                    default:
                        /* left */
                        ;
                }

                pango_cairo_show_layout(cairo, layout);

                cairo_restore(cairo);

                g_object_unref(layout);
            }
        }
    }
}
예제 #19
0
static boolean pango_textlayout(textpara_t * para, char **fontpath)
{
    static char buf[1024];  /* returned in fontpath, only good until next call */
    static PangoFontMap *fontmap;
    static PangoContext *context;
    static PangoFontDescription *desc;
    static char *fontname;
    static double fontsize;
    static gv_font_map* gv_fmap;
    char *fnt, *psfnt = NULL;
    PangoLayout *layout;
    PangoRectangle logical_rect;
    cairo_font_options_t* options;
    PangoFont *font;
#ifdef ENABLE_PANGO_MARKUP
    PangoAttrList *attrs;
    GError *error = NULL;
    int flags;
#endif
    char *text;
    double textlayout_scale;

    if (!context) {
	fontmap = pango_cairo_font_map_new();
	gv_fmap = get_font_mapping(fontmap);
	context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap));
	options=cairo_font_options_create();
	cairo_font_options_set_antialias(options,CAIRO_ANTIALIAS_GRAY);
	cairo_font_options_set_hint_style(options,CAIRO_HINT_STYLE_FULL);
	cairo_font_options_set_hint_metrics(options,CAIRO_HINT_METRICS_ON);
	cairo_font_options_set_subpixel_order(options,CAIRO_SUBPIXEL_ORDER_BGR);
	pango_cairo_context_set_font_options(context, options);
	pango_cairo_context_set_resolution(context, FONT_DPI);
	cairo_font_options_destroy(options);
	g_object_unref(fontmap);
    }

    if (!fontname || strcmp(fontname, para->fontname) != 0 || fontsize != para->fontsize) {
	fontname = para->fontname;
	fontsize = para->fontsize;
	pango_font_description_free (desc);

	if (para->postscript_alias) {
	    psfnt = fnt = gv_fmap[para->postscript_alias->xfig_code].gv_font;
	    if(!psfnt)
		psfnt = fnt = pango_psfontResolve (para->postscript_alias);
	}
	else
	    fnt = fontname;

	desc = pango_font_description_from_string(fnt);
        /* all text layout is done at a scale of FONT_DPI (nominaly 96.) */
        pango_font_description_set_size (desc, (gint)(fontsize * PANGO_SCALE));

        if (fontpath && (font = pango_font_map_load_font(fontmap, context, desc))) {  /* -v support */
	    const char *fontclass;

	    fontclass = G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(font));

	    buf[0] = '\0';
	    if (psfnt) {
		strcat(buf, "(ps:pango  ");
		strcat(buf, psfnt);
		strcat(buf, ") ");
	    }
	    strcat(buf, "(");
	    strcat(buf, fontclass);
	    strcat(buf, ") ");
#ifdef HAVE_PANGO_FC_FONT_LOCK_FACE
	    if (strcmp(fontclass, "PangoCairoFcFont") == 0) {
	        FT_Face face;
	        PangoFcFont *fcfont;
	        FT_Stream stream;
	        FT_StreamDesc streamdesc;
	        fcfont = PANGO_FC_FONT(font);
	        face = pango_fc_font_lock_face(fcfont);
	        if (face) {
		    strcat(buf, "\"");
		    strcat(buf, face->family_name);
		    strcat(buf, ", ");
		    strcat(buf, face->style_name);
		    strcat(buf, "\" ");
    
		    stream = face->stream;
		    if (stream) {
			streamdesc = stream->pathname;
			if (streamdesc.pointer)
			    strcat(buf, (char*)streamdesc.pointer);
		        else
			    strcat(buf, "*no pathname available*");
		    }
		    else
			strcat(buf, "*no stream available*");
		}
	        pango_fc_font_unlock_face(fcfont);
	    }
	    else
#endif
	    {
    		PangoFontDescription *tdesc;
		char *tfont;
		
	        tdesc = pango_font_describe(font);
	        tfont = pango_font_description_to_string(tdesc);
	        strcat(buf, "\"");
	        strcat(buf, tfont);
	        strcat(buf, "\" ");
	        g_free(tfont);
	    }
            *fontpath = buf;
        }
    }

#ifdef ENABLE_PANGO_MARKUP
    if ((para->font) && (flags = para->font->flags)) {
	char* markup = N_NEW(strlen(para->str) + sizeof(FULL_MARKUP), char);
	strcpy(markup,"<span");

	if (flags & HTML_BF)
	    strcat(markup," weight=\"bold\"");
	if (flags & HTML_IF)
	    strcat(markup," style=\"italic\"");
	if (flags & HTML_UL)
	    strcat(markup," underline=\"single\"");
	strcat (markup,">");

	if (flags & HTML_SUP)
	    strcat(markup,"<sup>");
	if (flags & HTML_SUB)
	    strcat(markup,"<sub>");

	strcat (markup,para->str);

	if (flags & HTML_SUB)
	    strcat(markup,"</sub>");
	if (flags & HTML_SUP)
	    strcat(markup,"</sup>");

	strcat (markup,"</span>");
	if (!pango_parse_markup (markup, -1, 0, &attrs, &text, NULL, &error)) {
	    fprintf (stderr, "Error - pango_parse_markup: %s\n", error->message);
	    text = para->str;
	    attrs = NULL;
	}
	free (markup);
    }
예제 #20
0
static gboolean _button_draw(GtkWidget *widget, cairo_t *cr)
{
  g_return_val_if_fail(widget != NULL, FALSE);
  g_return_val_if_fail(DTGTK_IS_BUTTON(widget), FALSE);

  GtkStateFlags state = gtk_widget_get_state_flags(widget);

  GdkRGBA bg_color, fg_color;
  GtkStyleContext *context = gtk_widget_get_style_context(widget);
  gtk_style_context_get_background_color(context, state, &bg_color);
  gtk_style_context_get_color(context, state, &fg_color);

  /* update paint flags depending of states */
  int flags = DTGTK_BUTTON(widget)->icon_flags;

  /* set inner border */
  int border = DT_PIXEL_APPLY_DPI((flags & CPF_DO_NOT_USE_BORDER) ? 2 : 6);

  /* prelight */
  if(state & GTK_STATE_FLAG_PRELIGHT)
    flags |= CPF_PRELIGHT;
  else
    flags &= ~CPF_PRELIGHT;


  /* create pango text settings if label exists */
  PangoLayout *layout = NULL;
  int pw = 0, ph = 0;
  const gchar *text = gtk_button_get_label(GTK_BUTTON(widget));
  if(text)
  {
    layout = gtk_widget_create_pango_layout(widget, NULL);
    pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc);
    pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi);
    pango_layout_set_text(layout, text, -1);
    pango_layout_get_pixel_size(layout, &pw, &ph);
  }

  /* begin cairo drawing */
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int width = allocation.width;
  int height = allocation.height;

  /* draw standard button background if not transparent */
  if((flags & CPF_STYLE_FLAT))
  {
    if(flags & CPF_PRELIGHT)
    {
      cairo_rectangle(cr, 0, 0, width, height);
      gdk_cairo_set_source_rgba(cr, &bg_color);
      cairo_fill(cr);
    }
  }
  else if(!(flags & CPF_BG_TRANSPARENT))
  {
    /* draw default boxed button */
    gtk_render_background(context, cr, 0, 0, width, height);
    if(!(flags & CPF_DO_NOT_USE_BORDER))
      gtk_render_frame(context, cr, 0, 0, width, height);
  }

  gdk_cairo_set_source_rgba(cr, &fg_color);

  /* draw icon */
  if(DTGTK_BUTTON(widget)->icon)
  {
    int icon_width = text ? height - (border * 2) : width - (border * 2);
    int icon_height = height - (border * 2);

    if(icon_width > 0 && icon_height > 0)
    {
      if(text)
        DTGTK_BUTTON(widget)
            ->icon(cr, border, border, height - (border * 2), height - (border * 2), flags);
      else
        DTGTK_BUTTON(widget)
            ->icon(cr, border, border, width - (border * 2), height - (border * 2), flags);
    }
  }

  /* draw label */
  if(text)
  {
    int lx = DT_PIXEL_APPLY_DPI(2), ly = ((height / 2.0) - (ph / 2.0));
    if(DTGTK_BUTTON(widget)->icon) lx += width;
    cairo_move_to(cr, lx, ly);
    cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.5);
    pango_cairo_show_layout(cr, layout);
    g_object_unref(layout);
  }

  return FALSE;
}
cairo_surface_t*
render_text_to_surface (gchar*                      text,
			gint                        width,
			gint                        height,
			const cairo_font_options_t* font_opts,
			gdouble                     dpi)
{
	cairo_surface_t*      surface;
	cairo_t*              cr;
	PangoFontDescription* desc;
	PangoLayout*          layout;

	// sanity check
	if (!text      ||
	    width <= 0 ||
	    height <= 0)
		return NULL;

	// create surface
	surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
					      width,
					      height);
	if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
		return NULL;

	// create context
	cr = cairo_create (surface);
	if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
	{
		cairo_surface_destroy (surface);
		return NULL;
	}

	// clear context
	cairo_scale (cr, 1.0f, 1.0f);
	cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
	cairo_paint (cr);

	//
	layout = pango_cairo_create_layout (cr);
	desc = pango_font_description_new ();

	pango_font_description_set_size (desc, 12 * PANGO_SCALE);
	pango_font_description_set_family_static (desc, "Candara");
	pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL);
	pango_font_description_set_style (desc, PANGO_STYLE_NORMAL);

	pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
	pango_layout_set_font_description (layout, desc);
	pango_font_description_free (desc);
	pango_layout_set_width (layout, width * PANGO_SCALE);
	pango_layout_set_height (layout, height * PANGO_SCALE);
	pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
	pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);

	// print and layout string (pango-wise)
	pango_layout_set_text (layout, text, -1);

	// make sure system-wide font-options like hinting, antialiasing etc.
	// are taken into account
	pango_cairo_context_set_font_options (pango_layout_get_context (layout),
					      font_opts);
	pango_cairo_context_set_resolution  (pango_layout_get_context (layout),
					     dpi);
	pango_layout_context_changed (layout);

	// draw pango-text to our cairo-context
	cairo_move_to (cr, 0.0f, 0.0f);
	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
	cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f);

	// this call leaks 3803 bytes, I've no idea how to fix that
	pango_cairo_show_layout (cr, layout);

	// clean up
	g_object_unref (layout);
	cairo_destroy (cr);

	return surface;	
}
예제 #22
0
static gboolean _tristatebutton_expose(GtkWidget *widget, GdkEventExpose *event)
{
  g_return_val_if_fail(widget != NULL, FALSE);
  g_return_val_if_fail(DTGTK_IS_TRISTATEBUTTON(widget), FALSE);
  g_return_val_if_fail(event != NULL, FALSE);
  GtkStyle *style = gtk_widget_get_style(widget);
  int state = gtk_widget_get_state(widget);

  /* fix text style */
  for(int i = 0; i < 5; i++) style->text[i] = style->fg[i];

  /* fetch flags */
  int flags = DTGTK_TRISTATEBUTTON(widget)->icon_flags;

  /* set inner border */
  int border = DT_PIXEL_APPLY_DPI((flags & CPF_DO_NOT_USE_BORDER) ? 2 : 6);

  /* update active state paint flag */
  gboolean active = DTGTK_TRISTATEBUTTON(widget)->state > 0;
  if(active)
    flags |= CPF_ACTIVE;
  else
    flags &= ~(CPF_ACTIVE);


  /* begin cairo drawing */
  cairo_t *cr;
  cr = gdk_cairo_create(gtk_widget_get_window(widget));

  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int x = allocation.x;
  int y = allocation.y;
  int width = allocation.width;
  int height = allocation.height;

  /* draw standard button background if not transparent nor flat styled */
  if((flags & CPF_STYLE_FLAT))
  {
    if(state != GTK_STATE_NORMAL)
    {
      cairo_rectangle(cr, x, y, width, height);
      cairo_set_source_rgba(cr, style->bg[state].red / 65535.0, style->bg[state].green / 65535.0,
                            style->bg[state].blue / 65535.0, 0.5);
      cairo_fill(cr);
    }
  }
  else if(!(flags & CPF_BG_TRANSPARENT))
  {
    cairo_rectangle(cr, x, y, width, height);
    float rs = 1.0, gs = 1.0, bs = 1.0;

    if(DTGTK_TRISTATEBUTTON(widget)->state == 1)
      rs = gs = bs = 3.0;
    else if(DTGTK_TRISTATEBUTTON(widget)->state == 2)
      rs = 3.0;

    cairo_set_source_rgba(cr, (style->bg[state].red / 65535.0) * rs, (style->bg[state].green / 65535.0) * gs,
                          (style->bg[state].blue / 65535.0) * bs, 0.5);
    cairo_fill(cr);
  }

  /* create pango text settings if label exists */
  PangoLayout *layout = NULL;
  int pw = 0, ph = 0;
  const gchar *text = gtk_button_get_label(GTK_BUTTON(widget));
  if(text)
  {
    layout = pango_cairo_create_layout(cr);
    pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc);
    pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi);
    pango_layout_set_text(layout, text, -1);
    pango_layout_get_pixel_size(layout, &pw, &ph);
  }

  cairo_set_source_rgb(cr, style->fg[state].red / 65535.0, style->fg[state].green / 65535.0,
                       style->fg[state].blue / 65535.0);

  /* draw button image if any */
  GtkWidget *image = gtk_button_get_image(GTK_BUTTON(widget));
  if(image)
  {
    GdkPixbuf *pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(image));

    if(pixbuf)
    {
      /* Draw the pixbuf */
      gint pbw = gdk_pixbuf_get_width(pixbuf);
      gint pbh = gdk_pixbuf_get_height(pixbuf);
      gdk_cairo_set_source_pixbuf(cr, pixbuf, allocation.x + ((allocation.width / 2) - (pbw / 2)),
                                  allocation.y + ((allocation.height / 2) - (pbh / 2)));
      cairo_paint(cr);
    }
  }


  /* draw icon */
  if(DTGTK_TRISTATEBUTTON(widget)->icon)
  {
    //     if (flags & CPF_IGNORE_FG_STATE)
    //       state = GTK_STATE_NORMAL;


    if(text)
      DTGTK_TRISTATEBUTTON(widget)
          ->icon(cr, x + border, y + border, height - (border * 2), height - (border * 2), flags);
    else
      DTGTK_TRISTATEBUTTON(widget)
          ->icon(cr, x + border, y + border, width - (border * 2), height - (border * 2), flags);
  }


  /* draw label */
  if(text)
  {
    int lx = x + DT_PIXEL_APPLY_DPI(2), ly = y + ((height / 2.0) - (ph / 2.0));
    cairo_translate(cr, lx, ly);
    pango_cairo_show_layout(cr, layout);
    g_object_unref(layout);
  }

  cairo_destroy(cr);

  return FALSE;
}
예제 #23
0
static gboolean _togglebutton_draw(GtkWidget *widget, cairo_t *cr)
{
  g_return_val_if_fail(widget != NULL, FALSE);
  g_return_val_if_fail(DTGTK_IS_TOGGLEBUTTON(widget), FALSE);

  GtkDarktableToggleButton *button = DTGTK_TOGGLEBUTTON(widget);

  GtkStateFlags state = gtk_widget_get_state_flags(widget);

  GdkRGBA bg_color, fg_color;
  GtkStyleContext *context = gtk_widget_get_style_context(widget);
  if(button->icon_flags & CPF_CUSTOM_BG)
    bg_color = button->bg;
  else
    gtk_style_context_get_background_color(context, state, &bg_color);
  if(button->icon_flags & CPF_CUSTOM_FG)
    fg_color = button->fg;
  else
    gtk_style_context_get_color(context, state, &fg_color);

  /* fetch flags */
  int flags = DTGTK_TOGGLEBUTTON(widget)->icon_flags;

  /* set inner border */
  int border = DT_PIXEL_APPLY_DPI((flags & CPF_DO_NOT_USE_BORDER) ? 2 : 6);

  /* update active state paint flag */
  gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
  if(active)
    flags |= CPF_ACTIVE;
  else
    flags &= ~(CPF_ACTIVE);

  /* prelight */
  if(state & GTK_STATE_FLAG_PRELIGHT)
    flags |= CPF_PRELIGHT;
  else
    flags &= ~CPF_PRELIGHT;

  /* begin cairo drawing */
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int width = allocation.width;
  int height = allocation.height;

  /* draw standard button background if not transparent nor flat styled */
  if((flags & CPF_STYLE_FLAT))
  {
    if(flags & CPF_PRELIGHT || flags & CPF_ACTIVE)
    {
      cairo_rectangle(cr, 0, 0, width, height);
      gdk_cairo_set_source_rgba(cr, &bg_color);
      cairo_fill(cr);
    }
  }
  else if(!(flags & CPF_BG_TRANSPARENT))
  {
    /* draw default boxed button */
    gtk_render_background(context, cr, 0, 0, width, height);
    if(!(flags & CPF_DO_NOT_USE_BORDER))
      gtk_render_frame(context, cr, 0, 0, width, height);
  }


  /* create pango text settings if label exists */
  PangoLayout *layout = NULL;
  int pw = 0, ph = 0;
  const gchar *text = gtk_button_get_label(GTK_BUTTON(widget));
  if(text)
  {
    layout = pango_cairo_create_layout(cr);
    pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc);
    pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi);
    pango_layout_set_text(layout, text, -1);
    pango_layout_get_pixel_size(layout, &pw, &ph);
  }

  gdk_cairo_set_source_rgba(cr, &fg_color);

  /* draw icon */
  if(DTGTK_TOGGLEBUTTON(widget)->icon)
  {
    //     if (flags & CPF_IGNORE_FG_STATE)
    //       state = GTK_STATE_NORMAL;

    int icon_width = text ? height - (border * 2) : width - (border * 2);
    int icon_height = height - (border * 2);

    if(icon_width > 0 && icon_height > 0)
    {
      if(text)
        DTGTK_TOGGLEBUTTON(widget)
            ->icon(cr, border, border, height - (border * 2), height - (border * 2), flags);
      else
        DTGTK_TOGGLEBUTTON(widget)
            ->icon(cr, border, border, width - (border * 2), height - (border * 2), flags);
    }
  }


  /* draw label */
  if(text)
  {
    int lx = DT_PIXEL_APPLY_DPI(2), ly = ((height / 2.0) - (ph / 2.0));
    // if (DTGTK_TOGGLEBUTTON (widget)->icon) lx += width;
    // GdkRectangle t={x,y,x+width,y+height};
    // gtk_paint_layout(style,gtk_widget_get_window(widget),
    // state,TRUE,&t,widget,"togglebutton",lx,ly,layout);
    cairo_translate(cr, lx, ly);
    pango_cairo_show_layout(cr, layout);
    g_object_unref(layout);
  }

  return FALSE;
}
예제 #24
0
static boolean pango_textlayout(textspan_t * span, char **fontpath)
{
    static char buf[1024];  /* returned in fontpath, only good until next call */
    static PangoFontMap *fontmap;
    static PangoContext *context;
    static PangoFontDescription *desc;
    static char *fontname;
    static double fontsize;
    static gv_font_map* gv_fmap;
    char *fnt, *psfnt = NULL;
    PangoLayout *layout;
    PangoRectangle logical_rect;
    cairo_font_options_t* options;
    PangoFont *font;
#ifdef ENABLE_PANGO_MARKUP
    PangoAttrList *attrs;
    GError *error = NULL;
    int flags;
#endif
    char *text;
    double textlayout_scale;
    PostscriptAlias *pA;

    if (!context) {
	fontmap = pango_cairo_font_map_new();
	gv_fmap = get_font_mapping(fontmap);
#ifdef HAVE_PANGO_FONT_MAP_CREATE_CONTEXT
	context = pango_font_map_create_context (fontmap);
#else
	context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap));
#endif
	options=cairo_font_options_create();
	cairo_font_options_set_antialias(options,CAIRO_ANTIALIAS_GRAY);
	cairo_font_options_set_hint_style(options,CAIRO_HINT_STYLE_FULL);
	cairo_font_options_set_hint_metrics(options,CAIRO_HINT_METRICS_ON);
	cairo_font_options_set_subpixel_order(options,CAIRO_SUBPIXEL_ORDER_BGR);
	pango_cairo_context_set_font_options(context, options);
	pango_cairo_context_set_resolution(context, FONT_DPI);
	cairo_font_options_destroy(options);
	g_object_unref(fontmap);
    }

    if (!fontname || strcmp(fontname, span->font->name) != 0 || fontsize != span->font->size) {
	fontname = span->font->name;
	fontsize = span->font->size;
	pango_font_description_free (desc);

	pA = span->font->postscript_alias;
	if (pA) {
	    psfnt = fnt = gv_fmap[pA->xfig_code].gv_font;
	    if(!psfnt)
		psfnt = fnt = pango_psfontResolve (pA);
	}
	else
	    fnt = fontname;

	desc = pango_font_description_from_string(fnt);
        /* all text layout is done at a scale of FONT_DPI (nominaly 96.) */
        pango_font_description_set_size (desc, (gint)(fontsize * PANGO_SCALE));

        if (fontpath && (font = pango_font_map_load_font(fontmap, context, desc))) {  /* -v support */
	    const char *fontclass;

	    fontclass = G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(font));

	    buf[0] = '\0';
	    if (psfnt) {
		strcat(buf, "(ps:pango  ");
		strcat(buf, psfnt);
		strcat(buf, ") ");
	    }
	    strcat(buf, "(");
	    strcat(buf, fontclass);
	    strcat(buf, ") ");
#ifdef HAVE_PANGO_FC_FONT_LOCK_FACE
	    if (strcmp(fontclass, "PangoCairoFcFont") == 0) {
	        FT_Face face;
	        PangoFcFont *fcfont;
	        FT_Stream stream;
	        FT_StreamDesc streamdesc;
	        fcfont = PANGO_FC_FONT(font);
	        face = pango_fc_font_lock_face(fcfont);
	        if (face) {
		    strcat(buf, "\"");
		    strcat(buf, face->family_name);
		    strcat(buf, ", ");
		    strcat(buf, face->style_name);
		    strcat(buf, "\" ");
    
		    stream = face->stream;
		    if (stream) {
			streamdesc = stream->pathname;
			if (streamdesc.pointer)
			    strcat(buf, (char*)streamdesc.pointer);
		        else
			    strcat(buf, "*no pathname available*");
		    }
		    else
			strcat(buf, "*no stream available*");
		}
	        pango_fc_font_unlock_face(fcfont);
	    }
	    else
#endif
	    {
    		PangoFontDescription *tdesc;
		char *tfont;
		
	        tdesc = pango_font_describe(font);
	        tfont = pango_font_description_to_string(tdesc);
	        strcat(buf, "\"");
	        strcat(buf, tfont);
	        strcat(buf, "\" ");
	        g_free(tfont);
	    }
            *fontpath = buf;
        }
    }

#ifdef ENABLE_PANGO_MARKUP
    if ((span->font) && (flags = span->font->flags)) {
	unsigned char buf[BUFSIZ];
	agxbuf xb;

	agxbinit(&xb, BUFSIZ, buf);
	agxbput(&xb,"<span");

	if (flags & HTML_BF)
	    agxbput(&xb," weight=\"bold\"");
	if (flags & HTML_IF)
	    agxbput(&xb," style=\"italic\"");
	if (flags & HTML_UL)
	    agxbput(&xb," underline=\"single\"");
	if (flags & HTML_S)
	    agxbput(&xb," strikethrough=\"true\"");
	agxbput (&xb,">");

	if (flags & HTML_SUP)
	    agxbput(&xb,"<sup>");
	if (flags & HTML_SUB)
	    agxbput(&xb,"<sub>");

	agxbput (&xb,xml_string0(span->str, TRUE));

	if (flags & HTML_SUB)
	    agxbput(&xb,"</sub>");
	if (flags & HTML_SUP)
	    agxbput(&xb,"</sup>");

	agxbput (&xb,"</span>");
	if (!pango_parse_markup (agxbuse(&xb), -1, 0, &attrs, &text, NULL, &error)) {
	    fprintf (stderr, "Error - pango_parse_markup: %s\n", error->message);
	    text = span->str;
	    attrs = NULL;
	}
	agxbfree (&xb);
    }
    else {
	text = span->str;
	attrs = NULL;
    }
#else
    text = span->str;
#endif

    layout = pango_layout_new (context);
    span->layout = (void *)layout;    /* layout free with textspan - see labels.c */
    span->free_layout = pango_free_layout;    /* function for freeing pango layout */

    pango_layout_set_text (layout, text, -1);
    pango_layout_set_font_description (layout, desc);
#ifdef ENABLE_PANGO_MARKUP
    if (attrs)
	pango_layout_set_attributes (layout, attrs);
#endif

    pango_layout_get_extents (layout, NULL, &logical_rect);

    /* if pango doesn't like the font then it sets width=0 but height = garbage */
    if (logical_rect.width == 0)
	logical_rect.height = 0;

    textlayout_scale = POINTS_PER_INCH / (FONT_DPI * PANGO_SCALE);
    span->size.x = (int)(logical_rect.width * textlayout_scale + 1);    /* round up so that width/height are never too small */
    span->size.y = (int)(logical_rect.height * textlayout_scale + 1);

    /* FIXME  -- Horrible kluge !!! */

    /* For now we are using pango for single line blocks only.
     * The logical_rect.height seems to be too high from the font metrics on some platforms.
     * Use an assumed height based on the point size.
     */

    span->size.y = (int)(span->font->size * 1.1 + .5);

    /* The y offset from baseline to 0,0 of the bitmap representation */
#if !defined(WIN32) && defined PANGO_VERSION_MAJOR && (PANGO_VERSION_MAJOR >= 1)
    span->yoffset_layout = pango_layout_get_baseline (layout) * textlayout_scale;
#else
    {
	/* do it the hard way on rhel5/centos5 */
	PangoLayoutIter *iter = pango_layout_get_iter (layout);
	span->yoffset_layout = pango_layout_iter_get_baseline (iter) * textlayout_scale;
    }
#endif

    /* The distance below midline for y centering of text strings */
    span->yoffset_centerline = 0.2 * span->font->size;

    if (logical_rect.width == 0)
	return FALSE;
    return TRUE;
}