1 /*
2   ==============================================================================
3 
4    This file is part of the JUCE library.
5    Copyright (c) 2020 - Raw Material Software Limited
6 
7    JUCE is an open source library subject to commercial or open-source
8    licensing.
9 
10    By using JUCE, you agree to the terms of both the JUCE 6 End-User License
11    Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
12 
13    End User License Agreement: www.juce.com/juce-6-licence
14    Privacy Policy: www.juce.com/juce-privacy-policy
15 
16    Or: You may also use this code under the terms of the GPL v3 (see
17    www.gnu.org/licenses).
18 
19    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21    DISCLAIMED.
22 
23   ==============================================================================
24 */
25 
26 namespace juce
27 {
28 
29 //==============================================================================
30 /**
31     A typeface that can be populated with custom glyphs.
32 
33     You can create a CustomTypeface if you need one that contains your own glyphs,
34     or if you need to load a typeface from a Juce-formatted binary stream.
35 
36     If you want to create a copy of a native face, you can use addGlyphsFromOtherTypeface()
37     to copy glyphs into this face.
38 
39     NOTE! For most people this class is almost certainly NOT the right tool to use!
40     If what you want to do is to embed a font into your exe, then your best plan is
41     probably to embed your TTF/OTF font file into your binary using the Projucer,
42     and then call Typeface::createSystemTypefaceFor() to load it from memory.
43 
44     @see Typeface, Font
45 
46     @tags{Graphics}
47 */
48 class JUCE_API  CustomTypeface  : public Typeface
49 {
50 public:
51     //==============================================================================
52     /** Creates a new, empty typeface. */
53     CustomTypeface();
54 
55     /** Loads a typeface from a previously saved stream.
56         The stream must have been created by writeToStream().
57 
58         NOTE! Since this class was written, support was added for loading real font files from
59         memory, so for most people, using Typeface::createSystemTypefaceFor() to load a real font
60         is more appropriate than using this class to store it in a proprietary format.
61 
62         @see writeToStream
63     */
64     explicit CustomTypeface (InputStream& serialisedTypefaceStream);
65 
66     /** Destructor. */
67     ~CustomTypeface() override;
68 
69     //==============================================================================
70     /** Resets this typeface, deleting all its glyphs and settings. */
71     void clear();
72 
73     /** Sets the vital statistics for the typeface.
74         @param fontFamily the typeface's font family
75         @param ascent     the ascent - this is normalised to a height of 1.0 and this is
76                           the value that will be returned by Typeface::getAscent(). The
77                           descent is assumed to be (1.0 - ascent)
78         @param isBold     should be true if the typeface is bold
79         @param isItalic   should be true if the typeface is italic
80         @param defaultCharacter   the character to be used as a replacement if there's
81                           no glyph available for the character that's being drawn
82     */
83     void setCharacteristics (const String& fontFamily, float ascent,
84                              bool isBold, bool isItalic,
85                              juce_wchar defaultCharacter) noexcept;
86 
87     /** Sets the vital statistics for the typeface.
88         @param fontFamily the typeface's font family
89         @param fontStyle  the typeface's font style
90         @param ascent     the ascent - this is normalised to a height of 1.0 and this is
91                           the value that will be returned by Typeface::getAscent(). The
92                           descent is assumed to be (1.0 - ascent)
93         @param defaultCharacter  the character to be used as a replacement if there's
94                           no glyph available for the character that's being drawn
95     */
96     void setCharacteristics (const String& fontFamily, const String& fontStyle,
97                              float ascent, juce_wchar defaultCharacter) noexcept;
98 
99     /** Adds a glyph to the typeface.
100 
101         The path that is passed in is normalised so that the font height is 1.0, and its
102         origin is the anchor point of the character on its baseline.
103 
104         The width is the nominal width of the character, and any extra kerning values that
105         are specified will be added to this width.
106     */
107     void addGlyph (juce_wchar character, const Path& path, float width) noexcept;
108 
109     /** Specifies an extra kerning amount to be used between a pair of characters.
110         The amount will be added to the nominal width of the first character when laying out a string.
111     */
112     void addKerningPair (juce_wchar char1, juce_wchar char2, float extraAmount) noexcept;
113 
114     /** Adds a range of glyphs from another typeface.
115         This will attempt to pull in the paths and kerning information from another typeface and
116         add it to this one.
117     */
118     void addGlyphsFromOtherTypeface (Typeface& typefaceToCopy, juce_wchar characterStartIndex, int numCharacters) noexcept;
119 
120     /** Saves this typeface as a Juce-formatted font file.
121         A CustomTypeface can be created to reload the data that is written - see the CustomTypeface
122         constructor.
123 
124         NOTE! Since this class was written, support was added for loading real font files from
125         memory, so for most people, using Typeface::createSystemTypefaceFor() to load a real font
126         is more appropriate than using this class to store it in a proprietary format.
127     */
128     bool writeToStream (OutputStream& outputStream);
129 
130     //==============================================================================
131     // The following methods implement the basic Typeface behaviour.
132     float getAscent() const override;
133     float getDescent() const override;
134     float getHeightToPointsFactor() const override;
135     float getStringWidth (const String&) override;
136     void getGlyphPositions (const String&, Array<int>& glyphs, Array<float>& xOffsets) override;
137     bool getOutlineForGlyph (int glyphNumber, Path&) override;
138     EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform&, float fontHeight) override;
139 
140 protected:
141     //==============================================================================
142     juce_wchar defaultCharacter;
143     float ascent;
144 
145     //==============================================================================
146     /** If a subclass overrides this, it can load glyphs into the font on-demand.
147         When methods such as getGlyphPositions() or getOutlineForGlyph() are asked for a
148         particular character and there's no corresponding glyph, they'll call this
149         method so that a subclass can try to add that glyph, returning true if it
150         manages to do so.
151     */
152     virtual bool loadGlyphIfPossible (juce_wchar characterNeeded);
153 
154 private:
155     //==============================================================================
156     class GlyphInfo;
157     OwnedArray<GlyphInfo> glyphs;
158     short lookupTable[128];
159 
160     GlyphInfo* findGlyph (const juce_wchar character, bool loadIfNeeded) noexcept;
161 
162     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomTypeface)
163 };
164 
165 } // namespace juce
166