From b1d73f2086d7fd44977d19990b7308b3e992b71b Mon Sep 17 00:00:00 2001 From: jules Date: Sat, 14 Jul 2012 10:02:45 +0100 Subject: [PATCH] Minor internal refactoring and clean-ups. --- .../JuceDemo/Source/demos/CodeEditorDemo.cpp | 3 +- .../contexts/juce_GraphicsContext.cpp | 173 +++++++------- .../contexts/juce_GraphicsContext.h | 6 +- .../fonts/juce_AttributedString.cpp | 2 +- modules/juce_graphics/fonts/juce_Font.h | 4 - .../fonts/juce_GlyphArrangement.cpp | 215 ++++++++---------- .../fonts/juce_GlyphArrangement.h | 5 +- .../juce_graphics/fonts/juce_TextLayout.cpp | 4 +- .../juce_graphics/native/juce_mac_Fonts.mm | 2 +- .../components/juce_Component.cpp | 14 +- .../properties/juce_ChoicePropertyComponent.h | 7 +- .../code_editor/juce_CodeEditorComponent.cpp | 65 +++--- 12 files changed, 244 insertions(+), 256 deletions(-) diff --git a/extras/JuceDemo/Source/demos/CodeEditorDemo.cpp b/extras/JuceDemo/Source/demos/CodeEditorDemo.cpp index 99a5c5d3b6..a8da9aabc9 100644 --- a/extras/JuceDemo/Source/demos/CodeEditorDemo.cpp +++ b/extras/JuceDemo/Source/demos/CodeEditorDemo.cpp @@ -42,7 +42,8 @@ public: // Create the editor.. addAndMakeVisible (editor = new CodeEditorComponent (codeDocument, &cppTokeniser)); - editor->loadContent ("\n\n/* Code editor demo! Please be gentle, this component is still an alpha version! */\n\n"); + editor->loadContent ("\n\n/* Code editor demo! To see a real-world example of the " + "code editor in action, try the Introjucer! */\n\n"); // Create a file chooser control to load files into it.. addAndMakeVisible (&fileChooser); diff --git a/modules/juce_graphics/contexts/juce_GraphicsContext.cpp b/modules/juce_graphics/contexts/juce_GraphicsContext.cpp index f2fe30f06b..7a51e3a095 100644 --- a/modules/juce_graphics/contexts/juce_GraphicsContext.cpp +++ b/modules/juce_graphics/contexts/juce_GraphicsContext.cpp @@ -48,16 +48,17 @@ LowLevelGraphicsContext::~LowLevelGraphicsContext() //============================================================================== Graphics::Graphics (const Image& imageToDrawOnto) - : context (imageToDrawOnto.createLowLevelContext()), - contextToDelete (context), + : context (*imageToDrawOnto.createLowLevelContext()), + contextToDelete (&context), saveStatePending (false) { } Graphics::Graphics (LowLevelGraphicsContext* const internalContext) noexcept - : context (internalContext), + : context (*internalContext), saveStatePending (false) { + jassert (internalContext != nullptr); } Graphics::~Graphics() @@ -68,20 +69,20 @@ Graphics::~Graphics() void Graphics::resetToDefaultState() { saveStateIfPending(); - context->setFill (FillType()); - context->setFont (Font()); - context->setInterpolationQuality (Graphics::mediumResamplingQuality); + context.setFill (FillType()); + context.setFont (Font()); + context.setInterpolationQuality (Graphics::mediumResamplingQuality); } bool Graphics::isVectorDevice() const { - return context->isVectorDevice(); + return context.isVectorDevice(); } bool Graphics::reduceClipRegion (const Rectangle& area) { saveStateIfPending(); - return context->clipToRectangle (area); + return context.clipToRectangle (area); } bool Graphics::reduceClipRegion (const int x, const int y, const int w, const int h) @@ -92,37 +93,37 @@ bool Graphics::reduceClipRegion (const int x, const int y, const int w, const in bool Graphics::reduceClipRegion (const RectangleList& clipRegion) { saveStateIfPending(); - return context->clipToRectangleList (clipRegion); + return context.clipToRectangleList (clipRegion); } bool Graphics::reduceClipRegion (const Path& path, const AffineTransform& transform) { saveStateIfPending(); - context->clipToPath (path, transform); - return ! context->isClipEmpty(); + context.clipToPath (path, transform); + return ! context.isClipEmpty(); } bool Graphics::reduceClipRegion (const Image& image, const AffineTransform& transform) { saveStateIfPending(); - context->clipToImageAlpha (image, transform); - return ! context->isClipEmpty(); + context.clipToImageAlpha (image, transform); + return ! context.isClipEmpty(); } void Graphics::excludeClipRegion (const Rectangle& rectangleToExclude) { saveStateIfPending(); - context->excludeClipRectangle (rectangleToExclude); + context.excludeClipRectangle (rectangleToExclude); } bool Graphics::isClipEmpty() const { - return context->isClipEmpty(); + return context.isClipEmpty(); } Rectangle Graphics::getClipBounds() const { - return context->getClipBounds(); + return context.getClipBounds(); } void Graphics::saveState() @@ -136,7 +137,7 @@ void Graphics::restoreState() if (saveStatePending) saveStatePending = false; else - context->restoreState(); + context.restoreState(); } void Graphics::saveStateIfPending() @@ -144,49 +145,49 @@ void Graphics::saveStateIfPending() if (saveStatePending) { saveStatePending = false; - context->saveState(); + context.saveState(); } } void Graphics::setOrigin (const int newOriginX, const int newOriginY) { saveStateIfPending(); - context->setOrigin (newOriginX, newOriginY); + context.setOrigin (newOriginX, newOriginY); } void Graphics::addTransform (const AffineTransform& transform) { saveStateIfPending(); - context->addTransform (transform); + context.addTransform (transform); } bool Graphics::clipRegionIntersects (const Rectangle& area) const { - return context->clipRegionIntersects (area); + return context.clipRegionIntersects (area); } void Graphics::beginTransparencyLayer (float layerOpacity) { saveStateIfPending(); - context->beginTransparencyLayer (layerOpacity); + context.beginTransparencyLayer (layerOpacity); } void Graphics::endTransparencyLayer() { - context->endTransparencyLayer(); + context.endTransparencyLayer(); } //============================================================================== void Graphics::setColour (const Colour& newColour) { saveStateIfPending(); - context->setFill (newColour); + context.setFill (newColour); } void Graphics::setOpacity (const float newOpacity) { saveStateIfPending(); - context->setOpacity (newOpacity); + context.setOpacity (newOpacity); } void Graphics::setGradientFill (const ColourGradient& gradient) @@ -197,31 +198,31 @@ void Graphics::setGradientFill (const ColourGradient& gradient) void Graphics::setTiledImageFill (const Image& imageToUse, const int anchorX, const int anchorY, const float opacity) { saveStateIfPending(); - context->setFill (FillType (imageToUse, AffineTransform::translation ((float) anchorX, (float) anchorY))); - context->setOpacity (opacity); + context.setFill (FillType (imageToUse, AffineTransform::translation ((float) anchorX, (float) anchorY))); + context.setOpacity (opacity); } void Graphics::setFillType (const FillType& newFill) { saveStateIfPending(); - context->setFill (newFill); + context.setFill (newFill); } //============================================================================== void Graphics::setFont (const Font& newFont) { saveStateIfPending(); - context->setFont (newFont); + context.setFont (newFont); } void Graphics::setFont (const float newFontHeight) { - setFont (context->getFont().withHeight (newFontHeight)); + setFont (context.getFont().withHeight (newFontHeight)); } Font Graphics::getCurrentFont() const { - return context->getFont(); + return context.getFont(); } //============================================================================== @@ -229,10 +230,10 @@ void Graphics::drawSingleLineText (const String& text, const int startX, const i const Justification& justification) const { if (text.isNotEmpty() - && startX < context->getClipBounds().getRight()) + && startX < context.getClipBounds().getRight()) { GlyphArrangement arr; - arr.addLineOfText (context->getFont(), text, (float) startX, (float) baselineY); + arr.addLineOfText (context.getFont(), text, (float) startX, (float) baselineY); // Don't pass any vertical placement flags to this method - they'll be ignored. jassert (justification.getOnlyVerticalFlags() == 0); @@ -260,7 +261,7 @@ void Graphics::drawTextAsPath (const String& text, const AffineTransform& transf if (text.isNotEmpty()) { GlyphArrangement arr; - arr.addLineOfText (context->getFont(), text, 0.0f, 0.0f); + arr.addLineOfText (context.getFont(), text, 0.0f, 0.0f); arr.draw (*this, transform); } } @@ -268,10 +269,10 @@ void Graphics::drawTextAsPath (const String& text, const AffineTransform& transf void Graphics::drawMultiLineText (const String& text, const int startX, const int baselineY, const int maximumLineWidth) const { if (text.isNotEmpty() - && startX < context->getClipBounds().getRight()) + && startX < context.getClipBounds().getRight()) { GlyphArrangement arr; - arr.addJustifiedText (context->getFont(), text, + arr.addJustifiedText (context.getFont(), text, (float) startX, (float) baselineY, (float) maximumLineWidth, Justification::left); arr.draw (*this); @@ -283,11 +284,11 @@ void Graphics::drawText (const String& text, const Justification& justificationType, const bool useEllipsesIfTooBig) const { - if (text.isNotEmpty() && context->clipRegionIntersects (Rectangle (x, y, width, height))) + if (text.isNotEmpty() && context.clipRegionIntersects (Rectangle (x, y, width, height))) { GlyphArrangement arr; - arr.addCurtailedLineOfText (context->getFont(), text, + arr.addCurtailedLineOfText (context.getFont(), text, 0.0f, 0.0f, (float) width, useEllipsesIfTooBig); @@ -306,11 +307,11 @@ void Graphics::drawFittedText (const String& text, { if (text.isNotEmpty() && width > 0 && height > 0 - && context->clipRegionIntersects (Rectangle (x, y, width, height))) + && context.clipRegionIntersects (Rectangle (x, y, width, height))) { GlyphArrangement arr; - arr.addFittedText (context->getFont(), text, + arr.addFittedText (context.getFont(), text, (float) x, (float) y, (float) width, (float) height, justification, maximumNumberOfLines, @@ -326,12 +327,12 @@ void Graphics::fillRect (int x, int y, int width, int height) const // passing in a silly number can cause maths problems in rendering! jassert (areCoordsSensibleNumbers (x, y, width, height)); - context->fillRect (Rectangle (x, y, width, height), false); + context.fillRect (Rectangle (x, y, width, height), false); } void Graphics::fillRect (const Rectangle& r) const { - context->fillRect (r, false); + context.fillRect (r, false); } void Graphics::fillRect (const float x, const float y, const float width, const float height) const @@ -346,24 +347,24 @@ void Graphics::fillRect (const float x, const float y, const float width, const void Graphics::setPixel (int x, int y) const { - context->fillRect (Rectangle (x, y, 1, 1), false); + context.fillRect (Rectangle (x, y, 1, 1), false); } void Graphics::fillAll() const { - fillRect (context->getClipBounds()); + fillRect (context.getClipBounds()); } void Graphics::fillAll (const Colour& colourToUse) const { if (! colourToUse.isTransparent()) { - const Rectangle clip (context->getClipBounds()); + const Rectangle clip (context.getClipBounds()); - context->saveState(); - context->setFill (colourToUse); - context->fillRect (clip, false); - context->restoreState(); + context.saveState(); + context.setFill (colourToUse); + context.fillRect (clip, false); + context.restoreState(); } } @@ -371,8 +372,8 @@ void Graphics::fillAll (const Colour& colourToUse) const //============================================================================== void Graphics::fillPath (const Path& path, const AffineTransform& transform) const { - if ((! context->isClipEmpty()) && ! path.isEmpty()) - context->fillPath (path, transform); + if ((! context.isClipEmpty()) && ! path.isEmpty()) + context.fillPath (path, transform); } void Graphics::strokePath (const Path& path, @@ -380,7 +381,7 @@ void Graphics::strokePath (const Path& path, const AffineTransform& transform) const { Path stroke; - strokeType.createStrokedPath (stroke, path, transform, context->getScaleFactor()); + strokeType.createStrokedPath (stroke, path, transform, context.getScaleFactor()); fillPath (stroke); } @@ -391,10 +392,10 @@ void Graphics::drawRect (const int x, const int y, const int width, const int he // passing in a silly number can cause maths problems in rendering! jassert (areCoordsSensibleNumbers (x, y, width, height)); - context->fillRect (Rectangle (x, y, width, lineThickness), false); - context->fillRect (Rectangle (x, y + lineThickness, lineThickness, height - lineThickness * 2), false); - context->fillRect (Rectangle (x + width - lineThickness, y + lineThickness, lineThickness, height - lineThickness * 2), false); - context->fillRect (Rectangle (x, y + height - lineThickness, width, lineThickness), false); + context.fillRect (Rectangle (x, y, width, lineThickness), false); + context.fillRect (Rectangle (x, y + lineThickness, lineThickness, height - lineThickness * 2), false); + context.fillRect (Rectangle (x + width - lineThickness, y + lineThickness, lineThickness, height - lineThickness * 2), false); + context.fillRect (Rectangle (x, y + height - lineThickness, width, lineThickness), false); } void Graphics::drawRect (const float x, const float y, const float width, const float height, const float lineThickness) const @@ -424,24 +425,24 @@ void Graphics::drawBevel (const int x, const int y, const int width, const int h if (clipRegionIntersects (Rectangle (x, y, width, height))) { - context->saveState(); + context.saveState(); for (int i = bevelThickness; --i >= 0;) { const float op = useGradient ? (sharpEdgeOnOutside ? bevelThickness - i : i) / (float) bevelThickness : 1.0f; - context->setFill (topLeftColour.withMultipliedAlpha (op)); - context->fillRect (Rectangle (x + i, y + i, width - i * 2, 1), false); - context->setFill (topLeftColour.withMultipliedAlpha (op * 0.75f)); - context->fillRect (Rectangle (x + i, y + i + 1, 1, height - i * 2 - 2), false); - context->setFill (bottomRightColour.withMultipliedAlpha (op)); - context->fillRect (Rectangle (x + i, y + height - i - 1, width - i * 2, 1), false); - context->setFill (bottomRightColour.withMultipliedAlpha (op * 0.75f)); - context->fillRect (Rectangle (x + width - i - 1, y + i + 1, 1, height - i * 2 - 2), false); + context.setFill (topLeftColour.withMultipliedAlpha (op)); + context.fillRect (Rectangle (x + i, y + i, width - i * 2, 1), false); + context.setFill (topLeftColour.withMultipliedAlpha (op * 0.75f)); + context.fillRect (Rectangle (x + i, y + i + 1, 1, height - i * 2 - 2), false); + context.setFill (bottomRightColour.withMultipliedAlpha (op)); + context.fillRect (Rectangle (x + i, y + height - i - 1, width - i * 2, 1), false); + context.setFill (bottomRightColour.withMultipliedAlpha (op * 0.75f)); + context.fillRect (Rectangle (x + width - i - 1, y + i + 1, 1, height - i * 2 - 2), false); } - context->restoreState(); + context.restoreState(); } } @@ -518,20 +519,20 @@ void Graphics::fillCheckerBoard (const Rectangle& area, if (checkWidth > 0 && checkHeight > 0) { - context->saveState(); + context.saveState(); if (colour1 == colour2) { - context->setFill (colour1); - context->fillRect (area, false); + context.setFill (colour1); + context.fillRect (area, false); } else { - const Rectangle clipped (context->getClipBounds().getIntersection (area)); + const Rectangle clipped (context.getClipBounds().getIntersection (area)); if (! clipped.isEmpty()) { - context->clipToRectangle (clipped); + context.clipToRectangle (clipped); const int checkNumX = (clipped.getX() - area.getX()) / checkWidth; const int checkNumY = (clipped.getY() - area.getY()) / checkHeight; @@ -542,39 +543,39 @@ void Graphics::fillCheckerBoard (const Rectangle& area, for (int i = 0; i < 2; ++i) { - context->setFill (i == ((checkNumX ^ checkNumY) & 1) ? colour1 : colour2); + context.setFill (i == ((checkNumX ^ checkNumY) & 1) ? colour1 : colour2); int cy = i; for (int y = startY; y < bottom; y += checkHeight) for (int x = startX + (cy++ & 1) * checkWidth; x < right; x += checkWidth * 2) - context->fillRect (Rectangle (x, y, checkWidth, checkHeight), false); + context.fillRect (Rectangle (x, y, checkWidth, checkHeight), false); } } } - context->restoreState(); + context.restoreState(); } } //============================================================================== void Graphics::drawVerticalLine (const int x, float top, float bottom) const { - context->drawVerticalLine (x, top, bottom); + context.drawVerticalLine (x, top, bottom); } void Graphics::drawHorizontalLine (const int y, float left, float right) const { - context->drawHorizontalLine (y, left, right); + context.drawHorizontalLine (y, left, right); } void Graphics::drawLine (const float x1, const float y1, const float x2, const float y2) const { - context->drawLine (Line (x1, y1, x2, y2)); + context.drawLine (Line (x1, y1, x2, y2)); } void Graphics::drawLine (const Line& line) const { - context->drawLine (line); + context.drawLine (line); } void Graphics::drawLine (const float x1, const float y1, const float x2, const float y2, const float lineThickness) const @@ -617,7 +618,7 @@ void Graphics::drawDashedLine (const Line& line, const float* const dashL if (lineThickness != 1.0f) drawLine (segment, lineThickness); else - context->drawLine (segment); + context.drawLine (segment); } } } @@ -627,7 +628,7 @@ void Graphics::drawDashedLine (const Line& line, const float* const dashL void Graphics::setImageResamplingQuality (const Graphics::ResamplingQuality newQuality) { saveStateIfPending(); - context->setInterpolationQuality (newQuality); + context.setInterpolationQuality (newQuality); } //============================================================================== @@ -688,7 +689,7 @@ void Graphics::drawImage (const Image& imageToDraw, jassert (areCoordsSensibleNumbers (dx, dy, dw, dh)); jassert (areCoordsSensibleNumbers (sx, sy, sw, sh)); - if (imageToDraw.isValid() && context->clipRegionIntersects (Rectangle (dx, dy, dw, dh))) + if (imageToDraw.isValid() && context.clipRegionIntersects (Rectangle (dx, dy, dw, dh))) { drawImageTransformed (imageToDraw.getClippedImage (Rectangle (sx, sy, sw, sh)), AffineTransform::scale (dw / (float) sw, dh / (float) sh) @@ -701,18 +702,18 @@ void Graphics::drawImageTransformed (const Image& imageToDraw, const AffineTransform& transform, const bool fillAlphaChannelWithCurrentBrush) const { - if (imageToDraw.isValid() && ! context->isClipEmpty()) + if (imageToDraw.isValid() && ! context.isClipEmpty()) { if (fillAlphaChannelWithCurrentBrush) { - context->saveState(); - context->clipToImageAlpha (imageToDraw, transform); + context.saveState(); + context.clipToImageAlpha (imageToDraw, transform); fillAll(); - context->restoreState(); + context.restoreState(); } else { - context->drawImage (imageToDraw, transform); + context.drawImage (imageToDraw, transform); } } } diff --git a/modules/juce_graphics/contexts/juce_GraphicsContext.h b/modules/juce_graphics/contexts/juce_GraphicsContext.h index 8a3129d969..0acda2b867 100644 --- a/modules/juce_graphics/contexts/juce_GraphicsContext.h +++ b/modules/juce_graphics/contexts/juce_GraphicsContext.h @@ -688,14 +688,14 @@ public: For internal use only. NB. The context will NOT be deleted by this object when it is deleted. */ - Graphics (LowLevelGraphicsContext* internalContext) noexcept; + Graphics (LowLevelGraphicsContext*) noexcept; /** @internal */ - LowLevelGraphicsContext* getInternalContext() const noexcept { return context; } + LowLevelGraphicsContext& getInternalContext() const noexcept { return context; } private: //============================================================================== - LowLevelGraphicsContext* const context; + LowLevelGraphicsContext& context; ScopedPointer contextToDelete; bool saveStatePending; diff --git a/modules/juce_graphics/fonts/juce_AttributedString.cpp b/modules/juce_graphics/fonts/juce_AttributedString.cpp index a84e237359..953f6d7314 100644 --- a/modules/juce_graphics/fonts/juce_AttributedString.cpp +++ b/modules/juce_graphics/fonts/juce_AttributedString.cpp @@ -207,7 +207,7 @@ void AttributedString::draw (Graphics& g, const Rectangle& area) const { if (text.isNotEmpty() && g.clipRegionIntersects (area.getSmallestIntegerContainer())) { - if (! g.getInternalContext()->drawTextLayout (*this, area)) + if (! g.getInternalContext().drawTextLayout (*this, area)) { TextLayout layout; layout.createLayout (*this, area.getWidth()); diff --git a/modules/juce_graphics/fonts/juce_Font.h b/modules/juce_graphics/fonts/juce_Font.h index 03825095b3..bfd357499f 100644 --- a/modules/juce_graphics/fonts/juce_Font.h +++ b/modules/juce_graphics/fonts/juce_Font.h @@ -212,7 +212,6 @@ public: //============================================================================== /** Returns the total height of this font. - This is the maximum height, from the top of the ascent to the bottom of the descenders. @@ -288,7 +287,6 @@ public: //============================================================================== /** Returns the font's horizontal scale. - A value of 1.0 is the normal scale, less than this will be narrower, greater than 1.0 will be stretched out. @@ -350,13 +348,11 @@ public: //============================================================================== /** Returns the total width of a string as it would be drawn using this font. - For a more accurate floating-point result, use getStringWidthFloat(). */ int getStringWidth (const String& text) const; /** Returns the total width of a string as it would be drawn using this font. - @see getStringWidth */ float getStringWidthFloat (const String& text) const; diff --git a/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp b/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp index e6df03cbce..fd2d1a48c8 100644 --- a/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp +++ b/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp @@ -23,6 +23,11 @@ ============================================================================== */ +PositionedGlyph::PositionedGlyph() noexcept + : character (0), glyph (0), x (0), y (0), w (0), whitespace (false) +{ +} + PositionedGlyph::PositionedGlyph (const Font& font_, const juce_wchar character_, const int glyph_, const float x_, const float y_, const float w_, const bool whitespace_) : font (font_), character (character_), glyph (glyph_), @@ -54,21 +59,19 @@ void PositionedGlyph::draw (const Graphics& g) const { if (! isWhitespace()) { - LowLevelGraphicsContext* const context = g.getInternalContext(); - context->setFont (font); - context->drawGlyph (glyph, AffineTransform::translation (x, y)); + LowLevelGraphicsContext& context = g.getInternalContext(); + context.setFont (font); + context.drawGlyph (glyph, AffineTransform::translation (x, y)); } } -void PositionedGlyph::draw (const Graphics& g, - const AffineTransform& transform) const +void PositionedGlyph::draw (const Graphics& g, const AffineTransform& transform) const { if (! isWhitespace()) { - LowLevelGraphicsContext* const context = g.getInternalContext(); - context->setFont (font); - context->drawGlyph (glyph, AffineTransform::translation (x, y) - .followedBy (transform)); + LowLevelGraphicsContext& context = g.getInternalContext(); + context.setFont (font); + context.drawGlyph (glyph, AffineTransform::translation (x, y).followedBy (transform)); } } @@ -126,18 +129,13 @@ GlyphArrangement::GlyphArrangement() } GlyphArrangement::GlyphArrangement (const GlyphArrangement& other) + : glyphs (other.glyphs) { - addGlyphArrangement (other); } GlyphArrangement& GlyphArrangement::operator= (const GlyphArrangement& other) { - if (this != &other) - { - clear(); - addGlyphArrangement (other); - } - + glyphs = other.glyphs; return *this; } @@ -151,23 +149,20 @@ void GlyphArrangement::clear() glyphs.clear(); } -PositionedGlyph& GlyphArrangement::getGlyph (const int index) const +PositionedGlyph& GlyphArrangement::getGlyph (const int index) const noexcept { - jassert (isPositiveAndBelow (index, glyphs.size())); - - return *glyphs [index]; + return glyphs.getReference (index); } //============================================================================== void GlyphArrangement::addGlyphArrangement (const GlyphArrangement& other) { - glyphs.ensureStorageAllocated (glyphs.size() + other.glyphs.size()); - glyphs.addCopiesOf (other.glyphs); + glyphs.addArray (other.glyphs); } void GlyphArrangement::addGlyph (const PositionedGlyph& glyph) { - glyphs.add (new PositionedGlyph (glyph)); + glyphs.add (glyph); } void GlyphArrangement::removeRangeOfGlyphs (int startIndex, const int num) @@ -181,9 +176,7 @@ void GlyphArrangement::addLineOfText (const Font& font, const float xOffset, const float yOffset) { - addCurtailedLineOfText (font, text, - xOffset, yOffset, - 1.0e10f, false); + addCurtailedLineOfText (font, text, xOffset, yOffset, 1.0e10f, false); } void GlyphArrangement::addCurtailedLineOfText (const Font& font, @@ -205,7 +198,6 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font, for (int i = 0; i < textLen; ++i) { - const float thisX = xOffsets.getUnchecked (i); const float nextX = xOffsets.getUnchecked (i + 1); if (nextX > maxWidthPixels + 1.0f) @@ -218,12 +210,13 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font, } else { + const float thisX = xOffsets.getUnchecked (i); const bool isWhitespace = t.isWhitespace(); - glyphs.add (new PositionedGlyph (font, t.getAndAdvance(), - newGlyphs.getUnchecked(i), - xOffset + thisX, yOffset, - nextX - thisX, isWhitespace)); + glyphs.add (PositionedGlyph (font, t.getAndAdvance(), + newGlyphs.getUnchecked(i), + xOffset + thisX, yOffset, + nextX - thisX, isWhitespace)); } } } @@ -245,9 +238,9 @@ int GlyphArrangement::insertEllipsis (const Font& font, const float maxXPos, while (endIndex > startIndex) { - const PositionedGlyph* pg = glyphs.getUnchecked (--endIndex); - xOffset = pg->x; - yOffset = pg->y; + const PositionedGlyph& pg = glyphs.getReference (--endIndex); + xOffset = pg.x; + yOffset = pg.y; glyphs.remove (endIndex); ++numDeleted; @@ -258,8 +251,8 @@ int GlyphArrangement::insertEllipsis (const Font& font, const float maxXPos, for (int i = 3; --i >= 0;) { - glyphs.insert (endIndex++, new PositionedGlyph (font, '.', dotGlyphs.getFirst(), - xOffset, yOffset, dx, false)); + glyphs.insert (endIndex++, PositionedGlyph (font, '.', dotGlyphs.getFirst(), + xOffset, yOffset, dx, false)); --numDeleted; xOffset += dx; @@ -286,33 +279,33 @@ void GlyphArrangement::addJustifiedText (const Font& font, { int i = lineStartIndex; - if (glyphs.getUnchecked(i)->getCharacter() != '\n' - && glyphs.getUnchecked(i)->getCharacter() != '\r') + if (glyphs.getReference(i).getCharacter() != '\n' + && glyphs.getReference(i).getCharacter() != '\r') ++i; - const float lineMaxX = glyphs.getUnchecked (lineStartIndex)->getLeft() + maxLineWidth; + const float lineMaxX = glyphs.getReference (lineStartIndex).getLeft() + maxLineWidth; int lastWordBreakIndex = -1; while (i < glyphs.size()) { - const PositionedGlyph* pg = glyphs.getUnchecked (i); - const juce_wchar c = pg->getCharacter(); + const PositionedGlyph& pg = glyphs.getReference (i); + const juce_wchar c = pg.getCharacter(); if (c == '\r' || c == '\n') { ++i; if (c == '\r' && i < glyphs.size() - && glyphs.getUnchecked(i)->getCharacter() == '\n') + && glyphs.getReference(i).getCharacter() == '\n') ++i; break; } - else if (pg->isWhitespace()) + else if (pg.isWhitespace()) { lastWordBreakIndex = i + 1; } - else if (pg->getRight() - 0.0001f >= lineMaxX) + else if (pg.getRight() - 0.0001f >= lineMaxX) { if (lastWordBreakIndex >= 0) i = lastWordBreakIndex; @@ -323,14 +316,14 @@ void GlyphArrangement::addJustifiedText (const Font& font, ++i; } - const float currentLineStartX = glyphs.getUnchecked (lineStartIndex)->getLeft(); + const float currentLineStartX = glyphs.getReference (lineStartIndex).getLeft(); float currentLineEndX = currentLineStartX; for (int j = i; --j >= lineStartIndex;) { - if (! glyphs.getUnchecked (j)->isWhitespace()) + if (! glyphs.getReference (j).isWhitespace()) { - currentLineEndX = glyphs.getUnchecked (j)->getRight(); + currentLineEndX = glyphs.getReference (j).getRight(); break; } } @@ -373,19 +366,12 @@ void GlyphArrangement::addFittedText (const Font& f, float dy = y - bb.getY(); - if (layout.testFlags (Justification::verticallyCentred)) - dy += (height - bb.getHeight()) * 0.5f; - else if (layout.testFlags (Justification::bottom)) - dy += height - bb.getHeight(); + if (layout.testFlags (Justification::verticallyCentred)) dy += (height - bb.getHeight()) * 0.5f; + else if (layout.testFlags (Justification::bottom)) dy += (height - bb.getHeight()); ga.moveRangeOfGlyphs (0, -1, 0.0f, dy); - glyphs.ensureStorageAllocated (glyphs.size() + ga.glyphs.size()); - - for (int i = 0; i < ga.glyphs.size(); ++i) - glyphs.add (ga.glyphs.getUnchecked (i)); - - ga.glyphs.clear (false); + glyphs.addArray (ga.glyphs); return; } @@ -394,8 +380,8 @@ void GlyphArrangement::addFittedText (const Font& f, if (glyphs.size() > startIndex) { - float lineWidth = glyphs.getUnchecked (glyphs.size() - 1)->getRight() - - glyphs.getUnchecked (startIndex)->getLeft(); + float lineWidth = glyphs.getReference (glyphs.size() - 1).getRight() + - glyphs.getReference (startIndex).getLeft(); if (lineWidth <= 0) return; @@ -440,8 +426,8 @@ void GlyphArrangement::addFittedText (const Font& f, removeRangeOfGlyphs (startIndex, -1); addLineOfText (font, txt, x, y); - lineWidth = glyphs.getUnchecked (glyphs.size() - 1)->getRight() - - glyphs.getUnchecked (startIndex)->getLeft(); + lineWidth = glyphs.getReference (glyphs.size() - 1).getRight() + - glyphs.getReference (startIndex).getLeft(); } if (numLines > lineWidth / width || newFontHeight < 8.0f) @@ -459,7 +445,7 @@ void GlyphArrangement::addFittedText (const Font& f, { int i = startIndex; lastLineStartIndex = i; - float lineStartX = glyphs.getUnchecked (startIndex)->getLeft(); + float lineStartX = glyphs.getReference (startIndex).getLeft(); if (line == numLines - 1) { @@ -470,7 +456,7 @@ void GlyphArrangement::addFittedText (const Font& f, { while (i < glyphs.size()) { - lineWidth = (glyphs.getUnchecked (i)->getRight() - lineStartX); + lineWidth = (glyphs.getReference (i).getRight() - lineStartX); if (lineWidth > widthPerLine) { @@ -480,10 +466,10 @@ void GlyphArrangement::addFittedText (const Font& f, while (i < glyphs.size()) { - if ((glyphs.getUnchecked (i)->getRight() - lineStartX) * minimumHorizontalScale < width) + if ((glyphs.getReference (i).getRight() - lineStartX) * minimumHorizontalScale < width) { - if (glyphs.getUnchecked (i)->isWhitespace() - || glyphs.getUnchecked (i)->getCharacter() == '-') + if (glyphs.getReference (i).isWhitespace() + || glyphs.getReference (i).getCharacter() == '-') { ++i; break; @@ -496,8 +482,8 @@ void GlyphArrangement::addFittedText (const Font& f, for (int back = 1; back < jmin (5, i - startIndex - 1); ++back) { - if (glyphs.getUnchecked (i - back)->isWhitespace() - || glyphs.getUnchecked (i - back)->getCharacter() == '-') + if (glyphs.getReference (i - back).isWhitespace() + || glyphs.getReference (i - back).getCharacter() == '-') { i -= back - 1; break; @@ -517,12 +503,12 @@ void GlyphArrangement::addFittedText (const Font& f, } int wsStart = i; - while (wsStart > 0 && glyphs.getUnchecked (wsStart - 1)->isWhitespace()) + while (wsStart > 0 && glyphs.getReference (wsStart - 1).isWhitespace()) --wsStart; int wsEnd = i; - while (wsEnd < glyphs.size() && glyphs.getUnchecked (wsEnd)->isWhitespace()) + while (wsEnd < glyphs.size() && glyphs.getReference (wsEnd).isWhitespace()) ++wsEnd; removeRangeOfGlyphs (wsStart, wsEnd - wsStart); @@ -548,8 +534,7 @@ void GlyphArrangement::addFittedText (const Font& f, } //============================================================================== -void GlyphArrangement::moveRangeOfGlyphs (int startIndex, int num, - const float dx, const float dy) +void GlyphArrangement::moveRangeOfGlyphs (int startIndex, int num, const float dx, const float dy) { jassert (startIndex >= 0); @@ -559,7 +544,7 @@ void GlyphArrangement::moveRangeOfGlyphs (int startIndex, int num, num = glyphs.size() - startIndex; while (--num >= 0) - glyphs.getUnchecked (startIndex++)->moveBy (dx, dy); + glyphs.getReference (startIndex++).moveBy (dx, dy); } } @@ -567,15 +552,15 @@ int GlyphArrangement::fitLineIntoSpace (int start, int numGlyphs, float x, float const Justification& justification, float minimumHorizontalScale) { int numDeleted = 0; - const float lineStartX = glyphs.getUnchecked (start)->getLeft(); - float lineWidth = glyphs.getUnchecked (start + numGlyphs - 1)->getRight() - lineStartX; + const float lineStartX = glyphs.getReference (start).getLeft(); + float lineWidth = glyphs.getReference (start + numGlyphs - 1).getRight() - lineStartX; if (lineWidth > w) { if (minimumHorizontalScale < 1.0f) { stretchRangeOfGlyphs (start, numGlyphs, jmax (minimumHorizontalScale, w / lineWidth)); - lineWidth = glyphs.getUnchecked (start + numGlyphs - 1)->getRight() - lineStartX - 0.5f; + lineWidth = glyphs.getReference (start + numGlyphs - 1).getRight() - lineStartX - 0.5f; } if (lineWidth > w) @@ -599,15 +584,15 @@ void GlyphArrangement::stretchRangeOfGlyphs (int startIndex, int num, if (num > 0) { - const float xAnchor = glyphs.getUnchecked (startIndex)->getLeft(); + const float xAnchor = glyphs.getReference (startIndex).getLeft(); while (--num >= 0) { - PositionedGlyph* const pg = glyphs.getUnchecked (startIndex++); + PositionedGlyph& pg = glyphs.getReference (startIndex++); - pg->x = xAnchor + (pg->x - xAnchor) * horizontalScaleFactor; - pg->font.setHorizontalScale (pg->font.getHorizontalScale() * horizontalScaleFactor); - pg->w *= horizontalScaleFactor; + pg.x = xAnchor + (pg.x - xAnchor) * horizontalScaleFactor; + pg.font.setHorizontalScale (pg.font.getHorizontalScale() * horizontalScaleFactor); + pg.w *= horizontalScaleFactor; } } } @@ -623,10 +608,10 @@ Rectangle GlyphArrangement::getBoundingBox (int startIndex, int num, cons while (--num >= 0) { - const PositionedGlyph* const pg = glyphs.getUnchecked (startIndex++); + const PositionedGlyph& pg = glyphs.getReference (startIndex++); - if (includeWhitespace || ! pg->isWhitespace()) - result = result.getUnion (pg->getBounds()); + if (includeWhitespace || ! pg.isWhitespace()) + result = result.getUnion (pg.getBounds()); } return result; @@ -667,12 +652,12 @@ void GlyphArrangement::justifyGlyphs (const int startIndex, const int num, if (justification.testFlags (Justification::horizontallyJustified)) { int lineStart = 0; - float baseY = glyphs.getUnchecked (startIndex)->getBaselineY(); + float baseY = glyphs.getReference (startIndex).getBaselineY(); int i; for (i = 0; i < num; ++i) { - const float glyphY = glyphs.getUnchecked (startIndex + i)->getBaselineY(); + const float glyphY = glyphs.getReference (startIndex + i).getBaselineY(); if (glyphY != baseY) { @@ -692,15 +677,15 @@ void GlyphArrangement::justifyGlyphs (const int startIndex, const int num, void GlyphArrangement::spreadOutLine (const int start, const int num, const float targetWidth) { if (start + num < glyphs.size() - && glyphs.getUnchecked (start + num - 1)->getCharacter() != '\r' - && glyphs.getUnchecked (start + num - 1)->getCharacter() != '\n') + && glyphs.getReference (start + num - 1).getCharacter() != '\r' + && glyphs.getReference (start + num - 1).getCharacter() != '\n') { int numSpaces = 0; int spacesAtEnd = 0; for (int i = 0; i < num; ++i) { - if (glyphs.getUnchecked (start + i)->isWhitespace()) + if (glyphs.getReference (start + i).isWhitespace()) { ++spacesAtEnd; ++numSpaces; @@ -715,8 +700,8 @@ void GlyphArrangement::spreadOutLine (const int start, const int num, const floa if (numSpaces > 0) { - const float startX = glyphs.getUnchecked (start)->getLeft(); - const float endX = glyphs.getUnchecked (start + num - 1 - spacesAtEnd)->getRight(); + const float startX = glyphs.getReference (start).getLeft(); + const float endX = glyphs.getReference (start + num - 1 - spacesAtEnd).getRight(); const float extraPaddingBetweenWords = (targetWidth - (endX - startX)) / (float) numSpaces; @@ -725,9 +710,9 @@ void GlyphArrangement::spreadOutLine (const int start, const int num, const floa for (int i = 0; i < num; ++i) { - glyphs.getUnchecked (start + i)->moveBy (deltaX, 0.0f); + glyphs.getReference (start + i).moveBy (deltaX, 0.0f); - if (glyphs.getUnchecked (start + i)->isWhitespace()) + if (glyphs.getReference (start + i).isWhitespace()) deltaX += extraPaddingBetweenWords; } } @@ -739,22 +724,22 @@ void GlyphArrangement::draw (const Graphics& g) const { for (int i = 0; i < glyphs.size(); ++i) { - const PositionedGlyph* const pg = glyphs.getUnchecked(i); + const PositionedGlyph& pg = glyphs.getReference(i); - if (pg->font.isUnderlined()) + if (pg.font.isUnderlined()) { - const float lineThickness = (pg->font.getDescent()) * 0.3f; + const float lineThickness = (pg.font.getDescent()) * 0.3f; - float nextX = pg->x + pg->w; + float nextX = pg.x + pg.w; - if (i < glyphs.size() - 1 && glyphs.getUnchecked (i + 1)->y == pg->y) - nextX = glyphs.getUnchecked (i + 1)->x; + if (i < glyphs.size() - 1 && glyphs.getReference (i + 1).y == pg.y) + nextX = glyphs.getReference (i + 1).x; - g.fillRect (pg->x, pg->y + lineThickness * 2.0f, - nextX - pg->x, lineThickness); + g.fillRect (pg.x, pg.y + lineThickness * 2.0f, + nextX - pg.x, lineThickness); } - pg->draw (g); + pg.draw (g); } } @@ -762,39 +747,37 @@ void GlyphArrangement::draw (const Graphics& g, const AffineTransform& transform { for (int i = 0; i < glyphs.size(); ++i) { - const PositionedGlyph* const pg = glyphs.getUnchecked(i); + const PositionedGlyph& pg = glyphs.getReference(i); - if (pg->font.isUnderlined()) + if (pg.font.isUnderlined()) { - const float lineThickness = (pg->font.getDescent()) * 0.3f; + const float lineThickness = (pg.font.getDescent()) * 0.3f; - float nextX = pg->x + pg->w; + float nextX = pg.x + pg.w; - if (i < glyphs.size() - 1 && glyphs.getUnchecked (i + 1)->y == pg->y) - nextX = glyphs.getUnchecked (i + 1)->x; + if (i < glyphs.size() - 1 && glyphs.getReference (i + 1).y == pg.y) + nextX = glyphs.getReference (i + 1).x; Path p; - p.addLineSegment (Line (pg->x, pg->y + lineThickness * 2.0f, - nextX, pg->y + lineThickness * 2.0f), - lineThickness); - + p.addLineSegment (Line (pg.x, pg.y + lineThickness * 2.0f, + nextX, pg.y + lineThickness * 2.0f), lineThickness); g.fillPath (p, transform); } - pg->draw (g, transform); + pg.draw (g, transform); } } void GlyphArrangement::createPath (Path& path) const { for (int i = 0; i < glyphs.size(); ++i) - glyphs.getUnchecked (i)->createPath (path); + glyphs.getReference (i).createPath (path); } -int GlyphArrangement::findGlyphIndexAt (float x, float y) const +int GlyphArrangement::findGlyphIndexAt (const float x, const float y) const { for (int i = 0; i < glyphs.size(); ++i) - if (glyphs.getUnchecked (i)->hitTest (x, y)) + if (glyphs.getReference (i).hitTest (x, y)) return i; return -1; diff --git a/modules/juce_graphics/fonts/juce_GlyphArrangement.h b/modules/juce_graphics/fonts/juce_GlyphArrangement.h index 23c90d064e..07198b6ae5 100644 --- a/modules/juce_graphics/fonts/juce_GlyphArrangement.h +++ b/modules/juce_graphics/fonts/juce_GlyphArrangement.h @@ -44,6 +44,7 @@ class JUCE_API PositionedGlyph { public: //============================================================================== + PositionedGlyph() noexcept; PositionedGlyph (const Font& font, juce_wchar character, int glyphNumber, float anchorX, float baselineY, float width, bool isWhitespace); @@ -140,7 +141,7 @@ public: careful not to pass an out-of-range index here, as it doesn't do any bounds-checking. */ - PositionedGlyph& getGlyph (int index) const; + PositionedGlyph& getGlyph (int index) const noexcept; //============================================================================== /** Clears all text from the arrangement and resets it. @@ -301,7 +302,7 @@ public: private: //============================================================================== - OwnedArray glyphs; + Array glyphs; int insertEllipsis (const Font&, float maxXPos, int startIndex, int endIndex); int fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font&, diff --git a/modules/juce_graphics/fonts/juce_TextLayout.cpp b/modules/juce_graphics/fonts/juce_TextLayout.cpp index d4c35bf779..7e1bc3fd84 100644 --- a/modules/juce_graphics/fonts/juce_TextLayout.cpp +++ b/modules/juce_graphics/fonts/juce_TextLayout.cpp @@ -197,9 +197,9 @@ void TextLayout::addLine (Line* line) void TextLayout::draw (Graphics& g, const Rectangle& area) const { - const Point origin (justification.appliedToRectangle (Rectangle (0, 0, width, getHeight()), area).getPosition()); + const Point origin (justification.appliedToRectangle (Rectangle (width, getHeight()), area).getPosition()); - LowLevelGraphicsContext& context = *g.getInternalContext(); + LowLevelGraphicsContext& context = g.getInternalContext(); for (int i = 0; i < getNumLines(); ++i) { diff --git a/modules/juce_graphics/native/juce_mac_Fonts.mm b/modules/juce_graphics/native/juce_mac_Fonts.mm index 146935fc66..82f262f244 100644 --- a/modules/juce_graphics/native/juce_mac_Fonts.mm +++ b/modules/juce_graphics/native/juce_mac_Fonts.mm @@ -1118,7 +1118,7 @@ struct DefaultFontNames #else : defaultSans ("Lucida Grande"), defaultSerif ("Times New Roman"), - defaultFixed ("Monaco"), + defaultFixed ("Menlo"), #endif defaultFallback ("Arial Unicode MS") { diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index 7e233a505e..a0926af14a 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -720,18 +720,18 @@ public: { Graphics imG (image); - LowLevelGraphicsContext* const lg = imG.getInternalContext(); + LowLevelGraphicsContext& lg = imG.getInternalContext(); for (RectangleList::Iterator i (validArea); i.next();) - lg->excludeClipRectangle (*i.getRectangle()); + lg.excludeClipRectangle (*i.getRectangle()); - if (! lg->isClipEmpty()) + if (! lg.isClipEmpty()) { if (! owner.isOpaque()) { - lg->setFill (Colours::transparentBlack); - lg->fillRect (bounds, true); - lg->setFill (Colours::black); + lg.setFill (Colours::transparentBlack); + lg.fillRect (bounds, true); + lg.setFill (Colours::black); } owner.paintEntireComponent (imG, true); @@ -1946,7 +1946,7 @@ void Component::paintEntireComponent (Graphics& g, const bool ignoreAlphaLevel) if (effect != nullptr) { - const float scale = g.getInternalContext()->getTargetDeviceScaleFactor(); + const float scale = g.getInternalContext().getTargetDeviceScaleFactor(); Image effectImage (flags.opaqueFlag ? Image::RGB : Image::ARGB, (int) (scale * getWidth()), (int) (scale * getHeight()), ! flags.opaqueFlag); diff --git a/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h b/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h index c1614dc45d..be55f410a9 100644 --- a/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h +++ b/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h @@ -89,9 +89,7 @@ public: virtual void setIndex (int newIndex); /** Returns the index of the item that should currently be shown. - - This is the index of the item in the choices StringArray that will be - shown. + This is the index of the item in the choices StringArray that will be shown. */ virtual int getIndex() const; @@ -102,8 +100,6 @@ public: //============================================================================== /** @internal */ void refresh(); - /** @internal */ - void comboBoxChanged (ComboBox*); protected: /** The list of options that will be shown in the combo box. @@ -120,6 +116,7 @@ private: class RemapperValueSource; void createComboBox(); + void comboBoxChanged (ComboBox*); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChoicePropertyComponent); }; diff --git a/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp b/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp index 59f72682a9..d34f95b62d 100644 --- a/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp +++ b/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp @@ -32,14 +32,14 @@ public: bool update (CodeDocument& document, int lineNum, CodeDocument::Iterator& source, - CodeTokeniser* analyser, const int spacesPerTab, + CodeTokeniser* tokeniser, const int spacesPerTab, const CodeDocument::Position& selectionStart, const CodeDocument::Position& selectionEnd) { Array newTokens; newTokens.ensureStorageAllocated (8); - if (analyser == nullptr) + if (tokeniser == nullptr) { newTokens.add (SyntaxToken (document.getLine (lineNum), -1)); } @@ -47,7 +47,7 @@ public: { const CodeDocument::Position pos (&document, lineNum, 0); createTokens (pos.getPosition(), pos.getLineText(), - source, analyser, newTokens); + source, *tokeniser, newTokens); } replaceTabsWithSpaces (newTokens, spacesPerTab); @@ -96,7 +96,7 @@ public: } void draw (CodeEditorComponent& owner, Graphics& g, const Font& font, - float x, const int y, const int baselineOffset, const int lineHeight, + float x, const float rightEdge, const int y, const int baselineOffset, const int lineHeight, const Colour& highlightColour) const { if (highlightColumnStart < highlightColumnEnd) @@ -106,19 +106,25 @@ public: roundToInt ((highlightColumnEnd - highlightColumnStart) * owner.getCharWidth()), lineHeight); } - int lastType = std::numeric_limits::min(); + const float baselineY = (float) (y + baselineOffset); + Colour lastColour (0x00000001); + GlyphArrangement ga; for (int i = 0; i < tokens.size(); ++i) { SyntaxToken& token = tokens.getReference(i); - if (lastType != token.tokenType) + const Colour newColour (owner.getColourForTokenType (token.tokenType)); + if (lastColour != newColour) { - lastType = token.tokenType; - g.setColour (owner.getColourForTokenType (lastType)); + ga.draw (g); + ga.clear(); + + lastColour = newColour; + g.setColour (newColour); } - g.drawSingleLineText (token.text, roundToInt (x), y + baselineOffset); + ga.addCurtailedLineOfText (font, token.text, x, baselineY, rightEdge - x, false); if (i < tokens.size() - 1) { @@ -126,8 +132,13 @@ public: token.width = font.getStringWidthFloat (token.text); x += token.width; + + if (x > rightEdge) + break; } } + + ga.draw (g); } private: @@ -153,7 +164,7 @@ private: static void createTokens (int startPosition, const String& lineText, CodeDocument::Iterator& source, - CodeTokeniser* analyser, + CodeTokeniser& tokeniser, Array & newTokens) { CodeDocument::Iterator lastIterator (source); @@ -161,7 +172,7 @@ private: for (;;) { - int tokenType = analyser->readNextToken (source); + int tokenType = tokeniser.readNextToken (source); int tokenStart = lastIterator.getPosition(); int tokenEnd = source.getPosition(); @@ -263,8 +274,8 @@ public: const int firstLineToDraw = jmax (0, clip.getY() / lineHeight); const int lastLineToDraw = jmin (editor.lines.size(), clip.getBottom() / lineHeight + 1); - const Font lineNumberFont (editor.getFont().withHeight (lineHeight * 0.8f)); - const float y = (lineHeight - lineNumberFont.getHeight()) / 2.0f + lineNumberFont.getAscent(); + const Font lineNumberFont (editor.getFont().withHeight (jmin (13.0f, lineHeight * 0.8f))); + const float y = lineHeight - editor.getFont().getDescent(); const float w = getWidth() - 2.0f; GlyphArrangement ga; @@ -439,12 +450,12 @@ void CodeEditorComponent::paint (Graphics& g) const Rectangle 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) (gutter - xOffset * charWidth); + const float rightEdge = (float) getWidth(); for (int i = firstLineToDraw; i < lastLineToDraw; ++i) - lines.getUnchecked(i)->draw (*this, g, font, - (float) (gutter - xOffset * charWidth), - lineHeight * i, baselineOffset, lineHeight, - highlightColour); + lines.getUnchecked(i)->draw (*this, g, font, x, rightEdge, lineHeight * i, + baselineOffset, lineHeight, highlightColour); } void CodeEditorComponent::setScrollbarThickness (const int thickness) @@ -488,10 +499,8 @@ void CodeEditorComponent::rebuildLineTokens() for (int i = 0; i < numNeeded; ++i) { - CodeEditorLine* const line = lines.getUnchecked(i); - - if (line->update (document, firstLineOnScreen + i, source, codeTokeniser, spacesPerTab, - selectionStart, selectionEnd)) + if (lines.getUnchecked(i)->update (document, firstLineOnScreen + i, source, codeTokeniser, + spacesPerTab, selectionStart, selectionEnd)) { minLineToRepaint = jmin (minLineToRepaint, i); maxLineToRepaint = jmax (maxLineToRepaint, i); @@ -1346,14 +1355,14 @@ void CodeEditorComponent::updateCachedIterators (int maxLineNum) { for (;;) { - CodeDocument::Iterator* const last = cachedIterators.getLast(); + CodeDocument::Iterator& last = *cachedIterators.getLast(); - if (last->getLine() >= maxLineNum) + if (last.getLine() >= maxLineNum) break; - CodeDocument::Iterator* t = new CodeDocument::Iterator (*last); + CodeDocument::Iterator* t = new CodeDocument::Iterator (last); cachedIterators.add (t); - const int targetLine = last->getLine() + linesBetweenCachedSources; + const int targetLine = last.getLine() + linesBetweenCachedSources; for (;;) { @@ -1375,10 +1384,10 @@ void CodeEditorComponent::getIteratorForPosition (int position, CodeDocument::It { for (int i = cachedIterators.size(); --i >= 0;) { - CodeDocument::Iterator* t = cachedIterators.getUnchecked (i); - if (t->getPosition() <= position) + const CodeDocument::Iterator& t = *cachedIterators.getUnchecked (i); + if (t.getPosition() <= position) { - source = *t; + source = t; break; } }