~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to app/vectors/gimpvectors-import.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* The GIMP -- an image manipulation program
 
1
/* GIMP - The GNU Image Manipulation Program
2
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
3
 *
4
4
 * GimpVectors Import
95
95
                                       gboolean              merge,
96
96
                                       gboolean              scale,
97
97
                                       gint                  position,
 
98
                                       GList               **ret_vectors,
98
99
                                       GError              **error);
99
100
 
100
101
static void  svg_parser_start_element (GMarkupParseContext  *context,
187
188
 *
188
189
 * Imports one or more paths and basic shapes from a SVG file.
189
190
 *
190
 
 * Return value: %TRUE on success, %FALSE if an error occured
 
191
 * Return value: %TRUE on success, %FALSE if an error occurred
191
192
 **/
192
193
gboolean
193
194
gimp_vectors_import_file (GimpImage    *image,
195
196
                          gboolean      merge,
196
197
                          gboolean      scale,
197
198
                          gint          position,
 
199
                          GList       **ret_vectors,
198
200
                          GError      **error)
199
201
{
200
202
  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
201
203
  g_return_val_if_fail (filename != NULL, FALSE);
 
204
  g_return_val_if_fail (ret_vectors == NULL || *ret_vectors == NULL, FALSE);
202
205
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
203
206
 
204
207
  return gimp_vectors_import (image, filename, NULL, 0, merge, scale, position,
205
 
                              error);
 
208
                              ret_vectors, error);
206
209
}
207
210
 
208
211
/**
216
219
 *
217
220
 * Imports one or more paths and basic shapes from a SVG file.
218
221
 *
219
 
 * Return value: %TRUE on success, %FALSE if an error occured
 
222
 * Return value: %TRUE on success, %FALSE if an error occurred
220
223
 **/
221
224
gboolean
222
225
gimp_vectors_import_buffer (GimpImage    *image,
225
228
                            gboolean      merge,
226
229
                            gboolean      scale,
227
230
                            gint          position,
 
231
                            GList       **ret_vectors,
228
232
                            GError      **error)
229
233
{
230
234
  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
231
235
  g_return_val_if_fail (buffer != NULL || len == 0, FALSE);
 
236
  g_return_val_if_fail (ret_vectors == NULL || *ret_vectors == NULL, FALSE);
232
237
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
233
238
 
234
239
  return gimp_vectors_import (image, NULL, buffer, len, merge, scale, position,
235
 
                              error);
 
240
                              ret_vectors, error);
236
241
}
237
242
 
238
243
static gboolean
243
248
                     gboolean      merge,
244
249
                     gboolean      scale,
245
250
                     gint          position,
 
251
                     GList       **ret_vectors,
246
252
                     GError      **error)
247
253
{
248
254
  GimpXmlParser *xml_parser;
299
305
                  gimp_image_add_vectors (image, vectors, position);
300
306
                  gimp_vectors_freeze (vectors);
301
307
 
 
308
                  if (ret_vectors)
 
309
                    *ret_vectors = g_list_prepend (*ret_vectors, vectors);
 
310
 
302
311
                  if (position != -1)
303
312
                    position++;
304
313
                }
464
473
 
465
474
  while (*names)
466
475
    {
467
 
      if (strcmp (*names, "x") == 0)
468
 
        {
469
 
          parse_svg_length (*values,
470
 
                            handler->width, parser->image->xresolution, &x);
471
 
        }
472
 
      else if (strcmp (*names, "y") == 0)
473
 
        {
474
 
          parse_svg_length (*values,
475
 
                            handler->height, parser->image->yresolution, &y);
476
 
        }
477
 
      else if (strcmp (*names, "width") == 0)
478
 
        {
479
 
          parse_svg_length (*values,
480
 
                            handler->width, parser->image->xresolution, &w);
481
 
        }
482
 
      else if (strcmp (*names, "height") == 0)
483
 
        {
484
 
          parse_svg_length (*values,
485
 
                            handler->height, parser->image->yresolution, &h);
486
 
        }
487
 
      else if (strcmp (*names, "viewBox") == 0)
488
 
        {
489
 
          viewbox = *values;
 
476
      switch (*names[0])
 
477
        {
 
478
        case 'x':
 
479
          if (strcmp (*names, "x") == 0)
 
480
            parse_svg_length (*values,
 
481
                              handler->width, parser->image->xresolution, &x);
 
482
          break;
 
483
 
 
484
        case 'y':
 
485
          if (strcmp (*names, "y") == 0)
 
486
            parse_svg_length (*values,
 
487
                              handler->height, parser->image->yresolution, &y);
 
488
          break;
 
489
 
 
490
        case 'w':
 
491
          if (strcmp (*names, "width") == 0)
 
492
            parse_svg_length (*values,
 
493
                              handler->width, parser->image->xresolution, &w);
 
494
          break;
 
495
 
 
496
        case 'h':
 
497
          if (strcmp (*names, "height") == 0)
 
498
            parse_svg_length (*values,
 
499
                              handler->height, parser->image->yresolution, &h);
 
500
          break;
 
501
 
 
502
        case 'v':
 
503
          if (strcmp (*names, "viewBox") == 0)
 
504
            viewbox = *values;
 
505
          break;
490
506
        }
491
507
 
492
508
      names++;
576
592
 
577
593
  while (*names)
578
594
    {
579
 
      if (strcmp (*names, "id") == 0 && !path->id)
580
 
        {
581
 
          path->id = g_strdup (*values);
582
 
        }
583
 
      else if (strcmp (*names, "d") == 0 && !path->strokes)
584
 
        {
585
 
          path->strokes = parse_path_data (*values);
586
 
        }
587
 
      else if (strcmp (*names, "transform") == 0 && !handler->transform)
588
 
        {
589
 
          GimpMatrix3  matrix;
590
 
 
591
 
          if (parse_svg_transform (*values, &matrix))
592
 
            handler->transform = g_memdup (&matrix, sizeof (GimpMatrix3));
 
595
      switch (*names[0])
 
596
        {
 
597
        case 'i':
 
598
          if (strcmp (*names, "id") == 0 && !path->id)
 
599
            path->id = g_strdup (*values);
 
600
          break;
 
601
 
 
602
        case 'd':
 
603
          if (strcmp (*names, "d") == 0 && !path->strokes)
 
604
            path->strokes = parse_path_data (*values);
 
605
          break;
 
606
 
 
607
        case 't':
 
608
          if (strcmp (*names, "transform") == 0 && !handler->transform)
 
609
            {
 
610
              GimpMatrix3  matrix;
 
611
 
 
612
              if (parse_svg_transform (*values, &matrix))
 
613
                handler->transform = g_memdup (&matrix, sizeof (GimpMatrix3));
 
614
            }
 
615
          break;
593
616
        }
594
617
 
595
618
      names++;
615
638
 
616
639
  while (*names)
617
640
    {
618
 
      if (strcmp (*names, "id") == 0 && !path->id)
619
 
        {
620
 
          path->id = g_strdup (*values);
621
 
        }
622
 
      else if (strcmp (*names, "x") == 0)
623
 
        {
624
 
          parse_svg_length (*values,
625
 
                            handler->width, parser->image->xresolution,
626
 
                            &x);
627
 
        }
628
 
      else if (strcmp (*names, "y") == 0)
629
 
        {
630
 
          parse_svg_length (*values,
631
 
                            handler->height, parser->image->yresolution,
632
 
                            &y);
633
 
        }
634
 
      else if (strcmp (*names, "width") == 0)
635
 
        {
636
 
          parse_svg_length (*values,
637
 
                            handler->width, parser->image->xresolution,
638
 
                            &width);
639
 
        }
640
 
      else if (strcmp (*names, "height") == 0)
641
 
        {
642
 
          parse_svg_length (*values,
643
 
                            handler->height, parser->image->yresolution,
644
 
                            &height);
645
 
        }
646
 
      else if (strcmp (*names, "rx") == 0)
647
 
        {
648
 
          parse_svg_length (*values,
649
 
                            handler->width, parser->image->xresolution,
650
 
                            &rx);
651
 
        }
652
 
      else if (strcmp (*names, "ry") == 0)
653
 
        {
654
 
          parse_svg_length (*values,
655
 
                            handler->height, parser->image->yresolution,
656
 
                            &ry);
657
 
        }
658
 
      else if (strcmp (*names, "transform") == 0 && !handler->transform)
659
 
        {
660
 
          GimpMatrix3  matrix;
661
 
 
662
 
          if (parse_svg_transform (*values, &matrix))
663
 
            handler->transform = g_memdup (&matrix, sizeof (GimpMatrix3));
 
641
      switch (*names[0])
 
642
        {
 
643
        case 'i':
 
644
          if (strcmp (*names, "id") == 0 && !path->id)
 
645
            path->id = g_strdup (*values);
 
646
          break;
 
647
 
 
648
        case 'x':
 
649
          if (strcmp (*names, "x") == 0)
 
650
            parse_svg_length (*values,
 
651
                              handler->width, parser->image->xresolution,
 
652
                              &x);
 
653
          break;
 
654
 
 
655
        case 'y':
 
656
          if (strcmp (*names, "y") == 0)
 
657
            parse_svg_length (*values,
 
658
                              handler->height, parser->image->yresolution,
 
659
                              &y);
 
660
          break;
 
661
 
 
662
        case 'w':
 
663
          if (strcmp (*names, "width") == 0)
 
664
            parse_svg_length (*values,
 
665
                              handler->width, parser->image->xresolution,
 
666
                              &width);
 
667
          break;
 
668
 
 
669
        case 'h':
 
670
          if (strcmp (*names, "height") == 0)
 
671
            parse_svg_length (*values,
 
672
                              handler->height, parser->image->yresolution,
 
673
                              &height);
 
674
          break;
 
675
 
 
676
        case 'r':
 
677
          if (strcmp (*names, "rx") == 0)
 
678
            parse_svg_length (*values,
 
679
                              handler->width, parser->image->xresolution,
 
680
                              &rx);
 
681
          else if (strcmp (*names, "ry") == 0)
 
682
            parse_svg_length (*values,
 
683
                              handler->height, parser->image->yresolution,
 
684
                              &ry);
 
685
          break;
 
686
 
 
687
        case 't':
 
688
          if (strcmp (*names, "transform") == 0 && !handler->transform)
 
689
            {
 
690
              GimpMatrix3  matrix;
 
691
 
 
692
              if (parse_svg_transform (*values, &matrix))
 
693
                handler->transform = g_memdup (&matrix, sizeof (GimpMatrix3));
 
694
            }
 
695
          break;
664
696
        }
665
697
 
666
698
      names++;
758
790
 
759
791
  while (*names)
760
792
    {
761
 
      if (strcmp (*names, "id") == 0 && !path->id)
762
 
        {
763
 
          path->id = g_strdup (*values);
764
 
        }
765
 
      else if (strcmp (*names, "cx") == 0)
766
 
        {
767
 
          parse_svg_length (*values,
768
 
                            handler->width, parser->image->xresolution,
769
 
                            &center.x);
770
 
        }
771
 
      else if (strcmp (*names, "cy") == 0)
772
 
        {
773
 
          parse_svg_length (*values,
774
 
                            handler->height, parser->image->yresolution,
775
 
                            &center.y);
776
 
        }
777
 
      else if (strcmp (*names, "r") == 0)
778
 
        {
779
 
          parse_svg_length (*values,
780
 
                            handler->width, parser->image->xresolution,
781
 
                            &rx);
782
 
          parse_svg_length (*values,
783
 
                            handler->height, parser->image->yresolution,
784
 
                            &ry);
785
 
        }
786
 
      else if (strcmp (*names, "rx") == 0)
787
 
        {
788
 
          parse_svg_length (*values,
789
 
                            handler->width, parser->image->xresolution,
790
 
                            &rx);
791
 
        }
792
 
      else if (strcmp (*names, "ry") == 0)
793
 
        {
794
 
          parse_svg_length (*values,
795
 
                            handler->height, parser->image->yresolution,
796
 
                            &ry);
797
 
        }
798
 
      else if (strcmp (*names, "transform") == 0 && !handler->transform)
799
 
        {
800
 
          GimpMatrix3  matrix;
801
 
 
802
 
          if (parse_svg_transform (*values, &matrix))
803
 
            handler->transform = g_memdup (&matrix, sizeof (GimpMatrix3));
 
793
      switch (*names[0])
 
794
        {
 
795
        case 'i':
 
796
          if (strcmp (*names, "id") == 0 && !path->id)
 
797
            path->id = g_strdup (*values);
 
798
          break;
 
799
 
 
800
        case 'c':
 
801
          if (strcmp (*names, "cx") == 0)
 
802
            parse_svg_length (*values,
 
803
                              handler->width, parser->image->xresolution,
 
804
                              &center.x);
 
805
          else if (strcmp (*names, "cy") == 0)
 
806
            parse_svg_length (*values,
 
807
                              handler->height, parser->image->yresolution,
 
808
                              &center.y);
 
809
          break;
 
810
 
 
811
        case 'r':
 
812
          if (strcmp (*names, "r") == 0)
 
813
            {
 
814
              parse_svg_length (*values,
 
815
                                handler->width, parser->image->xresolution,
 
816
                                &rx);
 
817
              parse_svg_length (*values,
 
818
                                handler->height, parser->image->yresolution,
 
819
                                &ry);
 
820
            }
 
821
          else if (strcmp (*names, "rx") == 0)
 
822
            {
 
823
              parse_svg_length (*values,
 
824
                                handler->width, parser->image->xresolution,
 
825
                                &rx);
 
826
            }
 
827
          else if (strcmp (*names, "ry") == 0)
 
828
            {
 
829
              parse_svg_length (*values,
 
830
                                handler->height, parser->image->yresolution,
 
831
                                &ry);
 
832
            }
 
833
          break;
 
834
 
 
835
        case 't':
 
836
          if (strcmp (*names, "transform") == 0 && !handler->transform)
 
837
            {
 
838
              GimpMatrix3  matrix;
 
839
 
 
840
              if (parse_svg_transform (*values, &matrix))
 
841
                handler->transform = g_memdup (&matrix, sizeof (GimpMatrix3));
 
842
            }
 
843
          break;
804
844
        }
805
845
 
806
846
      names++;
810
850
  if (rx >= 0.0 && ry >= 0.0)
811
851
    path->strokes = g_list_prepend (path->strokes,
812
852
                                    gimp_bezier_stroke_new_ellipse (&center,
813
 
                                                                    rx, ry));
 
853
                                                                    rx, ry,
 
854
                                                                    0.0));
814
855
 
815
856
  handler->paths = g_list_prepend (handler->paths, path);
816
857
}
828
869
 
829
870
  while (*names)
830
871
    {
831
 
      if (strcmp (*names, "id") == 0 && !path->id)
832
 
        {
833
 
          path->id = g_strdup (*values);
834
 
        }
835
 
      else if (strcmp (*names, "x1") == 0)
836
 
        {
837
 
          parse_svg_length (*values,
838
 
                            handler->width, parser->image->xresolution,
839
 
                            &start.x);
840
 
        }
841
 
      else if (strcmp (*names, "y1") == 0)
842
 
        {
843
 
          parse_svg_length (*values,
844
 
                            handler->height, parser->image->yresolution,
845
 
                            &start.y);
846
 
        }
847
 
      else if (strcmp (*names, "x2") == 0)
848
 
        {
849
 
          parse_svg_length (*values,
850
 
                            handler->width, parser->image->xresolution,
851
 
                            &end.x);
852
 
        }
853
 
      else if (strcmp (*names, "y2") == 0)
854
 
        {
855
 
          parse_svg_length (*values,
856
 
                            handler->height, parser->image->yresolution,
857
 
                            &end.y);
858
 
        }
859
 
      else if (strcmp (*names, "transform") == 0 && !handler->transform)
860
 
        {
861
 
          GimpMatrix3  matrix;
862
 
 
863
 
          if (parse_svg_transform (*values, &matrix))
864
 
            handler->transform = g_memdup (&matrix, sizeof (GimpMatrix3));
 
872
      switch (*names[0])
 
873
        {
 
874
        case 'i':
 
875
          if (strcmp (*names, "id") == 0 && !path->id)
 
876
            path->id = g_strdup (*values);
 
877
          break;
 
878
 
 
879
        case 'x':
 
880
          if (strcmp (*names, "x1") == 0)
 
881
            parse_svg_length (*values,
 
882
                              handler->width, parser->image->xresolution,
 
883
                              &start.x);
 
884
          else if (strcmp (*names, "x2") == 0)
 
885
            parse_svg_length (*values,
 
886
                              handler->width, parser->image->xresolution,
 
887
                              &end.x);
 
888
          break;
 
889
 
 
890
        case 'y':
 
891
          if (strcmp (*names, "y1") == 0)
 
892
            parse_svg_length (*values,
 
893
                              handler->height, parser->image->yresolution,
 
894
                              &start.y);
 
895
          else if (strcmp (*names, "y2") == 0)
 
896
            parse_svg_length (*values,
 
897
                              handler->height, parser->image->yresolution,
 
898
                              &end.y);
 
899
          break;
 
900
 
 
901
        case 't':
 
902
          if (strcmp (*names, "transform") == 0 && !handler->transform)
 
903
            {
 
904
              GimpMatrix3  matrix;
 
905
 
 
906
              if (parse_svg_transform (*values, &matrix))
 
907
                handler->transform = g_memdup (&matrix, sizeof (GimpMatrix3));
 
908
            }
 
909
          break;
865
910
        }
866
911
 
867
912
      names++;
887
932
 
888
933
  while (*names)
889
934
    {
890
 
      if (strcmp (*names, "id") == 0 && !path->id)
891
 
        {
892
 
          path->id = g_strdup (*values);
893
 
        }
894
 
      else if (strcmp (*names, "points") == 0 && !points)
895
 
        {
896
 
          const gchar *p = *values;
897
 
          const gchar *m = NULL;
898
 
          const gchar *l = NULL;
899
 
          gint         n = 0;
900
 
 
901
 
          while (*p)
902
 
            {
903
 
              while (g_ascii_isspace (*p) || *p == ',')
904
 
                p++;
905
 
 
906
 
              switch (n)
907
 
                {
908
 
                case 0:
909
 
                  m = p;
910
 
                  break;
911
 
                case 2:
912
 
                  l = p;
913
 
                  break;
914
 
                }
915
 
 
916
 
              while (*p && !g_ascii_isspace (*p) && *p != ',')
917
 
                p++;
918
 
 
919
 
              n++;
920
 
            }
921
 
 
922
 
          if ((n > 3) && (n % 2 == 0))
923
 
            {
924
 
              points = g_string_sized_new (p - *values + 8);
925
 
 
926
 
              g_string_append_len (points, "M ", 2);
927
 
              g_string_append_len (points, m, l - m);
928
 
 
929
 
              g_string_append_len (points, "L ", 2);
930
 
              g_string_append_len (points, l, p - l);
931
 
 
932
 
              if (strcmp (handler->name, "polygon") == 0)
933
 
                g_string_append_c (points, 'Z');
934
 
            }
935
 
        }
936
 
      else if (strcmp (*names, "transform") == 0 && !handler->transform)
937
 
        {
938
 
          GimpMatrix3  matrix;
939
 
 
940
 
          if (parse_svg_transform (*values, &matrix))
941
 
            handler->transform = g_memdup (&matrix, sizeof (GimpMatrix3));
 
935
      switch (*names[0])
 
936
        {
 
937
        case 'i':
 
938
          if (strcmp (*names, "id") == 0 && !path->id)
 
939
            path->id = g_strdup (*values);
 
940
          break;
 
941
 
 
942
        case 'p':
 
943
          if (strcmp (*names, "points") == 0 && !points)
 
944
            {
 
945
              const gchar *p = *values;
 
946
              const gchar *m = NULL;
 
947
              const gchar *l = NULL;
 
948
              gint         n = 0;
 
949
 
 
950
              while (*p)
 
951
                {
 
952
                  while (g_ascii_isspace (*p) || *p == ',')
 
953
                    p++;
 
954
 
 
955
                  switch (n)
 
956
                    {
 
957
                    case 0:
 
958
                      m = p;
 
959
                      break;
 
960
                    case 2:
 
961
                      l = p;
 
962
                      break;
 
963
                    }
 
964
 
 
965
                  while (*p && !g_ascii_isspace (*p) && *p != ',')
 
966
                    p++;
 
967
 
 
968
                  n++;
 
969
                }
 
970
 
 
971
              if ((n > 3) && (n % 2 == 0))
 
972
                {
 
973
                  points = g_string_sized_new (p - *values + 8);
 
974
 
 
975
                  g_string_append_len (points, "M ", 2);
 
976
                  g_string_append_len (points, m, l - m);
 
977
 
 
978
                  g_string_append_len (points, "L ", 2);
 
979
                  g_string_append_len (points, l, p - l);
 
980
 
 
981
                  if (strcmp (handler->name, "polygon") == 0)
 
982
                    g_string_append_c (points, 'Z');
 
983
                }
 
984
            }
 
985
          break;
 
986
 
 
987
        case 't':
 
988
          if (strcmp (*names, "transform") == 0 && !handler->transform)
 
989
            {
 
990
              GimpMatrix3  matrix;
 
991
 
 
992
              if (parse_svg_transform (*values, &matrix))
 
993
                handler->transform = g_memdup (&matrix, sizeof (GimpMatrix3));
 
994
            }
 
995
          break;
942
996
        }
943
997
 
944
998
      names++;
1305
1359
    {
1306
1360
      c = data[i];
1307
1361
      if (c >= '0' && c <= '9')
1308
 
        {
1309
 
          /* digit */
1310
 
          if (in_num)
1311
 
            {
1312
 
              if (in_exp)
1313
 
                {
1314
 
                  exp = (exp * 10) + c - '0';
1315
 
                  exp_wait_sign = FALSE;
1316
 
                }
1317
 
              else if (in_frac)
1318
 
                val += (frac *= 0.1) * (c - '0');
1319
 
              else
1320
 
                val = (val * 10) + c - '0';
1321
 
            }
1322
 
          else
1323
 
            {
1324
 
              in_num = TRUE;
1325
 
              in_frac = FALSE;
1326
 
              in_exp = FALSE;
1327
 
              exp = 0;
1328
 
              exp_sign = 1;
1329
 
              exp_wait_sign = FALSE;
1330
 
              val = c - '0';
1331
 
              sign = 1;
1332
 
            }
1333
 
        }
 
1362
        {
 
1363
          /* digit */
 
1364
          if (in_num)
 
1365
            {
 
1366
              if (in_exp)
 
1367
                {
 
1368
                  exp = (exp * 10) + c - '0';
 
1369
                  exp_wait_sign = FALSE;
 
1370
                }
 
1371
              else if (in_frac)
 
1372
                val += (frac *= 0.1) * (c - '0');
 
1373
              else
 
1374
                val = (val * 10) + c - '0';
 
1375
            }
 
1376
          else
 
1377
            {
 
1378
              in_num = TRUE;
 
1379
              in_frac = FALSE;
 
1380
              in_exp = FALSE;
 
1381
              exp = 0;
 
1382
              exp_sign = 1;
 
1383
              exp_wait_sign = FALSE;
 
1384
              val = c - '0';
 
1385
              sign = 1;
 
1386
            }
 
1387
        }
1334
1388
      else if (c == '.')
1335
 
        {
1336
 
          if (!in_num)
1337
 
            {
1338
 
              in_num = TRUE;
1339
 
              val = 0;
1340
 
            }
1341
 
          in_frac = TRUE;
1342
 
          frac = 1;
1343
 
        }
 
1389
        {
 
1390
          if (!in_num)
 
1391
            {
 
1392
              in_num = TRUE;
 
1393
              val = 0;
 
1394
            }
 
1395
          in_frac = TRUE;
 
1396
          frac = 1;
 
1397
        }
1344
1398
      else if ((c == 'E' || c == 'e') && in_num)
1345
 
        {
1346
 
          in_exp = TRUE;
1347
 
          exp_wait_sign = TRUE;
1348
 
          exp = 0;
1349
 
          exp_sign = 1;
1350
 
        }
 
1399
        {
 
1400
          in_exp = TRUE;
 
1401
          exp_wait_sign = TRUE;
 
1402
          exp = 0;
 
1403
          exp_sign = 1;
 
1404
        }
1351
1405
      else if ((c == '+' || c == '-') && in_exp)
1352
 
        {
1353
 
          exp_sign = c == '+' ? 1 : -1;
1354
 
        }
 
1406
        {
 
1407
          exp_sign = c == '+' ? 1 : -1;
 
1408
        }
1355
1409
      else if (in_num)
1356
 
        {
1357
 
          /* end of number */
1358
 
 
1359
 
          val *= sign * pow (10, exp_sign * exp);
1360
 
          if (ctx.rel)
1361
 
            {
1362
 
              /* Handle relative coordinates. This switch statement attempts
1363
 
                 to determine _what_ the coords are relative to. This is
1364
 
                 underspecified in the 12 Apr working draft. */
1365
 
              switch (ctx.cmd)
1366
 
                {
1367
 
                case 'l':
1368
 
                case 'm':
1369
 
                case 'c':
1370
 
                case 's':
1371
 
                case 'q':
1372
 
                case 't':
1373
 
                  /* rule: even-numbered params are x-relative, odd-numbered
1374
 
                     are y-relative */
1375
 
                  if ((ctx.param & 1) == 0)
1376
 
                    val += ctx.cpx;
1377
 
                  else if ((ctx.param & 1) == 1)
1378
 
                    val += ctx.cpy;
1379
 
                  break;
1380
 
 
1381
 
                case 'a':
1382
 
                  /* rule: sixth and seventh are x and y, rest are not
1383
 
                     relative */
1384
 
                  if (ctx.param == 5)
1385
 
                    val += ctx.cpx;
1386
 
                  else if (ctx.param == 6)
1387
 
                    val += ctx.cpy;
1388
 
                  break;
1389
 
                case 'h':
1390
 
                  /* rule: x-relative */
1391
 
                  val += ctx.cpx;
1392
 
                  break;
1393
 
                case 'v':
1394
 
                  /* rule: y-relative */
1395
 
                  val += ctx.cpy;
1396
 
                  break;
1397
 
                }
1398
 
            }
1399
 
 
1400
 
          ctx.params[ctx.param++] = val;
1401
 
          parse_path_do_cmd (&ctx, FALSE);
1402
 
          in_num = FALSE;
1403
 
        }
 
1410
        {
 
1411
          /* end of number */
 
1412
 
 
1413
          val *= sign * pow (10, exp_sign * exp);
 
1414
          if (ctx.rel)
 
1415
            {
 
1416
              /* Handle relative coordinates. This switch statement attempts
 
1417
                 to determine _what_ the coords are relative to. This is
 
1418
                 underspecified in the 12 Apr working draft. */
 
1419
              switch (ctx.cmd)
 
1420
                {
 
1421
                case 'l':
 
1422
                case 'm':
 
1423
                case 'c':
 
1424
                case 's':
 
1425
                case 'q':
 
1426
                case 't':
 
1427
                  /* rule: even-numbered params are x-relative, odd-numbered
 
1428
                     are y-relative */
 
1429
                  if ((ctx.param & 1) == 0)
 
1430
                    val += ctx.cpx;
 
1431
                  else if ((ctx.param & 1) == 1)
 
1432
                    val += ctx.cpy;
 
1433
                  break;
 
1434
 
 
1435
                case 'a':
 
1436
                  /* rule: sixth and seventh are x and y, rest are not
 
1437
                     relative */
 
1438
                  if (ctx.param == 5)
 
1439
                    val += ctx.cpx;
 
1440
                  else if (ctx.param == 6)
 
1441
                    val += ctx.cpy;
 
1442
                  break;
 
1443
                case 'h':
 
1444
                  /* rule: x-relative */
 
1445
                  val += ctx.cpx;
 
1446
                  break;
 
1447
                case 'v':
 
1448
                  /* rule: y-relative */
 
1449
                  val += ctx.cpy;
 
1450
                  break;
 
1451
                }
 
1452
            }
 
1453
 
 
1454
          ctx.params[ctx.param++] = val;
 
1455
          parse_path_do_cmd (&ctx, FALSE);
 
1456
          in_num = FALSE;
 
1457
        }
1404
1458
 
1405
1459
      if (c == '\0')
1406
 
        break;
 
1460
        break;
1407
1461
      else if ((c == '+' || c == '-') && !exp_wait_sign)
1408
 
        {
1409
 
          sign = c == '+' ? 1 : -1;
1410
 
          val = 0;
1411
 
          in_num = TRUE;
1412
 
          in_frac = FALSE;
1413
 
          in_exp = FALSE;
1414
 
          exp = 0;
1415
 
          exp_sign = 1;
1416
 
          exp_wait_sign = FALSE;
1417
 
        }
 
1462
        {
 
1463
          sign = c == '+' ? 1 : -1;
 
1464
          val = 0;
 
1465
          in_num = TRUE;
 
1466
          in_frac = FALSE;
 
1467
          in_exp = FALSE;
 
1468
          exp = 0;
 
1469
          exp_sign = 1;
 
1470
          exp_wait_sign = FALSE;
 
1471
        }
1418
1472
      else if (c == 'z' || c == 'Z')
1419
 
        {
1420
 
          if (ctx.param)
1421
 
            parse_path_do_cmd (&ctx, TRUE);
 
1473
        {
 
1474
          if (ctx.param)
 
1475
            parse_path_do_cmd (&ctx, TRUE);
1422
1476
          if (ctx.stroke)
1423
1477
            gimp_stroke_close (ctx.stroke);
1424
 
        }
 
1478
        }
1425
1479
      else if (c >= 'A' && c <= 'Z' && c != 'E')
1426
 
        {
1427
 
          if (ctx.param)
1428
 
            parse_path_do_cmd (&ctx, TRUE);
1429
 
          ctx.cmd = c + 'a' - 'A';
1430
 
          ctx.rel = FALSE;
1431
 
        }
 
1480
        {
 
1481
          if (ctx.param)
 
1482
            parse_path_do_cmd (&ctx, TRUE);
 
1483
          ctx.cmd = c + 'a' - 'A';
 
1484
          ctx.rel = FALSE;
 
1485
        }
1432
1486
      else if (c >= 'a' && c <= 'z' && c != 'e')
1433
 
        {
1434
 
          if (ctx.param)
1435
 
            parse_path_do_cmd (&ctx, TRUE);
1436
 
          ctx.cmd = c;
1437
 
          ctx.rel = TRUE;
1438
 
        }
 
1487
        {
 
1488
          if (ctx.param)
 
1489
            parse_path_do_cmd (&ctx, TRUE);
 
1490
          ctx.cmd = c;
 
1491
          ctx.rel = TRUE;
 
1492
        }
1439
1493
      /* else c _should_ be whitespace or , */
1440
1494
    }
1441
1495
 
1453
1507
  if (ctx->rel)
1454
1508
    {
1455
1509
      for (i = ctx->param; i < n_params; i++)
1456
 
        {
1457
 
          if (i > 2)
1458
 
            ctx->params[i] = ctx->params[i - 2];
1459
 
          else if (i == 1)
1460
 
            ctx->params[i] = ctx->cpy;
1461
 
          else if (i == 0)
1462
 
            /* we shouldn't get here (ctx->param > 0 as precondition) */
1463
 
            ctx->params[i] = ctx->cpx;
1464
 
        }
 
1510
        {
 
1511
          if (i > 2)
 
1512
            ctx->params[i] = ctx->params[i - 2];
 
1513
          else if (i == 1)
 
1514
            ctx->params[i] = ctx->cpy;
 
1515
          else if (i == 0)
 
1516
            /* we shouldn't get here (ctx->param > 0 as precondition) */
 
1517
            ctx->params[i] = ctx->cpx;
 
1518
        }
1465
1519
    }
1466
1520
  else
1467
1521
    {
1468
1522
      for (i = ctx->param; i < n_params; i++)
1469
 
        ctx->params[i] = 0.0;
 
1523
        ctx->params[i] = 0.0;
1470
1524
    }
1471
1525
}
1472
1526
 
1481
1535
    case 'm':
1482
1536
      /* moveto */
1483
1537
      if (ctx->param == 2 || final)
1484
 
        {
1485
 
          parse_path_default_xy (ctx, 2);
 
1538
        {
 
1539
          parse_path_default_xy (ctx, 2);
1486
1540
 
1487
1541
          coords.x = ctx->cpx = ctx->rpx = ctx->params[0];
1488
1542
          coords.y = ctx->cpy = ctx->rpy = ctx->params[1];
1490
1544
          ctx->stroke = gimp_bezier_stroke_new_moveto (&coords);
1491
1545
          ctx->strokes = g_list_prepend (ctx->strokes, ctx->stroke);
1492
1546
 
1493
 
          ctx->param = 0;
1494
 
        }
 
1547
          ctx->param = 0;
 
1548
        }
1495
1549
      break;
 
1550
 
1496
1551
    case 'l':
1497
1552
      /* lineto */
1498
1553
      if (ctx->param == 2 || final)
1499
 
        {
1500
 
          parse_path_default_xy (ctx, 2);
 
1554
        {
 
1555
          parse_path_default_xy (ctx, 2);
1501
1556
 
1502
1557
          coords.x = ctx->cpx = ctx->rpx = ctx->params[0];
1503
1558
          coords.y = ctx->cpy = ctx->rpy = ctx->params[1];
1504
1559
 
1505
1560
          gimp_bezier_stroke_lineto (ctx->stroke, &coords);
1506
1561
 
1507
 
          ctx->param = 0;
1508
 
        }
 
1562
          ctx->param = 0;
 
1563
        }
1509
1564
      break;
 
1565
 
1510
1566
    case 'c':
1511
1567
      /* curveto */
1512
1568
      if (ctx->param == 6 || final)
1513
 
        {
 
1569
        {
1514
1570
          GimpCoords ctrl1 = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 };
1515
1571
          GimpCoords ctrl2 = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 };
1516
1572
 
1517
 
          parse_path_default_xy (ctx, 6);
 
1573
          parse_path_default_xy (ctx, 6);
1518
1574
 
1519
 
          ctrl1.x  = ctx->params[0];
1520
 
          ctrl1.y  = ctx->params[1];
1521
 
          ctrl2.x  = ctx->rpx = ctx->params[2];
1522
 
          ctrl2.y  = ctx->rpy = ctx->params[3];
1523
 
          coords.x = ctx->cpx = ctx->params[4];
1524
 
          coords.y = ctx->cpy = ctx->params[5];
 
1575
          ctrl1.x  = ctx->params[0];
 
1576
          ctrl1.y  = ctx->params[1];
 
1577
          ctrl2.x  = ctx->rpx = ctx->params[2];
 
1578
          ctrl2.y  = ctx->rpy = ctx->params[3];
 
1579
          coords.x = ctx->cpx = ctx->params[4];
 
1580
          coords.y = ctx->cpy = ctx->params[5];
1525
1581
 
1526
1582
          gimp_bezier_stroke_cubicto (ctx->stroke, &ctrl1, &ctrl2, &coords);
1527
1583
 
1528
 
          ctx->param = 0;
1529
 
        }
 
1584
          ctx->param = 0;
 
1585
        }
1530
1586
      break;
 
1587
 
1531
1588
    case 's':
1532
1589
      /* smooth curveto */
1533
1590
      if (ctx->param == 4 || final)
1534
 
        {
 
1591
        {
1535
1592
          GimpCoords ctrl1 = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 };
1536
1593
          GimpCoords ctrl2 = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 };
1537
1594
 
1538
 
          parse_path_default_xy (ctx, 4);
 
1595
          parse_path_default_xy (ctx, 4);
1539
1596
 
1540
1597
          ctrl1.x  = 2 * ctx->cpx - ctx->rpx;
1541
 
          ctrl1.y  = 2 * ctx->cpy - ctx->rpy;
 
1598
          ctrl1.y  = 2 * ctx->cpy - ctx->rpy;
1542
1599
          ctrl2.x  = ctx->rpx = ctx->params[0];
1543
1600
          ctrl2.y  = ctx->rpy = ctx->params[1];
1544
 
          coords.x = ctx->cpx = ctx->params[2];
1545
 
          coords.y = ctx->cpy = ctx->params[3];
 
1601
          coords.x = ctx->cpx = ctx->params[2];
 
1602
          coords.y = ctx->cpy = ctx->params[3];
1546
1603
 
1547
1604
          gimp_bezier_stroke_cubicto (ctx->stroke, &ctrl1, &ctrl2, &coords);
1548
1605
 
1549
 
          ctx->param = 0;
1550
 
        }
 
1606
          ctx->param = 0;
 
1607
        }
1551
1608
      break;
 
1609
 
1552
1610
    case 'h':
1553
1611
      /* horizontal lineto */
1554
1612
      if (ctx->param == 1)
1555
 
        {
 
1613
        {
1556
1614
          coords.x = ctx->cpx = ctx->rpx = ctx->params[0];
1557
1615
          coords.y = ctx->cpy;
1558
1616
 
1559
1617
          gimp_bezier_stroke_lineto (ctx->stroke, &coords);
1560
1618
 
1561
 
          ctx->param = 0;
1562
 
        }
 
1619
          ctx->param = 0;
 
1620
        }
1563
1621
      break;
 
1622
 
1564
1623
    case 'v':
1565
1624
      /* vertical lineto */
1566
1625
      if (ctx->param == 1)
1567
 
        {
 
1626
        {
1568
1627
          coords.x = ctx->cpx;
1569
1628
          coords.y = ctx->cpy = ctx->rpy = ctx->params[0];
1570
1629
 
1571
1630
          gimp_bezier_stroke_lineto (ctx->stroke, &coords);
1572
1631
 
1573
 
          ctx->param = 0;
1574
 
        }
 
1632
          ctx->param = 0;
 
1633
        }
1575
1634
      break;
1576
1635
 
1577
1636
    case 'q':
1578
1637
      /* quadratic bezier curveto */
1579
1638
      if (ctx->param == 4 || final)
1580
 
        {
 
1639
        {
1581
1640
          GimpCoords ctrl = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 };
1582
1641
 
1583
 
          parse_path_default_xy (ctx, 4);
 
1642
          parse_path_default_xy (ctx, 4);
1584
1643
 
1585
 
          ctrl.x   = ctx->rpx = ctx->params[0];
1586
 
          ctrl.y   = ctx->rpy = ctx->params[1];
1587
 
          coords.x = ctx->cpx = ctx->params[2];
1588
 
          coords.y = ctx->cpy = ctx->params[3];
 
1644
          ctrl.x   = ctx->rpx = ctx->params[0];
 
1645
          ctrl.y   = ctx->rpy = ctx->params[1];
 
1646
          coords.x = ctx->cpx = ctx->params[2];
 
1647
          coords.y = ctx->cpy = ctx->params[3];
1589
1648
 
1590
1649
          gimp_bezier_stroke_conicto (ctx->stroke, &ctrl, &coords);
1591
1650
 
1592
 
          ctx->param = 0;
1593
 
        }
 
1651
          ctx->param = 0;
 
1652
        }
1594
1653
      break;
 
1654
 
1595
1655
    case 't':
1596
1656
      /* truetype quadratic bezier curveto */
1597
1657
      if (ctx->param == 2 || final)
1598
 
        {
 
1658
        {
1599
1659
          GimpCoords ctrl = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 };
1600
1660
 
1601
 
          parse_path_default_xy (ctx, 2);
 
1661
          parse_path_default_xy (ctx, 2);
1602
1662
 
1603
1663
          ctrl.x   = ctx->rpx = 2 * ctx->cpx - ctx->rpx;
1604
1664
          ctrl.y   = ctx->rpy = 2 * ctx->cpy - ctx->rpy;
1605
 
          coords.x = ctx->cpx = ctx->params[0];
1606
 
          coords.y = ctx->cpy = ctx->params[1];
 
1665
          coords.x = ctx->cpx = ctx->params[0];
 
1666
          coords.y = ctx->cpy = ctx->params[1];
1607
1667
 
1608
1668
          gimp_bezier_stroke_conicto (ctx->stroke, &ctrl, &coords);
1609
1669
 
1610
 
          ctx->param = 0;
1611
 
        }
 
1670
          ctx->param = 0;
 
1671
        }
1612
1672
      else if (final)
1613
 
        {
1614
 
          if (ctx->param > 2)
1615
 
            {
 
1673
        {
 
1674
          if (ctx->param > 2)
 
1675
            {
1616
1676
              GimpCoords ctrl = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 };
1617
1677
 
1618
 
              parse_path_default_xy (ctx, 4);
 
1678
              parse_path_default_xy (ctx, 4);
1619
1679
 
1620
1680
              ctrl.x   = ctx->rpx = ctx->params[0];
1621
1681
              ctrl.y   = ctx->rpy = ctx->params[1];
1623
1683
              coords.y = ctx->cpy = ctx->params[3];
1624
1684
 
1625
1685
              gimp_bezier_stroke_conicto (ctx->stroke, &ctrl, &coords);
1626
 
            }
1627
 
          else
1628
 
            {
1629
 
              parse_path_default_xy (ctx, 2);
 
1686
            }
 
1687
          else
 
1688
            {
 
1689
              parse_path_default_xy (ctx, 2);
1630
1690
 
1631
1691
              coords.x = ctx->cpx = ctx->rpx = ctx->params[0];
1632
1692
              coords.y = ctx->cpy = ctx->rpy = ctx->params[1];
1633
1693
 
1634
1694
              gimp_bezier_stroke_lineto (ctx->stroke, &coords);
1635
 
            }
 
1695
            }
1636
1696
 
1637
 
          ctx->param = 0;
1638
 
        }
 
1697
          ctx->param = 0;
 
1698
        }
1639
1699
      break;
 
1700
 
1640
1701
    case 'a':
1641
1702
      if (ctx->param == 7 || final)
1642
 
        {
 
1703
        {
1643
1704
          coords.x = ctx->cpx = ctx->rpx = ctx->params[5];
1644
1705
          coords.y = ctx->cpy = ctx->rpy = ctx->params[6];
1645
1706
 
1648
1709
                                    gimp_deg_to_rad (ctx->params[2]),
1649
1710
                                    ctx->params[3], ctx->params[4],
1650
1711
                                    &coords);
1651
 
          ctx->param = 0;
1652
 
        }
 
1712
          ctx->param = 0;
 
1713
        }
1653
1714
      break;
 
1715
 
1654
1716
    default:
1655
1717
      ctx->param = 0;
1656
1718
      break;