|
24 | 24 |
|
25 | 25 | package processing.core; |
26 | 26 |
|
| 27 | +import static java.awt.Font.BOLD; |
| 28 | +import static java.awt.Font.ITALIC; |
| 29 | +import static java.awt.Font.PLAIN; |
27 | 30 | import processing.data.*; |
28 | 31 |
|
29 | 32 | // TODO replace these with PMatrix2D |
@@ -331,6 +334,10 @@ protected PShape parseChild(XML elem) { |
331 | 334 | } else if (name.equals("rect")) { |
332 | 335 | shape = createShape(this, elem, true); |
333 | 336 | shape.parseRect(); |
| 337 | + |
| 338 | + } else if (name.equals("image")) { |
| 339 | + shape = createShape(this, elem, true); |
| 340 | + shape.parseImage(); |
334 | 341 |
|
335 | 342 | } else if (name.equals("polygon")) { |
336 | 343 | shape = createShape(this, elem, true); |
@@ -360,8 +367,10 @@ protected PShape parseChild(XML elem) { |
360 | 367 | // return new FontGlyph(this, elem); |
361 | 368 |
|
362 | 369 | } else if (name.equals("text")) { // || name.equals("font")) { |
363 | | - PGraphics.showWarning("Text and fonts in SVG files are " + |
364 | | - "not currently supported, convert text to outlines instead."); |
| 370 | + return new Text(this, elem); |
| 371 | + |
| 372 | + } else if (name.equals("tspan")) { |
| 373 | + return new LineOfText(this, elem); |
365 | 374 |
|
366 | 375 | } else if (name.equals("filter")) { |
367 | 376 | PGraphics.showWarning("Filters are not supported."); |
@@ -441,8 +450,23 @@ protected void parseRect() { |
441 | 450 | getFloatWithUnit(element, "height", svgHeight) |
442 | 451 | }; |
443 | 452 | } |
| 453 | + |
| 454 | + |
| 455 | + protected void parseImage() { |
| 456 | + kind = RECT; |
| 457 | + textureMode = NORMAL; |
444 | 458 |
|
| 459 | + family = PRIMITIVE; |
| 460 | + params = new float[] { |
| 461 | + getFloatWithUnit(element, "x", svgWidth), |
| 462 | + getFloatWithUnit(element, "y", svgHeight), |
| 463 | + getFloatWithUnit(element, "width", svgWidth), |
| 464 | + getFloatWithUnit(element, "height", svgHeight) |
| 465 | + }; |
445 | 466 |
|
| 467 | + this.imagePath = element.getString("xlink:href"); |
| 468 | + } |
| 469 | + |
446 | 470 | /** |
447 | 471 | * Parse a polyline or polygon from an SVG file. |
448 | 472 | * Syntax defined at http://www.w3.org/TR/SVG/shapes.html#PointsBNF |
@@ -1572,8 +1596,179 @@ public RadialGradient(PShapeSVG parent, XML properties) { |
1572 | 1596 |
|
1573 | 1597 |
|
1574 | 1598 | // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
| 1599 | + |
| 1600 | + public static float TEXT_QUALITY = 1; |
| 1601 | + protected PFont parseFont(XML properties) { |
| 1602 | + |
| 1603 | +// FontFace fontFace = new FontFace(this, properties); |
| 1604 | + String fontFamily = null; |
| 1605 | + float size = 10; |
| 1606 | + int weight = PLAIN; // 0 |
| 1607 | + int italic = 0; |
| 1608 | + |
| 1609 | + if (properties.hasAttribute("style")) { |
| 1610 | + String styleText = properties.getString("style"); |
| 1611 | + String[] styleTokens = PApplet.splitTokens(styleText, ";"); |
| 1612 | + |
| 1613 | + //PApplet.println(styleTokens); |
| 1614 | + for (int i = 0; i < styleTokens.length; i++) { |
| 1615 | + |
| 1616 | + String[] tokens = PApplet.splitTokens(styleTokens[i], ":"); |
| 1617 | + //PApplet.println(tokens); |
| 1618 | + |
| 1619 | + tokens[0] = PApplet.trim(tokens[0]); |
| 1620 | + |
| 1621 | + if (tokens[0].equals("font-style")) { |
| 1622 | + // PApplet.println("font-style: " + tokens[1]); |
| 1623 | + if (tokens[1].contains("italic")) { |
| 1624 | + italic = ITALIC; |
| 1625 | + } |
| 1626 | + } else if (tokens[0].equals("font-variant")) { |
| 1627 | + // PApplet.println("font-variant: " + tokens[1]); |
| 1628 | + // setFillOpacity(tokens[1]); |
| 1629 | + |
| 1630 | + } else if (tokens[0].equals("font-weight")) { |
| 1631 | + // PApplet.println("font-weight: " + tokens[1]); |
| 1632 | + |
| 1633 | + if (tokens[1].contains("bold")) { |
| 1634 | + weight = BOLD; |
| 1635 | + // PApplet.println("Bold weight ! "); |
| 1636 | + } |
| 1637 | + |
| 1638 | + |
| 1639 | + } else if (tokens[0].equals("font-stretch")) { |
| 1640 | + // not supported. |
| 1641 | + |
| 1642 | + } else if (tokens[0].equals("font-size")) { |
| 1643 | + // PApplet.println("font-size: " + tokens[1]); |
| 1644 | + size = Float.parseFloat(tokens[1].split("px")[0]); |
| 1645 | + // PApplet.println("font-size-parsed: " + size); |
| 1646 | + } else if (tokens[0].equals("line-height")) { |
| 1647 | + // not supported |
| 1648 | + |
| 1649 | + } else if (tokens[0].equals("font-family")) { |
| 1650 | + // PApplet.println("Font-family: " + tokens[1]); |
| 1651 | + fontFamily = tokens[1]; |
| 1652 | + |
| 1653 | + } else if (tokens[0].equals("text-align")) { |
| 1654 | + // not supported |
| 1655 | + |
| 1656 | + } else if (tokens[0].equals("letter-spacing")) { |
| 1657 | + // not supported |
| 1658 | + |
| 1659 | + } else if (tokens[0].equals("word-spacing")) { |
| 1660 | + // not supported |
| 1661 | + |
| 1662 | + } else if (tokens[0].equals("writing-mode")) { |
| 1663 | + // not supported |
| 1664 | + |
| 1665 | + } else if (tokens[0].equals("text-anchor")) { |
| 1666 | + // not supported |
| 1667 | + |
| 1668 | + } else { |
| 1669 | + // Other attributes are not yet implemented |
| 1670 | + } |
| 1671 | + } |
| 1672 | + } |
| 1673 | + if (fontFamily == null) { |
| 1674 | + return null; |
| 1675 | + } |
| 1676 | + size = size * TEXT_QUALITY; |
| 1677 | + |
| 1678 | + return createFont(fontFamily, weight | italic, size, true); |
| 1679 | + } |
| 1680 | + |
| 1681 | + protected PFont createFont(String name, int weight, float size, boolean smooth) { |
| 1682 | + |
| 1683 | +// System.out.println("Try to create a font of " + name + " family, " + weight); |
| 1684 | + java.awt.Font baseFont = new java.awt.Font(name, weight, (int) size); // PFont.findFont(name);ç |
| 1685 | + |
| 1686 | +// System.out.println("Resulting family : " + baseFont.getFamily() + " " + baseFont.getStyle()); |
| 1687 | + PFont outputPFont = new PFont(baseFont.deriveFont(size), smooth, null); |
| 1688 | + |
| 1689 | +// System.out.println("Resulting PFont family : " + outputPFont.getName()); |
| 1690 | + return outputPFont; |
| 1691 | + } |
| 1692 | + |
| 1693 | + public static class Text extends PShapeSVG { |
| 1694 | + |
| 1695 | + protected PFont font; |
| 1696 | + |
| 1697 | + public Text(PShapeSVG parent, XML properties) { |
| 1698 | + super(parent, properties, true); |
| 1699 | + |
| 1700 | + // get location |
| 1701 | + float x = Float.parseFloat(properties.getString("x")); |
| 1702 | + float y = Float.parseFloat(properties.getString("y")); |
| 1703 | + |
| 1704 | + if (matrix == null) { |
| 1705 | + matrix = new PMatrix2D(); |
| 1706 | + } |
| 1707 | + matrix.translate(x, y); |
| 1708 | + |
| 1709 | + family = GROUP; |
| 1710 | + |
| 1711 | + font = parseFont(properties); |
1575 | 1712 |
|
| 1713 | + } |
| 1714 | + |
| 1715 | +// @Override |
| 1716 | +// public void drawImpl(PGraphics g){ |
| 1717 | +// } |
| 1718 | + } |
| 1719 | + |
| 1720 | + public static class LineOfText extends PShapeSVG { |
1576 | 1721 |
|
| 1722 | + String textToDisplay; |
| 1723 | + PFont font; |
| 1724 | + |
| 1725 | + public LineOfText(PShapeSVG parent, XML properties) { |
| 1726 | + |
| 1727 | + // TODO: child should ideally be parsed too... |
| 1728 | + // for inline content. |
| 1729 | + super(parent, properties, false); |
| 1730 | + |
| 1731 | +// // get location |
| 1732 | + float x = Float.parseFloat(properties.getString("x")); |
| 1733 | + float y = Float.parseFloat(properties.getString("y")); |
| 1734 | + |
| 1735 | + float parentX = Float.parseFloat(parent.element.getString("x")); |
| 1736 | + float parentY = Float.parseFloat(parent.element.getString("y")); |
| 1737 | + |
| 1738 | + if (matrix == null) matrix = new PMatrix2D(); |
| 1739 | + matrix.translate(x - parentX, (y - parentY) / 2f); |
| 1740 | + |
| 1741 | + // get the first properties |
| 1742 | + parseColors(properties); |
| 1743 | + font = parseFont(properties); |
| 1744 | + |
| 1745 | + // It is a line.. |
| 1746 | + boolean isALine = properties.getString("role") == "line"; |
| 1747 | + // NO inline content yet. |
| 1748 | + if (this.childCount > 0) { |
| 1749 | + } |
| 1750 | + |
| 1751 | + String text = properties.getContent(); |
| 1752 | + textToDisplay = text; |
| 1753 | + } |
| 1754 | + |
| 1755 | + @Override |
| 1756 | + public void drawImpl(PGraphics g) { |
| 1757 | + if (font == null) { |
| 1758 | + font = ((Text) parent).font; |
| 1759 | + if (font == null) { |
| 1760 | + return; |
| 1761 | + } |
| 1762 | + } |
| 1763 | + |
| 1764 | + pre(g); |
| 1765 | + g.textFont(font, font.size / TEXT_QUALITY); |
| 1766 | + g.text(textToDisplay, 0, 0); |
| 1767 | + post(g); |
| 1768 | + } |
| 1769 | + |
| 1770 | + } |
| 1771 | + |
1577 | 1772 | public static class Font extends PShapeSVG { |
1578 | 1773 | public FontFace face; |
1579 | 1774 |
|
|
0 commit comments