Browse Source

Refactored AttributedString so that every part of the string has a single font and colour associated with it, to avoid some problems caused by fonts being undefined.

tags/2021-05-28
jules 9 years ago
parent
commit
1a7caaa58f
6 changed files with 257 additions and 208 deletions
  1. +174
    -53
      modules/juce_graphics/fonts/juce_AttributedString.cpp
  2. +20
    -28
      modules/juce_graphics/fonts/juce_AttributedString.h
  3. +7
    -66
      modules/juce_graphics/fonts/juce_TextLayout.cpp
  4. +1
    -1
      modules/juce_graphics/juce_graphics.h
  5. +32
    -35
      modules/juce_graphics/native/juce_mac_Fonts.mm
  6. +23
    -25
      modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp

+ 174
- 53
modules/juce_graphics/fonts/juce_AttributedString.cpp View File

@@ -22,31 +22,156 @@
==============================================================================
*/
AttributedString::Attribute::Attribute (Range<int> range_, Colour colour_)
: range (range_), colour (new Colour (colour_))
namespace
{
int getLength (const Array<AttributedString::Attribute>& atts) noexcept
{
return atts.size() != 0 ? atts.getReference (atts.size() - 1).range.getEnd() : 0;
}
void splitAttributeRanges (Array<AttributedString::Attribute>& atts, int position)
{
for (int i = atts.size(); --i >= 0;)
{
const AttributedString::Attribute& att = atts.getReference (i);
const int offset = position - att.range.getStart();
if (offset >= 0)
{
if (offset > 0 && position < att.range.getEnd())
{
atts.insert (i + 1, att);
atts.getReference (i).range.setEnd (position);
atts.getReference (i + 1).range.setStart (position);
}
break;
}
}
}
Range<int> splitAttributeRanges (Array<AttributedString::Attribute>& atts, Range<int> newRange)
{
newRange = newRange.getIntersectionWith (Range<int> (0, getLength (atts)));
if (! newRange.isEmpty())
{
splitAttributeRanges (atts, newRange.getStart());
splitAttributeRanges (atts, newRange.getEnd());
}
return newRange;
}
void mergeAdjacentRanges (Array<AttributedString::Attribute>& atts)
{
for (int i = atts.size() - 1; --i >= 0;)
{
AttributedString::Attribute& a1 = atts.getReference (i);
AttributedString::Attribute& a2 = atts.getReference (i + 1);
if (a1.colour == a2.colour && a1.font == a2.font)
{
a1.range.setEnd (a2.range.getEnd());
atts.remove (i + 1);
if (i < atts.size() - 1)
++i;
}
}
}
void appendRange (Array<AttributedString::Attribute>& atts,
int length, const Font* f, const Colour* c)
{
if (atts.size() == 0)
{
atts.add (AttributedString::Attribute (Range<int> (0, length),
f != nullptr ? *f : Font(),
c != nullptr ? *c : Colour (0xff000000)));
}
else
{
const int start = getLength (atts);
atts.add (AttributedString::Attribute (Range<int> (start, start + length),
f != nullptr ? *f : atts.getReference (atts.size() - 1).font,
c != nullptr ? *c : atts.getReference (atts.size() - 1).colour));
mergeAdjacentRanges (atts);
}
}
void applyFontAndColour (Array<AttributedString::Attribute>& atts,
Range<int> range, const Font* f, const Colour* c)
{
range = splitAttributeRanges (atts, range);
for (int i = 0; i < atts.size(); ++i)
{
AttributedString::Attribute& att = atts.getReference (i);
if (range.getStart() < att.range.getEnd())
{
if (range.getEnd() <= att.range.getStart())
break;
if (c != nullptr) att.colour = *c;
if (f != nullptr) att.font = *f;
}
}
mergeAdjacentRanges (atts);
}
void truncate (Array<AttributedString::Attribute>& atts, int newLength)
{
splitAttributeRanges (atts, newLength);
for (int i = atts.size(); --i >= 0;)
if (atts.getReference (i).range.getStart() >= newLength)
atts.remove (i);
}
}
AttributedString::Attribute::Attribute (Range<int> range_, const Font& font_)
: range (range_), font (new Font (font_))
//==============================================================================
AttributedString::Attribute::Attribute() noexcept : colour (0xff000000) {}
AttributedString::Attribute::~Attribute() noexcept {}
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
AttributedString::Attribute::Attribute (Attribute&& other) noexcept
: range (other.range),
font (static_cast<Font&&> (other.font)),
colour (other.colour)
{
}
AttributedString::Attribute& AttributedString::Attribute::operator= (Attribute&& other) noexcept
{
range = other.range;
font = static_cast<Font&&> (other.font);
colour = other.colour;
return *this;
}
#endif
AttributedString::Attribute::Attribute (const Attribute& other)
AttributedString::Attribute::Attribute (const Attribute& other) noexcept
: range (other.range),
font (other.font.createCopy()),
colour (other.colour.createCopy())
font (other.font),
colour (other.colour)
{
}
AttributedString::Attribute::Attribute (const Attribute& other, const int offset)
: range (other.range + offset),
font (other.font.createCopy()),
colour (other.colour.createCopy())
AttributedString::Attribute& AttributedString::Attribute::operator= (const Attribute& other) noexcept
{
range = other.range;
font = other.font;
colour = other.colour;
return *this;
}
AttributedString::Attribute::~Attribute() {}
AttributedString::Attribute::Attribute (Range<int> r, const Font& f, Colour c) noexcept
: range (r), font (f), colour (c)
{
}
//==============================================================================
AttributedString::AttributedString()
@@ -58,12 +183,12 @@ AttributedString::AttributedString()
}
AttributedString::AttributedString (const String& newString)
: text (newString),
lineSpacing (0.0f),
: lineSpacing (0.0f),
justification (Justification::left),
wordWrap (AttributedString::byWord),
readingDirection (AttributedString::natural)
{
setText (newString);
}
AttributedString::AttributedString (const AttributedString& other)
@@ -71,9 +196,9 @@ AttributedString::AttributedString (const AttributedString& other)
lineSpacing (other.lineSpacing),
justification (other.justification),
wordWrap (other.wordWrap),
readingDirection (other.readingDirection)
readingDirection (other.readingDirection),
attributes (other.attributes)
{
attributes.addCopiesOf (other.attributes);
}
AttributedString& AttributedString::operator= (const AttributedString& other)
@@ -85,8 +210,7 @@ AttributedString& AttributedString::operator= (const AttributedString& other)
justification = other.justification;
wordWrap = other.wordWrap;
readingDirection = other.readingDirection;
attributes.clear();
attributes.addCopiesOf (other.attributes);
attributes = other.attributes;
}
return *this;
@@ -99,7 +223,7 @@ AttributedString::AttributedString (AttributedString&& other) noexcept
justification (other.justification),
wordWrap (other.wordWrap),
readingDirection (other.readingDirection),
attributes (static_cast<OwnedArray<Attribute>&&> (other.attributes))
attributes (static_cast<Array<Attribute>&&> (other.attributes))
{
}
@@ -110,58 +234,61 @@ AttributedString& AttributedString::operator= (AttributedString&& other) noexcep
justification = other.justification;
wordWrap = other.wordWrap;
readingDirection = other.readingDirection;
attributes = static_cast<OwnedArray<Attribute>&&> (other.attributes);
attributes = static_cast<Array<Attribute>&&> (other.attributes);
return *this;
}
#endif
AttributedString::~AttributedString() {}
AttributedString::~AttributedString() noexcept {}
void AttributedString::setText (const String& other)
void AttributedString::setText (const String& newText)
{
text = other;
const int newLength = newText.length();
const int oldLength = getLength (attributes);
if (newLength > oldLength)
appendRange (attributes, newLength - oldLength, nullptr, nullptr);
else if (newLength < oldLength)
truncate (attributes, newLength);
text = newText;
}
void AttributedString::append (const String& textToAppend)
{
text += textToAppend;
appendRange (attributes, textToAppend.length(), nullptr, nullptr);
}
void AttributedString::append (const String& textToAppend, const Font& font)
{
const int oldLength = text.length();
const int newLength = textToAppend.length();
text += textToAppend;
setFont (Range<int> (oldLength, oldLength + newLength), font);
appendRange (attributes, textToAppend.length(), &font, nullptr);
}
void AttributedString::append (const String& textToAppend, Colour colour)
{
const int oldLength = text.length();
const int newLength = textToAppend.length();
text += textToAppend;
setColour (Range<int> (oldLength, oldLength + newLength), colour);
appendRange (attributes, textToAppend.length(), nullptr, &colour);
}
void AttributedString::append (const String& textToAppend, const Font& font, Colour colour)
{
const int oldLength = text.length();
const int newLength = textToAppend.length();
text += textToAppend;
setFont (Range<int> (oldLength, oldLength + newLength), font);
setColour (Range<int> (oldLength, oldLength + newLength), colour);
appendRange (attributes, textToAppend.length(), &font, &colour);
}
void AttributedString::append (const AttributedString& other)
{
const int originalLength = text.length();
const int originalLength = getLength (attributes);
const int originalNumAtts = attributes.size();
text += other.text;
attributes.addArray (other.attributes);
for (int i = 0; i < other.attributes.size(); ++i)
attributes.add (new Attribute (*other.attributes.getUnchecked(i), originalLength));
for (int i = originalNumAtts; i < attributes.size(); ++i)
attributes.getReference (i).range += originalLength;
mergeAdjacentRanges (attributes);
}
void AttributedString::clear()
@@ -192,36 +319,30 @@ void AttributedString::setLineSpacing (const float newLineSpacing) noexcept
void AttributedString::setColour (Range<int> range, Colour colour)
{
attributes.add (new Attribute (range, colour));
applyFontAndColour (attributes, range, nullptr, &colour);
}
void AttributedString::setColour (Colour colour)
void AttributedString::setFont (Range<int> range, const Font& font)
{
for (int i = attributes.size(); --i >= 0;)
if (attributes.getUnchecked(i)->getColour() != nullptr)
attributes.remove (i);
setColour (Range<int> (0, text.length()), colour);
applyFontAndColour (attributes, range, &font, nullptr);
}
void AttributedString::setFont (Range<int> range, const Font& font)
void AttributedString::setColour (Colour colour)
{
attributes.add (new Attribute (range, font));
setColour (Range<int> (0, getLength (attributes)), colour);
}
void AttributedString::setFont (const Font& font)
{
for (int i = attributes.size(); --i >= 0;)
if (attributes.getUnchecked(i)->getFont() != nullptr)
attributes.remove (i);
setFont (Range<int> (0, text.length()), font);
setFont (Range<int> (0, getLength (attributes)), font);
}
void AttributedString::draw (Graphics& g, const Rectangle<float>& area) const
{
if (text.isNotEmpty() && g.clipRegionIntersects (area.getSmallestIntegerContainer()))
{
jassert (text.length() == getLength (attributes));
if (! g.getInternalContext().drawTextLayout (*this, area))
{
TextLayout layout;


+ 20
- 28
modules/juce_graphics/fonts/juce_AttributedString.h View File

@@ -53,7 +53,7 @@ public:
#endif
/** Destructor. */
~AttributedString();
~AttributedString() noexcept;
//==============================================================================
/** Returns the complete text of this attributed string. */
@@ -150,36 +150,28 @@ public:
class JUCE_API Attribute
{
public:
/** Creates an attribute that changes the colour for a range of characters.
@see AttributedString::setColour()
*/
Attribute (Range<int> range, Colour colour);
/** Creates an attribute that changes the font for a range of characters.
@see AttributedString::setFont()
*/
Attribute (Range<int> range, const Font& font);
Attribute (const Attribute&);
~Attribute();
/** If this attribute specifies a font, this returns it; otherwise it returns nullptr. */
const Font* getFont() const noexcept { return font; }
/** If this attribute specifies a colour, this returns it; otherwise it returns nullptr. */
const Colour* getColour() const noexcept { return colour; }
Attribute() noexcept;
~Attribute() noexcept;
Attribute (const Attribute&) noexcept;
Attribute& operator= (const Attribute&) noexcept;
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Attribute (Attribute&&) noexcept;
Attribute& operator= (Attribute&&) noexcept;
#endif
/** Creates an attribute that specifies the font and colour for a range of characters. */
Attribute (Range<int> range, const Font& font, Colour colour) noexcept;
/** The range of characters to which this attribute will be applied. */
const Range<int> range;
Range<int> range;
private:
ScopedPointer<Font> font;
ScopedPointer<Colour> colour;
/** The font for this range of characters. */
Font font;
friend class AttributedString;
Attribute (const Attribute&, int);
Attribute& operator= (const Attribute&);
/** The colour for this range of characters. */
Colour colour;
private:
JUCE_LEAK_DETECTOR (Attribute)
};
@@ -189,7 +181,7 @@ public:
/** Returns one of the string's attributes.
The index provided must be less than getNumAttributes(), and >= 0.
*/
const Attribute* getAttribute (int index) const noexcept { return attributes.getUnchecked (index); }
const Attribute& getAttribute (int index) const noexcept { return attributes.getReference (index); }
//==============================================================================
/** Adds a colour attribute for the specified range. */
@@ -210,7 +202,7 @@ private:
Justification justification;
WordWrap wordWrap;
ReadingDirection readingDirection;
OwnedArray<Attribute> attributes;
Array<Attribute> attributes;
JUCE_LEAK_DETECTOR (AttributedString)
};


+ 7
- 66
modules/juce_graphics/fonts/juce_TextLayout.cpp View File

@@ -287,29 +287,6 @@ void TextLayout::createLayoutWithBalancedLineLengths (const AttributedString& te
//==============================================================================
namespace TextLayoutHelpers
{
struct FontAndColour
{
FontAndColour (const Font* f) noexcept : font (f), colour (0xff000000) {}
const Font* font;
Colour colour;
bool operator!= (const FontAndColour& other) const noexcept
{
return (font != other.font && *font != *other.font) || colour != other.colour;
}
};
struct RunAttribute
{
RunAttribute (const FontAndColour& fc, const Range<int> r) noexcept
: fontAndColour (fc), range (r)
{}
FontAndColour fontAndColour;
Range<int> range;
};
struct Token
{
Token (const String& t, const Font& f, Colour c, const bool whitespace)
@@ -337,7 +314,6 @@ namespace TextLayoutHelpers
void createLayout (const AttributedString& text, TextLayout& layout)
{
tokens.ensureStorageAllocated (64);
layout.ensureStorageAllocated (totalLines);
addTextRuns (text);
@@ -465,10 +441,8 @@ namespace TextLayoutHelpers
return CharacterFunctions::isWhitespace (c) ? 2 : 1;
}
void appendText (const AttributedString& text, const Range<int> stringRange,
const Font& font, Colour colour)
void appendText (const String& stringText, const Font& font, Colour colour)
{
const String stringText (text.getText().substring (stringRange.getStart(), stringRange.getEnd()));
String::CharPointerType t (stringText.getCharPointer());
String currentString;
int lastCharType = 0;
@@ -551,48 +525,15 @@ namespace TextLayoutHelpers
void addTextRuns (const AttributedString& text)
{
Font defaultFont;
Array<RunAttribute> runAttributes;
const int numAttributes = text.getNumAttributes();
tokens.ensureStorageAllocated (jmax (64, numAttributes));
for (int i = 0; i < numAttributes; ++i)
{
const int stringLength = text.getText().length();
int rangeStart = 0;
FontAndColour lastFontAndColour (&defaultFont);
// Iterate through every character in the string
for (int i = 0; i < stringLength; ++i)
{
FontAndColour newFontAndColour (&defaultFont);
const int numCharacterAttributes = text.getNumAttributes();
for (int j = 0; j < numCharacterAttributes; ++j)
{
const AttributedString::Attribute& attr = *text.getAttribute (j);
const AttributedString::Attribute& attr = text.getAttribute (i);
if (attr.range.contains (i))
{
if (const Font* f = attr.getFont()) newFontAndColour.font = f;
if (const Colour* c = attr.getColour()) newFontAndColour.colour = *c;
}
}
if (i > 0 && newFontAndColour != lastFontAndColour)
{
runAttributes.add (RunAttribute (lastFontAndColour, Range<int> (rangeStart, i)));
rangeStart = i;
}
lastFontAndColour = newFontAndColour;
}
if (rangeStart < stringLength)
runAttributes.add (RunAttribute (lastFontAndColour, Range<int> (rangeStart, stringLength)));
}
for (int i = 0; i < runAttributes.size(); ++i)
{
const RunAttribute& r = runAttributes.getReference(i);
appendText (text, r.range, *(r.fontAndColour.font), r.fontAndColour.colour);
appendText (text.getText().substring (attr.range.getStart(), attr.range.getEnd()),
attr.font, attr.colour);
}
}


+ 1
- 1
modules/juce_graphics/juce_graphics.h View File

@@ -91,9 +91,9 @@ class LowLevelGraphicsContext;
#include "images/juce_ImageCache.h"
#include "images/juce_ImageConvolutionKernel.h"
#include "images/juce_ImageFileFormat.h"
#include "fonts/juce_AttributedString.h"
#include "fonts/juce_Typeface.h"
#include "fonts/juce_Font.h"
#include "fonts/juce_AttributedString.h"
#include "fonts/juce_GlyphArrangement.h"
#include "fonts/juce_TextLayout.h"
#include "fonts/juce_CustomTypeface.h"


+ 32
- 35
modules/juce_graphics/native/juce_mac_Fonts.mm View File

@@ -229,7 +229,7 @@ namespace CoreTextTypeLayout
for (int i = 0; i < numCharacterAttributes; ++i)
{
const AttributedString::Attribute& attr = *text.getAttribute (i);
const AttributedString::Attribute& attr = text.getAttribute (i);
const int rangeStart = attr.range.getStart();
if (rangeStart >= attribStringLen)
@@ -237,42 +237,40 @@ namespace CoreTextTypeLayout
CFRange range = CFRangeMake (rangeStart, jmin (attr.range.getEnd(), (int) attribStringLen) - rangeStart);
if (const Font* const f = attr.getFont())
if (CTFontRef ctFontRef = getOrCreateFont (attr.font))
{
if (CTFontRef ctFontRef = getOrCreateFont (*f))
{
ctFontRef = getFontWithPointSize (ctFontRef, f->getHeight() * getHeightToPointsFactor (ctFontRef));
CFAttributedStringSetAttribute (attribString, range, kCTFontAttributeName, ctFontRef);
ctFontRef = getFontWithPointSize (ctFontRef, attr.font.getHeight() * getHeightToPointsFactor (ctFontRef));
float extraKerning = f->getExtraKerningFactor();
CFAttributedStringSetAttribute (attribString, range, kCTFontAttributeName, ctFontRef);
if (extraKerning != 0.0f)
{
extraKerning *= f->getHeight();
float extraKerning = attr.font.getExtraKerningFactor();
CFNumberRef numberRef = CFNumberCreate (0, kCFNumberFloatType, &extraKerning);
CFAttributedStringSetAttribute (attribString, range, kCTKernAttributeName, numberRef);
CFRelease (numberRef);
}
if (extraKerning != 0.0f)
{
extraKerning *= attr.font.getHeight();
CFRelease (ctFontRef);
CFNumberRef numberRef = CFNumberCreate (0, kCFNumberFloatType, &extraKerning);
CFAttributedStringSetAttribute (attribString, range, kCTKernAttributeName, numberRef);
CFRelease (numberRef);
}
CFRelease (ctFontRef);
}
if (const Colour* const col = attr.getColour())
{
const Colour col (attr.colour);
#if JUCE_IOS
const CGFloat components[] = { col->getFloatRed(),
col->getFloatGreen(),
col->getFloatBlue(),
col->getFloatAlpha() };
const CGFloat components[] = { col.getFloatRed(),
col.getFloatGreen(),
col.getFloatBlue(),
col.getFloatAlpha() };
CGColorRef colour = CGColorCreate (rgbColourSpace, components);
#else
CGColorRef colour = CGColorCreateGenericRGB (col->getFloatRed(),
col->getFloatGreen(),
col->getFloatBlue(),
col->getFloatAlpha());
CGColorRef colour = CGColorCreateGenericRGB (col.getFloatRed(),
col.getFloatGreen(),
col.getFloatBlue(),
col.getFloatAlpha());
#endif
CFAttributedStringSetAttribute (attribString, range, kCTForegroundColorAttributeName, colour);
@@ -449,7 +447,7 @@ namespace CoreTextTypeLayout
CFDictionaryRef runAttributes = CTRunGetAttributes (run);
CTFontRef ctRunFont;
if (CFDictionaryGetValueIfPresent (runAttributes, kCTFontAttributeName, (const void **) &ctRunFont))
if (CFDictionaryGetValueIfPresent (runAttributes, kCTFontAttributeName, (const void**) &ctRunFont))
{
CFStringRef cfsFontName = CTFontCopyPostScriptName (ctRunFont);
CTFontRef ctFontRef = CTFontCreateWithName (cfsFontName, referenceFontSize, nullptr);
@@ -1176,17 +1174,16 @@ static bool canAllTypefacesBeUsedInLayout (const AttributedString& text)
for (int i = 0; i < numCharacterAttributes; ++i)
{
if (const Font* const f = text.getAttribute (i)->getFont())
Typeface* t = text.getAttribute(i).font.getTypeface();
if (OSXTypeface* tf = dynamic_cast<OSXTypeface*> (t))
{
if (OSXTypeface* tf = dynamic_cast<OSXTypeface*> (f->getTypeface()))
{
if (tf->isMemoryFont)
return false;
}
else if (dynamic_cast<CustomTypeface*> (f->getTypeface()) != nullptr)
{
if (tf->isMemoryFont)
return false;
}
}
else if (dynamic_cast<CustomTypeface*> (t) != nullptr)
{
return false;
}
}


+ 23
- 25
modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp View File

@@ -22,7 +22,7 @@
==============================================================================
*/
//==================================================================================================
#if JUCE_USE_DIRECTWRITE
namespace DirectWriteTypeLayout
{
@@ -41,7 +41,7 @@ namespace DirectWriteTypeLayout
JUCE_COMRESULT QueryInterface (REFIID refId, void** result) override
{
if (refId == __uuidof (IDWritePixelSnapping))
return castToType <IDWritePixelSnapping> (result);
return castToType<IDWritePixelSnapping> (result);
return ComBaseClassHelper<IDWriteTextRenderer>::QueryInterface (refId, result);
}
@@ -54,12 +54,9 @@ namespace DirectWriteTypeLayout
JUCE_COMRESULT GetCurrentTransform (void*, DWRITE_MATRIX* matrix) override
{
matrix->m11 = 1.0f;
matrix->m12 = 0.0f;
matrix->m21 = 0.0f;
matrix->m22 = 1.0f;
matrix->dx = 0.0f;
matrix->dy = 0.0f;
matrix->m11 = 1.0f; matrix->m12 = 0.0f;
matrix->m21 = 0.0f; matrix->m22 = 1.0f;
matrix->dx = 0.0f; matrix->dy = 0.0f;
return S_OK;
}
@@ -172,10 +169,13 @@ namespace DirectWriteTypeLayout
Font getFontForRun (const DWRITE_GLYPH_RUN& glyphRun, float fontHeight)
{
for (int i = 0; i < attributedString.getNumAttributes(); ++i)
if (const Font* font = attributedString.getAttribute(i)->getFont())
if (WindowsDirectWriteTypeface* wt = dynamic_cast<WindowsDirectWriteTypeface*> (font->getTypeface()))
if (wt->getIDWriteFontFace() == glyphRun.fontFace)
return font->withHeight (fontHeight);
{
const Font& font = attributedString.getAttribute(i).font;
if (WindowsDirectWriteTypeface* wt = dynamic_cast<WindowsDirectWriteTypeface*> (font.getTypeface()))
if (wt->getIDWriteFontFace() == glyphRun.fontFace)
return font.withHeight (fontHeight);
}
ComSmartPtr<IDWriteFont> dwFont;
HRESULT hr = fontCollection.GetFontFromFontFace (glyphRun.fontFace, dwFont.resetAndGetPointerAddress());
@@ -253,9 +253,8 @@ namespace DirectWriteTypeLayout
range.startPosition = attr.range.getStart();
range.length = jmin (attr.range.getLength(), textLen - attr.range.getStart());
if (const Font* const font = attr.getFont())
{
const String familyName (FontStyleHelpers::getConcreteFamilyName (*font));
const String familyName (FontStyleHelpers::getConcreteFamilyName (attr.font));
BOOL fontFound = false;
uint32 fontIndex;
@@ -275,7 +274,7 @@ namespace DirectWriteTypeLayout
{
hr = fontFamily->GetFont (i, dwFont.resetAndGetPointerAddress());
if (font->getTypefaceStyle() == getFontFaceName (dwFont))
if (attr.font.getTypefaceStyle() == getFontFaceName (dwFont))
break;
}
@@ -285,16 +284,16 @@ namespace DirectWriteTypeLayout
textLayout.SetFontStyle (dwFont->GetStyle(), range);
const float fontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (*dwFont);
textLayout.SetFontSize (font->getHeight() * fontHeightToEmSizeFactor, range);
textLayout.SetFontSize (attr.font.getHeight() * fontHeightToEmSizeFactor, range);
}
if (const Colour* const colour = attr.getColour())
{
const Colour col (attr.colour);
ComSmartPtr<ID2D1SolidColorBrush> d2dBrush;
renderTarget.CreateSolidColorBrush (D2D1::ColorF (colour->getFloatRed(),
colour->getFloatGreen(),
colour->getFloatBlue(),
colour->getFloatAlpha()),
renderTarget.CreateSolidColorBrush (D2D1::ColorF (col.getFloatRed(),
col.getFloatGreen(),
col.getFloatBlue(),
col.getFloatAlpha()),
d2dBrush.resetAndGetPointerAddress());
// We need to call SetDrawingEffect with a legimate brush to get DirectWrite to break text based on colours
@@ -353,7 +352,7 @@ namespace DirectWriteTypeLayout
const int numAttributes = text.getNumAttributes();
for (int i = 0; i < numAttributes; ++i)
addAttributedRange (*text.getAttribute (i), *textLayout, textLen, renderTarget, fontCollection);
addAttributedRange (text.getAttribute (i), *textLayout, textLen, renderTarget, fontCollection);
return true;
}
@@ -419,9 +418,8 @@ static bool canAllTypefacesBeUsedInLayout (const AttributedString& text)
const int numCharacterAttributes = text.getNumAttributes();
for (int i = 0; i < numCharacterAttributes; ++i)
if (const Font* const font = text.getAttribute (i)->getFont())
if (dynamic_cast<WindowsDirectWriteTypeface*> (font->getTypeface()) == nullptr)
return false;
if (dynamic_cast<WindowsDirectWriteTypeface*> (text.getAttribute(i).font.getTypeface()) == nullptr)
return false;
return true;
}


Loading…
Cancel
Save