I modified my JUCE without touching the drawImage methods. What I did is basically adding a buffered Image (called bitmap3) to the FontGlyphAlphaMap class. Then I added an int parameter that specifies the gamma curve to use to Graphics::drawText() and this gamma curve is then given to the GlyphArrangement::draw() and subsequently PositionedGlyph::draw() methods. At the moment, my Graphics::drawText() even chooses itself the gamma curve to use, depending on the brightness of the used text colour.
I used 15 gamma curves. Here’s the main code of FontGlyphAlphaMap:
I know that this code will not work if more FontGlyphAlphaMap instances are used concurrently (because they will try to access bitmap3 concurrently).
[code]#include “…/…/…/…/juce_core/basics/juce_StandardHeader.h”
BEGIN_JUCE_NAMESPACE
#include “juce_GlyphArrangement.h”
#include “…/contexts/juce_LowLevelGraphicsSoftwareRenderer.h”
#include “…/imaging/juce_Image.h”
#include “…/…/…/application/juce_DeletedAtShutdown.h”
#define SHOULD_WRAP(x, wrapwidth) (((x) - 0.0001f) >= (wrapwidth))
//==============================================================================
// GAMMA CURVES implementation
#define GAMMARANGE 0.5
uint8 gammaCurves[NUMGAMMACURVES][256];
bool gammaCurvesHaveBeenGenerated=false;
Image* bitmap3=0;
class Bitmap3Gen
{
public:
Bitmap3Gen()
{
bitmap3=new Image(Image::SingleChannel,30,30,true);
}
~Bitmap3Gen()
{
deleteAndZero(bitmap3);
}
} Bitmap3Gen_;
void generateGammaCurvesIfNeeded()
{
if (gammaCurvesHaveBeenGenerated) return;
gammaCurvesHaveBeenGenerated=true;
for (int i=0; i<NUMGAMMACURVES; i++)
{
float gamma=float(i)/float(NUMGAMMACURVES-1);
gamma-=0.5f;
gamma*=2.0f;
gamma=powf(float(GAMMARANGE),gamma);
for (int j=0; j<256; j++)
{
float val=float(j)/255.0f;
val=powf(val,gamma);
val*=255.0f;
gammaCurves[i][j]=(uint8)val;
}
}
}
//==============================================================================
class FontGlyphAlphaMap
{
public:
//==============================================================================
bool draw (const Graphics& g, float x, const float y, const int gammaCurve) const throw()
{
int i,j;
if (bitmap1 == 0) return false;
// choose bitmap1 or bitmap2 as source, depending on font size and x position
x += xOrigin;
const float xFloor = floorf (x);
const int intX = (int) xFloor;
Image *source=((x - xFloor) >= 0.5f && bitmap2 != 0) ? bitmap2 : bitmap1;
if (bitmap2==0) return false;
int h=source->getHeight();
int w=source->getWidth();
// processing only needed for small fonts and if gammaCurve used
if (w>=30 || h>=30 || gammaCurve==NOGAMMACORRECTION)
{
g.drawImageAt (source, intX, (int) floorf (y + yOrigin), true);
return true;
}
// this is a small font (<30 pixels in width or height)
uint8 *gc=gammaCurves[gammaCurve];
int lineStride, pixelStride;
uint8 *p=source->lockPixelDataReadWrite(0,0,source->getWidth(),source->getHeight(),lineStride,pixelStride);
uint8 *p_=p;
int lineStride2, pixelStride2;
uint8 *p2=bitmap3->lockPixelDataReadWrite(0,0,bitmap3->getWidth(),bitmap3->getHeight(),lineStride2,pixelStride2);
uint8 *p2_=p2;
for (i=0; i<h; i++)
{
for (j=0; j<w; j++) p2[j]=gc[p[j]];
p+=lineStride;
p2+=lineStride2;
}
g.drawImageAt (bitmap3,
intX, (int) floorf (y + yOrigin), true);
// clear bitmap3 again
p2=p2_;
for (i=0; i<h; i++)
{
for (j=0; j<w; j++) p2[j]=0;
p2+=lineStride2;
}
source->releasePixelDataReadWrite(p_);
bitmap3->releasePixelDataReadWrite(p2_);
return true;
}
juce_UseDebuggingNewOperator[/code]