View | Details | Raw Unified | Return to bug 52849
Collapse All | Expand All

(-)src/java/org/apache/fop/fonts/FontEventProducer.java (+7 lines)
Lines 79-82 Link Here
79
     */
79
     */
80
    void fontDirectoryNotFound(Object source, String dir);
80
    void fontDirectoryNotFound(Object source, String dir);
81
81
82
    /**
83
     * The SVG text will be stroked as shapes.
84
     * @param source
85
     * @param fontFamily
86
     * @event.severity WARN
87
     */
88
    void svgTextStrokedAsShapes(Object source, String fontFamily);
82
}
89
}
(-)src/java/org/apache/fop/fonts/FontEventProducer.xml (-1 / +2 lines)
Lines 20-24 Link Here
20
  <message key="fontSubstituted">Font "{requested}" not found. Substituting with "{effective}".</message>
20
  <message key="fontSubstituted">Font "{requested}" not found. Substituting with "{effective}".</message>
21
  <message key="fontLoadingErrorAtAutoDetection">Unable to load font file: {fontURL}.[ Reason: {e}]</message>
21
  <message key="fontLoadingErrorAtAutoDetection">Unable to load font file: {fontURL}.[ Reason: {e}]</message>
22
  <message key="glyphNotAvailable">Glyph "{ch}" (0x{ch,hex}[, {ch,glyph-name}]) not available in font "{fontName}".</message>
22
  <message key="glyphNotAvailable">Glyph "{ch}" (0x{ch,hex}[, {ch,glyph-name}]) not available in font "{fontName}".</message>
23
  <message key="fontDirectoryNotFound">'{dir}' does not exist or is not a directory.</message>
23
  <message key="fontDirectoryNotFound">The font directory {dir} could not be found.</message>
24
  <message key="svgTextStrokedAsShapes">The SVG text for font {fontFamily} will be stroked as shapes.</message>
24
</catalogue>
25
</catalogue>
(-)src/java/org/apache/fop/fonts/FontEventListener.java (+7 lines)
Lines 54-57 Link Here
54
     * @param dir the directory in the config file
54
     * @param dir the directory in the config file
55
     */
55
     */
56
    void fontDirectoryNotFound(Object source, String dir);
56
    void fontDirectoryNotFound(Object source, String dir);
57
58
    /**
59
     * The SVG text will be stroked as shapes.
60
     * @param source
61
     * @param fontFamily
62
     */
63
    void svgTextStrokedAsShapes(Object source, String fontFamily);
57
}
64
}
(-)src/java/org/apache/fop/fonts/FontInfo.java (-1 / +25 lines)
Lines 63-69 Link Here
63
     *  a collection of missing fonts; used to make sure the user gets
63
     *  a collection of missing fonts; used to make sure the user gets
64
     *  a warning for a missing font only once (not every time the font is used)
64
     *  a warning for a missing font only once (not every time the font is used)
65
     */
65
     */
66
    private Set<FontTriplet> loggedFontKeys = null;
66
    private Set<FontTriplet> loggedFontKeys;
67
68
    private Set<String> gvtFontFamilies;
67
69
68
    /** Cache for Font instances. */
70
    /** Cache for Font instances. */
69
    private Map<FontTriplet, Map<Integer, Font>> fontInstanceCache = null;
71
    private Map<FontTriplet, Map<Integer, Font>> fontInstanceCache = null;
Lines 472-477 Link Here
472
        }
474
        }
473
    }
475
    }
474
476
477
    private Set<String> getGVTFontFamilies() {
478
        if (gvtFontFamilies == null) {
479
            gvtFontFamilies = new HashSet<String>();
480
        }
481
        return gvtFontFamilies;
482
    }
483
484
    /**
485
     * Notify listeners or log a message that the SVG text for the given font will be stroked as shapes.
486
     * @param fontFamily a SVG font family
487
     */
488
    public void notifyStrokingSVGTextAsShapes(String fontFamily) {
489
        if (!getGVTFontFamilies().contains(fontFamily)) {
490
            getGVTFontFamilies().add(fontFamily);
491
            if (this.eventListener != null) {
492
                this.eventListener.svgTextStrokedAsShapes(this, fontFamily);
493
            } else {
494
                log.warn("The SVG text for font " + fontFamily + " will be stroked as shapes.");
495
            }
496
        }
497
    }
498
475
    /**
499
    /**
476
     * Find a font with a given family and style by trying
500
     * Find a font with a given family and style by trying
477
     * different font weights according to the spec.
501
     * different font weights according to the spec.
(-)src/java/org/apache/fop/fonts/FontEventAdapter.java (+5 lines)
Lines 66-69 Link Here
66
        getEventProducer().fontDirectoryNotFound(source, dir);
66
        getEventProducer().fontDirectoryNotFound(source, dir);
67
    }
67
    }
68
68
69
    /** {@inheritDoc} */
70
    public void svgTextStrokedAsShapes(Object source, String fontFamily) {
71
        getEventProducer().svgTextStrokedAsShapes(source, fontFamily);
72
    }
73
69
}
74
}
(-)src/java/org/apache/fop/tools/fontlist/FontListMain.java (+4 lines)
Lines 147-152 Link Here
147
                //ignore
147
                //ignore
148
            }
148
            }
149
149
150
            public void svgTextStrokedAsShapes(Object source, String fontFamily) {
151
                // ignore
152
            }
153
150
        };
154
        };
151
155
152
        FontListGenerator listGenerator = new FontListGenerator();
156
        FontListGenerator listGenerator = new FontListGenerator();
(-)src/java/org/apache/fop/svg/ACIUtils.java (-1 / +9 lines)
Lines 96-104 Link Here
96
        }
96
        }
97
97
98
        if (gvtFonts != null) {
98
        if (gvtFonts != null) {
99
            boolean haveInstanceOfSVGFontFamily = false;
99
            for (GVTFontFamily fam : gvtFonts) {
100
            for (GVTFontFamily fam : gvtFonts) {
100
                if (fam instanceof SVGFontFamily) {
101
                if (fam instanceof SVGFontFamily) {
101
                    return null; //Let Batik paint this text!
102
                    haveInstanceOfSVGFontFamily = true;
102
                }
103
                }
103
                String fontFamily = fam.getFamilyName();
104
                String fontFamily = fam.getFamilyName();
104
                if (fontInfo.hasFont(fontFamily, style, weight)) {
105
                if (fontInfo.hasFont(fontFamily, style, weight)) {
Lines 116-121 Link Here
116
                    firstFontFamily = fontFamily;
117
                    firstFontFamily = fontFamily;
117
                }
118
                }
118
            }
119
            }
120
            // SVG fonts are embedded fonts in the SVG document and are rarely used; however if they are used
121
            // but the fonts also exists in the system and are known to FOP then FOP should use them; then the
122
            // decision whether Batik should stroke the text should be made after no matching fonts are found
123
            if (fonts.isEmpty() && haveInstanceOfSVGFontFamily) {
124
                fontInfo.notifyStrokingSVGTextAsShapes(firstFontFamily);
125
                return null; // Let Batik paint this text!
126
            }
119
        }
127
        }
120
        if (fonts.isEmpty()) {
128
        if (fonts.isEmpty()) {
121
            if (firstFontFamily == null) {
129
            if (firstFontFamily == null) {
(-)test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java (+10 lines)
Lines 57-60 Link Here
57
                MimeConstants.MIME_PDF);
57
                MimeConstants.MIME_PDF);
58
    }
58
    }
59
59
60
    @Test
61
    public void testSVGFontStrokedAsShapes() throws FOPException, TransformerException, IOException,
62
            SAXException {
63
        // svg-fonts.fo embeds two fonts; one that is present in the system and the other is not; the
64
        // missing font is stroked as shapes while the fonts that exists is stroked as text
65
        InputStream inStream = getClass().getResourceAsStream("svg-fonts.fo");
66
        eventsTests.doTest(inStream, null, FontEventProducer.class.getName() + ".svgTextStrokedAsShapes",
67
                MimeConstants.MIME_PDF);
68
    }
69
60
}
70
}
(-)test/java/org/apache/fop/fonts/svg-fonts.fo (+37 lines)
Line 0 Link Here
1
<?xml version="1.0" standalone="no"?>
2
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
3
  <fo:layout-master-set>
4
    <fo:simple-page-master master-name="page">
5
      <fo:region-body />
6
    </fo:simple-page-master>
7
  </fo:layout-master-set>
8
  <fo:page-sequence master-reference="page">
9
    <fo:flow flow-name="xsl-region-body">
10
      <fo:block>
11
        <fo:instream-foreign-object>
12
          <svg:svg width="250" height="50">
13
            <svg:font horiz-adv-x="1000">
14
              <svg:font-face font-family="Missing" units-per-em="1000" underline-position="-100"
15
                underline-thickness="50" />
16
              <svg:glyph unicode="A" horiz-adv-x="686" d="M162,186l362,0l78,-186l84,0l-308,708l-70,0l-308,-708l84,0M343,624l153,-372l-307,0z" />
17
              <svg:glyph unicode="C" horiz-adv-x="704" d="M620,154C567,72 491,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C492,660 571,613 599,567l63,47C600,693 505,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C534,-18 632,39 679,112z" />
18
              <svg:glyph unicode="F" horiz-adv-x="556" d="M168,335l330,0l0,66l-330,0l0,241l355,0l0,66l-427,0l0,-708l72,0z" />
19
              <svg:glyph unicode="G" horiz-adv-x="778" d="M673,631C610,694 529,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C503,-18 606,7 685,54l0,347l-241,0l0,-66l169,0l0,-237C560,68 490,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C504,660 571,629 619,578z" />
20
            </svg:font>
21
            <svg:font horiz-adv-x="1000">
22
              <!-- this is not Helvetica but it is here to increase coverage and show the code takes expected path -->
23
              <svg:font-face font-family="Helvetica" units-per-em="1000" underline-position="-100"
24
                underline-thickness="50" />
25
              <svg:glyph unicode="A" horiz-adv-x="686" d="M162,186l362,0l78,-186l84,0l-308,708l-70,0l-308,-708l84,0M343,624l153,-372l-307,0z" />
26
              <svg:glyph unicode="C" horiz-adv-x="704" d="M620,154C567,72 491,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C492,660 571,613 599,567l63,47C600,693 505,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C534,-18 632,39 679,112z" />
27
              <svg:glyph unicode="F" horiz-adv-x="556" d="M168,335l330,0l0,66l-330,0l0,241l355,0l0,66l-427,0l0,-708l72,0z" />
28
              <svg:glyph unicode="G" horiz-adv-x="778" d="M673,631C610,694 529,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C503,-18 606,7 685,54l0,347l-241,0l0,-66l169,0l0,-237C560,68 490,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C504,660 571,629 619,578z" />
29
            </svg:font>
30
            <svg:text x="20" y="20" font-family="Missing" font-size="12">ACFG</svg:text>
31
            <svg:text x="20" y="40" font-family="Helvetica" font-size="12">ACFG</svg:text>
32
          </svg:svg>
33
        </fo:instream-foreign-object>
34
      </fo:block>
35
    </fo:flow>
36
  </fo:page-sequence>
37
</fo:root>

Return to bug 52849