From 1a7caaa58fa900ef87a3c72dd78a204fe738c346 Mon Sep 17 00:00:00 2001 From: jules Date: Sun, 3 Jan 2016 13:16:18 +0000 Subject: [PATCH] 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. --- .../fonts/juce_AttributedString.cpp | 235 +++++++++++++----- .../fonts/juce_AttributedString.h | 48 ++-- .../juce_graphics/fonts/juce_TextLayout.cpp | 73 +----- modules/juce_graphics/juce_graphics.h | 2 +- .../juce_graphics/native/juce_mac_Fonts.mm | 71 +++--- .../juce_win32_DirectWriteTypeLayout.cpp | 48 ++-- 6 files changed, 263 insertions(+), 214 deletions(-) diff --git a/modules/juce_graphics/fonts/juce_AttributedString.cpp b/modules/juce_graphics/fonts/juce_AttributedString.cpp index e1d9cbec29..990e5d9a41 100644 --- a/modules/juce_graphics/fonts/juce_AttributedString.cpp +++ b/modules/juce_graphics/fonts/juce_AttributedString.cpp @@ -22,31 +22,156 @@ ============================================================================== */ -AttributedString::Attribute::Attribute (Range range_, Colour colour_) - : range (range_), colour (new Colour (colour_)) +namespace { + int getLength (const Array& atts) noexcept + { + return atts.size() != 0 ? atts.getReference (atts.size() - 1).range.getEnd() : 0; + } + + void splitAttributeRanges (Array& 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 splitAttributeRanges (Array& atts, Range newRange) + { + newRange = newRange.getIntersectionWith (Range (0, getLength (atts))); + + if (! newRange.isEmpty()) + { + splitAttributeRanges (atts, newRange.getStart()); + splitAttributeRanges (atts, newRange.getEnd()); + } + + return newRange; + } + + void mergeAdjacentRanges (Array& 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& atts, + int length, const Font* f, const Colour* c) + { + if (atts.size() == 0) + { + atts.add (AttributedString::Attribute (Range (0, length), + f != nullptr ? *f : Font(), + c != nullptr ? *c : Colour (0xff000000))); + } + else + { + const int start = getLength (atts); + atts.add (AttributedString::Attribute (Range (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& atts, + Range 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& 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 range_, const Font& font_) - : range (range_), font (new Font (font_)) -{ -} +//============================================================================== +AttributedString::Attribute::Attribute() noexcept : colour (0xff000000) {} +AttributedString::Attribute::~Attribute() noexcept {} -AttributedString::Attribute::Attribute (const Attribute& other) +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +AttributedString::Attribute::Attribute (Attribute&& other) noexcept : range (other.range), - font (other.font.createCopy()), - colour (other.colour.createCopy()) + font (static_cast (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= (Attribute&& other) noexcept +{ + range = other.range; + font = static_cast (other.font); + colour = other.colour; + return *this; +} +#endif + +AttributedString::Attribute::Attribute (const Attribute& other) noexcept + : range (other.range), + font (other.font), + colour (other.colour) { } -AttributedString::Attribute::~Attribute() {} +AttributedString::Attribute& AttributedString::Attribute::operator= (const Attribute& other) noexcept +{ + range = other.range; + font = other.font; + colour = other.colour; + return *this; +} + +AttributedString::Attribute::Attribute (Range 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&&> (other.attributes)) + attributes (static_cast&&> (other.attributes)) { } @@ -110,58 +234,61 @@ AttributedString& AttributedString::operator= (AttributedString&& other) noexcep justification = other.justification; wordWrap = other.wordWrap; readingDirection = other.readingDirection; - attributes = static_cast&&> (other.attributes); + attributes = static_cast&&> (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 (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 (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 (oldLength, oldLength + newLength), font); - setColour (Range (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 range, Colour colour) { - attributes.add (new Attribute (range, colour)); -} - -void AttributedString::setColour (Colour colour) -{ - for (int i = attributes.size(); --i >= 0;) - if (attributes.getUnchecked(i)->getColour() != nullptr) - attributes.remove (i); - - setColour (Range (0, text.length()), colour); + applyFontAndColour (attributes, range, nullptr, &colour); } void AttributedString::setFont (Range range, const Font& font) { - attributes.add (new Attribute (range, font)); + applyFontAndColour (attributes, range, &font, nullptr); +} + +void AttributedString::setColour (Colour colour) +{ + setColour (Range (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 (0, text.length()), font); + setFont (Range (0, getLength (attributes)), font); } void AttributedString::draw (Graphics& g, const Rectangle& area) const { if (text.isNotEmpty() && g.clipRegionIntersects (area.getSmallestIntegerContainer())) { + jassert (text.length() == getLength (attributes)); + if (! g.getInternalContext().drawTextLayout (*this, area)) { TextLayout layout; diff --git a/modules/juce_graphics/fonts/juce_AttributedString.h b/modules/juce_graphics/fonts/juce_AttributedString.h index 6f46e1f186..d320103040 100644 --- a/modules/juce_graphics/fonts/juce_AttributedString.h +++ b/modules/juce_graphics/fonts/juce_AttributedString.h @@ -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 range, Colour 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 changes the font for a range of characters. - @see AttributedString::setFont() - */ - Attribute (Range 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; } + /** Creates an attribute that specifies the font and colour for a range of characters. */ + Attribute (Range range, const Font& font, Colour colour) noexcept; /** The range of characters to which this attribute will be applied. */ - const Range range; + Range range; + + /** The font for this range of characters. */ + Font font; + + /** The colour for this range of characters. */ + Colour colour; private: - ScopedPointer font; - ScopedPointer colour; - - friend class AttributedString; - Attribute (const Attribute&, int); - Attribute& operator= (const Attribute&); - 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 attributes; + Array attributes; JUCE_LEAK_DETECTOR (AttributedString) }; diff --git a/modules/juce_graphics/fonts/juce_TextLayout.cpp b/modules/juce_graphics/fonts/juce_TextLayout.cpp index 450aa86036..2418eefc16 100644 --- a/modules/juce_graphics/fonts/juce_TextLayout.cpp +++ b/modules/juce_graphics/fonts/juce_TextLayout.cpp @@ -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 r) noexcept - : fontAndColour (fc), range (r) - {} - - FontAndColour fontAndColour; - Range 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 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 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); + const AttributedString::Attribute& attr = text.getAttribute (i); - // 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); - - 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 (rangeStart, i))); - rangeStart = i; - } - - lastFontAndColour = newFontAndColour; - } - - if (rangeStart < stringLength) - runAttributes.add (RunAttribute (lastFontAndColour, Range (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); } } diff --git a/modules/juce_graphics/juce_graphics.h b/modules/juce_graphics/juce_graphics.h index a792131886..3aa7a16e5c 100644 --- a/modules/juce_graphics/juce_graphics.h +++ b/modules/juce_graphics/juce_graphics.h @@ -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" diff --git a/modules/juce_graphics/native/juce_mac_Fonts.mm b/modules/juce_graphics/native/juce_mac_Fonts.mm index 329eee84ba..de1597b151 100644 --- a/modules/juce_graphics/native/juce_mac_Fonts.mm +++ b/modules/juce_graphics/native/juce_mac_Fonts.mm @@ -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, attr.font.getHeight() * getHeightToPointsFactor (ctFontRef)); + + CFAttributedStringSetAttribute (attribString, range, kCTFontAttributeName, ctFontRef); + + float extraKerning = attr.font.getExtraKerningFactor(); + + if (extraKerning != 0.0f) { - ctFontRef = getFontWithPointSize (ctFontRef, f->getHeight() * getHeightToPointsFactor (ctFontRef)); + extraKerning *= attr.font.getHeight(); - CFAttributedStringSetAttribute (attribString, range, kCTFontAttributeName, ctFontRef); - - float extraKerning = f->getExtraKerningFactor(); - - if (extraKerning != 0.0f) - { - extraKerning *= f->getHeight(); - - CFNumberRef numberRef = CFNumberCreate (0, kCFNumberFloatType, &extraKerning); - CFAttributedStringSetAttribute (attribString, range, kCTKernAttributeName, numberRef); - CFRelease (numberRef); - } - - 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 (t)) { - if (OSXTypeface* tf = dynamic_cast (f->getTypeface())) - { - if (tf->isMemoryFont) - return false; - } - else if (dynamic_cast (f->getTypeface()) != nullptr) - { + if (tf->isMemoryFont) return false; - } + } + else if (dynamic_cast (t) != nullptr) + { + return false; } } diff --git a/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp b/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp index af39452628..e5d47236f8 100644 --- a/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp +++ b/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp @@ -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 (result); + return castToType (result); return ComBaseClassHelper::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 (font->getTypeface())) - if (wt->getIDWriteFontFace() == glyphRun.fontFace) - return font->withHeight (fontHeight); + { + const Font& font = attributedString.getAttribute(i).font; + + if (WindowsDirectWriteTypeface* wt = dynamic_cast (font.getTypeface())) + if (wt->getIDWriteFontFace() == glyphRun.fontFace) + return font.withHeight (fontHeight); + } ComSmartPtr 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 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 (font->getTypeface()) == nullptr) - return false; + if (dynamic_cast (text.getAttribute(i).font.getTypeface()) == nullptr) + return false; return true; }