LMMS
Loading...
Searching...
No Matches
juce_Typeface.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - 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 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-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
26namespace juce
27{
28
30{
31 static const char* getStyleName (const bool bold,
32 const bool italic) noexcept
33 {
34 if (bold && italic) return "Bold Italic";
35 if (bold) return "Bold";
36 if (italic) return "Italic";
37 return "Regular";
38 }
39
40 static const char* getStyleName (const int styleFlags) noexcept
41 {
42 return getStyleName ((styleFlags & Font::bold) != 0,
43 (styleFlags & Font::italic) != 0);
44 }
45
46 static bool isBold (const String& style) noexcept
47 {
48 return style.containsWholeWordIgnoreCase ("Bold");
49 }
50
51 static bool isItalic (const String& style) noexcept
52 {
53 return style.containsWholeWordIgnoreCase ("Italic")
54 || style.containsWholeWordIgnoreCase ("Oblique");
55 }
56
57 static bool isPlaceholderFamilyName (const String& family)
58 {
59 return family == Font::getDefaultSansSerifFontName()
62 }
63
65 {
67 : sans (findName (Font::getDefaultSansSerifFontName())),
68 serif (findName (Font::getDefaultSerifFontName())),
69 mono (findName (Font::getDefaultMonospacedFontName()))
70 {
71 }
72
73 String lookUp (const String& placeholder)
74 {
75 if (placeholder == Font::getDefaultSansSerifFontName()) return sans;
76 if (placeholder == Font::getDefaultSerifFontName()) return serif;
77 if (placeholder == Font::getDefaultMonospacedFontName()) return mono;
78
79 return findName (placeholder);
80 }
81
82 private:
83 static String findName (const String& placeholder)
84 {
85 const Font f (placeholder, Font::getDefaultStyle(), 15.0f);
86 return Font::getDefaultTypefaceForFont (f)->getName();
87 }
88
90 };
91
93 {
94 static ConcreteFamilyNames names;
95 return names.lookUp (placeholder);
96 }
97
98 static String getConcreteFamilyName (const Font& font)
99 {
100 const String& family = font.getTypefaceName();
101
103 : family;
104 }
105};
106
107//==============================================================================
108Typeface::Typeface (const String& faceName, const String& styleName) noexcept
109 : name (faceName), style (styleName)
110{
111}
112
113Typeface::~Typeface() = default;
114
116{
117 const Font fallbackFont (Font::getFallbackFontName(), Font::getFallbackFontStyle(), 10.0f);
118 return fallbackFont.getTypefacePtr();
119}
120
121EdgeTable* Typeface::getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform, float fontHeight)
122{
123 Path path;
124
125 if (getOutlineForGlyph (glyphNumber, path) && ! path.isEmpty())
126 {
127 applyVerticalHintingTransform (fontHeight, path);
128
129 return new EdgeTable (path.getBoundsTransformed (transform).getSmallestIntegerContainer().expanded (1, 0),
130 path, transform);
131 }
132
133 return nullptr;
134}
135
136//==============================================================================
138{
140 {
141 Font font (t);
142 font = font.withHeight ((float) standardHeight);
143
144 top = getAverageY (font, "BDEFPRTZOQ", true);
145 middle = getAverageY (font, "acegmnopqrsuvwxy", true);
146 bottom = getAverageY (font, "BDELZOC", false);
147 }
148
149 void applyVerticalHintingTransform (float fontSize, Path& path)
150 {
151 if (cachedSize != fontSize)
152 {
153 cachedSize = fontSize;
154 cachedScale = Scaling (top, middle, bottom, fontSize);
155 }
156
157 if (bottom < top + 3.0f / fontSize)
158 return;
159
160 Path result;
161
162 for (Path::Iterator i (path); i.next();)
163 {
164 switch (i.elementType)
165 {
166 case Path::Iterator::startNewSubPath: result.startNewSubPath (i.x1, cachedScale.apply (i.y1)); break;
167 case Path::Iterator::lineTo: result.lineTo (i.x1, cachedScale.apply (i.y1)); break;
168 case Path::Iterator::quadraticTo: result.quadraticTo (i.x1, cachedScale.apply (i.y1),
169 i.x2, cachedScale.apply (i.y2)); break;
170 case Path::Iterator::cubicTo: result.cubicTo (i.x1, cachedScale.apply (i.y1),
171 i.x2, cachedScale.apply (i.y2),
172 i.x3, cachedScale.apply (i.y3)); break;
173 case Path::Iterator::closePath: result.closeSubPath(); break;
174 default: jassertfalse; break;
175 }
176 }
177
178 result.swapWithPath (path);
179 }
180
181private:
182 struct Scaling
183 {
185
186 Scaling (float t, float m, float b, float fontSize) noexcept : middle (m)
187 {
188 const float newT = std::floor (fontSize * t + 0.5f) / fontSize;
189 const float newB = std::floor (fontSize * b + 0.5f) / fontSize;
190 const float newM = std::floor (fontSize * m + 0.3f) / fontSize; // this is slightly biased so that lower-case letters
191 // are more likely to become taller than shorter.
192 upperScale = jlimit (0.9f, 1.1f, (newM - newT) / (m - t));
193 lowerScale = jlimit (0.9f, 1.1f, (newB - newM) / (b - m));
194
195 upperOffset = newM - m * upperScale;
196 lowerOffset = newB - b * lowerScale;
197 }
198
199 float apply (float y) const noexcept
200 {
201 return y < middle ? (y * upperScale + upperOffset)
202 : (y * lowerScale + lowerOffset);
203 }
204
206 };
207
208 float cachedSize = 0;
210
211 static float getAverageY (const Font& font, const char* chars, bool getTop)
212 {
214 ga.addLineOfText (font, chars, 0, 0);
215
216 Array<float> yValues;
217
218 for (auto& glyph : ga)
219 {
220 Path p;
221 glyph.createPath (p);
222 auto bounds = p.getBounds();
223
224 if (! p.isEmpty())
225 yValues.add (getTop ? bounds.getY() : bounds.getBottom());
226 }
227
228 std::sort (yValues.begin(), yValues.end());
229
230 auto median = yValues[yValues.size() / 2];
231 float total = 0;
232 int num = 0;
233
234 for (auto y : yValues)
235 {
236 if (std::abs (median - y) < 0.05f * (float) standardHeight)
237 {
238 total += y;
239 ++num;
240 }
241 }
242
243 return num < 4 ? 0.0f : total / ((float) num * (float) standardHeight);
244 }
245
246 enum { standardHeight = 100 };
247 float top = 0, middle = 0, bottom = 0;
248};
249
251{
252 if (fontSize > 3.0f && fontSize < 25.0f)
253 {
255
256 if (hintingParams == nullptr)
257 hintingParams.reset (new HintingParams (*this));
258
259 return hintingParams->applyVerticalHintingTransform (fontSize, path);
260 }
261}
262
263} // namespace juce
#define noexcept
Definition DistrhoDefines.h:72
Definition juce_AffineTransform.h:43
Definition juce_Array.h:56
int size() const noexcept
Definition juce_Array.h:215
ElementType * begin() noexcept
Definition juce_Array.h:328
ElementType * end() noexcept
Definition juce_Array.h:344
void add(const ElementType &newElement)
Definition juce_Array.h:418
Definition juce_EdgeTable.h:38
Definition juce_Font.h:42
static const String & getFallbackFontStyle()
Definition juce_Font.cpp:534
JUCE_NODISCARD Font withHeight(float height) const
Definition juce_Font.cpp:549
static const String & getDefaultStyle()
Definition juce_Font.cpp:468
static const String & getFallbackFontName()
Definition juce_Font.cpp:520
static Typeface::Ptr getDefaultTypefaceForFont(const Font &font)
Definition juce_linux_Fonts.cpp:215
static const String & getDefaultSansSerifFontName()
Definition juce_Font.cpp:465
String getTypefaceName() const noexcept
Definition juce_Font.cpp:470
static const String & getDefaultMonospacedFontName()
Definition juce_Font.cpp:467
@ bold
Definition juce_Font.h:51
@ italic
Definition juce_Font.h:52
static const String & getDefaultSerifFontName()
Definition juce_Font.cpp:466
Definition juce_GlyphArrangement.h:117
void addLineOfText(const Font &font, const String &text, float x, float y)
Definition juce_GlyphArrangement.cpp:144
Definition juce_Path.h:725
@ quadraticTo
Definition juce_Path.h:745
@ closePath
Definition juce_Path.h:747
@ lineTo
Definition juce_Path.h:744
@ cubicTo
Definition juce_Path.h:746
@ startNewSubPath
Definition juce_Path.h:743
Definition juce_Path.h:65
Rectangle< float > getBoundsTransformed(const AffineTransform &transform) const noexcept
Definition juce_Path.cpp:205
bool isEmpty() const noexcept
Definition juce_Path.cpp:179
Rectangle< int > getSmallestIntegerContainer() const noexcept
Definition juce_Rectangle.h:840
Rectangle expanded(ValueType deltaX, ValueType deltaY) const noexcept
Definition juce_Rectangle.h:451
Definition juce_String.h:53
static Ptr getFallbackTypeface()
Definition juce_Typeface.cpp:115
void applyVerticalHintingTransform(float fontHeight, Path &path)
Definition juce_Typeface.cpp:250
std::unique_ptr< HintingParams > hintingParams
Definition juce_Typeface.h:155
virtual bool getOutlineForGlyph(int glyphNumber, Path &path)=0
virtual EdgeTable * getEdgeTableForGlyph(int glyphNumber, const AffineTransform &transform, float fontHeight)
Definition juce_Typeface.cpp:121
Typeface(const String &name, const String &style) noexcept
Definition juce_Typeface.cpp:108
ReferenceCountedObjectPtr< Typeface > Ptr
Definition juce_Typeface.h:51
CriticalSection hintingLock
Definition juce_Typeface.h:156
~Typeface() override
unsigned * m
Definition inflate.c:1559
struct huft * t
Definition inflate.c:943
int y
Definition inflate.c:1588
register unsigned i
Definition inflate.c:1575
unsigned f
Definition inflate.c:1572
static const char * name
Definition pugl.h:1582
#define jassertfalse
static const SerdStyle style
Definition sratom.c:36
Definition carla_juce.cpp:31
CriticalSection::ScopedLockType ScopedLock
Definition juce_CriticalSection.h:186
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Definition juce_MathsFunctions.h:262
Definition juce_Typeface.cpp:65
ConcreteFamilyNames()
Definition juce_Typeface.cpp:66
String sans
Definition juce_Typeface.cpp:89
String mono
Definition juce_Typeface.cpp:89
String serif
Definition juce_Typeface.cpp:89
String lookUp(const String &placeholder)
Definition juce_Typeface.cpp:73
static String findName(const String &placeholder)
Definition juce_Typeface.cpp:83
Definition juce_Typeface.cpp:30
static String getConcreteFamilyNameFromPlaceholder(const String &placeholder)
Definition juce_Typeface.cpp:92
static bool isItalic(const String &style) noexcept
Definition juce_Typeface.cpp:51
static bool isBold(const String &style) noexcept
Definition juce_Typeface.cpp:46
static const char * getStyleName(const int styleFlags) noexcept
Definition juce_Typeface.cpp:40
static bool isPlaceholderFamilyName(const String &family)
Definition juce_Typeface.cpp:57
static const char * getStyleName(const bool bold, const bool italic) noexcept
Definition juce_Typeface.cpp:31
static String getConcreteFamilyName(const Font &font)
Definition juce_Typeface.cpp:98
Definition juce_Typeface.cpp:183
float lowerOffset
Definition juce_Typeface.cpp:205
float middle
Definition juce_Typeface.cpp:205
float apply(float y) const noexcept
Definition juce_Typeface.cpp:199
float upperOffset
Definition juce_Typeface.cpp:205
float lowerScale
Definition juce_Typeface.cpp:205
float upperScale
Definition juce_Typeface.cpp:205
Scaling(float t, float m, float b, float fontSize) noexcept
Definition juce_Typeface.cpp:186
Scaling() noexcept
Definition juce_Typeface.cpp:184
Definition juce_Typeface.cpp:138
float cachedSize
Definition juce_Typeface.cpp:208
float top
Definition juce_Typeface.cpp:247
float middle
Definition juce_Typeface.cpp:247
float bottom
Definition juce_Typeface.cpp:247
void applyVerticalHintingTransform(float fontSize, Path &path)
Definition juce_Typeface.cpp:149
HintingParams(Typeface &t)
Definition juce_Typeface.cpp:139
static float getAverageY(const Font &font, const char *chars, bool getTop)
Definition juce_Typeface.cpp:211
Scaling cachedScale
Definition juce_Typeface.cpp:209
@ standardHeight
Definition juce_Typeface.cpp:246
uch * p
Definition crypt.c:594
b
Definition crypt.c:628
int result
Definition process.c:1455