fix macOS build (following Projucer changes made in Windows, which removed /Applications/JUCE/modules from its headers). move JUCE headers under source control, so that Windows and macOS can both build against same version of JUCE. remove AUv3 target (I think it's an iOS thing, so it will never work with this macOS fluidsynth dylib).

This commit is contained in:
Alex Birch
2018-06-17 13:34:53 +01:00
parent a2be47c887
commit dff4d13a1d
1563 changed files with 601601 additions and 3466 deletions

View File

@ -0,0 +1,540 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
27th April 2017).
End User License Agreement: www.juce.com/juce-5-licence
Privacy Policy: www.juce.com/juce-5-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
// this will throw an assertion if you try to draw something that's not
// possible in postscript
#define WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS 0
//==============================================================================
#if JUCE_DEBUG && WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS
#define notPossibleInPostscriptAssert jassertfalse
#else
#define notPossibleInPostscriptAssert
#endif
//==============================================================================
LowLevelGraphicsPostScriptRenderer::LowLevelGraphicsPostScriptRenderer (OutputStream& resultingPostScript,
const String& documentTitle,
const int totalWidth_,
const int totalHeight_)
: out (resultingPostScript),
totalWidth (totalWidth_),
totalHeight (totalHeight_),
needToClip (true)
{
stateStack.add (new SavedState());
stateStack.getLast()->clip = Rectangle<int> (totalWidth_, totalHeight_);
const float scale = jmin ((520.0f / totalWidth_), (750.0f / totalHeight));
out << "%!PS-Adobe-3.0 EPSF-3.0"
"\n%%BoundingBox: 0 0 600 824"
"\n%%Pages: 0"
"\n%%Creator: ROLI Ltd. JUCE"
"\n%%Title: " << documentTitle <<
"\n%%CreationDate: none"
"\n%%LanguageLevel: 2"
"\n%%EndComments"
"\n%%BeginProlog"
"\n%%BeginResource: JRes"
"\n/bd {bind def} bind def"
"\n/c {setrgbcolor} bd"
"\n/m {moveto} bd"
"\n/l {lineto} bd"
"\n/rl {rlineto} bd"
"\n/ct {curveto} bd"
"\n/cp {closepath} bd"
"\n/pr {3 index 3 index moveto 1 index 0 rlineto 0 1 index rlineto pop neg 0 rlineto pop pop closepath} bd"
"\n/doclip {initclip newpath} bd"
"\n/endclip {clip newpath} bd"
"\n%%EndResource"
"\n%%EndProlog"
"\n%%BeginSetup"
"\n%%EndSetup"
"\n%%Page: 1 1"
"\n%%BeginPageSetup"
"\n%%EndPageSetup\n\n"
<< "40 800 translate\n"
<< scale << ' ' << scale << " scale\n\n";
}
LowLevelGraphicsPostScriptRenderer::~LowLevelGraphicsPostScriptRenderer()
{
}
//==============================================================================
bool LowLevelGraphicsPostScriptRenderer::isVectorDevice() const
{
return true;
}
void LowLevelGraphicsPostScriptRenderer::setOrigin (Point<int> o)
{
if (! o.isOrigin())
{
stateStack.getLast()->xOffset += o.x;
stateStack.getLast()->yOffset += o.y;
needToClip = true;
}
}
void LowLevelGraphicsPostScriptRenderer::addTransform (const AffineTransform& /*transform*/)
{
//xxx
jassertfalse;
}
float LowLevelGraphicsPostScriptRenderer::getPhysicalPixelScaleFactor() { return 1.0f; }
bool LowLevelGraphicsPostScriptRenderer::clipToRectangle (const Rectangle<int>& r)
{
needToClip = true;
return stateStack.getLast()->clip.clipTo (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset));
}
bool LowLevelGraphicsPostScriptRenderer::clipToRectangleList (const RectangleList<int>& clipRegion)
{
needToClip = true;
return stateStack.getLast()->clip.clipTo (clipRegion);
}
void LowLevelGraphicsPostScriptRenderer::excludeClipRectangle (const Rectangle<int>& r)
{
needToClip = true;
stateStack.getLast()->clip.subtract (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset));
}
void LowLevelGraphicsPostScriptRenderer::clipToPath (const Path& path, const AffineTransform& transform)
{
writeClip();
Path p (path);
p.applyTransform (transform.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset));
writePath (p);
out << "clip\n";
}
void LowLevelGraphicsPostScriptRenderer::clipToImageAlpha (const Image& /*sourceImage*/, const AffineTransform& /*transform*/)
{
needToClip = true;
jassertfalse; // xxx
}
bool LowLevelGraphicsPostScriptRenderer::clipRegionIntersects (const Rectangle<int>& r)
{
return stateStack.getLast()->clip.intersectsRectangle (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset));
}
Rectangle<int> LowLevelGraphicsPostScriptRenderer::getClipBounds() const
{
return stateStack.getLast()->clip.getBounds().translated (-stateStack.getLast()->xOffset,
-stateStack.getLast()->yOffset);
}
bool LowLevelGraphicsPostScriptRenderer::isClipEmpty() const
{
return stateStack.getLast()->clip.isEmpty();
}
//==============================================================================
LowLevelGraphicsPostScriptRenderer::SavedState::SavedState()
: xOffset (0),
yOffset (0)
{
}
LowLevelGraphicsPostScriptRenderer::SavedState::~SavedState()
{
}
void LowLevelGraphicsPostScriptRenderer::saveState()
{
stateStack.add (new SavedState (*stateStack.getLast()));
}
void LowLevelGraphicsPostScriptRenderer::restoreState()
{
jassert (stateStack.size() > 0);
if (stateStack.size() > 0)
stateStack.removeLast();
}
void LowLevelGraphicsPostScriptRenderer::beginTransparencyLayer (float)
{
}
void LowLevelGraphicsPostScriptRenderer::endTransparencyLayer()
{
}
//==============================================================================
void LowLevelGraphicsPostScriptRenderer::writeClip()
{
if (needToClip)
{
needToClip = false;
out << "doclip ";
int itemsOnLine = 0;
for (auto& i : stateStack.getLast()->clip)
{
if (++itemsOnLine == 6)
{
itemsOnLine = 0;
out << '\n';
}
out << i.getX() << ' ' << -i.getY() << ' '
<< i.getWidth() << ' ' << -i.getHeight() << " pr ";
}
out << "endclip\n";
}
}
void LowLevelGraphicsPostScriptRenderer::writeColour (Colour colour)
{
Colour c (Colours::white.overlaidWith (colour));
if (lastColour != c)
{
lastColour = c;
out << String (c.getFloatRed(), 3) << ' '
<< String (c.getFloatGreen(), 3) << ' '
<< String (c.getFloatBlue(), 3) << " c\n";
}
}
void LowLevelGraphicsPostScriptRenderer::writeXY (const float x, const float y) const
{
out << String (x, 2) << ' '
<< String (-y, 2) << ' ';
}
void LowLevelGraphicsPostScriptRenderer::writePath (const Path& path) const
{
out << "newpath ";
float lastX = 0.0f;
float lastY = 0.0f;
int itemsOnLine = 0;
Path::Iterator i (path);
while (i.next())
{
if (++itemsOnLine == 4)
{
itemsOnLine = 0;
out << '\n';
}
switch (i.elementType)
{
case Path::Iterator::startNewSubPath:
writeXY (i.x1, i.y1);
lastX = i.x1;
lastY = i.y1;
out << "m ";
break;
case Path::Iterator::lineTo:
writeXY (i.x1, i.y1);
lastX = i.x1;
lastY = i.y1;
out << "l ";
break;
case Path::Iterator::quadraticTo:
{
const float cp1x = lastX + (i.x1 - lastX) * 2.0f / 3.0f;
const float cp1y = lastY + (i.y1 - lastY) * 2.0f / 3.0f;
const float cp2x = cp1x + (i.x2 - lastX) / 3.0f;
const float cp2y = cp1y + (i.y2 - lastY) / 3.0f;
writeXY (cp1x, cp1y);
writeXY (cp2x, cp2y);
writeXY (i.x2, i.y2);
out << "ct ";
lastX = i.x2;
lastY = i.y2;
}
break;
case Path::Iterator::cubicTo:
writeXY (i.x1, i.y1);
writeXY (i.x2, i.y2);
writeXY (i.x3, i.y3);
out << "ct ";
lastX = i.x3;
lastY = i.y3;
break;
case Path::Iterator::closePath:
out << "cp ";
break;
default:
jassertfalse;
break;
}
}
out << '\n';
}
void LowLevelGraphicsPostScriptRenderer::writeTransform (const AffineTransform& trans) const
{
out << "[ "
<< trans.mat00 << ' '
<< trans.mat10 << ' '
<< trans.mat01 << ' '
<< trans.mat11 << ' '
<< trans.mat02 << ' '
<< trans.mat12 << " ] concat ";
}
//==============================================================================
void LowLevelGraphicsPostScriptRenderer::setFill (const FillType& fillType)
{
stateStack.getLast()->fillType = fillType;
}
void LowLevelGraphicsPostScriptRenderer::setOpacity (float /*opacity*/)
{
}
void LowLevelGraphicsPostScriptRenderer::setInterpolationQuality (Graphics::ResamplingQuality /*quality*/)
{
}
//==============================================================================
void LowLevelGraphicsPostScriptRenderer::fillRect (const Rectangle<int>& r, const bool /*replaceExistingContents*/)
{
fillRect (r.toFloat());
}
void LowLevelGraphicsPostScriptRenderer::fillRect (const Rectangle<float>& r)
{
if (stateStack.getLast()->fillType.isColour())
{
writeClip();
writeColour (stateStack.getLast()->fillType.colour);
Rectangle<float> r2 (r.translated ((float) stateStack.getLast()->xOffset,
(float) stateStack.getLast()->yOffset));
out << r2.getX() << ' ' << -r2.getBottom() << ' ' << r2.getWidth() << ' ' << r2.getHeight() << " rectfill\n";
}
else
{
Path p;
p.addRectangle (r);
fillPath (p, AffineTransform());
}
}
void LowLevelGraphicsPostScriptRenderer::fillRectList (const RectangleList<float>& list)
{
fillPath (list.toPath(), AffineTransform());
}
//==============================================================================
void LowLevelGraphicsPostScriptRenderer::fillPath (const Path& path, const AffineTransform& t)
{
if (stateStack.getLast()->fillType.isColour())
{
writeClip();
Path p (path);
p.applyTransform (t.translated ((float) stateStack.getLast()->xOffset,
(float) stateStack.getLast()->yOffset));
writePath (p);
writeColour (stateStack.getLast()->fillType.colour);
out << "fill\n";
}
else if (stateStack.getLast()->fillType.isGradient())
{
// this doesn't work correctly yet - it could be improved to handle solid gradients, but
// postscript can't do semi-transparent ones.
notPossibleInPostscriptAssert; // you can disable this warning by setting the WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS flag at the top of this file
writeClip();
out << "gsave ";
{
Path p (path);
p.applyTransform (t.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset));
writePath (p);
out << "clip\n";
}
const Rectangle<int> bounds (stateStack.getLast()->clip.getBounds());
// ideally this would draw lots of lines or ellipses to approximate the gradient, but for the
// time-being, this just fills it with the average colour..
writeColour (stateStack.getLast()->fillType.gradient->getColourAtPosition (0.5f));
out << bounds.getX() << ' ' << -bounds.getBottom() << ' ' << bounds.getWidth() << ' ' << bounds.getHeight() << " rectfill\n";
out << "grestore\n";
}
}
//==============================================================================
void LowLevelGraphicsPostScriptRenderer::writeImage (const Image& im,
const int sx, const int sy,
const int maxW, const int maxH) const
{
out << "{<\n";
const int w = jmin (maxW, im.getWidth());
const int h = jmin (maxH, im.getHeight());
int charsOnLine = 0;
const Image::BitmapData srcData (im, 0, 0, w, h);
Colour pixel;
for (int y = h; --y >= 0;)
{
for (int x = 0; x < w; ++x)
{
const uint8* pixelData = srcData.getPixelPointer (x, y);
if (x >= sx && y >= sy)
{
if (im.isARGB())
{
PixelARGB p (*(const PixelARGB*) pixelData);
p.unpremultiply();
pixel = Colours::white.overlaidWith (Colour (p));
}
else if (im.isRGB())
{
pixel = Colour (*((const PixelRGB*) pixelData));
}
else
{
pixel = Colour ((uint8) 0, (uint8) 0, (uint8) 0, *pixelData);
}
}
else
{
pixel = Colours::transparentWhite;
}
const uint8 pixelValues[3] = { pixel.getRed(), pixel.getGreen(), pixel.getBlue() };
out << String::toHexString (pixelValues, 3, 0);
charsOnLine += 3;
if (charsOnLine > 100)
{
out << '\n';
charsOnLine = 0;
}
}
}
out << "\n>}\n";
}
void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, const AffineTransform& transform)
{
const int w = sourceImage.getWidth();
const int h = sourceImage.getHeight();
writeClip();
out << "gsave ";
writeTransform (transform.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset)
.scaled (1.0f, -1.0f));
RectangleList<int> imageClip;
sourceImage.createSolidAreaMask (imageClip, 0.5f);
out << "newpath ";
int itemsOnLine = 0;
for (auto& i : imageClip)
{
if (++itemsOnLine == 6)
{
out << '\n';
itemsOnLine = 0;
}
out << i.getX() << ' ' << i.getY() << ' ' << i.getWidth() << ' ' << i.getHeight() << " pr ";
}
out << " clip newpath\n";
out << w << ' ' << h << " scale\n";
out << w << ' ' << h << " 8 [" << w << " 0 0 -" << h << ' ' << (int) 0 << ' ' << h << " ]\n";
writeImage (sourceImage, 0, 0, w, h);
out << "false 3 colorimage grestore\n";
needToClip = true;
}
//==============================================================================
void LowLevelGraphicsPostScriptRenderer::drawLine (const Line <float>& line)
{
Path p;
p.addLineSegment (line, 1.0f);
fillPath (p, AffineTransform());
}
//==============================================================================
void LowLevelGraphicsPostScriptRenderer::setFont (const Font& newFont)
{
stateStack.getLast()->font = newFont;
}
const Font& LowLevelGraphicsPostScriptRenderer::getFont()
{
return stateStack.getLast()->font;
}
void LowLevelGraphicsPostScriptRenderer::drawGlyph (int glyphNumber, const AffineTransform& transform)
{
Path p;
Font& font = stateStack.getLast()->font;
font.getTypeface()->getOutlineForGlyph (glyphNumber, p);
fillPath (p, AffineTransform::scale (font.getHeight() * font.getHorizontalScale(), font.getHeight()).followedBy (transform));
}
} // namespace juce