1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-20 01:14:20 +00:00

CodeEditorComponent rendering improvements. Faster OSX font lookup.

This commit is contained in:
jules 2013-06-16 10:08:05 +01:00
parent a7b0ec0678
commit 4b128378cf
9 changed files with 75 additions and 70 deletions

View file

@ -567,7 +567,7 @@ static void createTabTextLayout (const TabBarButton& button, const Rectangle<int
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));
@ -580,6 +580,7 @@ static Colour getTabBackgroundColour (TabBarButton& button)
void IntrojucerLookAndFeel::drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown)
{
const Rectangle<int> activeArea (button.getActiveArea());
const Colour bkg (getTabBackgroundColour (button));
g.setGradientFill (ColourGradient (bkg.brighter (0.1f), 0, (float) activeArea.getY(),

View file

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

View file

@ -46,8 +46,7 @@ CodeDocument& SourceCodeDocument::getCodeDocument()
Component* SourceCodeDocument::createEditor()
{
SourceCodeEditor* e = new SourceCodeEditor (this);
e->createEditor (getCodeDocument());
SourceCodeEditor* e = new SourceCodeEditor (this, getCodeDocument());
applyLastState (*(e->editor));
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)
{
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()
@ -130,14 +141,6 @@ SourceCodeEditor::~SourceCodeEditor()
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)
{
if (editor != nullptr)

View file

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

View file

@ -329,9 +329,9 @@ JucerDocumentEditor::JucerDocumentEditor (JucerDocument* const doc)
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);

View file

@ -39,6 +39,8 @@ extern "C"
}
#endif
static CTFontRef getCTFontFromTypeface (const Font& f);
namespace CoreTextTypeLayout
{
static String findBestAvailableStyle (const Font& font, CGAffineTransform& requiredTransform)
@ -187,6 +189,18 @@ namespace CoreTextTypeLayout
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)
{
@ -213,13 +227,14 @@ namespace CoreTextTypeLayout
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())
@ -416,11 +431,11 @@ class OSXTypeface : public Typeface
public:
OSXTypeface (const Font& font)
: Typeface (font.getTypefaceName(),
font.getTypefaceStyle()),
font.getTypefaceStyle()),
fontRef (nullptr),
ctFontRef (nullptr),
fontHeightToPointsFactor (1.0f),
renderingTransform (CGAffineTransformIdentity),
ctFontRef (nullptr),
attributedStringAtts (nullptr),
ascent (0.0f),
unitsToHeightScaleFactor (0.0f)
@ -566,12 +581,12 @@ public:
//==============================================================================
CGFontRef fontRef;
CTFontRef ctFontRef;
float fontHeightToPointsFactor;
CGAffineTransform renderingTransform;
private:
CTFontRef ctFontRef;
CFDictionaryRef attributedStringAtts;
float ascent, unitsToHeightScaleFactor;
AffineTransform pathTransform;
@ -598,6 +613,15 @@ private:
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 names;

View file

@ -158,28 +158,21 @@ void DrawableText::recalculateCoordinates (Expression::Scope* scope)
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)
{
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);
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

View file

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

View file

@ -81,8 +81,7 @@ public:
}
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 Colour highlightColour) const
{
@ -93,9 +92,11 @@ public:
roundToInt ((highlightColumnEnd - highlightColumnStart) * characterWidth), lineH);
}
const float baselineY = (float) (y + baselineOffset);
Colour lastColour (0x00000001);
GlyphArrangement ga;
AttributedString as;
as.setJustification (Justification::centredLeft);
int column = 0;
for (int i = 0; i < tokens.size(); ++i)
@ -104,26 +105,12 @@ public:
if (tokenX > rightClip)
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;
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:
@ -484,20 +471,18 @@ void CodeEditorComponent::paint (Graphics& g)
g.reduceClipRegion (gutterSize, 0, verticalScrollBar.getX() - gutterSize, horizontalScrollBar.getY());
g.setFont (font);
const int baselineOffset = (int) font.getAscent();
const Colour highlightColour (findColour (CodeEditorComponent::highlightColourId));
const Rectangle<int> clip (g.getClipBounds());
const int firstLineToDraw = jmax (0, clip.getY() / lineHeight);
const int lastLineToDraw = jmin (lines.size(), clip.getBottom() / lineHeight + 1);
const float x = (float) (gutterSize - xOffset * charWidth);
const float leftClip = (float) clip.getX();
const float rightClip = (float) clip.getRight();
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)