/gimp-2.8.0/app/pdb/vectors-cmds.c

# · C · 2466 lines · 2125 code · 244 blank · 97 comment · 90 complexity · 905b72111582827acab55c4f26acba56 MD5 · raw file

Large files are truncated click here to view the full file

  1. /* GIMP - The GNU Image Manipulation Program
  2. * Copyright (C) 1995-2003 Spencer Kimball and Peter Mattis
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. /* NOTE: This file is auto-generated by pdbgen.pl. */
  18. #include "config.h"
  19. #include <string.h>
  20. #include <gegl.h>
  21. #include "pdb-types.h"
  22. #include "core/gimpimage-undo-push.h"
  23. #include "core/gimpimage.h"
  24. #include "core/gimplayer.h"
  25. #include "core/gimplist.h"
  26. #include "core/gimpparamspecs.h"
  27. #include "text/gimptext-vectors.h"
  28. #include "text/gimptextlayer.h"
  29. #include "vectors/gimpanchor.h"
  30. #include "vectors/gimpbezierstroke.h"
  31. #include "vectors/gimpstroke-new.h"
  32. #include "vectors/gimpvectors-export.h"
  33. #include "vectors/gimpvectors-import.h"
  34. #include "vectors/gimpvectors.h"
  35. #include "gimppdb.h"
  36. #include "gimppdb-utils.h"
  37. #include "gimpprocedure.h"
  38. #include "internal-procs.h"
  39. #include "gimp-intl.h"
  40. static GValueArray *
  41. vectors_new_invoker (GimpProcedure *procedure,
  42. Gimp *gimp,
  43. GimpContext *context,
  44. GimpProgress *progress,
  45. const GValueArray *args,
  46. GError **error)
  47. {
  48. gboolean success = TRUE;
  49. GValueArray *return_vals;
  50. GimpImage *image;
  51. const gchar *name;
  52. GimpVectors *vectors = NULL;
  53. image = gimp_value_get_image (&args->values[0], gimp);
  54. name = g_value_get_string (&args->values[1]);
  55. if (success)
  56. {
  57. vectors = gimp_vectors_new (image, name);
  58. }
  59. return_vals = gimp_procedure_get_return_values (procedure, success,
  60. error ? *error : NULL);
  61. if (success)
  62. gimp_value_set_vectors (&return_vals->values[1], vectors);
  63. return return_vals;
  64. }
  65. static GValueArray *
  66. vectors_new_from_text_layer_invoker (GimpProcedure *procedure,
  67. Gimp *gimp,
  68. GimpContext *context,
  69. GimpProgress *progress,
  70. const GValueArray *args,
  71. GError **error)
  72. {
  73. gboolean success = TRUE;
  74. GValueArray *return_vals;
  75. GimpImage *image;
  76. GimpLayer *layer;
  77. GimpVectors *vectors = NULL;
  78. image = gimp_value_get_image (&args->values[0], gimp);
  79. layer = gimp_value_get_layer (&args->values[1], gimp);
  80. if (success)
  81. {
  82. if (gimp_pdb_layer_is_text_layer (layer, FALSE, error))
  83. {
  84. gint x, y;
  85. vectors = gimp_text_vectors_new (image,
  86. gimp_text_layer_get_text (GIMP_TEXT_LAYER (layer)));
  87. gimp_item_get_offset (GIMP_ITEM (layer), &x, &y);
  88. gimp_item_translate (GIMP_ITEM (vectors), x, y, FALSE);
  89. }
  90. else
  91. {
  92. success = FALSE;
  93. }
  94. }
  95. return_vals = gimp_procedure_get_return_values (procedure, success,
  96. error ? *error : NULL);
  97. if (success)
  98. gimp_value_set_vectors (&return_vals->values[1], vectors);
  99. return return_vals;
  100. }
  101. static GValueArray *
  102. vectors_copy_invoker (GimpProcedure *procedure,
  103. Gimp *gimp,
  104. GimpContext *context,
  105. GimpProgress *progress,
  106. const GValueArray *args,
  107. GError **error)
  108. {
  109. gboolean success = TRUE;
  110. GValueArray *return_vals;
  111. GimpVectors *vectors;
  112. GimpVectors *vectors_copy = NULL;
  113. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  114. if (success)
  115. {
  116. vectors_copy = GIMP_VECTORS (gimp_item_duplicate (GIMP_ITEM (vectors),
  117. G_TYPE_FROM_INSTANCE (vectors)));
  118. if (! vectors_copy)
  119. success = FALSE;
  120. }
  121. return_vals = gimp_procedure_get_return_values (procedure, success,
  122. error ? *error : NULL);
  123. if (success)
  124. gimp_value_set_vectors (&return_vals->values[1], vectors_copy);
  125. return return_vals;
  126. }
  127. static GValueArray *
  128. vectors_get_strokes_invoker (GimpProcedure *procedure,
  129. Gimp *gimp,
  130. GimpContext *context,
  131. GimpProgress *progress,
  132. const GValueArray *args,
  133. GError **error)
  134. {
  135. gboolean success = TRUE;
  136. GValueArray *return_vals;
  137. GimpVectors *vectors;
  138. gint32 num_strokes = 0;
  139. gint32 *stroke_ids = NULL;
  140. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  141. if (success)
  142. {
  143. num_strokes = gimp_vectors_get_n_strokes (vectors);
  144. if (num_strokes)
  145. {
  146. GimpStroke *cur_stroke;
  147. gint i = 0;
  148. stroke_ids = g_new (gint32, num_strokes);
  149. for (cur_stroke = gimp_vectors_stroke_get_next (vectors, NULL);
  150. cur_stroke;
  151. cur_stroke = gimp_vectors_stroke_get_next (vectors, cur_stroke))
  152. {
  153. stroke_ids[i] = gimp_stroke_get_ID (cur_stroke);
  154. i++;
  155. }
  156. }
  157. }
  158. return_vals = gimp_procedure_get_return_values (procedure, success,
  159. error ? *error : NULL);
  160. if (success)
  161. {
  162. g_value_set_int (&return_vals->values[1], num_strokes);
  163. gimp_value_take_int32array (&return_vals->values[2], stroke_ids, num_strokes);
  164. }
  165. return return_vals;
  166. }
  167. static GValueArray *
  168. vectors_stroke_get_length_invoker (GimpProcedure *procedure,
  169. Gimp *gimp,
  170. GimpContext *context,
  171. GimpProgress *progress,
  172. const GValueArray *args,
  173. GError **error)
  174. {
  175. gboolean success = TRUE;
  176. GValueArray *return_vals;
  177. GimpVectors *vectors;
  178. gint32 stroke_id;
  179. gdouble precision;
  180. gdouble length = 0.0;
  181. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  182. stroke_id = g_value_get_int (&args->values[1]);
  183. precision = g_value_get_double (&args->values[2]);
  184. if (success)
  185. {
  186. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, FALSE, error);
  187. if (stroke)
  188. length = gimp_stroke_get_length (stroke, precision);
  189. else
  190. success = FALSE;
  191. }
  192. return_vals = gimp_procedure_get_return_values (procedure, success,
  193. error ? *error : NULL);
  194. if (success)
  195. g_value_set_double (&return_vals->values[1], length);
  196. return return_vals;
  197. }
  198. static GValueArray *
  199. vectors_stroke_get_point_at_dist_invoker (GimpProcedure *procedure,
  200. Gimp *gimp,
  201. GimpContext *context,
  202. GimpProgress *progress,
  203. const GValueArray *args,
  204. GError **error)
  205. {
  206. gboolean success = TRUE;
  207. GValueArray *return_vals;
  208. GimpVectors *vectors;
  209. gint32 stroke_id;
  210. gdouble dist;
  211. gdouble precision;
  212. gdouble x_point = 0.0;
  213. gdouble y_point = 0.0;
  214. gdouble slope = 0.0;
  215. gboolean valid = FALSE;
  216. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  217. stroke_id = g_value_get_int (&args->values[1]);
  218. dist = g_value_get_double (&args->values[2]);
  219. precision = g_value_get_double (&args->values[3]);
  220. if (success)
  221. {
  222. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, FALSE, error);
  223. if (stroke)
  224. {
  225. GimpCoords coord;
  226. valid = gimp_stroke_get_point_at_dist (stroke, dist, precision,
  227. &coord, &slope);
  228. x_point = valid ? coord.x : 0;
  229. y_point = valid ? coord.y : 0;
  230. }
  231. else
  232. success = FALSE;
  233. }
  234. return_vals = gimp_procedure_get_return_values (procedure, success,
  235. error ? *error : NULL);
  236. if (success)
  237. {
  238. g_value_set_double (&return_vals->values[1], x_point);
  239. g_value_set_double (&return_vals->values[2], y_point);
  240. g_value_set_double (&return_vals->values[3], slope);
  241. g_value_set_boolean (&return_vals->values[4], valid);
  242. }
  243. return return_vals;
  244. }
  245. static GValueArray *
  246. vectors_remove_stroke_invoker (GimpProcedure *procedure,
  247. Gimp *gimp,
  248. GimpContext *context,
  249. GimpProgress *progress,
  250. const GValueArray *args,
  251. GError **error)
  252. {
  253. gboolean success = TRUE;
  254. GimpVectors *vectors;
  255. gint32 stroke_id;
  256. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  257. stroke_id = g_value_get_int (&args->values[1]);
  258. if (success)
  259. {
  260. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, TRUE, error);
  261. if (stroke)
  262. {
  263. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  264. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  265. _("Remove path stroke"),
  266. vectors);
  267. gimp_vectors_stroke_remove (vectors, stroke);
  268. }
  269. else
  270. success = FALSE;
  271. }
  272. return gimp_procedure_get_return_values (procedure, success,
  273. error ? *error : NULL);
  274. }
  275. static GValueArray *
  276. vectors_stroke_close_invoker (GimpProcedure *procedure,
  277. Gimp *gimp,
  278. GimpContext *context,
  279. GimpProgress *progress,
  280. const GValueArray *args,
  281. GError **error)
  282. {
  283. gboolean success = TRUE;
  284. GimpVectors *vectors;
  285. gint32 stroke_id;
  286. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  287. stroke_id = g_value_get_int (&args->values[1]);
  288. if (success)
  289. {
  290. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, TRUE, error);
  291. if (stroke)
  292. {
  293. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  294. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  295. _("Close path stroke"),
  296. vectors);
  297. gimp_stroke_close (stroke);
  298. }
  299. else
  300. success = FALSE;
  301. }
  302. return gimp_procedure_get_return_values (procedure, success,
  303. error ? *error : NULL);
  304. }
  305. static GValueArray *
  306. vectors_stroke_translate_invoker (GimpProcedure *procedure,
  307. Gimp *gimp,
  308. GimpContext *context,
  309. GimpProgress *progress,
  310. const GValueArray *args,
  311. GError **error)
  312. {
  313. gboolean success = TRUE;
  314. GimpVectors *vectors;
  315. gint32 stroke_id;
  316. gint32 off_x;
  317. gint32 off_y;
  318. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  319. stroke_id = g_value_get_int (&args->values[1]);
  320. off_x = g_value_get_int (&args->values[2]);
  321. off_y = g_value_get_int (&args->values[3]);
  322. if (success)
  323. {
  324. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, TRUE, error);
  325. if (stroke)
  326. {
  327. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  328. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  329. _("Translate path stroke"),
  330. vectors);
  331. gimp_stroke_translate (stroke, off_x, off_y);
  332. }
  333. else
  334. success = FALSE;
  335. }
  336. return gimp_procedure_get_return_values (procedure, success,
  337. error ? *error : NULL);
  338. }
  339. static GValueArray *
  340. vectors_stroke_scale_invoker (GimpProcedure *procedure,
  341. Gimp *gimp,
  342. GimpContext *context,
  343. GimpProgress *progress,
  344. const GValueArray *args,
  345. GError **error)
  346. {
  347. gboolean success = TRUE;
  348. GimpVectors *vectors;
  349. gint32 stroke_id;
  350. gdouble scale_x;
  351. gdouble scale_y;
  352. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  353. stroke_id = g_value_get_int (&args->values[1]);
  354. scale_x = g_value_get_double (&args->values[2]);
  355. scale_y = g_value_get_double (&args->values[3]);
  356. if (success)
  357. {
  358. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, TRUE, error);
  359. if (stroke)
  360. {
  361. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  362. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  363. _("Scale path stroke"),
  364. vectors);
  365. gimp_stroke_scale (stroke, scale_x, scale_y);
  366. }
  367. else
  368. success = FALSE;
  369. }
  370. return gimp_procedure_get_return_values (procedure, success,
  371. error ? *error : NULL);
  372. }
  373. static GValueArray *
  374. vectors_stroke_rotate_invoker (GimpProcedure *procedure,
  375. Gimp *gimp,
  376. GimpContext *context,
  377. GimpProgress *progress,
  378. const GValueArray *args,
  379. GError **error)
  380. {
  381. gboolean success = TRUE;
  382. GimpVectors *vectors;
  383. gint32 stroke_id;
  384. gdouble center_x;
  385. gdouble center_y;
  386. gdouble angle;
  387. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  388. stroke_id = g_value_get_int (&args->values[1]);
  389. center_x = g_value_get_double (&args->values[2]);
  390. center_y = g_value_get_double (&args->values[3]);
  391. angle = g_value_get_double (&args->values[4]);
  392. if (success)
  393. {
  394. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, TRUE, error);
  395. if (stroke)
  396. {
  397. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  398. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  399. _("Rotate path stroke"),
  400. vectors);
  401. gimp_stroke_rotate (stroke, center_x, center_y, angle);
  402. }
  403. else
  404. success = FALSE;
  405. }
  406. return gimp_procedure_get_return_values (procedure, success,
  407. error ? *error : NULL);
  408. }
  409. static GValueArray *
  410. vectors_stroke_flip_invoker (GimpProcedure *procedure,
  411. Gimp *gimp,
  412. GimpContext *context,
  413. GimpProgress *progress,
  414. const GValueArray *args,
  415. GError **error)
  416. {
  417. gboolean success = TRUE;
  418. GimpVectors *vectors;
  419. gint32 stroke_id;
  420. gint32 flip_type;
  421. gdouble axis;
  422. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  423. stroke_id = g_value_get_int (&args->values[1]);
  424. flip_type = g_value_get_enum (&args->values[2]);
  425. axis = g_value_get_double (&args->values[3]);
  426. if (success)
  427. {
  428. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, TRUE, error);
  429. if (stroke)
  430. {
  431. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  432. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  433. _("Flip path stroke"),
  434. vectors);
  435. gimp_stroke_flip (stroke, flip_type, axis);
  436. }
  437. else
  438. success = FALSE;
  439. }
  440. return gimp_procedure_get_return_values (procedure, success,
  441. error ? *error : NULL);
  442. }
  443. static GValueArray *
  444. vectors_stroke_flip_free_invoker (GimpProcedure *procedure,
  445. Gimp *gimp,
  446. GimpContext *context,
  447. GimpProgress *progress,
  448. const GValueArray *args,
  449. GError **error)
  450. {
  451. gboolean success = TRUE;
  452. GimpVectors *vectors;
  453. gint32 stroke_id;
  454. gdouble x1;
  455. gdouble y1;
  456. gdouble x2;
  457. gdouble y2;
  458. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  459. stroke_id = g_value_get_int (&args->values[1]);
  460. x1 = g_value_get_double (&args->values[2]);
  461. y1 = g_value_get_double (&args->values[3]);
  462. x2 = g_value_get_double (&args->values[4]);
  463. y2 = g_value_get_double (&args->values[5]);
  464. if (success)
  465. {
  466. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, TRUE, error);
  467. if (stroke)
  468. {
  469. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  470. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  471. _("Flip path stroke"),
  472. vectors);
  473. gimp_stroke_flip_free (stroke, x1, y1, x2, y2);
  474. }
  475. else
  476. success = FALSE;
  477. }
  478. return gimp_procedure_get_return_values (procedure, success,
  479. error ? *error : NULL);
  480. }
  481. static GValueArray *
  482. vectors_stroke_get_points_invoker (GimpProcedure *procedure,
  483. Gimp *gimp,
  484. GimpContext *context,
  485. GimpProgress *progress,
  486. const GValueArray *args,
  487. GError **error)
  488. {
  489. gboolean success = TRUE;
  490. GValueArray *return_vals;
  491. GimpVectors *vectors;
  492. gint32 stroke_id;
  493. gint32 type = 0;
  494. gint32 num_points = 0;
  495. gdouble *controlpoints = NULL;
  496. gboolean closed = FALSE;
  497. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  498. stroke_id = g_value_get_int (&args->values[1]);
  499. if (success)
  500. {
  501. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, FALSE, error);
  502. if (GIMP_IS_BEZIER_STROKE (stroke))
  503. {
  504. GArray *points_array;
  505. gint i;
  506. points_array = gimp_stroke_control_points_get (stroke, &closed);
  507. if (points_array)
  508. {
  509. num_points = points_array->len;
  510. controlpoints = g_new (gdouble, num_points * 2);
  511. type = GIMP_VECTORS_STROKE_TYPE_BEZIER;
  512. for (i = 0; i < num_points; i++)
  513. {
  514. controlpoints[2*i] = g_array_index (points_array,
  515. GimpAnchor, i).position.x;
  516. controlpoints[2*i+1] = g_array_index (points_array,
  517. GimpAnchor, i).position.y;
  518. }
  519. g_array_free (points_array, TRUE);
  520. num_points *= 2;
  521. }
  522. else
  523. success = FALSE;
  524. }
  525. else
  526. success = FALSE;
  527. }
  528. return_vals = gimp_procedure_get_return_values (procedure, success,
  529. error ? *error : NULL);
  530. if (success)
  531. {
  532. g_value_set_enum (&return_vals->values[1], type);
  533. g_value_set_int (&return_vals->values[2], num_points);
  534. gimp_value_take_floatarray (&return_vals->values[3], controlpoints, num_points);
  535. g_value_set_boolean (&return_vals->values[4], closed);
  536. }
  537. return return_vals;
  538. }
  539. static GValueArray *
  540. vectors_stroke_new_from_points_invoker (GimpProcedure *procedure,
  541. Gimp *gimp,
  542. GimpContext *context,
  543. GimpProgress *progress,
  544. const GValueArray *args,
  545. GError **error)
  546. {
  547. gboolean success = TRUE;
  548. GValueArray *return_vals;
  549. GimpVectors *vectors;
  550. gint32 type;
  551. gint32 num_points;
  552. const gdouble *controlpoints;
  553. gboolean closed;
  554. gint32 stroke_id = 0;
  555. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  556. type = g_value_get_enum (&args->values[1]);
  557. num_points = g_value_get_int (&args->values[2]);
  558. controlpoints = gimp_value_get_floatarray (&args->values[3]);
  559. closed = g_value_get_boolean (&args->values[4]);
  560. if (success)
  561. {
  562. GimpStroke *stroke;
  563. GimpCoords *coords;
  564. GimpCoords default_coords = GIMP_COORDS_DEFAULT_VALUES;
  565. gint i;
  566. success = FALSE;
  567. if (type == GIMP_VECTORS_STROKE_TYPE_BEZIER &&
  568. num_points % 6 == 0)
  569. {
  570. coords = g_new (GimpCoords, num_points/2);
  571. for (i = 0; i < num_points/2; i++)
  572. {
  573. coords[i] = default_coords;
  574. coords[i].x = controlpoints[i*2];
  575. coords[i].y = controlpoints[i*2+1];
  576. }
  577. stroke = gimp_stroke_new_from_coords (type, coords, num_points/2, closed);
  578. if (stroke)
  579. {
  580. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  581. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  582. _("Add path stroke"),
  583. vectors);
  584. gimp_vectors_stroke_add (vectors, stroke);
  585. g_object_unref (stroke);
  586. stroke_id = gimp_stroke_get_ID (stroke);
  587. success = TRUE;
  588. }
  589. g_free (coords);
  590. }
  591. }
  592. return_vals = gimp_procedure_get_return_values (procedure, success,
  593. error ? *error : NULL);
  594. if (success)
  595. g_value_set_int (&return_vals->values[1], stroke_id);
  596. return return_vals;
  597. }
  598. static GValueArray *
  599. vectors_stroke_interpolate_invoker (GimpProcedure *procedure,
  600. Gimp *gimp,
  601. GimpContext *context,
  602. GimpProgress *progress,
  603. const GValueArray *args,
  604. GError **error)
  605. {
  606. gboolean success = TRUE;
  607. GValueArray *return_vals;
  608. GimpVectors *vectors;
  609. gint32 stroke_id;
  610. gdouble precision;
  611. gint32 num_coords = 0;
  612. gdouble *coords = NULL;
  613. gboolean closed = FALSE;
  614. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  615. stroke_id = g_value_get_int (&args->values[1]);
  616. precision = g_value_get_double (&args->values[2]);
  617. if (success)
  618. {
  619. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, FALSE, error);
  620. if (stroke)
  621. {
  622. GArray *coords_array;
  623. gint i;
  624. coords_array = gimp_stroke_interpolate (stroke, precision, &closed);
  625. if (coords_array)
  626. {
  627. num_coords = coords_array->len;
  628. coords = g_new (gdouble, num_coords * 2);
  629. for (i = 0; i < num_coords; i++)
  630. {
  631. coords[2*i] = g_array_index (coords_array, GimpCoords, i).x;
  632. coords[2*i+1] = g_array_index (coords_array, GimpCoords, i).y;
  633. }
  634. g_array_free (coords_array, TRUE);
  635. num_coords *= 2;
  636. }
  637. else
  638. success = FALSE;
  639. }
  640. else
  641. success = FALSE;
  642. }
  643. return_vals = gimp_procedure_get_return_values (procedure, success,
  644. error ? *error : NULL);
  645. if (success)
  646. {
  647. g_value_set_int (&return_vals->values[1], num_coords);
  648. gimp_value_take_floatarray (&return_vals->values[2], coords, num_coords);
  649. g_value_set_boolean (&return_vals->values[3], closed);
  650. }
  651. return return_vals;
  652. }
  653. static GValueArray *
  654. vectors_bezier_stroke_new_moveto_invoker (GimpProcedure *procedure,
  655. Gimp *gimp,
  656. GimpContext *context,
  657. GimpProgress *progress,
  658. const GValueArray *args,
  659. GError **error)
  660. {
  661. gboolean success = TRUE;
  662. GValueArray *return_vals;
  663. GimpVectors *vectors;
  664. gdouble x0;
  665. gdouble y0;
  666. gint32 stroke_id = 0;
  667. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  668. x0 = g_value_get_double (&args->values[1]);
  669. y0 = g_value_get_double (&args->values[2]);
  670. if (success)
  671. {
  672. if (gimp_pdb_item_is_writable (GIMP_ITEM (vectors), error) &&
  673. gimp_pdb_item_is_not_group (GIMP_ITEM (vectors), error))
  674. {
  675. GimpStroke *stroke;
  676. GimpCoords coord0 = GIMP_COORDS_DEFAULT_VALUES;
  677. coord0.x = x0;
  678. coord0.y = y0;
  679. stroke = gimp_bezier_stroke_new_moveto (&coord0);
  680. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  681. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  682. _("Add path stroke"),
  683. vectors);
  684. gimp_vectors_stroke_add (vectors, stroke);
  685. g_object_unref (stroke);
  686. stroke_id = gimp_stroke_get_ID (stroke);
  687. }
  688. else
  689. success = FALSE;
  690. }
  691. return_vals = gimp_procedure_get_return_values (procedure, success,
  692. error ? *error : NULL);
  693. if (success)
  694. g_value_set_int (&return_vals->values[1], stroke_id);
  695. return return_vals;
  696. }
  697. static GValueArray *
  698. vectors_bezier_stroke_lineto_invoker (GimpProcedure *procedure,
  699. Gimp *gimp,
  700. GimpContext *context,
  701. GimpProgress *progress,
  702. const GValueArray *args,
  703. GError **error)
  704. {
  705. gboolean success = TRUE;
  706. GimpVectors *vectors;
  707. gint32 stroke_id;
  708. gdouble x0;
  709. gdouble y0;
  710. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  711. stroke_id = g_value_get_int (&args->values[1]);
  712. x0 = g_value_get_double (&args->values[2]);
  713. y0 = g_value_get_double (&args->values[3]);
  714. if (success)
  715. {
  716. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, TRUE, error);
  717. if (stroke)
  718. {
  719. GimpCoords coord0 = GIMP_COORDS_DEFAULT_VALUES;
  720. coord0.x = x0;
  721. coord0.y = y0;
  722. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  723. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  724. _("Extend path stroke"),
  725. vectors);
  726. gimp_bezier_stroke_lineto (stroke, &coord0);
  727. }
  728. else
  729. success = FALSE;
  730. }
  731. return gimp_procedure_get_return_values (procedure, success,
  732. error ? *error : NULL);
  733. }
  734. static GValueArray *
  735. vectors_bezier_stroke_conicto_invoker (GimpProcedure *procedure,
  736. Gimp *gimp,
  737. GimpContext *context,
  738. GimpProgress *progress,
  739. const GValueArray *args,
  740. GError **error)
  741. {
  742. gboolean success = TRUE;
  743. GimpVectors *vectors;
  744. gint32 stroke_id;
  745. gdouble x0;
  746. gdouble y0;
  747. gdouble x1;
  748. gdouble y1;
  749. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  750. stroke_id = g_value_get_int (&args->values[1]);
  751. x0 = g_value_get_double (&args->values[2]);
  752. y0 = g_value_get_double (&args->values[3]);
  753. x1 = g_value_get_double (&args->values[4]);
  754. y1 = g_value_get_double (&args->values[5]);
  755. if (success)
  756. {
  757. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, TRUE, error);
  758. if (stroke)
  759. {
  760. GimpCoords coord0 = GIMP_COORDS_DEFAULT_VALUES;
  761. GimpCoords coord1 = GIMP_COORDS_DEFAULT_VALUES;
  762. coord0.x = x0;
  763. coord0.y = y0;
  764. coord1.x = x1;
  765. coord1.y = y1;
  766. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  767. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  768. _("Extend path stroke"),
  769. vectors);
  770. gimp_bezier_stroke_conicto (stroke, &coord0, &coord1);
  771. }
  772. else
  773. success = FALSE;
  774. }
  775. return gimp_procedure_get_return_values (procedure, success,
  776. error ? *error : NULL);
  777. }
  778. static GValueArray *
  779. vectors_bezier_stroke_cubicto_invoker (GimpProcedure *procedure,
  780. Gimp *gimp,
  781. GimpContext *context,
  782. GimpProgress *progress,
  783. const GValueArray *args,
  784. GError **error)
  785. {
  786. gboolean success = TRUE;
  787. GimpVectors *vectors;
  788. gint32 stroke_id;
  789. gdouble x0;
  790. gdouble y0;
  791. gdouble x1;
  792. gdouble y1;
  793. gdouble x2;
  794. gdouble y2;
  795. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  796. stroke_id = g_value_get_int (&args->values[1]);
  797. x0 = g_value_get_double (&args->values[2]);
  798. y0 = g_value_get_double (&args->values[3]);
  799. x1 = g_value_get_double (&args->values[4]);
  800. y1 = g_value_get_double (&args->values[5]);
  801. x2 = g_value_get_double (&args->values[6]);
  802. y2 = g_value_get_double (&args->values[7]);
  803. if (success)
  804. {
  805. GimpStroke *stroke = gimp_pdb_get_vectors_stroke (vectors, stroke_id, TRUE, error);
  806. if (stroke)
  807. {
  808. GimpCoords coord0 = GIMP_COORDS_DEFAULT_VALUES;
  809. GimpCoords coord1 = GIMP_COORDS_DEFAULT_VALUES;
  810. GimpCoords coord2 = GIMP_COORDS_DEFAULT_VALUES;
  811. coord0.x = x0;
  812. coord0.y = y0;
  813. coord1.x = x1;
  814. coord1.y = y1;
  815. coord2.x = x2;
  816. coord2.y = y2;
  817. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  818. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  819. _("Extend path stroke"),
  820. vectors);
  821. gimp_bezier_stroke_cubicto (stroke, &coord0, &coord1, &coord2);
  822. }
  823. else
  824. success = FALSE;
  825. }
  826. return gimp_procedure_get_return_values (procedure, success,
  827. error ? *error : NULL);
  828. }
  829. static GValueArray *
  830. vectors_bezier_stroke_new_ellipse_invoker (GimpProcedure *procedure,
  831. Gimp *gimp,
  832. GimpContext *context,
  833. GimpProgress *progress,
  834. const GValueArray *args,
  835. GError **error)
  836. {
  837. gboolean success = TRUE;
  838. GValueArray *return_vals;
  839. GimpVectors *vectors;
  840. gdouble x0;
  841. gdouble y0;
  842. gdouble radius_x;
  843. gdouble radius_y;
  844. gdouble angle;
  845. gint32 stroke_id = 0;
  846. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  847. x0 = g_value_get_double (&args->values[1]);
  848. y0 = g_value_get_double (&args->values[2]);
  849. radius_x = g_value_get_double (&args->values[3]);
  850. radius_y = g_value_get_double (&args->values[4]);
  851. angle = g_value_get_double (&args->values[5]);
  852. if (success)
  853. {
  854. if (gimp_pdb_item_is_writable (GIMP_ITEM (vectors), error) &&
  855. gimp_pdb_item_is_not_group (GIMP_ITEM (vectors), error))
  856. {
  857. GimpStroke *stroke;
  858. GimpCoords coord0 = GIMP_COORDS_DEFAULT_VALUES;
  859. coord0.x = x0;
  860. coord0.y = y0;
  861. stroke = gimp_bezier_stroke_new_ellipse (&coord0, radius_x, radius_y, angle);
  862. if (gimp_item_is_attached (GIMP_ITEM (vectors)))
  863. gimp_image_undo_push_vectors_mod (gimp_item_get_image (GIMP_ITEM (vectors)),
  864. _("Add path stroke"),
  865. vectors);
  866. gimp_vectors_stroke_add (vectors, stroke);
  867. g_object_unref (stroke);
  868. stroke_id = gimp_stroke_get_ID (stroke);
  869. }
  870. else
  871. success = FALSE;
  872. }
  873. return_vals = gimp_procedure_get_return_values (procedure, success,
  874. error ? *error : NULL);
  875. if (success)
  876. g_value_set_int (&return_vals->values[1], stroke_id);
  877. return return_vals;
  878. }
  879. static GValueArray *
  880. vectors_to_selection_invoker (GimpProcedure *procedure,
  881. Gimp *gimp,
  882. GimpContext *context,
  883. GimpProgress *progress,
  884. const GValueArray *args,
  885. GError **error)
  886. {
  887. gboolean success = TRUE;
  888. GimpVectors *vectors;
  889. gint32 operation;
  890. gboolean antialias;
  891. gboolean feather;
  892. gdouble feather_radius_x;
  893. gdouble feather_radius_y;
  894. vectors = gimp_value_get_vectors (&args->values[0], gimp);
  895. operation = g_value_get_enum (&args->values[1]);
  896. antialias = g_value_get_boolean (&args->values[2]);
  897. feather = g_value_get_boolean (&args->values[3]);
  898. feather_radius_x = g_value_get_double (&args->values[4]);
  899. feather_radius_y = g_value_get_double (&args->values[5]);
  900. if (success)
  901. {
  902. if (gimp_pdb_item_is_attached (GIMP_ITEM (vectors), NULL, FALSE, error))
  903. gimp_item_to_selection (GIMP_ITEM (vectors),
  904. operation,
  905. antialias,
  906. feather,
  907. feather_radius_x,
  908. feather_radius_y);
  909. else
  910. success = FALSE;
  911. }
  912. return gimp_procedure_get_return_values (procedure, success,
  913. error ? *error : NULL);
  914. }
  915. static GValueArray *
  916. vectors_import_from_file_invoker (GimpProcedure *procedure,
  917. Gimp *gimp,
  918. GimpContext *context,
  919. GimpProgress *progress,
  920. const GValueArray *args,
  921. GError **error)
  922. {
  923. gboolean success = TRUE;
  924. GValueArray *return_vals;
  925. GimpImage *image;
  926. const gchar *filename;
  927. gboolean merge;
  928. gboolean scale;
  929. gint32 num_vectors = 0;
  930. gint32 *vectors_ids = NULL;
  931. image = gimp_value_get_image (&args->values[0], gimp);
  932. filename = g_value_get_string (&args->values[1]);
  933. merge = g_value_get_boolean (&args->values[2]);
  934. scale = g_value_get_boolean (&args->values[3]);
  935. if (success)
  936. {
  937. GList *list, *vectors_list = NULL;
  938. /* FIXME tree */
  939. success = gimp_vectors_import_file (image, filename,
  940. merge, scale, NULL, -1,
  941. &vectors_list, error);
  942. if (success)
  943. {
  944. num_vectors = g_list_length (vectors_list);
  945. if (num_vectors)
  946. {
  947. gint i;
  948. vectors_ids = g_new (gint32, num_vectors);
  949. list = vectors_list;
  950. for (i = 0; i < num_vectors; i++, list = g_list_next (list))
  951. vectors_ids[i] = gimp_item_get_ID (GIMP_ITEM (list->data));
  952. g_list_free (vectors_list);
  953. }
  954. }
  955. }
  956. return_vals = gimp_procedure_get_return_values (procedure, success,
  957. error ? *error : NULL);
  958. if (success)
  959. {
  960. g_value_set_int (&return_vals->values[1], num_vectors);
  961. gimp_value_take_int32array (&return_vals->values[2], vectors_ids, num_vectors);
  962. }
  963. return return_vals;
  964. }
  965. static GValueArray *
  966. vectors_import_from_string_invoker (GimpProcedure *procedure,
  967. Gimp *gimp,
  968. GimpContext *context,
  969. GimpProgress *progress,
  970. const GValueArray *args,
  971. GError **error)
  972. {
  973. gboolean success = TRUE;
  974. GValueArray *return_vals;
  975. GimpImage *image;
  976. const gchar *string;
  977. gint32 length;
  978. gboolean merge;
  979. gboolean scale;
  980. gint32 num_vectors = 0;
  981. gint32 *vectors_ids = NULL;
  982. image = gimp_value_get_image (&args->values[0], gimp);
  983. string = g_value_get_string (&args->values[1]);
  984. length = g_value_get_int (&args->values[2]);
  985. merge = g_value_get_boolean (&args->values[3]);
  986. scale = g_value_get_boolean (&args->values[4]);
  987. if (success)
  988. {
  989. GList *list, *vectors_list = NULL;
  990. /* FIXME tree */
  991. success = gimp_vectors_import_buffer (image, string, length,
  992. merge, scale, NULL, -1,
  993. &vectors_list, error);
  994. if (success)
  995. {
  996. num_vectors = g_list_length (vectors_list);
  997. if (num_vectors)
  998. {
  999. gint i;
  1000. vectors_ids = g_new (gint32, num_vectors);
  1001. list = vectors_list;
  1002. for (i = 0; i < num_vectors; i++, list = g_list_next (list))
  1003. vectors_ids[i] = gimp_item_get_ID (GIMP_ITEM (list->data));
  1004. g_list_free (vectors_list);
  1005. }
  1006. }
  1007. }
  1008. return_vals = gimp_procedure_get_return_values (procedure, success,
  1009. error ? *error : NULL);
  1010. if (success)
  1011. {
  1012. g_value_set_int (&return_vals->values[1], num_vectors);
  1013. gimp_value_take_int32array (&return_vals->values[2], vectors_ids, num_vectors);
  1014. }
  1015. return return_vals;
  1016. }
  1017. static GValueArray *
  1018. vectors_export_to_file_invoker (GimpProcedure *procedure,
  1019. Gimp *gimp,
  1020. GimpContext *context,
  1021. GimpProgress *progress,
  1022. const GValueArray *args,
  1023. GError **error)
  1024. {
  1025. gboolean success = TRUE;
  1026. GimpImage *image;
  1027. const gchar *filename;
  1028. GimpVectors *vectors;
  1029. image = gimp_value_get_image (&args->values[0], gimp);
  1030. filename = g_value_get_string (&args->values[1]);
  1031. vectors = gimp_value_get_vectors (&args->values[2], gimp);
  1032. if (success)
  1033. {
  1034. success = gimp_vectors_export_file (image, vectors, filename, error);
  1035. }
  1036. return gimp_procedure_get_return_values (procedure, success,
  1037. error ? *error : NULL);
  1038. }
  1039. static GValueArray *
  1040. vectors_export_to_string_invoker (GimpProcedure *procedure,
  1041. Gimp *gimp,
  1042. GimpContext *context,
  1043. GimpProgress *progress,
  1044. const GValueArray *args,
  1045. GError **error)
  1046. {
  1047. gboolean success = TRUE;
  1048. GValueArray *return_vals;
  1049. GimpImage *image;
  1050. GimpVectors *vectors;
  1051. gchar *string = NULL;
  1052. image = gimp_value_get_image (&args->values[0], gimp);
  1053. vectors = gimp_value_get_vectors (&args->values[1], gimp);
  1054. if (success)
  1055. {
  1056. string = gimp_vectors_export_string (image, vectors);
  1057. success = (string != NULL);
  1058. }
  1059. return_vals = gimp_procedure_get_return_values (procedure, success,
  1060. error ? *error : NULL);
  1061. if (success)
  1062. g_value_take_string (&return_vals->values[1], string);
  1063. return return_vals;
  1064. }
  1065. void
  1066. register_vectors_procs (GimpPDB *pdb)
  1067. {
  1068. GimpProcedure *procedure;
  1069. /*
  1070. * gimp-vectors-new
  1071. */
  1072. procedure = gimp_procedure_new (vectors_new_invoker);
  1073. gimp_object_set_static_name (GIMP_OBJECT (procedure),
  1074. "gimp-vectors-new");
  1075. gimp_procedure_set_static_strings (procedure,
  1076. "gimp-vectors-new",
  1077. "Creates a new empty vectors object.",
  1078. "Creates a new empty vectors object. The vectors object needs to be added to the image using 'gimp-image-insert-vectors'.",
  1079. "Simon Budig",
  1080. "Simon Budig",
  1081. "2005",
  1082. NULL);
  1083. gimp_procedure_add_argument (procedure,
  1084. gimp_param_spec_image_id ("image",
  1085. "image",
  1086. "The image",
  1087. pdb->gimp, FALSE,
  1088. GIMP_PARAM_READWRITE));
  1089. gimp_procedure_add_argument (procedure,
  1090. gimp_param_spec_string ("name",
  1091. "name",
  1092. "the name of the new vector object.",
  1093. FALSE, FALSE, FALSE,
  1094. NULL,
  1095. GIMP_PARAM_READWRITE));
  1096. gimp_procedure_add_return_value (procedure,
  1097. gimp_param_spec_vectors_id ("vectors",
  1098. "vectors",
  1099. "the current vector object, 0 if no vector exists in the image.",
  1100. pdb->gimp, FALSE,
  1101. GIMP_PARAM_READWRITE));
  1102. gimp_pdb_register_procedure (pdb, procedure);
  1103. g_object_unref (procedure);
  1104. /*
  1105. * gimp-vectors-new-from-text-layer
  1106. */
  1107. procedure = gimp_procedure_new (vectors_new_from_text_layer_invoker);
  1108. gimp_object_set_static_name (GIMP_OBJECT (procedure),
  1109. "gimp-vectors-new-from-text-layer");
  1110. gimp_procedure_set_static_strings (procedure,
  1111. "gimp-vectors-new-from-text-layer",
  1112. "Creates a new vectors object from a text layer.",
  1113. "Creates a new vectors object from a text layer. The vectors object needs to be added to the image using 'gimp-image-insert-vectors'.",
  1114. "Marcus Heese <heese@cip.ifi.lmu.de>",
  1115. "Marcus Heese",
  1116. "2008",
  1117. NULL);
  1118. gimp_procedure_add_argument (procedure,
  1119. gimp_param_spec_image_id ("image",
  1120. "image",
  1121. "The image.",
  1122. pdb->gimp, FALSE,
  1123. GIMP_PARAM_READWRITE));
  1124. gimp_procedure_add_argument (procedure,
  1125. gimp_param_spec_layer_id ("layer",
  1126. "layer",
  1127. "The text layer.",
  1128. pdb->gimp, FALSE,
  1129. GIMP_PARAM_READWRITE));
  1130. gimp_procedure_add_return_value (procedure,
  1131. gimp_param_spec_vectors_id ("vectors",
  1132. "vectors",
  1133. "The vectors of the text layer.",
  1134. pdb->gimp, FALSE,
  1135. GIMP_PARAM_READWRITE));
  1136. gimp_pdb_register_procedure (pdb, procedure);
  1137. g_object_unref (procedure);
  1138. /*
  1139. * gimp-vectors-copy
  1140. */
  1141. procedure = gimp_procedure_new (vectors_copy_invoker);
  1142. gimp_object_set_static_name (GIMP_OBJECT (procedure),
  1143. "gimp-vectors-copy");
  1144. gimp_procedure_set_static_strings (procedure,
  1145. "gimp-vectors-copy",
  1146. "Copy a vectors object.",
  1147. "This procedure copies the specified vectors object and returns the copy.",
  1148. "Barak Itkin <lightningismyname@gmail.com>",
  1149. "Barak Itkin",
  1150. "2008",
  1151. NULL);
  1152. gimp_procedure_add_argument (procedure,
  1153. gimp_param_spec_vectors_id ("vectors",
  1154. "vectors",
  1155. "The vectors object to copy",
  1156. pdb->gimp, FALSE,
  1157. GIMP_PARAM_READWRITE));
  1158. gimp_procedure_add_return_value (procedure,
  1159. gimp_param_spec_vectors_id ("vectors-copy",
  1160. "vectors copy",
  1161. "The newly copied vectors object",
  1162. pdb->gimp, FALSE,
  1163. GIMP_PARAM_READWRITE));
  1164. gimp_pdb_register_procedure (pdb, procedure);
  1165. g_object_unref (procedure);
  1166. /*
  1167. * gimp-vectors-get-strokes
  1168. */
  1169. procedure = gimp_procedure_new (vectors_get_strokes_invoker);
  1170. gimp_object_set_static_name (GIMP_OBJECT (procedure),
  1171. "gimp-vectors-get-strokes");
  1172. gimp_procedure_set_static_strings (procedure,
  1173. "gimp-vectors-get-strokes",
  1174. "List the strokes associated with the passed path.",
  1175. "Returns an Array with the stroke-IDs associated with the passed path.",
  1176. "Simon Budig",
  1177. "Simon Budig",
  1178. "2005",
  1179. NULL);
  1180. gimp_procedure_add_argument (procedure,
  1181. gimp_param_spec_vectors_id ("vectors",
  1182. "vectors",
  1183. "The vectors object",
  1184. pdb->gimp, FALSE,
  1185. GIMP_PARAM_READWRITE));
  1186. gimp_procedure_add_return_value (procedure,
  1187. gimp_param_spec_int32 ("num-strokes",
  1188. "num strokes",
  1189. "The number of strokes returned.",
  1190. 0, G_MAXINT32, 0,
  1191. GIMP_PARAM_READWRITE));
  1192. gimp_procedure_add_return_value (procedure,
  1193. gimp_param_spec_int32_array ("stroke-ids",
  1194. "stroke ids",
  1195. "List of the strokes belonging to the path.",
  1196. GIMP_PARAM_READWRITE));
  1197. gimp_pdb_register_procedure (pdb, procedure);
  1198. g_object_unref (procedure);
  1199. /*
  1200. * gimp-vectors-stroke-get-length
  1201. */
  1202. procedure = gimp_procedure_new (vectors_stroke_get_length_invoker);
  1203. gimp_object_set_static_name (GIMP_OBJECT (procedure),
  1204. "gimp-vectors-stroke-get-length");
  1205. gimp_procedure_set_static_strings (procedure,
  1206. "gimp-vectors-stroke-get-length",
  1207. "Measure the length of the given stroke.",