Browse Source

CodeEditorComponent rendering improvements. Faster OSX font lookup.

tags/2021-05-28
jules 12 years ago
parent
commit
4b128378cf
9 changed files with 75 additions and 70 deletions
  1. +2
    -1
      extras/Introjucer/Source/Application/jucer_AppearanceSettings.cpp
  2. +1
    -0
      extras/Introjucer/Source/Application/jucer_AppearanceSettings.h
  3. +14
    -11
      extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.cpp
  4. +3
    -4
      extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.h
  5. +3
    -3
      extras/Introjucer/Source/ComponentEditor/ui/jucer_JucerDocumentEditor.cpp
  6. +33
    -9
      modules/juce_graphics/native/juce_mac_Fonts.mm
  7. +8
    -15
      modules/juce_gui_basics/drawables/juce_DrawableText.cpp
  8. +0
    -1
      modules/juce_gui_basics/drawables/juce_DrawableText.h
  9. +11
    -26
      modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp

+ 2
- 1
extras/Introjucer/Source/Application/jucer_AppearanceSettings.cpp View File

@@ -567,7 +567,7 @@ static void createTabTextLayout (const TabBarButton& button, const Rectangle<int
textLayout.createLayout (s, (float) textArea.getWidth()); textLayout.createLayout (s, (float) textArea.getWidth());
} }
static Colour getTabBackgroundColour (TabBarButton& button)
Colour IntrojucerLookAndFeel::getTabBackgroundColour (TabBarButton& button)
{ {
const Colour bkg (button.findColour (mainBackgroundColourId).contrasting (0.15f)); const Colour bkg (button.findColour (mainBackgroundColourId).contrasting (0.15f));
@@ -580,6 +580,7 @@ static Colour getTabBackgroundColour (TabBarButton& button)
void IntrojucerLookAndFeel::drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown) void IntrojucerLookAndFeel::drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown)
{ {
const Rectangle<int> activeArea (button.getActiveArea()); const Rectangle<int> activeArea (button.getActiveArea());
const Colour bkg (getTabBackgroundColour (button)); const Colour bkg (getTabBackgroundColour (button));
g.setGradientFill (ColourGradient (bkg.brighter (0.1f), 0, (float) activeArea.getY(), g.setGradientFill (ColourGradient (bkg.brighter (0.1f), 0, (float) activeArea.getY(),


+ 1
- 0
extras/Introjucer/Source/Application/jucer_AppearanceSettings.h View File

@@ -89,6 +89,7 @@ public:
int getTabButtonOverlap (int tabDepth); int getTabButtonOverlap (int tabDepth);
int getTabButtonSpaceAroundImage(); int getTabButtonSpaceAroundImage();
int getTabButtonBestWidth (TabBarButton& button, int tabDepth); int getTabButtonBestWidth (TabBarButton& button, int tabDepth);
static Colour getTabBackgroundColour (TabBarButton& button);
void drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown); void drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown);
Rectangle<int> getTabButtonExtraComponentBounds (const TabBarButton& button, Rectangle<int>& textArea, Component& comp); Rectangle<int> getTabButtonExtraComponentBounds (const TabBarButton& button, Rectangle<int>& textArea, Component& comp);


+ 14
- 11
extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.cpp View File

@@ -46,8 +46,7 @@ CodeDocument& SourceCodeDocument::getCodeDocument()
Component* SourceCodeDocument::createEditor() Component* SourceCodeDocument::createEditor()
{ {
SourceCodeEditor* e = new SourceCodeEditor (this);
e->createEditor (getCodeDocument());
SourceCodeEditor* e = new SourceCodeEditor (this, getCodeDocument());
applyLastState (*(e->editor)); applyLastState (*(e->editor));
return e; return e;
} }
@@ -114,9 +113,21 @@ void SourceCodeDocument::applyLastState (CodeEditorComponent& editor) const
} }
//============================================================================== //==============================================================================
SourceCodeEditor::SourceCodeEditor (OpenDocumentManager::Document* doc)
SourceCodeEditor::SourceCodeEditor (OpenDocumentManager::Document* doc, CodeDocument& codeDocument)
: DocumentEditorComponent (doc) : DocumentEditorComponent (doc)
{ {
setOpaque (true);
if (document->getFile().hasFileExtension (sourceOrHeaderFileExtensions))
setEditor (new CppCodeEditorComponent (document->getFile(), codeDocument));
else
setEditor (new GenericCodeEditorComponent (document->getFile(), codeDocument, nullptr));
}
SourceCodeEditor::SourceCodeEditor (OpenDocumentManager::Document* doc, CodeEditorComponent* ed)
: DocumentEditorComponent (doc)
{
setEditor (ed);
} }
SourceCodeEditor::~SourceCodeEditor() SourceCodeEditor::~SourceCodeEditor()
@@ -130,14 +141,6 @@ SourceCodeEditor::~SourceCodeEditor()
doc->updateLastState (*editor); doc->updateLastState (*editor);
} }
void SourceCodeEditor::createEditor (CodeDocument& codeDocument)
{
if (document->getFile().hasFileExtension (sourceOrHeaderFileExtensions))
setEditor (new CppCodeEditorComponent (document->getFile(), codeDocument));
else
setEditor (new GenericCodeEditorComponent (document->getFile(), codeDocument, nullptr));
}
void SourceCodeEditor::setEditor (CodeEditorComponent* newEditor) void SourceCodeEditor::setEditor (CodeEditorComponent* newEditor)
{ {
if (editor != nullptr) if (editor != nullptr)


+ 3
- 4
extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.h View File

@@ -141,12 +141,10 @@ class SourceCodeEditor : public DocumentEditorComponent,
private CodeDocument::Listener private CodeDocument::Listener
{ {
public: public:
SourceCodeEditor (OpenDocumentManager::Document* document);
SourceCodeEditor (OpenDocumentManager::Document* document, CodeDocument&);
SourceCodeEditor (OpenDocumentManager::Document* document, CodeEditorComponent*);
~SourceCodeEditor(); ~SourceCodeEditor();
void createEditor (CodeDocument& codeDocument);
void setEditor (CodeEditorComponent*);
void scrollToKeepRangeOnScreen (Range<int> range); void scrollToKeepRangeOnScreen (Range<int> range);
void highlight (Range<int> range, bool cursorAtStart); void highlight (Range<int> range, bool cursorAtStart);
@@ -165,6 +163,7 @@ private:
void codeDocumentTextInserted (const String&, int); void codeDocumentTextInserted (const String&, int);
void codeDocumentTextDeleted (int, int); void codeDocumentTextDeleted (int, int);
void setEditor (CodeEditorComponent*);
void updateColourScheme(); void updateColourScheme();
void checkSaveState(); void checkSaveState();


+ 3
- 3
extras/Introjucer/Source/ComponentEditor/ui/jucer_JucerDocumentEditor.cpp View File

@@ -329,9 +329,9 @@ JucerDocumentEditor::JucerDocumentEditor (JucerDocument* const doc)
tabbedComponent.addTab ("Resources", tabColour, new ResourceEditorPanel (*document), true); tabbedComponent.addTab ("Resources", tabColour, new ResourceEditorPanel (*document), true);
SourceCodeEditor* codeEditor = new SourceCodeEditor (&document->getCppDocument());
codeEditor->setEditor (new CppCodeEditorComponent (document->getCppFile(),
document->getCppDocument().getCodeDocument()));
SourceCodeEditor* codeEditor = new SourceCodeEditor (&document->getCppDocument(),
new CppCodeEditorComponent (document->getCppFile(),
document->getCppDocument().getCodeDocument()));
tabbedComponent.addTab ("Code", tabColour, codeEditor, true); tabbedComponent.addTab ("Code", tabColour, codeEditor, true);


+ 33
- 9
modules/juce_graphics/native/juce_mac_Fonts.mm View File

@@ -39,6 +39,8 @@ extern "C"
} }
#endif #endif
static CTFontRef getCTFontFromTypeface (const Font& f);
namespace CoreTextTypeLayout namespace CoreTextTypeLayout
{ {
static String findBestAvailableStyle (const Font& font, CGAffineTransform& requiredTransform) static String findBestAvailableStyle (const Font& font, CGAffineTransform& requiredTransform)
@@ -187,6 +189,18 @@ namespace CoreTextTypeLayout
HeapBlock<CGPoint> local; HeapBlock<CGPoint> local;
}; };
static CTFontRef getOrCreateFont (const Font& f)
{
if (CTFontRef ctf = getCTFontFromTypeface (f))
{
CFRetain (ctf);
return ctf;
}
CGAffineTransform transform;
return createCTFont (f, referenceFontSize, transform);
}
//============================================================================== //==============================================================================
static CFAttributedStringRef createCFAttributedString (const AttributedString& text) static CFAttributedStringRef createCFAttributedString (const AttributedString& text)
{ {
@@ -213,13 +227,14 @@ namespace CoreTextTypeLayout
if (const Font* const f = attr->getFont()) if (const Font* const f = attr->getFont())
{ {
CGAffineTransform transform;
CTFontRef ctFontRef = createCTFont (*f, referenceFontSize, transform);
ctFontRef = getFontWithPointSize (ctFontRef, f->getHeight() * getHeightToPointsFactor (ctFontRef));
if (CTFontRef ctFontRef = getOrCreateFont (*f))
{
ctFontRef = getFontWithPointSize (ctFontRef, f->getHeight() * getHeightToPointsFactor (ctFontRef));
CFAttributedStringSetAttribute (attribString, CFRangeMake (range.getStart(), range.getLength()),
kCTFontAttributeName, ctFontRef);
CFRelease (ctFontRef);
CFAttributedStringSetAttribute (attribString, CFRangeMake (range.getStart(), range.getLength()),
kCTFontAttributeName, ctFontRef);
CFRelease (ctFontRef);
}
} }
if (const Colour* const col = attr->getColour()) if (const Colour* const col = attr->getColour())
@@ -416,11 +431,11 @@ class OSXTypeface : public Typeface
public: public:
OSXTypeface (const Font& font) OSXTypeface (const Font& font)
: Typeface (font.getTypefaceName(), : Typeface (font.getTypefaceName(),
font.getTypefaceStyle()),
font.getTypefaceStyle()),
fontRef (nullptr), fontRef (nullptr),
ctFontRef (nullptr),
fontHeightToPointsFactor (1.0f), fontHeightToPointsFactor (1.0f),
renderingTransform (CGAffineTransformIdentity), renderingTransform (CGAffineTransformIdentity),
ctFontRef (nullptr),
attributedStringAtts (nullptr), attributedStringAtts (nullptr),
ascent (0.0f), ascent (0.0f),
unitsToHeightScaleFactor (0.0f) unitsToHeightScaleFactor (0.0f)
@@ -566,12 +581,12 @@ public:
//============================================================================== //==============================================================================
CGFontRef fontRef; CGFontRef fontRef;
CTFontRef ctFontRef;
float fontHeightToPointsFactor; float fontHeightToPointsFactor;
CGAffineTransform renderingTransform; CGAffineTransform renderingTransform;
private: private:
CTFontRef ctFontRef;
CFDictionaryRef attributedStringAtts; CFDictionaryRef attributedStringAtts;
float ascent, unitsToHeightScaleFactor; float ascent, unitsToHeightScaleFactor;
AffineTransform pathTransform; AffineTransform pathTransform;
@@ -598,6 +613,15 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSXTypeface) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSXTypeface)
}; };
CTFontRef getCTFontFromTypeface (const Font& f)
{
if (OSXTypeface* tf = dynamic_cast <OSXTypeface*> (f.getTypeface()))
return tf->ctFontRef;
return 0;
}
StringArray Font::findAllTypefaceNames() StringArray Font::findAllTypefaceNames()
{ {
StringArray names; StringArray names;


+ 8
- 15
modules/juce_gui_basics/drawables/juce_DrawableText.cpp View File

@@ -158,28 +158,21 @@ void DrawableText::recalculateCoordinates (Expression::Scope* scope)
repaint(); repaint();
} }
const AffineTransform DrawableText::getArrangementAndTransform (GlyphArrangement& glyphs) const
{
const float w = Line<float> (resolvedPoints[0], resolvedPoints[1]).getLength();
const float h = Line<float> (resolvedPoints[0], resolvedPoints[2]).getLength();
glyphs.addFittedText (scaledFont, text, 0, 0, w, h, justification, 0x100000);
return AffineTransform::fromTargetPoints (0, 0, resolvedPoints[0].x, resolvedPoints[0].y,
w, 0, resolvedPoints[1].x, resolvedPoints[1].y,
0, h, resolvedPoints[2].x, resolvedPoints[2].y);
}
//============================================================================== //==============================================================================
void DrawableText::paint (Graphics& g) void DrawableText::paint (Graphics& g)
{ {
transformContextToCorrectOrigin (g); transformContextToCorrectOrigin (g);
const float w = Line<float> (resolvedPoints[0], resolvedPoints[1]).getLength();
const float h = Line<float> (resolvedPoints[0], resolvedPoints[2]).getLength();
g.addTransform (AffineTransform::fromTargetPoints (0, 0, resolvedPoints[0].x, resolvedPoints[0].y,
w, 0, resolvedPoints[1].x, resolvedPoints[1].y,
0, h, resolvedPoints[2].x, resolvedPoints[2].y));
g.setFont (scaledFont);
g.setColour (colour); g.setColour (colour);
GlyphArrangement ga;
const AffineTransform transform (getArrangementAndTransform (ga));
ga.draw (g, transform);
g.drawFittedText (text, Rectangle<int> (w, h), justification, 0x100000);
} }
Rectangle<float> DrawableText::getDrawableBounds() const Rectangle<float> DrawableText::getDrawableBounds() const


+ 0
- 1
modules/juce_gui_basics/drawables/juce_DrawableText.h View File

@@ -149,7 +149,6 @@ private:
bool registerCoordinates (RelativeCoordinatePositionerBase&); bool registerCoordinates (RelativeCoordinatePositionerBase&);
void recalculateCoordinates (Expression::Scope*); void recalculateCoordinates (Expression::Scope*);
void refreshBounds(); void refreshBounds();
const AffineTransform getArrangementAndTransform (GlyphArrangement& glyphs) const;
DrawableText& operator= (const DrawableText&); DrawableText& operator= (const DrawableText&);
JUCE_LEAK_DETECTOR (DrawableText) JUCE_LEAK_DETECTOR (DrawableText)


+ 11
- 26
modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp View File

@@ -81,8 +81,7 @@ public:
} }
void draw (CodeEditorComponent& owner, Graphics& g, const Font& fontToUse, void draw (CodeEditorComponent& owner, Graphics& g, const Font& fontToUse,
const float leftClip, const float rightClip,
const float x, const int y, const int baselineOffset,
const float rightClip, const float x, const int y,
const int lineH, const float characterWidth, const int lineH, const float characterWidth,
const Colour highlightColour) const const Colour highlightColour) const
{ {
@@ -93,9 +92,11 @@ public:
roundToInt ((highlightColumnEnd - highlightColumnStart) * characterWidth), lineH); roundToInt ((highlightColumnEnd - highlightColumnStart) * characterWidth), lineH);
} }
const float baselineY = (float) (y + baselineOffset);
Colour lastColour (0x00000001); Colour lastColour (0x00000001);
GlyphArrangement ga;
AttributedString as;
as.setJustification (Justification::centredLeft);
int column = 0; int column = 0;
for (int i = 0; i < tokens.size(); ++i) for (int i = 0; i < tokens.size(); ++i)
@@ -104,26 +105,12 @@ public:
if (tokenX > rightClip) if (tokenX > rightClip)
break; break;
SyntaxToken& token = tokens.getReference(i);
const Colour newColour (owner.getColourForTokenType (token.tokenType));
if (lastColour != newColour)
{
ga.draw (g);
ga.clear();
lastColour = newColour;
g.setColour (newColour);
}
const SyntaxToken& token = tokens.getReference(i);
as.append (token.text, fontToUse, owner.getColourForTokenType (token.tokenType));
column += token.length; column += token.length;
if (x + column * characterWidth >= leftClip)
ga.addCurtailedLineOfText (fontToUse, token.text, tokenX, baselineY,
(rightClip - tokenX) + characterWidth, false);
} }
ga.draw (g);
as.draw (g, Rectangle<int> (x, y, 10000, lineH).toFloat());
} }
private: private:
@@ -484,20 +471,18 @@ void CodeEditorComponent::paint (Graphics& g)
g.reduceClipRegion (gutterSize, 0, verticalScrollBar.getX() - gutterSize, horizontalScrollBar.getY()); g.reduceClipRegion (gutterSize, 0, verticalScrollBar.getX() - gutterSize, horizontalScrollBar.getY());
g.setFont (font); g.setFont (font);
const int baselineOffset = (int) font.getAscent();
const Colour highlightColour (findColour (CodeEditorComponent::highlightColourId)); const Colour highlightColour (findColour (CodeEditorComponent::highlightColourId));
const Rectangle<int> clip (g.getClipBounds()); const Rectangle<int> clip (g.getClipBounds());
const int firstLineToDraw = jmax (0, clip.getY() / lineHeight); const int firstLineToDraw = jmax (0, clip.getY() / lineHeight);
const int lastLineToDraw = jmin (lines.size(), clip.getBottom() / lineHeight + 1); const int lastLineToDraw = jmin (lines.size(), clip.getBottom() / lineHeight + 1);
const float x = (float) (gutterSize - xOffset * charWidth); const float x = (float) (gutterSize - xOffset * charWidth);
const float leftClip = (float) clip.getX();
const float rightClip = (float) clip.getRight(); const float rightClip = (float) clip.getRight();
for (int i = firstLineToDraw; i < lastLineToDraw; ++i) for (int i = firstLineToDraw; i < lastLineToDraw; ++i)
lines.getUnchecked(i)->draw (*this, g, font, leftClip, rightClip,
x, lineHeight * i, baselineOffset,
lineHeight, charWidth, highlightColour);
lines.getUnchecked(i)->draw (*this, g, font, rightClip,
x, lineHeight * i, lineHeight,
charWidth, highlightColour);
} }
void CodeEditorComponent::setScrollbarThickness (const int thickness) void CodeEditorComponent::setScrollbarThickness (const int thickness)


Loading…
Cancel
Save