/* 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) 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 "libpikabase/pikabase.h" #include "text-types.h" #include "core/pika.h" #include "core/pikadrawable-private.h" /* eek */ #include "core/pikaimage.h" #include "core/pikaparasitelist.h" #include "pikatext.h" #include "pikatext-parasite.h" #include "pikatextlayer.h" #include "pikatextlayer-xcf.h" #include "pika-intl.h" enum { TEXT_LAYER_XCF_NONE = 0, TEXT_LAYER_XCF_DONT_AUTO_RENAME = 1 << 0, TEXT_LAYER_XCF_MODIFIED = 1 << 1 }; static PikaLayer * pika_text_layer_from_layer (PikaLayer *layer, PikaText *text); gboolean pika_text_layer_xcf_load_hack (PikaLayer **layer) { const gchar *name; PikaText *text = NULL; const PikaParasite *parasite; gboolean before_xcf_v19 = FALSE; g_return_val_if_fail (layer != NULL, FALSE); g_return_val_if_fail (PIKA_IS_LAYER (*layer), FALSE); name = pika_text_parasite_name (); parasite = pika_item_parasite_find (PIKA_ITEM (*layer), name); if (parasite) { GError *error = NULL; text = pika_text_from_parasite (parasite, pika_item_get_image (PIKA_ITEM (*layer))->pika, &before_xcf_v19, &error); if (error) { pika_message (pika_item_get_image (PIKA_ITEM (*layer))->pika, NULL, PIKA_MESSAGE_ERROR, _("Problems parsing the text parasite for layer '%s':\n" "%s\n\n" "Some text properties may be wrong. " "Unless you want to edit the text layer, " "you don't need to worry about this."), pika_object_get_name (*layer), error->message); g_clear_error (&error); } } else { name = pika_text_gdyntext_parasite_name (); parasite = pika_item_parasite_find (PIKA_ITEM (*layer), name); if (parasite) { text = pika_text_from_gdyntext_parasite (parasite); before_xcf_v19 = TRUE; } } if (text) { *layer = pika_text_layer_from_layer (*layer, text); /* let the text layer knows what parasite was used to create it */ PIKA_TEXT_LAYER (*layer)->text_parasite = name; PIKA_TEXT_LAYER (*layer)->text_parasite_is_old = before_xcf_v19; } return (text != NULL); } void pika_text_layer_xcf_save_prepare (PikaTextLayer *layer) { PikaText *text; g_return_if_fail (PIKA_IS_TEXT_LAYER (layer)); /* If the layer has a text parasite already, it wasn't changed and we * can simply save the original parasite back which is still attached. */ if (layer->text_parasite) return; text = pika_text_layer_get_text (layer); if (text) { PikaParasite *parasite = pika_text_to_parasite (text); /* Don't push an undo because the parasite only exists temporarily * while the text layer is saved to XCF. */ pika_item_parasite_attach (PIKA_ITEM (layer), parasite, FALSE); pika_parasite_free (parasite); } } guint32 pika_text_layer_get_xcf_flags (PikaTextLayer *text_layer) { guint flags = 0; g_return_val_if_fail (PIKA_IS_TEXT_LAYER (text_layer), 0); if (! text_layer->auto_rename) flags |= TEXT_LAYER_XCF_DONT_AUTO_RENAME; if (text_layer->modified) flags |= TEXT_LAYER_XCF_MODIFIED; return flags; } void pika_text_layer_set_xcf_flags (PikaTextLayer *text_layer, guint32 flags) { g_return_if_fail (PIKA_IS_TEXT_LAYER (text_layer)); g_object_set (text_layer, "auto-rename", (flags & TEXT_LAYER_XCF_DONT_AUTO_RENAME) == 0, "modified", (flags & TEXT_LAYER_XCF_MODIFIED) != 0, NULL); } /** * pika_text_layer_from_layer: * @layer: a #PikaLayer object * @text: a #PikaText object * * Converts a standard #PikaLayer and a #PikaText object into a * #PikaTextLayer. The new text layer takes ownership of the @text and * @layer objects. The @layer object is rendered unusable by this * function. Don't even try to use if afterwards! * * This is a gross hack that is needed in order to load text layers * from XCF files in a backwards-compatible way. Please don't use it * for anything else! * * Returns: a newly allocated #PikaTextLayer object **/ static PikaLayer * pika_text_layer_from_layer (PikaLayer *layer, PikaText *text) { PikaTextLayer *text_layer; PikaDrawable *drawable; g_return_val_if_fail (PIKA_IS_LAYER (layer), NULL); g_return_val_if_fail (PIKA_IS_TEXT (text), NULL); text_layer = g_object_new (PIKA_TYPE_TEXT_LAYER, "image", pika_item_get_image (PIKA_ITEM (layer)), NULL); pika_item_replace_item (PIKA_ITEM (text_layer), PIKA_ITEM (layer)); drawable = PIKA_DRAWABLE (text_layer); pika_drawable_steal_buffer (drawable, PIKA_DRAWABLE (layer)); pika_layer_set_opacity (PIKA_LAYER (text_layer), pika_layer_get_opacity (layer), FALSE); pika_layer_set_mode (PIKA_LAYER (text_layer), pika_layer_get_mode (layer), FALSE); pika_layer_set_blend_space (PIKA_LAYER (text_layer), pika_layer_get_blend_space (layer), FALSE); pika_layer_set_composite_space (PIKA_LAYER (text_layer), pika_layer_get_composite_space (layer), FALSE); pika_layer_set_composite_mode (PIKA_LAYER (text_layer), pika_layer_get_composite_mode (layer), FALSE); pika_layer_set_lock_alpha (PIKA_LAYER (text_layer), pika_layer_get_lock_alpha (layer), FALSE); pika_text_layer_set_text (text_layer, text); g_object_unref (text); g_object_unref (layer); return PIKA_LAYER (text_layer); }