/* PIKA - Photo and Image Kooker Application * a rebranding of The GNU Image Manipulation Program (created with heckimp) * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio * * Original copyright, applying to most contents (license remains unchanged): * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * PikaText * Copyright (C) 2002-2003 Sven Neumann * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "config.h" #include #include #include #include "libpikacolor/pikacolor.h" #include "text-types.h" #include "core/pika.h" #include "core/pikachannel.h" #include "core/pikacontext.h" #include "core/pikadatafactory.h" #include "core/pikaimage.h" #include "core/pikadrawable.h" #include "core/pikaimage.h" #include "core/pikaimage-undo.h" #include "core/pikalayer-floating-selection.h" #include "pikatext.h" #include "pikatext-compat.h" #include "pikatextlayer.h" #include "pika-intl.h" PikaLayer * text_render (PikaImage *image, PikaDrawable *drawable, PikaContext *context, gint text_x, gint text_y, const gchar *fontname, const gchar *text, gint border, gboolean antialias) { PangoFontDescription *desc; PikaText *gtext; PikaLayer *layer; PikaRGB color; gchar *font; gdouble size; g_return_val_if_fail (PIKA_IS_IMAGE (image), NULL); g_return_val_if_fail (drawable == NULL || PIKA_IS_DRAWABLE (drawable), NULL); g_return_val_if_fail (drawable == NULL || pika_item_is_attached (PIKA_ITEM (drawable)), NULL); g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL); g_return_val_if_fail (fontname != NULL, NULL); g_return_val_if_fail (text != NULL, NULL); if (! pika_data_factory_data_wait (image->pika->font_factory)) return NULL; if (border < 0) border = 0; desc = pango_font_description_from_string (fontname); size = PANGO_PIXELS (pango_font_description_get_size (desc)); pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE); font = pango_font_description_to_string (desc); pango_font_description_free (desc); pika_context_get_foreground (context, &color); gtext = g_object_new (PIKA_TYPE_TEXT, "text", text, "font", font, "font-size", size, "antialias", antialias, "border", border, "color", &color, NULL); g_free (font); layer = pika_text_layer_new (image, gtext); g_object_unref (gtext); if (!layer) return NULL; /* Start a group undo */ pika_image_undo_group_start (image, PIKA_UNDO_GROUP_TEXT, _("Add Text Layer")); /* Set the layer offsets */ pika_item_set_offset (PIKA_ITEM (layer), text_x, text_y); /* If there is a selection mask clear it-- * this might not always be desired, but in general, * it seems like the correct behavior. */ if (! pika_channel_is_empty (pika_image_get_mask (image))) pika_channel_clear (pika_image_get_mask (image), NULL, TRUE); if (drawable == NULL) { /* If the drawable is NULL, create a new layer */ pika_image_add_layer (image, layer, NULL, -1, TRUE); } else { /* Otherwise, instantiate the text as the new floating selection */ floating_sel_attach (layer, drawable); } /* end the group undo */ pika_image_undo_group_end (image); return layer; } gboolean text_get_extents (Pika *pika, const gchar *fontname, const gchar *text, gint *width, gint *height, gint *ascent, gint *descent) { PangoFontDescription *font_desc; PangoContext *context; PangoLayout *layout; PangoFontMap *fontmap; PangoRectangle rect; g_return_val_if_fail (PIKA_IS_PIKA (pika), FALSE); g_return_val_if_fail (fontname != NULL, FALSE); g_return_val_if_fail (text != NULL, FALSE); if (! pika_data_factory_data_wait (pika->font_factory)) return FALSE; fontmap = pango_cairo_font_map_new_for_font_type (CAIRO_FONT_TYPE_FT); if (! fontmap) g_error ("You are using a Pango that has been built against a cairo " "that lacks the Freetype font backend"); pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (fontmap), 72.0); /* FIXME: resolution */ context = pango_font_map_create_context (fontmap); g_object_unref (fontmap); layout = pango_layout_new (context); g_object_unref (context); font_desc = pango_font_description_from_string (fontname); pango_layout_set_font_description (layout, font_desc); pango_font_description_free (font_desc); pango_layout_set_text (layout, text, -1); pango_layout_get_pixel_extents (layout, NULL, &rect); if (width) *width = rect.width; if (height) *height = rect.height; if (ascent || descent) { PangoLayoutIter *iter; PangoLayoutLine *line; iter = pango_layout_get_iter (layout); line = pango_layout_iter_get_line_readonly (iter); pango_layout_iter_free (iter); pango_layout_line_get_pixel_extents (line, NULL, &rect); if (ascent) *ascent = PANGO_ASCENT (rect); if (descent) *descent = - PANGO_DESCENT (rect); } g_object_unref (layout); return TRUE; }