mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Minor internal refactoring and clean-ups.
This commit is contained in:
parent
1f2c81980f
commit
b1d73f2086
12 changed files with 244 additions and 256 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<int>& 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<int>& rectangleToExclude)
|
||||
{
|
||||
saveStateIfPending();
|
||||
context->excludeClipRectangle (rectangleToExclude);
|
||||
context.excludeClipRectangle (rectangleToExclude);
|
||||
}
|
||||
|
||||
bool Graphics::isClipEmpty() const
|
||||
{
|
||||
return context->isClipEmpty();
|
||||
return context.isClipEmpty();
|
||||
}
|
||||
|
||||
Rectangle<int> 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<int>& 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<int> (x, y, width, height)))
|
||||
if (text.isNotEmpty() && context.clipRegionIntersects (Rectangle<int> (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<int> (x, y, width, height)))
|
||||
&& context.clipRegionIntersects (Rectangle<int> (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<int> (x, y, width, height), false);
|
||||
context.fillRect (Rectangle<int> (x, y, width, height), false);
|
||||
}
|
||||
|
||||
void Graphics::fillRect (const Rectangle<int>& 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<int> (x, y, 1, 1), false);
|
||||
context.fillRect (Rectangle<int> (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<int> clip (context->getClipBounds());
|
||||
const Rectangle<int> 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<int> (x, y, width, lineThickness), false);
|
||||
context->fillRect (Rectangle<int> (x, y + lineThickness, lineThickness, height - lineThickness * 2), false);
|
||||
context->fillRect (Rectangle<int> (x + width - lineThickness, y + lineThickness, lineThickness, height - lineThickness * 2), false);
|
||||
context->fillRect (Rectangle<int> (x, y + height - lineThickness, width, lineThickness), false);
|
||||
context.fillRect (Rectangle<int> (x, y, width, lineThickness), false);
|
||||
context.fillRect (Rectangle<int> (x, y + lineThickness, lineThickness, height - lineThickness * 2), false);
|
||||
context.fillRect (Rectangle<int> (x + width - lineThickness, y + lineThickness, lineThickness, height - lineThickness * 2), false);
|
||||
context.fillRect (Rectangle<int> (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<int> (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<int> (x + i, y + i, width - i * 2, 1), false);
|
||||
context->setFill (topLeftColour.withMultipliedAlpha (op * 0.75f));
|
||||
context->fillRect (Rectangle<int> (x + i, y + i + 1, 1, height - i * 2 - 2), false);
|
||||
context->setFill (bottomRightColour.withMultipliedAlpha (op));
|
||||
context->fillRect (Rectangle<int> (x + i, y + height - i - 1, width - i * 2, 1), false);
|
||||
context->setFill (bottomRightColour.withMultipliedAlpha (op * 0.75f));
|
||||
context->fillRect (Rectangle<int> (x + width - i - 1, y + i + 1, 1, height - i * 2 - 2), false);
|
||||
context.setFill (topLeftColour.withMultipliedAlpha (op));
|
||||
context.fillRect (Rectangle<int> (x + i, y + i, width - i * 2, 1), false);
|
||||
context.setFill (topLeftColour.withMultipliedAlpha (op * 0.75f));
|
||||
context.fillRect (Rectangle<int> (x + i, y + i + 1, 1, height - i * 2 - 2), false);
|
||||
context.setFill (bottomRightColour.withMultipliedAlpha (op));
|
||||
context.fillRect (Rectangle<int> (x + i, y + height - i - 1, width - i * 2, 1), false);
|
||||
context.setFill (bottomRightColour.withMultipliedAlpha (op * 0.75f));
|
||||
context.fillRect (Rectangle<int> (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<int>& 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<int> clipped (context->getClipBounds().getIntersection (area));
|
||||
const Rectangle<int> 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<int>& 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<int> (x, y, checkWidth, checkHeight), false);
|
||||
context.fillRect (Rectangle<int> (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<float> (x1, y1, x2, y2));
|
||||
context.drawLine (Line<float> (x1, y1, x2, y2));
|
||||
}
|
||||
|
||||
void Graphics::drawLine (const Line<float>& 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<float>& 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<float>& 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<int> (dx, dy, dw, dh)))
|
||||
if (imageToDraw.isValid() && context.clipRegionIntersects (Rectangle<int> (dx, dy, dw, dh)))
|
||||
{
|
||||
drawImageTransformed (imageToDraw.getClippedImage (Rectangle<int> (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <LowLevelGraphicsContext> contextToDelete;
|
||||
|
||||
bool saveStatePending;
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ void AttributedString::draw (Graphics& g, const Rectangle<float>& 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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<float> 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<float> (pg->x, pg->y + lineThickness * 2.0f,
|
||||
nextX, pg->y + lineThickness * 2.0f),
|
||||
lineThickness);
|
||||
|
||||
p.addLineSegment (Line<float> (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;
|
||||
|
|
|
|||
|
|
@ -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 <PositionedGlyph> glyphs;
|
||||
Array <PositionedGlyph> 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&,
|
||||
|
|
|
|||
|
|
@ -197,9 +197,9 @@ void TextLayout::addLine (Line* line)
|
|||
|
||||
void TextLayout::draw (Graphics& g, const Rectangle<float>& area) const
|
||||
{
|
||||
const Point<float> origin (justification.appliedToRectangle (Rectangle<float> (0, 0, width, getHeight()), area).getPosition());
|
||||
const Point<float> origin (justification.appliedToRectangle (Rectangle<float> (width, getHeight()), area).getPosition());
|
||||
|
||||
LowLevelGraphicsContext& context = *g.getInternalContext();
|
||||
LowLevelGraphicsContext& context = g.getInternalContext();
|
||||
|
||||
for (int i = 0; i < getNumLines(); ++i)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1118,7 +1118,7 @@ struct DefaultFontNames
|
|||
#else
|
||||
: defaultSans ("Lucida Grande"),
|
||||
defaultSerif ("Times New Roman"),
|
||||
defaultFixed ("Monaco"),
|
||||
defaultFixed ("Menlo"),
|
||||
#endif
|
||||
defaultFallback ("Arial Unicode MS")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 <SyntaxToken> 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<int>::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 <SyntaxToken>& 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<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) (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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue