1 # -*- coding: utf-8 -*- 2 from __future__ import absolute_import, unicode_literals 3 import unittest 4 from fontTools.ufoLib.glifLib import GlifLibError, readGlyphFromString, writeGlyphToString 5 from .testSupport import Glyph, stripText 6 from itertools import islice 7 8 try: 9 basestring 10 except NameError: 11 basestring = str 12 # ---------- 13 # Test Cases 14 # ---------- 15 16 class TestGLIF1(unittest.TestCase): 17 18 def assertEqual(self, first, second, msg=None): 19 if isinstance(first, basestring): 20 first = stripText(first) 21 if isinstance(second, basestring): 22 second = stripText(second) 23 return super(TestGLIF1, self).assertEqual(first, second, msg=msg) 24 25 def pyToGLIF(self, py): 26 py = stripText(py) 27 glyph = Glyph() 28 exec(py, {"glyph" : glyph, "pointPen" : glyph}) 29 glif = writeGlyphToString(glyph.name, glyphObject=glyph, drawPointsFunc=glyph.drawPoints, formatVersion=1, validate=True) 30 # discard the first line containing the xml declaration 31 return "\n".join(islice(glif.splitlines(), 1, None)) 32 33 def glifToPy(self, glif): 34 glif = stripText(glif) 35 glif = "<?xml version=\"1.0\"?>\n" + glif 36 glyph = Glyph() 37 readGlyphFromString(glif, glyphObject=glyph, pointPen=glyph, validate=True) 38 return glyph.py() 39 40 def testTopElement(self): 41 # not glyph 42 glif = """ 43 <notglyph name="a" format="1"> 44 <outline> 45 </outline> 46 </notglyph> 47 """ 48 self.assertRaises(GlifLibError, self.glifToPy, glif) 49 50 def testName_legal(self): 51 # legal 52 glif = """ 53 <glyph name="a" format="1"> 54 <outline> 55 </outline> 56 </glyph> 57 """ 58 py = """ 59 glyph.name = "a" 60 """ 61 resultGlif = self.pyToGLIF(py) 62 resultPy = self.glifToPy(glif) 63 self.assertEqual(glif, resultGlif) 64 self.assertEqual(py, resultPy) 65 66 def testName_empty(self): 67 # empty 68 glif = """ 69 <glyph name="" format="1"> 70 <outline> 71 </outline> 72 </glyph> 73 """ 74 py = """ 75 glyph.name = "" 76 """ 77 self.assertRaises(GlifLibError, self.pyToGLIF, py) 78 self.assertRaises(GlifLibError, self.glifToPy, glif) 79 80 def testName_not_a_string(self): 81 # not a string 82 py = """ 83 glyph.name = 1 84 """ 85 self.assertRaises(GlifLibError, self.pyToGLIF, py) 86 87 def testFormat_legal(self): 88 # legal 89 glif = """ 90 <glyph name="a" format="1"> 91 <outline> 92 </outline> 93 </glyph> 94 """ 95 py = """ 96 glyph.name = "a" 97 """ 98 resultGlif = self.pyToGLIF(py) 99 resultPy = self.glifToPy(glif) 100 self.assertEqual(glif, resultGlif) 101 self.assertEqual(py, resultPy) 102 103 def testFormat_wrong_number(self): 104 # wrong number 105 glif = """ 106 <glyph name="a" format="-1"> 107 <outline> 108 </outline> 109 </glyph> 110 """ 111 self.assertRaises(GlifLibError, self.glifToPy, glif) 112 113 def testFormat_not_an_int(self): 114 # not an int 115 glif = """ 116 <glyph name="a" format="A"> 117 <outline> 118 </outline> 119 </glyph> 120 """ 121 self.assertRaises(GlifLibError, self.glifToPy, glif) 122 123 def testBogusGlyphStructure_unknown_element(self): 124 # unknown element 125 glif = """ 126 <glyph name="a" format="1"> 127 <unknown /> 128 </glyph> 129 """ 130 self.assertRaises(GlifLibError, self.glifToPy, glif) 131 132 def testBogusGlyphStructure_content(self): 133 # content 134 glif = """ 135 <glyph name="a" format="1"> 136 Hello World. 137 </glyph> 138 """ 139 self.assertRaises(GlifLibError, self.glifToPy, glif) 140 141 def testAdvance_legal_width_and_height(self): 142 # legal: width and height 143 glif = """ 144 <glyph name="a" format="1"> 145 <advance height="200" width="100"/> 146 <outline> 147 </outline> 148 </glyph> 149 """ 150 py = """ 151 glyph.name = "a" 152 glyph.width = 100 153 glyph.height = 200 154 """ 155 resultGlif = self.pyToGLIF(py) 156 resultPy = self.glifToPy(glif) 157 self.assertEqual(glif, resultGlif) 158 self.assertEqual(py, resultPy) 159 160 def testAdvance_legal_width_and_height_floats(self): 161 # legal: width and height floats 162 glif = """ 163 <glyph name="a" format="1"> 164 <advance height="200.1" width="100.1"/> 165 <outline> 166 </outline> 167 </glyph> 168 """ 169 py = """ 170 glyph.name = "a" 171 glyph.width = 100.1 172 glyph.height = 200.1 173 """ 174 resultGlif = self.pyToGLIF(py) 175 resultPy = self.glifToPy(glif) 176 self.assertEqual(glif, resultGlif) 177 self.assertEqual(py, resultPy) 178 179 def testAdvance_legal_width(self): 180 # legal: width 181 glif = """ 182 <glyph name="a" format="1"> 183 <advance width="100"/> 184 <outline> 185 </outline> 186 </glyph> 187 """ 188 py = """ 189 glyph.name = "a" 190 glyph.width = 100 191 """ 192 resultGlif = self.pyToGLIF(py) 193 resultPy = self.glifToPy(glif) 194 self.assertEqual(glif, resultGlif) 195 self.assertEqual(py, resultPy) 196 197 def testAdvance_legal_height(self): 198 # legal: height 199 glif = """ 200 <glyph name="a" format="1"> 201 <advance height="200"/> 202 <outline> 203 </outline> 204 </glyph> 205 """ 206 py = """ 207 glyph.name = "a" 208 glyph.height = 200 209 """ 210 resultGlif = self.pyToGLIF(py) 211 resultPy = self.glifToPy(glif) 212 self.assertEqual(glif, resultGlif) 213 self.assertEqual(py, resultPy) 214 215 def testAdvance_illegal_width(self): 216 # illegal: not a number 217 glif = """ 218 <glyph name="a" format="1"> 219 <advance width="a"/> 220 <outline> 221 </outline> 222 </glyph> 223 """ 224 py = """ 225 glyph.name = "a" 226 glyph.width = "a" 227 """ 228 self.assertRaises(GlifLibError, self.pyToGLIF, py) 229 self.assertRaises(GlifLibError, self.glifToPy, glif) 230 231 def testAdvance_illegal_height(self): 232 glif = """ 233 <glyph name="a" format="1"> 234 <advance height="a"/> 235 <outline> 236 </outline> 237 </glyph> 238 """ 239 py = """ 240 glyph.name = "a" 241 glyph.height = "a" 242 """ 243 self.assertRaises(GlifLibError, self.pyToGLIF, py) 244 self.assertRaises(GlifLibError, self.glifToPy, glif) 245 246 def testUnicodes_legal(self): 247 # legal 248 glif = """ 249 <glyph name="a" format="1"> 250 <unicode hex="0061"/> 251 <outline> 252 </outline> 253 </glyph> 254 """ 255 py = """ 256 glyph.name = "a" 257 glyph.unicodes = [97] 258 """ 259 resultGlif = self.pyToGLIF(py) 260 resultPy = self.glifToPy(glif) 261 self.assertEqual(glif, resultGlif) 262 self.assertEqual(py, resultPy) 263 264 def testUnicodes_legal_multiple(self): 265 glif = """ 266 <glyph name="a" format="1"> 267 <unicode hex="0062"/> 268 <unicode hex="0063"/> 269 <unicode hex="0061"/> 270 <outline> 271 </outline> 272 </glyph> 273 """ 274 py = """ 275 glyph.name = "a" 276 glyph.unicodes = [98, 99, 97] 277 """ 278 resultGlif = self.pyToGLIF(py) 279 resultPy = self.glifToPy(glif) 280 self.assertEqual(glif, resultGlif) 281 self.assertEqual(py, resultPy) 282 283 def testUnicodes_illegal(self): 284 # illegal 285 glif = """ 286 <glyph name="a" format="1"> 287 <unicode hex="1.1"/> 288 <outline> 289 </outline> 290 </glyph> 291 """ 292 py = """ 293 glyph.name = "zzzzzz" 294 glyph.unicodes = ["1.1"] 295 """ 296 self.assertRaises(GlifLibError, self.pyToGLIF, py) 297 self.assertRaises(GlifLibError, self.glifToPy, glif) 298 299 def testNote(self): 300 glif = """ 301 <glyph name="a" format="1"> 302 <note> 303 \U0001F4A9 304 </note> 305 <outline> 306 </outline> 307 </glyph> 308 """ 309 py = """ 310 glyph.name = "a" 311 glyph.note = "" 312 """ 313 resultGlif = self.pyToGLIF(py) 314 resultPy = self.glifToPy(glif) 315 self.assertEqual(glif, resultGlif) 316 self.assertEqual(py, resultPy) 317 318 def testLib_legal(self): 319 glif = """ 320 <glyph name="a" format="1"> 321 <outline> 322 </outline> 323 <lib> 324 <dict> 325 <key>dict</key> 326 <dict> 327 <key>hello</key> 328 <string>world</string> 329 </dict> 330 <key>float</key> 331 <real>2.5</real> 332 <key>int</key> 333 <integer>1</integer> 334 <key>list</key> 335 <array> 336 <string>a</string> 337 <string>b</string> 338 <integer>1</integer> 339 <real>2.5</real> 340 </array> 341 <key>string</key> 342 <string>a</string> 343 </dict> 344 </lib> 345 </glyph> 346 """ 347 py = """ 348 glyph.name = "a" 349 glyph.lib = {"dict" : {"hello" : "world"}, "float" : 2.5, "int" : 1, "list" : ["a", "b", 1, 2.5], "string" : "a"} 350 """ 351 resultGlif = self.pyToGLIF(py) 352 resultPy = self.glifToPy(glif) 353 self.assertEqual(glif, resultGlif) 354 self.assertEqual(py, resultPy) 355 356 def testOutline_unknown_element(self): 357 # unknown element 358 glif = """ 359 <glyph name="a" format="1"> 360 <outline> 361 <unknown/> 362 </outline> 363 </glyph> 364 """ 365 self.assertRaises(GlifLibError, self.glifToPy, glif) 366 367 def testOutline_content(self): 368 # content 369 glif = """ 370 <glyph name="a" format="1"> 371 <outline> 372 hello 373 </outline> 374 </glyph> 375 """ 376 self.assertRaises(GlifLibError, self.glifToPy, glif) 377 378 def testComponent_legal(self): 379 # legal 380 glif = """ 381 <glyph name="a" format="1"> 382 <outline> 383 <component base="x" xScale="2" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="4"/> 384 </outline> 385 </glyph> 386 """ 387 py = """ 388 glyph.name = "a" 389 pointPen.addComponent(*["x", (2, 3, 6, 5, 1, 4)]) 390 """ 391 resultGlif = self.pyToGLIF(py) 392 resultPy = self.glifToPy(glif) 393 self.assertEqual(glif, resultGlif) 394 self.assertEqual(py, resultPy) 395 396 def testComponent_illegal_no_base(self): 397 # no base 398 glif = """ 399 <glyph name="a" format="1"> 400 <outline> 401 <component xScale="2" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="4"/> 402 </outline> 403 </glyph> 404 """ 405 self.assertRaises(GlifLibError, self.glifToPy, glif) 406 407 def testComponent_bogus_transformation(self): 408 # bogus values in transformation 409 glif = """ 410 <glyph name="a" format="1"> 411 <outline> 412 <component base="x" xScale="a" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="4"/> 413 </outline> 414 </glyph> 415 """ 416 py = """ 417 glyph.name = "a" 418 pointPen.addComponent(*["x", ("a", 3, 6, 5, 1, 4)]) 419 """ 420 self.assertRaises(GlifLibError, self.pyToGLIF, py) 421 self.assertRaises(GlifLibError, self.glifToPy, glif) 422 glif = """ 423 <glyph name="a" format="1"> 424 <outline> 425 <component base="x" xScale="a" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="4"/> 426 </outline> 427 </glyph> 428 """ 429 py = """ 430 glyph.name = "a" 431 pointPen.addComponent(*["x", (2, "a", 6, 5, 1, 4)]) 432 """ 433 self.assertRaises(GlifLibError, self.pyToGLIF, py) 434 self.assertRaises(GlifLibError, self.glifToPy, glif) 435 glif = """ 436 <glyph name="a" format="1"> 437 <outline> 438 <component base="x" xScale="2" xyScale="3" yxScale="a" yScale="5" xOffset="1" yOffset="4"/> 439 </outline> 440 </glyph> 441 """ 442 py = """ 443 glyph.name = "a" 444 pointPen.addComponent(*["x", (2, 3, "a", 5, 1, 4)]) 445 """ 446 self.assertRaises(GlifLibError, self.pyToGLIF, py) 447 self.assertRaises(GlifLibError, self.glifToPy, glif) 448 glif = """ 449 <glyph name="a" format="1"> 450 <outline> 451 <component base="x" xScale="2" xyScale="3" yxScale="6" yScale="a" xOffset="1" yOffset="4"/> 452 </outline> 453 </glyph> 454 """ 455 py = """ 456 glyph.name = "a" 457 pointPen.addComponent(*["x", (2, 3, 6, "a", 1, 4)]) 458 """ 459 self.assertRaises(GlifLibError, self.pyToGLIF, py) 460 self.assertRaises(GlifLibError, self.glifToPy, glif) 461 glif = """ 462 <glyph name="a" format="1"> 463 <outline> 464 <component base="x" xScale="2" xyScale="3" yxScale="6" yScale="5" xOffset="a" yOffset="4"/> 465 </outline> 466 </glyph> 467 """ 468 py = """ 469 glyph.name = "a" 470 pointPen.addComponent(*["x", (2, 3, 6, 5, "a", 4)]) 471 """ 472 self.assertRaises(GlifLibError, self.pyToGLIF, py) 473 self.assertRaises(GlifLibError, self.glifToPy, glif) 474 glif = """ 475 <glyph name="a" format="1"> 476 <outline> 477 <component base="x" xScale="2" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="a"/> 478 </outline> 479 </glyph> 480 """ 481 py = """ 482 glyph.name = "a" 483 pointPen.addComponent(*["x", (2, 3, 6, 5, 1, "a")]) 484 """ 485 self.assertRaises(GlifLibError, self.pyToGLIF, py) 486 self.assertRaises(GlifLibError, self.glifToPy, glif) 487 488 def testContour_legal_one_contour(self): 489 # legal: one contour 490 glif = """ 491 <glyph name="a" format="1"> 492 <outline> 493 <contour> 494 </contour> 495 </outline> 496 </glyph> 497 """ 498 py = """ 499 glyph.name = "a" 500 pointPen.beginPath() 501 pointPen.endPath() 502 """ 503 resultGlif = self.pyToGLIF(py) 504 resultPy = self.glifToPy(glif) 505 self.assertEqual(glif, resultGlif) 506 self.assertEqual(py, resultPy) 507 508 def testContour_legal_two_contours(self): 509 # legal: two contours 510 glif = """ 511 <glyph name="a" format="1"> 512 <outline> 513 <contour> 514 <point x="1" y="2" type="move"/> 515 <point x="10" y="20" type="line"/> 516 </contour> 517 <contour> 518 <point x="1" y="2" type="move"/> 519 <point x="10" y="20" type="line"/> 520 </contour> 521 </outline> 522 </glyph> 523 """ 524 py = """ 525 glyph.name = "a" 526 pointPen.beginPath() 527 pointPen.addPoint(*[(1, 2)], **{"segmentType" : "move", "smooth" : False}) 528 pointPen.addPoint(*[(10, 20)], **{"segmentType" : "line", "smooth" : False}) 529 pointPen.endPath() 530 pointPen.beginPath() 531 pointPen.addPoint(*[(1, 2)], **{"segmentType" : "move", "smooth" : False}) 532 pointPen.addPoint(*[(10, 20)], **{"segmentType" : "line", "smooth" : False}) 533 pointPen.endPath() 534 """ 535 resultGlif = self.pyToGLIF(py) 536 resultPy = self.glifToPy(glif) 537 self.assertEqual(glif, resultGlif) 538 self.assertEqual(py, resultPy) 539 540 def testContour_illegal_unkonwn_element(self): 541 # unknown element 542 glif = """ 543 <glyph name="a" format="1"> 544 <outline> 545 <contour> 546 <unknown/> 547 </contour> 548 </outline> 549 </glyph> 550 """ 551 self.assertRaises(GlifLibError, self.glifToPy, glif) 552 553 def testPointCoordinates_legal_int(self): 554 # legal: int 555 glif = """ 556 <glyph name="a" format="1"> 557 <outline> 558 <contour> 559 <point x="1" y="-2" type="move"/> 560 <point x="0" y="0" type="line" name="this is here so that the contour isn't seen as an anchor"/> 561 </contour> 562 </outline> 563 </glyph> 564 """ 565 py = """ 566 glyph.name = "a" 567 pointPen.beginPath() 568 pointPen.addPoint(*[(1, -2)], **{"segmentType" : "move", "smooth" : False}) 569 pointPen.addPoint(*[(0, 0)], **{"name" : "this is here so that the contour isn't seen as an anchor", "segmentType" : "line", "smooth" : False}) 570 pointPen.endPath() 571 """ 572 resultGlif = self.pyToGLIF(py) 573 resultPy = self.glifToPy(glif) 574 self.assertEqual(glif, resultGlif) 575 self.assertEqual(py, resultPy) 576 577 def testPointCoordinates_legal_float(self): 578 # legal: float 579 glif = """ 580 <glyph name="a" format="1"> 581 <outline> 582 <contour> 583 <point x="1.1" y="-2.2" type="move"/> 584 <point x="0" y="0" type="line" name="this is here so that the contour isn't seen as an anchor"/> 585 </contour> 586 </outline> 587 </glyph> 588 """ 589 py = """ 590 glyph.name = "a" 591 pointPen.beginPath() 592 pointPen.addPoint(*[(1.1, -2.2)], **{"segmentType" : "move", "smooth" : False}) 593 pointPen.addPoint(*[(0, 0)], **{"name" : "this is here so that the contour isn't seen as an anchor", "segmentType" : "line", "smooth" : False}) 594 pointPen.endPath() 595 """ 596 resultGlif = self.pyToGLIF(py) 597 resultPy = self.glifToPy(glif) 598 self.assertEqual(glif, resultGlif) 599 self.assertEqual(py, resultPy) 600 601 def testPointCoordinates_illegal_x(self): 602 # illegal: string 603 glif = """ 604 <glyph name="a" format="1"> 605 <outline> 606 <contour> 607 <point x="a" y="2" type="move"/> 608 <point x="0" y="0" type="line" name="this is here so that the contour isn't seen as an anchor"/> 609 </contour> 610 </outline> 611 </glyph> 612 """ 613 py = """ 614 glyph.name = "a" 615 pointPen.beginPath() 616 pointPen.addPoint(*[("a", 2)], **{"segmentType" : "move", "smooth" : False}) 617 pointPen.addPoint(*[(0, 0)], **{"name" : "this is here so that the contour isn't seen as an anchor", "segmentType" : "line", "smooth" : False}) 618 pointPen.endPath() 619 """ 620 self.assertRaises(GlifLibError, self.pyToGLIF, py) 621 self.assertRaises(GlifLibError, self.glifToPy, glif) 622 623 def testPointCoordinates_illegal_y(self): 624 # legal: int 625 glif = """ 626 <glyph name="a" format="1"> 627 <outline> 628 <contour> 629 <point x="1" y="a" type="move"/> 630 <point x="0" y="0" type="line" name="this is here so that the contour isn't seen as an anchor"/> 631 </contour> 632 </outline> 633 </glyph> 634 """ 635 py = """ 636 glyph.name = "a" 637 pointPen.beginPath() 638 pointPen.addPoint(*[(1, "a")], **{"segmentType" : "move", "smooth" : False}) 639 pointPen.addPoint(*[(0, 0)], **{"name" : "this is here so that the contour isn't seen as an anchor", "segmentType" : "line", "smooth" : False}) 640 pointPen.endPath() 641 """ 642 self.assertRaises(GlifLibError, self.pyToGLIF, py) 643 self.assertRaises(GlifLibError, self.glifToPy, glif) 644 645 def testPointTypeMove_legal(self): 646 # legal 647 glif = """ 648 <glyph name="a" format="1"> 649 <outline> 650 <contour> 651 <point x="1" y="-2" type="move"/> 652 <point x="3" y="-4" type="line"/> 653 </contour> 654 </outline> 655 </glyph> 656 """ 657 py = """ 658 glyph.name = "a" 659 pointPen.beginPath() 660 pointPen.addPoint(*[(1, -2)], **{"segmentType" : "move", "smooth" : False}) 661 pointPen.addPoint(*[(3, -4)], **{"segmentType" : "line", "smooth" : False}) 662 pointPen.endPath() 663 """ 664 resultGlif = self.pyToGLIF(py) 665 resultPy = self.glifToPy(glif) 666 self.assertEqual(glif, resultGlif) 667 self.assertEqual(py, resultPy) 668 669 def testPointTypeMove_legal_smooth(self): 670 # legal: smooth=True 671 glif = """ 672 <glyph name="a" format="1"> 673 <outline> 674 <contour> 675 <point x="1" y="-2" type="move" smooth="yes"/> 676 <point x="3" y="-4" type="line"/> 677 </contour> 678 </outline> 679 </glyph> 680 """ 681 py = """ 682 glyph.name = "a" 683 pointPen.beginPath() 684 pointPen.addPoint(*[(1, -2)], **{"segmentType" : "move", "smooth" : True}) 685 pointPen.addPoint(*[(3, -4)], **{"segmentType" : "line", "smooth" : False}) 686 pointPen.endPath() 687 """ 688 resultGlif = self.pyToGLIF(py) 689 resultPy = self.glifToPy(glif) 690 self.assertEqual(glif, resultGlif) 691 self.assertEqual(py, resultPy) 692 693 def testPointTypeMove_illegal_not_at_start(self): 694 # illegal: not at start 695 glif = """ 696 <glyph name="a" format="1"> 697 <outline> 698 <contour> 699 <point x="3" y="-4" type="line"/> 700 <point x="1" y="-2" type="move"/> 701 </contour> 702 </outline> 703 </glyph> 704 """ 705 py = """ 706 glyph.name = "a" 707 pointPen.beginPath() 708 pointPen.addPoint(*[(3, -4)], **{"segmentType" : "line", "smooth" : False}) 709 pointPen.addPoint(*[(1, -2)], **{"segmentType" : "move", "smooth" : False}) 710 pointPen.endPath() 711 """ 712 self.assertRaises(GlifLibError, self.pyToGLIF, py) 713 self.assertRaises(GlifLibError, self.glifToPy, glif) 714 715 def testPointTypeLine_legal(self): 716 # legal 717 glif = """ 718 <glyph name="a" format="1"> 719 <outline> 720 <contour> 721 <point x="1" y="-2" type="move"/> 722 <point x="3" y="-4" type="line"/> 723 </contour> 724 </outline> 725 </glyph> 726 """ 727 py = """ 728 glyph.name = "a" 729 pointPen.beginPath() 730 pointPen.addPoint(*[(1, -2)], **{"segmentType" : "move", "smooth" : False}) 731 pointPen.addPoint(*[(3, -4)], **{"segmentType" : "line", "smooth" : False}) 732 pointPen.endPath() 733 """ 734 resultGlif = self.pyToGLIF(py) 735 resultPy = self.glifToPy(glif) 736 self.assertEqual(glif, resultGlif) 737 self.assertEqual(py, resultPy) 738 739 def testPointTypeLine_legal_start_of_contour(self): 740 # legal: start of contour 741 glif = """ 742 <glyph name="a" format="1"> 743 <outline> 744 <contour> 745 <point x="1" y="-2" type="line"/> 746 <point x="3" y="-4" type="line"/> 747 </contour> 748 </outline> 749 </glyph> 750 """ 751 py = """ 752 glyph.name = "a" 753 pointPen.beginPath() 754 pointPen.addPoint(*[(1, -2)], **{"segmentType" : "line", "smooth" : False}) 755 pointPen.addPoint(*[(3, -4)], **{"segmentType" : "line", "smooth" : False}) 756 pointPen.endPath() 757 """ 758 resultGlif = self.pyToGLIF(py) 759 resultPy = self.glifToPy(glif) 760 self.assertEqual(glif, resultGlif) 761 self.assertEqual(py, resultPy) 762 763 def testPointTypeLine_legal_smooth(self): 764 # legal: smooth=True 765 glif = """ 766 <glyph name="a" format="1"> 767 <outline> 768 <contour> 769 <point x="1" y="-2" type="move"/> 770 <point x="3" y="-4" type="line" smooth="yes"/> 771 </contour> 772 </outline> 773 </glyph> 774 """ 775 py = """ 776 glyph.name = "a" 777 pointPen.beginPath() 778 pointPen.addPoint(*[(1, -2)], **{"segmentType" : "move", "smooth" : False}) 779 pointPen.addPoint(*[(3, -4)], **{"segmentType" : "line", "smooth" : True}) 780 pointPen.endPath() 781 """ 782 resultGlif = self.pyToGLIF(py) 783 resultPy = self.glifToPy(glif) 784 self.assertEqual(glif, resultGlif) 785 self.assertEqual(py, resultPy) 786 787 def testPointTypeCurve_legal(self): 788 # legal 789 glif = """ 790 <glyph name="a" format="1"> 791 <outline> 792 <contour> 793 <point x="0" y="0" type="move"/> 794 <point x="0" y="65"/> 795 <point x="65" y="200"/> 796 <point x="100" y="200" type="curve"/> 797 </contour> 798 </outline> 799 </glyph> 800 """ 801 py = """ 802 glyph.name = "a" 803 pointPen.beginPath() 804 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False}) 805 pointPen.addPoint(*[(0, 65)], **{"smooth" : False}) 806 pointPen.addPoint(*[(65, 200)], **{"smooth" : False}) 807 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False}) 808 pointPen.endPath() 809 """ 810 resultGlif = self.pyToGLIF(py) 811 resultPy = self.glifToPy(glif) 812 self.assertEqual(glif, resultGlif) 813 self.assertEqual(py, resultPy) 814 815 def testPointTypeCurve_legal_start_of_contour(self): 816 # legal: start of contour 817 glif = """ 818 <glyph name="a" format="1"> 819 <outline> 820 <contour> 821 <point x="100" y="200" type="curve"/> 822 <point x="0" y="65"/> 823 <point x="65" y="200"/> 824 </contour> 825 </outline> 826 </glyph> 827 """ 828 py = """ 829 glyph.name = "a" 830 pointPen.beginPath() 831 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False}) 832 pointPen.addPoint(*[(0, 65)], **{"smooth" : False}) 833 pointPen.addPoint(*[(65, 200)], **{"smooth" : False}) 834 pointPen.endPath() 835 """ 836 resultGlif = self.pyToGLIF(py) 837 resultPy = self.glifToPy(glif) 838 self.assertEqual(glif, resultGlif) 839 self.assertEqual(py, resultPy) 840 841 def testPointTypeCurve_legal_smooth(self): 842 # legal: smooth=True 843 glif = """ 844 <glyph name="a" format="1"> 845 <outline> 846 <contour> 847 <point x="0" y="0" type="move"/> 848 <point x="0" y="65"/> 849 <point x="65" y="200"/> 850 <point x="100" y="200" type="curve" smooth="yes"/> 851 </contour> 852 </outline> 853 </glyph> 854 """ 855 py = """ 856 glyph.name = "a" 857 pointPen.beginPath() 858 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False}) 859 pointPen.addPoint(*[(0, 65)], **{"smooth" : False}) 860 pointPen.addPoint(*[(65, 200)], **{"smooth" : False}) 861 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : True}) 862 pointPen.endPath() 863 """ 864 resultGlif = self.pyToGLIF(py) 865 resultPy = self.glifToPy(glif) 866 self.assertEqual(glif, resultGlif) 867 self.assertEqual(py, resultPy) 868 869 def testPointTypeCurve_legal_no_off_curves(self): 870 # legal: no off-curves 871 glif = """ 872 <glyph name="a" format="1"> 873 <outline> 874 <contour> 875 <point x="0" y="0" type="move"/> 876 <point x="100" y="200" type="curve"/> 877 </contour> 878 </outline> 879 </glyph> 880 """ 881 py = """ 882 glyph.name = "a" 883 pointPen.beginPath() 884 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False}) 885 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False}) 886 pointPen.endPath() 887 """ 888 resultGlif = self.pyToGLIF(py) 889 resultPy = self.glifToPy(glif) 890 self.assertEqual(glif, resultGlif) 891 self.assertEqual(py, resultPy) 892 893 def testPointTypeCurve_legal_1_off_curve(self): 894 # legal: 1 off-curve 895 glif = """ 896 <glyph name="a" format="1"> 897 <outline> 898 <contour> 899 <point x="0" y="0" type="move"/> 900 <point x="50" y="100"/> 901 <point x="100" y="200" type="curve"/> 902 </contour> 903 </outline> 904 </glyph> 905 """ 906 py = """ 907 glyph.name = "a" 908 pointPen.beginPath() 909 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False}) 910 pointPen.addPoint(*[(50, 100)], **{"smooth" : False}) 911 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False}) 912 pointPen.endPath() 913 """ 914 resultGlif = self.pyToGLIF(py) 915 resultPy = self.glifToPy(glif) 916 self.assertEqual(glif, resultGlif) 917 self.assertEqual(py, resultPy) 918 919 def testPointTypeCurve_illegal_3_off_curves(self): 920 # illegal: 3 off-curves 921 glif = """ 922 <glyph name="a" format="1"> 923 <outline> 924 <contour> 925 <point x="0" y="0" type="move"/> 926 <point x="0" y="100"/> 927 <point x="35" y="125"/> 928 <point x="65" y="200"/> 929 <point x="100" y="200" type="curve"/> 930 </contour> 931 </outline> 932 </glyph> 933 """ 934 py = """ 935 glyph.name = "a" 936 pointPen.beginPath() 937 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False}) 938 pointPen.addPoint(*[(0, 100)], **{"smooth" : False}) 939 pointPen.addPoint(*[(35, 125)], **{"smooth" : False}) 940 pointPen.addPoint(*[(65, 200)], **{"smooth" : False}) 941 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False}) 942 pointPen.endPath() 943 """ 944 self.assertRaises(GlifLibError, self.pyToGLIF, py) 945 self.assertRaises(GlifLibError, self.glifToPy, glif) 946 947 def testPointQCurve_legal(self): 948 # legal 949 glif = """ 950 <glyph name="a" format="1"> 951 <outline> 952 <contour> 953 <point x="0" y="0" type="move"/> 954 <point x="0" y="65"/> 955 <point x="65" y="200"/> 956 <point x="100" y="200" type="qcurve"/> 957 </contour> 958 </outline> 959 </glyph> 960 """ 961 py = """ 962 glyph.name = "a" 963 pointPen.beginPath() 964 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False}) 965 pointPen.addPoint(*[(0, 65)], **{"smooth" : False}) 966 pointPen.addPoint(*[(65, 200)], **{"smooth" : False}) 967 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "qcurve", "smooth" : False}) 968 pointPen.endPath() 969 """ 970 resultGlif = self.pyToGLIF(py) 971 resultPy = self.glifToPy(glif) 972 self.assertEqual(glif, resultGlif) 973 self.assertEqual(py, resultPy) 974 975 def testPointQCurve_legal_start_of_contour(self): 976 # legal: start of contour 977 glif = """ 978 <glyph name="a" format="1"> 979 <outline> 980 <contour> 981 <point x="100" y="200" type="qcurve"/> 982 <point x="0" y="65"/> 983 <point x="65" y="200"/> 984 </contour> 985 </outline> 986 </glyph> 987 """ 988 py = """ 989 glyph.name = "a" 990 pointPen.beginPath() 991 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "qcurve", "smooth" : False}) 992 pointPen.addPoint(*[(0, 65)], **{"smooth" : False}) 993 pointPen.addPoint(*[(65, 200)], **{"smooth" : False}) 994 pointPen.endPath() 995 """ 996 resultGlif = self.pyToGLIF(py) 997 resultPy = self.glifToPy(glif) 998 self.assertEqual(glif, resultGlif) 999 self.assertEqual(py, resultPy) 1000 1001 def testPointQCurve_legal_smooth(self): 1002 # legal: smooth=True 1003 glif = """ 1004 <glyph name="a" format="1"> 1005 <outline> 1006 <contour> 1007 <point x="0" y="0" type="move"/> 1008 <point x="0" y="65"/> 1009 <point x="65" y="200"/> 1010 <point x="100" y="200" type="qcurve" smooth="yes"/> 1011 </contour> 1012 </outline> 1013 </glyph> 1014 """ 1015 py = """ 1016 glyph.name = "a" 1017 pointPen.beginPath() 1018 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False}) 1019 pointPen.addPoint(*[(0, 65)], **{"smooth" : False}) 1020 pointPen.addPoint(*[(65, 200)], **{"smooth" : False}) 1021 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "qcurve", "smooth" : True}) 1022 pointPen.endPath() 1023 """ 1024 resultGlif = self.pyToGLIF(py) 1025 resultPy = self.glifToPy(glif) 1026 self.assertEqual(glif, resultGlif) 1027 self.assertEqual(py, resultPy) 1028 1029 def testPointQCurve_legal_no_off_curves(self): 1030 # legal: no off-curves 1031 glif = """ 1032 <glyph name="a" format="1"> 1033 <outline> 1034 <contour> 1035 <point x="0" y="0" type="move"/> 1036 <point x="100" y="200" type="qcurve"/> 1037 </contour> 1038 </outline> 1039 </glyph> 1040 """ 1041 py = """ 1042 glyph.name = "a" 1043 pointPen.beginPath() 1044 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False}) 1045 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "qcurve", "smooth" : False}) 1046 pointPen.endPath() 1047 """ 1048 resultGlif = self.pyToGLIF(py) 1049 resultPy = self.glifToPy(glif) 1050 self.assertEqual(glif, resultGlif) 1051 self.assertEqual(py, resultPy) 1052 1053 def testPointQCurve_legal_one_off_curve(self): 1054 # legal: 1 off-curve 1055 glif = """ 1056 <glyph name="a" format="1"> 1057 <outline> 1058 <contour> 1059 <point x="0" y="0" type="move"/> 1060 <point x="50" y="100"/> 1061 <point x="100" y="200" type="qcurve"/> 1062 </contour> 1063 </outline> 1064 </glyph> 1065 """ 1066 py = """ 1067 glyph.name = "a" 1068 pointPen.beginPath() 1069 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False}) 1070 pointPen.addPoint(*[(50, 100)], **{"smooth" : False}) 1071 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "qcurve", "smooth" : False}) 1072 pointPen.endPath() 1073 """ 1074 resultGlif = self.pyToGLIF(py) 1075 resultPy = self.glifToPy(glif) 1076 self.assertEqual(glif, resultGlif) 1077 self.assertEqual(py, resultPy) 1078 1079 def testPointQCurve_legal_3_off_curves(self): 1080 # legal: 3 off-curves 1081 glif = """ 1082 <glyph name="a" format="1"> 1083 <outline> 1084 <contour> 1085 <point x="0" y="0" type="move"/> 1086 <point x="0" y="100"/> 1087 <point x="35" y="125"/> 1088 <point x="65" y="200"/> 1089 <point x="100" y="200" type="qcurve"/> 1090 </contour> 1091 </outline> 1092 </glyph> 1093 """ 1094 py = """ 1095 glyph.name = "a" 1096 pointPen.beginPath() 1097 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False}) 1098 pointPen.addPoint(*[(0, 100)], **{"smooth" : False}) 1099 pointPen.addPoint(*[(35, 125)], **{"smooth" : False}) 1100 pointPen.addPoint(*[(65, 200)], **{"smooth" : False}) 1101 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "qcurve", "smooth" : False}) 1102 pointPen.endPath() 1103 """ 1104 resultGlif = self.pyToGLIF(py) 1105 resultPy = self.glifToPy(glif) 1106 self.assertEqual(glif, resultGlif) 1107 self.assertEqual(py, resultPy) 1108 1109 def testSpecialCaseQCurve(self): 1110 # contour with no on curve 1111 glif = """ 1112 <glyph name="a" format="1"> 1113 <outline> 1114 <contour> 1115 <point x="0" y="0"/> 1116 <point x="0" y="100"/> 1117 <point x="100" y="100"/> 1118 <point x="100" y="0"/> 1119 </contour> 1120 </outline> 1121 </glyph> 1122 """ 1123 py = """ 1124 glyph.name = "a" 1125 pointPen.beginPath() 1126 pointPen.addPoint(*[(0, 0)], **{"smooth" : False}) 1127 pointPen.addPoint(*[(0, 100)], **{"smooth" : False}) 1128 pointPen.addPoint(*[(100, 100)], **{"smooth" : False}) 1129 pointPen.addPoint(*[(100, 0)], **{"smooth" : False}) 1130 pointPen.endPath() 1131 """ 1132 resultGlif = self.pyToGLIF(py) 1133 resultPy = self.glifToPy(glif) 1134 self.assertEqual(glif, resultGlif) 1135 self.assertEqual(py, resultPy) 1136 1137 def testPointTypeOffCurve_legal(self): 1138 # legal 1139 glif = """ 1140 <glyph name="a" format="1"> 1141 <outline> 1142 <contour> 1143 <point x="0" y="0" type="move"/> 1144 <point x="0" y="65"/> 1145 <point x="65" y="200"/> 1146 <point x="100" y="200" type="curve"/> 1147 </contour> 1148 </outline> 1149 </glyph> 1150 """ 1151 py = """ 1152 glyph.name = "a" 1153 pointPen.beginPath() 1154 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False}) 1155 pointPen.addPoint(*[(0, 65)], **{"smooth" : False}) 1156 pointPen.addPoint(*[(65, 200)], **{"smooth" : False}) 1157 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False}) 1158 pointPen.endPath() 1159 """ 1160 resultGlif = self.pyToGLIF(py) 1161 resultPy = self.glifToPy(glif) 1162 self.assertEqual(glif, resultGlif) 1163 self.assertEqual(py, resultPy) 1164 1165 def testPointTypeOffCurve_legal_start_of_contour(self): 1166 # legal: start of contour 1167 glif = """ 1168 <glyph name="a" format="1"> 1169 <outline> 1170 <contour> 1171 <point x="0" y="65"/> 1172 <point x="65" y="200"/> 1173 <point x="100" y="200" type="curve"/> 1174 </contour> 1175 </outline> 1176 </glyph> 1177 """ 1178 py = """ 1179 glyph.name = "a" 1180 pointPen.beginPath() 1181 pointPen.addPoint(*[(0, 65)], **{"smooth" : False}) 1182 pointPen.addPoint(*[(65, 200)], **{"smooth" : False}) 1183 pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False}) 1184 pointPen.endPath() 1185 """ 1186 resultGlif = self.pyToGLIF(py) 1187 resultPy = self.glifToPy(glif) 1188 self.assertEqual(glif, resultGlif) 1189 self.assertEqual(py, resultPy) 1190 1191 def testPointTypeOffCurve_illegal_before_move(self): 1192 # before move 1193 glif = """ 1194 <glyph name="a" format="1"> 1195 <outline> 1196 <contour> 1197 <point x="0" y="65"/> 1198 <point x="0" y="0" type="move"/> 1199 </contour> 1200 </outline> 1201 </glyph> 1202 """ 1203 py = """ 1204 glyph.name = "a" 1205 pointPen.beginPath() 1206 pointPen.addPoint(*[(0, 65)], **{"smooth" : False}) 1207 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False}) 1208 pointPen.endPath() 1209 """ 1210 self.assertRaises(GlifLibError, self.pyToGLIF, py) 1211 self.assertRaises(GlifLibError, self.glifToPy, glif) 1212 1213 def testPointTypeOffCurve_illegal_before_line(self): 1214 # before line 1215 glif = """ 1216 <glyph name="a" format="1"> 1217 <outline> 1218 <contour> 1219 <point x="0" y="65"/> 1220 <point x="0" y="0" type="line"/> 1221 </contour> 1222 </outline> 1223 </glyph> 1224 """ 1225 py = """ 1226 glyph.name = "a" 1227 pointPen.beginPath() 1228 pointPen.addPoint(*[(0, 65)], **{"smooth" : False}) 1229 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "line", "smooth" : False}) 1230 pointPen.endPath() 1231 """ 1232 self.assertRaises(GlifLibError, self.pyToGLIF, py) 1233 self.assertRaises(GlifLibError, self.glifToPy, glif) 1234 1235 def testPointTypeOffCurve_illegal_smooth(self): 1236 # smooth=True 1237 glif = """ 1238 <glyph name="a" format="1"> 1239 <outline> 1240 <contour> 1241 <point x="0" y="65" smooth="yes"/> 1242 <point x="0" y="0" type="curve"/> 1243 </contour> 1244 </outline> 1245 </glyph> 1246 """ 1247 py = """ 1248 glyph.name = "a" 1249 pointPen.beginPath() 1250 pointPen.addPoint(*[(0, 65)], **{"smooth" : True}) 1251 pointPen.addPoint(*[(0, 0)], **{"segmentType" : "curve", "smooth" : False}) 1252 pointPen.endPath() 1253 """ 1254 self.assertRaises(GlifLibError, self.pyToGLIF, py) 1255 self.assertRaises(GlifLibError, self.glifToPy, glif) 1256 1257 def testSinglePoint_legal_without_name(self): 1258 # legal 1259 # glif format 1 single point without a name was not an anchor 1260 glif = """ 1261 <glyph name="a" format="1"> 1262 <outline> 1263 <contour> 1264 <point x="1" y="2" type="move"/> 1265 </contour> 1266 </outline> 1267 </glyph> 1268 """ 1269 py = """ 1270 glyph.name = "a" 1271 pointPen.beginPath() 1272 pointPen.addPoint(*[(1, 2)], **{"segmentType" : "move", "smooth" : False}) 1273 pointPen.endPath() 1274 """ 1275 resultGlif = self.pyToGLIF(py) 1276 resultPy = self.glifToPy(glif) 1277 self.assertEqual(glif, resultGlif) 1278 self.assertEqual(py, resultPy) 1279 1280 def testAnchor_legal_with_name(self): 1281 glif = """ 1282 <glyph name="a" format="1"> 1283 <outline> 1284 <contour> 1285 <point x="1" y="2" type="move" name="test"/> 1286 </contour> 1287 </outline> 1288 </glyph> 1289 """ 1290 py = """ 1291 glyph.name = "a" 1292 glyph.anchors = [{"name" : "test", "x" : 1, "y" : 2}] 1293 """ 1294 resultGlif = self.pyToGLIF(py) 1295 resultPy = self.glifToPy(glif) 1296 self.assertEqual(glif, resultGlif) 1297 self.assertEqual(py, resultPy) 1298 1299 def testOpenContourLooseOffCurves_legal(self): 1300 # a piece of software was writing this kind of structure 1301 glif = """ 1302 <glyph name="a" format="1"> 1303 <outline> 1304 <contour> 1305 <point x="1" y="2" type="move"/> 1306 <point x="1" y="2"/> 1307 <point x="1" y="2"/> 1308 <point x="1" y="2" type="curve"/> 1309 <point x="1" y="2"/> 1310 </contour> 1311 </outline> 1312 </glyph> 1313 """ 1314 expectedPy = """ 1315 glyph.name = "a" 1316 pointPen.beginPath() 1317 pointPen.addPoint(*[(1, 2)], **{"segmentType" : "move", "smooth" : False}) 1318 pointPen.addPoint(*[(1, 2)], **{"smooth" : False}) 1319 pointPen.addPoint(*[(1, 2)], **{"smooth" : False}) 1320 pointPen.addPoint(*[(1, 2)], **{"segmentType" : "curve", "smooth" : False}) 1321 pointPen.endPath() 1322 """ 1323 resultPy = self.glifToPy(glif) 1324 self.assertEqual(resultPy, expectedPy) 1325 1326 def testOpenContourLooseOffCurves_illegal(self): 1327 py = """ 1328 glyph.name = "a" 1329 pointPen.beginPath() 1330 pointPen.addPoint(*[(1, 2)], **{"segmentType" : "move", "smooth" : False}) 1331 pointPen.addPoint(*[(1, 2)], **{"smooth" : False}) 1332 pointPen.addPoint(*[(1, 2)], **{"smooth" : False}) 1333 pointPen.addPoint(*[(1, 2)], **{"segmentType" : "curve", "smooth" : False}) 1334 pointPen.addPoint(*[(1, 2)], **{"smooth" : False}) 1335 pointPen.endPath() 1336 """ 1337 self.assertRaises(GlifLibError, self.pyToGLIF, py) 1338