Ok this version is way better.
#!/usr/bin/env python
# speech-bubble.py
# Created by TT
# ------------
#| Change Log |
# ------------
# Rel 1.0:
from gimpfu import *
def text_bubble(img, layer,textfile,font,fontsize,fontcolor,backgroundcolor):
# #Set up an undo group, so the operation will be undone in one step.
pdb.gimp_undo_push_group_start(img)
#get path points
vectors = pdb.gimp_image_get_active_vectors(img)
num_strokes,stroke_ids = pdb.gimp_vectors_get_strokes(vectors)
pathpoints = []
arrowpoints = []
for i in range(0,len(stroke_ids)):
_type,_num_points,controlpoints,_closed = pdb.gimp_vectors_stroke_get_points(vectors,stroke_ids[i])
index = 1
while (index*2+1 <= len(controlpoints)):
#grab just the 2 points of center control point
pathpoints.append(controlpoints[index*2:index*2+2])
arrowpoints.append(controlpoints[index*2+2:index*2+4])
index += 3; #increment by 3 to jump to next center control point
with open(textfile,"r") as in_file:
texts = in_file.read().split('\n[breaker]\n')
for i in range(0,len(texts)):
text = texts[i]
number = i+1 #since we're indexing text1, text2, text3 and so on.
# new path version
layer_group = pdb.gimp_layer_group_new(img) #make layer group
pdb.gimp_image_insert_layer(img,layer_group,None,0)
pdb.gimp_item_set_name(layer_group,text)
text_layer = pdb.gimp_text_layer_new(img,text,font,fontsize,0)#Units is either PIXELS(0) POINTS(1)
pdb.gimp_image_insert_layer(img,text_layer,layer_group,0)
pdb.gimp_text_layer_set_color(text_layer,fontcolor)
pdb.gimp_item_set_name(text_layer,'text #'+str(number))
pdb.plug_in_autocrop_layer(img,text_layer) #auto crop
x0 = 0; y0 = 0 #default at top left
ax0 = 0; ay0 = 0 #default of arrow pointing to here
if i <= len(pathpoints):
x0 = pathpoints[i][0]
y0 = pathpoints[i][1]
pdb.gimp_layer_set_offsets(text_layer,x0,y0)
ax0 = arrowpoints[i][0]
ay0 = arrowpoints[i][1]
bgwidth = text_layer.width + fontsize*2
bgheight = text_layer.height + fontsize*2
bglayer = pdb.gimp_layer_new(img,bgwidth,bgheight,RGBA_IMAGE,"bg #"+str(number),100,LAYER_MODE_NORMAL)
pdb.gimp_image_insert_layer(img,bglayer,layer_group,1)
pdb.gimp_layer_set_offsets(bglayer,x0-fontsize,y0-fontsize)
roundcorner = fontsize/2.0
pdb.gimp_image_select_round_rectangle(img,CHANNEL_OP_REPLACE,x0-fontsize,y0-fontsize,bgwidth,bgheight,roundcorner,roundcorner)
pdb.gimp_context_set_foreground(backgroundcolor)
pdb.gimp_edit_fill(bglayer,FILL_FOREGROUND)
mx = x0 + text_layer.width/2.0 #middle of text layer
my = y0 + text_layer.height/2.0
xdiff = (ax0 - mx); ydiff = (ay0 - my)
dist = (xdiff**2.0+ydiff**2.0)**0.5
scaledxdiff = xdiff/dist * fontsize
scaledydiff = ydiff/dist * fontsize
p0x = mx + scaledydiff
p0y = my - scaledxdiff
p1x = mx - scaledydiff
p1y = my + scaledxdiff
pdb.gimp_layer_resize_to_image_size(bglayer)
pdb.gimp_image_select_polygon(img,CHANNEL_OP_REPLACE,6,[p0x,p0y,p1x,p1y,ax0,ay0])
#pdb.gimp_context_set_foreground((255,0,0))
pdb.gimp_edit_fill(bglayer,FILL_FOREGROUND)
pdb.gimp_selection_none(img)
pdb.gimp_undo_push_group_end(img)
#Ensure the updated image is displayed now
pdb.gimp_displays_flush()
register(
"python_fu_text_bubble",
"Puts Text where path is drawn",
"Puts Text where path is drawn",
"TT",
"TT",
"2023.12.8",
"A Text Bubble",
"RGB*", # Alternately use RGB, RGB*, GRAY*, INDEXED etc.
[
#INPUT BEGINS
(PF_IMAGE, "img", "Image", None),
(PF_DRAWABLE, "layer", "Drawable", None),
(PF_FILENAME, "textfile", "Text File:", 0),
(PF_FONT, "font", "Font:", "Verdana"),
(PF_INT, "fontsize", "Font Size:", 20),
(PF_COLOR, "fontcolor", "Font Color:", (0, 0, 0) ),
(PF_COLOR, "backgroundcolor","Background Color:",(255,255,255)),
#INPUT ENDS
],
[],
text_bubble,
menu="<Image>/Python-Fu")
main()
Because it puts the texts into layer groups that's named like the text so users can choose to move active layer and move layer groups one at time which will move the text and background as the layer-group is moved.