@@ -29,17 +29,16 @@ | |||
//============================================================================== | |||
class FontsAndTextDemo : public Component, | |||
public ListBoxModel, | |||
public ButtonListener, | |||
public ComboBoxListener, | |||
public SliderListener | |||
{ | |||
public: | |||
//============================================================================== | |||
FontsAndTextDemo() | |||
: boldButton ("Bold"), | |||
italicButton ("Italic"), | |||
sizeLabel (String::empty, "Size"), | |||
kerningLabel (String::empty, "Kerning"), | |||
horizontalScaleLabel (String::empty, "Scale") | |||
: sizeLabel (String::empty, "Size:"), | |||
kerningLabel (String::empty, "Kerning:"), | |||
horizontalScaleLabel (String::empty, "Scale:"), | |||
styleLabel (String::empty, "Style:") | |||
{ | |||
setName ("Fonts"); | |||
@@ -55,13 +54,12 @@ public: | |||
textBox.setMultiLine (true, true); | |||
textBox.setReturnKeyStartsNewLine (true); | |||
textBox.setText ("The Quick Brown Fox Jumps Over The Lazy Dog\n\nAa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 0123456789"); | |||
textBox.setText ("The Quick Brown Fox Jumps Over The Lazy Dog\n\n" | |||
"Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 0123456789"); | |||
addAndMakeVisible (&boldButton); | |||
boldButton.addListener (this); | |||
addAndMakeVisible (&italicButton); | |||
italicButton.addListener (this); | |||
addAndMakeVisible (&fontStylesComboBox); | |||
fontStylesComboBox.addListener (this); | |||
styleLabel.attachToComponent (&fontStylesComboBox, true); | |||
addAndMakeVisible (&sizeSlider); | |||
sizeSlider.setRange (3.0, 150.0, 0.1); | |||
@@ -97,10 +95,6 @@ public: | |||
addAndMakeVisible (verticalDividerBar); | |||
} | |||
~FontsAndTextDemo() | |||
{ | |||
} | |||
void resized() | |||
{ | |||
// lay out the list box and vertical divider.. | |||
@@ -118,8 +112,7 @@ public: | |||
sizeSlider.setBounds (x, getHeight() - 106, getWidth() - x, 22); | |||
kerningSlider.setBounds (x, getHeight() - 82, getWidth() - x, 22); | |||
horizontalScaleSlider.setBounds (x, getHeight() - 58, getWidth() - x, 22); | |||
boldButton.setBounds (x, getHeight() - 34, (getWidth() - x) / 2, 22); | |||
italicButton.setBounds (x + (getWidth() - x) / 2, getHeight() - 34, (getWidth() - x) / 2, 22); | |||
fontStylesComboBox.setBounds (x, getHeight() - 34, (getWidth() - x) / 2, 22); | |||
} | |||
// implements the ListBoxModel method | |||
@@ -159,14 +152,32 @@ public: | |||
Font font (fonts [listBox->getSelectedRow()]); | |||
font.setHeight ((float) sizeSlider.getValue()); | |||
font.setBold (boldButton.getToggleState()); | |||
font.setItalic (italicButton.getToggleState()); | |||
font.setExtraKerningFactor ((float) kerningSlider.getValue()); | |||
font.setHorizontalScale ((float) horizontalScaleSlider.getValue()); | |||
updateStylesList (font); | |||
font.setTypefaceStyle (fontStylesComboBox.getText()); | |||
textBox.applyFontToAllText (font); | |||
} | |||
void updateStylesList (const Font& newFont) | |||
{ | |||
const StringArray newStyles (newFont.getAvailableStyles()); | |||
if (newStyles != currentStyleList) | |||
{ | |||
currentStyleList = newStyles; | |||
fontStylesComboBox.clear(); | |||
for (int i = 0; i < newStyles.size(); ++i) | |||
fontStylesComboBox.addItem (newStyles[i], i + 1); | |||
fontStylesComboBox.setSelectedItemIndex (0); | |||
} | |||
} | |||
void selectedRowsChanged (int /*lastRowselected*/) | |||
{ | |||
updatePreviewBoxText(); | |||
@@ -179,18 +190,23 @@ public: | |||
void sliderValueChanged (Slider*) | |||
{ | |||
// (this is called when the size slider is moved) | |||
updatePreviewBoxText(); | |||
} | |||
void comboBoxChanged (ComboBox*) | |||
{ | |||
updatePreviewBoxText(); | |||
} | |||
private: | |||
Array<Font> fonts; | |||
StringArray currentStyleList; | |||
ScopedPointer<ListBox> listBox; | |||
TextEditor textBox; | |||
ToggleButton boldButton, italicButton; | |||
ComboBox fontStylesComboBox; | |||
Slider sizeSlider, kerningSlider, horizontalScaleSlider; | |||
Label sizeLabel, kerningLabel, horizontalScaleLabel; | |||
Label sizeLabel, kerningLabel, horizontalScaleLabel, styleLabel; | |||
StretchableLayoutManager verticalLayout; | |||
ScopedPointer<StretchableLayoutResizerBar> verticalDividerBar; | |||
@@ -232,11 +232,14 @@ Font::Font() | |||
Font::Font (const float fontHeight, const int styleFlags) | |||
: font (new SharedFontInternal (Font::getDefaultStyle(), FontValues::limitFontHeight (fontHeight))) | |||
{ | |||
setStyleFlags(styleFlags); | |||
setStyleFlags (styleFlags); | |||
} | |||
Font::Font (const String& typefaceName, const float fontHeight, const int styleFlags) | |||
: font (new SharedFontInternal (typefaceName, Font::getDefaultStyle(), FontValues::limitFontHeight (fontHeight))) | |||
: font (new SharedFontInternal (typefaceName, | |||
FontStyleHelpers::getStyleName ((styleFlags & bold) != 0, | |||
(styleFlags & italic) != 0), | |||
FontValues::limitFontHeight (fontHeight))) | |||
{ | |||
setStyleFlags (styleFlags); | |||
} | |||
@@ -360,6 +363,11 @@ void Font::setTypefaceStyle (const String& typefaceStyle) | |||
} | |||
} | |||
StringArray Font::getAvailableStyles() const | |||
{ | |||
return findAllTypefaceStyles (getTypeface()->getName()); | |||
} | |||
Typeface* Font::getTypeface() const | |||
{ | |||
if (font->typeface == nullptr) | |||
@@ -129,7 +129,7 @@ public: | |||
or Font::getDefaultMonospacedFontName(), which are not actual platform-specific font family names, | |||
but are generic font family names that are used to represent the various default fonts. | |||
If you need to know the exact typeface font family being used, you can call | |||
Font::getTypeface()->getFamily(), which will give you the platform-specific font family. | |||
Font::getTypeface()->getName(), which will give you the platform-specific font family. | |||
If a suitable font isn't found on the machine, it'll just use a default instead. | |||
*/ | |||
@@ -144,7 +144,7 @@ public: | |||
but are generic font familiy names that are used to represent the various default fonts. | |||
If you need to know the exact typeface font family being used, you can call | |||
Font::getTypeface()->getFamily(), which will give you the platform-specific font family. | |||
Font::getTypeface()->getName(), which will give you the platform-specific font family. | |||
*/ | |||
const String& getTypefaceName() const noexcept; | |||
@@ -163,6 +163,9 @@ public: | |||
*/ | |||
const String& getTypefaceStyle() const noexcept; | |||
/** Returns a list of the styles that this font can use. */ | |||
StringArray getAvailableStyles() const; | |||
//============================================================================== | |||
/** Returns a typeface font family that represents the default sans-serif font. | |||
@@ -170,39 +170,31 @@ public: | |||
KnownTypeface (const File& file_, const int faceIndex_, const FTFaceWrapper& face) | |||
: file (file_), | |||
family (face.face->family_name), | |||
style (face.face->style_name), | |||
faceIndex (faceIndex_), | |||
isBold ((face.face->style_flags & FT_STYLE_FLAG_BOLD) != 0), | |||
isItalic ((face.face->style_flags & FT_STYLE_FLAG_ITALIC) != 0), | |||
isMonospaced ((face.face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0), | |||
isSansSerif (isFaceSansSerif (family)) | |||
{ | |||
} | |||
const File file; | |||
const String family; | |||
const String family, style; | |||
const int faceIndex; | |||
const bool isBold, isItalic, isMonospaced, isSansSerif; | |||
const bool isMonospaced, isSansSerif; | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (KnownTypeface); | |||
}; | |||
//============================================================================== | |||
FTFaceWrapper::Ptr createFace (const String& fontName, const bool bold, const bool italic) | |||
FTFaceWrapper::Ptr createFace (const String& fontName, const String& fontStyle) | |||
{ | |||
const KnownTypeface* ftFace = matchTypeface (fontName, bold, italic); | |||
const KnownTypeface* ftFace = matchTypeface (fontName, fontStyle); | |||
if (ftFace == nullptr) | |||
{ | |||
ftFace = matchTypeface (fontName, ! bold, italic); | |||
if (ftFace == nullptr) | |||
{ | |||
ftFace = matchTypeface (fontName, bold, ! italic); | |||
ftFace = matchTypeface (fontName, "Regular"); | |||
if (ftFace == nullptr) | |||
ftFace = matchTypeface (fontName, ! bold, ! italic); | |||
} | |||
} | |||
if (ftFace == nullptr) | |||
ftFace = matchTypeface (fontName, String::empty); | |||
if (ftFace != nullptr) | |||
{ | |||
@@ -241,7 +233,7 @@ public: | |||
const KnownTypeface* const face = faces.getUnchecked(i); | |||
if (face->family == family) | |||
s.addIfNotAlreadyThere (FontStyleHelpers::getStyleName (face->isBold, face->isItalic)); | |||
s.addIfNotAlreadyThere (face->style); | |||
} | |||
return s; | |||
@@ -274,15 +266,14 @@ private: | |||
FTLibWrapper::Ptr library; | |||
OwnedArray<KnownTypeface> faces; | |||
const KnownTypeface* matchTypeface (const String& familyName, const bool wantBold, const bool wantItalic) const noexcept | |||
const KnownTypeface* matchTypeface (const String& familyName, const String& style) const noexcept | |||
{ | |||
for (int i = 0; i < faces.size(); ++i) | |||
{ | |||
const KnownTypeface* const face = faces.getUnchecked(i); | |||
if (face->family == familyName | |||
&& face->isBold == wantBold | |||
&& face->isItalic == wantItalic) | |||
&& (face->style.equalsIgnoreCase (style) || style.isEmpty())) | |||
return face; | |||
} | |||
@@ -312,7 +303,7 @@ class FreeTypeTypeface : public CustomTypeface | |||
public: | |||
FreeTypeTypeface (const Font& font) | |||
: faceWrapper (FTTypefaceList::getInstance() | |||
->createFace (font.getTypefaceName(), font.isBold(), font.isItalic())) | |||
->createFace (font.getTypefaceName(), font.getTypefaceStyle())) | |||
{ | |||
if (faceWrapper != nullptr) | |||
{ | |||