Browse Source

Tweaks to some Direct2D code.

tags/2021-05-28
jules 13 years ago
parent
commit
38aee86ed1
3 changed files with 57 additions and 110 deletions
  1. +3
    -3
      modules/juce_graphics/juce_graphics.cpp
  2. +43
    -100
      modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp
  3. +11
    -7
      modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp

+ 3
- 3
modules/juce_graphics/juce_graphics.cpp View File

@@ -114,12 +114,12 @@ namespace juce
#elif JUCE_WINDOWS
#include "../juce_core/native/juce_win32_ComSmartPtr.h"
#if JUCE_DIRECT2D
#include "native/juce_win32_Direct2DGraphicsContext.cpp"
#endif
#include "native/juce_win32_DirectWriteTypeface.cpp"
#include "native/juce_win32_DirectWriteTypeLayout.cpp"
#include "native/juce_win32_Fonts.cpp"
#if JUCE_DIRECT2D
#include "native/juce_win32_Direct2DGraphicsContext.cpp"
#endif
#elif JUCE_LINUX
#include "native/juce_linux_Fonts.cpp"


+ 43
- 100
modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp View File

@@ -23,36 +23,6 @@
==============================================================================
*/
class SharedD2DFactory : public DeletedAtShutdown
{
public:
SharedD2DFactory()
{
jassertfalse; //xxx Direct2D support isn't ready for use yet!
D2D1CreateFactory (D2D1_FACTORY_TYPE_SINGLE_THREADED, d2dFactory.resetAndGetPointerAddress());
DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), (IUnknown**) directWriteFactory.resetAndGetPointerAddress());
if (directWriteFactory != nullptr)
directWriteFactory->GetSystemFontCollection (systemFonts.resetAndGetPointerAddress());
}
~SharedD2DFactory()
{
clearSingletonInstance();
}
juce_DeclareSingleton (SharedD2DFactory, false);
ComSmartPtr <ID2D1Factory> d2dFactory;
ComSmartPtr <IDWriteFactory> directWriteFactory;
ComSmartPtr <IDWriteFontCollection> systemFonts;
};
juce_ImplementSingleton (SharedD2DFactory)
//==============================================================================
class Direct2DLowLevelGraphicsContext : public LowLevelGraphicsContext
{
public:
@@ -68,10 +38,13 @@ public:
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties();
D2D1_HWND_RENDER_TARGET_PROPERTIES propsHwnd = D2D1::HwndRenderTargetProperties (hwnd, size);
HRESULT hr = SharedD2DFactory::getInstance()->d2dFactory->CreateHwndRenderTarget (props, propsHwnd, renderingTarget.resetAndGetPointerAddress());
// xxx check for error
hr = renderingTarget->CreateSolidColorBrush (D2D1::ColorF::ColorF (0.0f, 0.0f, 0.0f, 1.0f), colourBrush.resetAndGetPointerAddress());
const Direct2DFactories& factories = Direct2DFactories::getInstance();
if (factories.d2dFactory != nullptr)
{
HRESULT hr = factories.d2dFactory->CreateHwndRenderTarget (props, propsHwnd, renderingTarget.resetAndGetPointerAddress());
jassert (SUCCEEDED (hr)); (void) hr;
hr = renderingTarget->CreateSolidColorBrush (D2D1::ColorF::ColorF (0.0f, 0.0f, 0.0f, 1.0f), colourBrush.resetAndGetPointerAddress());
}
}
~Direct2DLowLevelGraphicsContext()
@@ -115,7 +88,7 @@ public:
currentState->origin.addXY (x, y);
}
void addTransform (const AffineTransform& transform)
void addTransform (const AffineTransform& /*transform*/)
{
//xxx todo
jassertfalse;
@@ -123,7 +96,7 @@ public:
float getScaleFactor()
{
jassertfalse; //xxx
//xxx
return 1.0f;
}
@@ -184,7 +157,7 @@ public:
currentState = states.getLast();
}
void beginTransparencyLayer (float opacity)
void beginTransparencyLayer (float /*opacity*/)
{
jassertfalse; //xxx todo
}
@@ -208,7 +181,7 @@ public:
{
}
void fillRect (const Rectangle<int>& r, bool replaceExistingContents)
void fillRect (const Rectangle<int>& r, bool /*replaceExistingContents*/)
{
currentState->createBrush();
renderingTarget->FillRectangle (rectangleToRectF (r + currentState->origin), currentState->currentBrush);
@@ -228,7 +201,7 @@ public:
const int x = currentState->origin.getX();
const int y = currentState->origin.getY();
renderingTarget->SetTransform (transformToMatrix (transform) * D2D1::Matrix3x2F::Translation (x, y));
renderingTarget->SetTransform (transformToMatrix (transform) * D2D1::Matrix3x2F::Translation ((FLOAT) x, (FLOAT) y));
D2D1_SIZE_U size;
size.width = image.getWidth();
@@ -272,8 +245,8 @@ public:
x += currentState->origin.getX();
const int y = currentState->origin.getY();
renderingTarget->DrawLine (D2D1::Point2F (x, y + top),
D2D1::Point2F (x, y + bottom),
renderingTarget->DrawLine (D2D1::Point2F ((FLOAT) x, y + top),
D2D1::Point2F ((FLOAT) x, y + bottom),
currentState->currentBrush);
}
@@ -285,8 +258,8 @@ public:
y += currentState->origin.getY();
const int x = currentState->origin.getX();
renderingTarget->DrawLine (D2D1::Point2F (x + left, y),
D2D1::Point2F (x + right, y),
renderingTarget->DrawLine (D2D1::Point2F (x + left, (FLOAT) y),
D2D1::Point2F (x + right, (FLOAT) y),
currentState->currentBrush);
}
@@ -302,39 +275,33 @@ public:
void drawGlyph (int glyphNumber, const AffineTransform& transform)
{
const float x = currentState->origin.getX();
const float y = currentState->origin.getY();
const float x = (float) currentState->origin.getX();
const float y = (float) currentState->origin.getY();
currentState->createBrush();
currentState->createFont();
float kerning = currentState->font.getExtraKerningFactor(); // xxx why does removing this line mess up the kerning??
float hScale = currentState->font.getHorizontalScale();
renderingTarget->SetTransform (D2D1::Matrix3x2F::Scale (hScale, 1) * transformToMatrix (transform) * D2D1::Matrix3x2F::Translation (x, y));
float dpiX = 0, dpiY = 0;
SharedD2DFactory::getInstance()->d2dFactory->GetDesktopDpi (&dpiX, &dpiY);
UINT32 glyphNum = glyphNumber;
UINT16 glyphNum1 = 0; // xxx needs a better name - what is this for?
currentState->currentFontFace->GetGlyphIndices (&glyphNum, 1, &glyphNum1);
const UINT16 glyphIndices = (UINT16) glyphNumber;
const FLOAT glyphAdvances = 0;
DWRITE_GLYPH_OFFSET offset;
offset.advanceOffset = 0;
offset.ascenderOffset = 0;
float glyphAdvances = 0;
DWRITE_GLYPH_RUN glyph;
glyph.fontFace = currentState->currentFontFace;
glyph.glyphCount = 1;
glyph.glyphIndices = &glyphNum1;
glyph.isSideways = FALSE;
glyph.glyphAdvances = &glyphAdvances;
glyph.glyphOffsets = &offset;
glyph.fontEmSize = (float) currentState->font.getHeight() * dpiX / 96.0f * (1 + currentState->fontScaling) / 2;
renderingTarget->DrawGlyphRun (D2D1::Point2F (0, 0), &glyph, currentState->currentBrush);
DWRITE_GLYPH_RUN glyphRun;
glyphRun.fontFace = currentState->currentFontFace;
glyphRun.fontEmSize = (FLOAT) (currentState->font.getHeight() * currentState->fontHeightToEmSizeFactor);
glyphRun.glyphCount = 1;
glyphRun.glyphIndices = &glyphIndices;
glyphRun.glyphAdvances = &glyphAdvances;
glyphRun.glyphOffsets = &offset;
glyphRun.isSideways = FALSE;
glyphRun.bidiLevel = 0;
renderingTarget->DrawGlyphRun (D2D1::Point2F (0, 0), &glyphRun, currentState->currentBrush);
renderingTarget->SetTransform (D2D1::IdentityMatrix());
}
@@ -344,7 +311,7 @@ public:
public:
SavedState (Direct2DLowLevelGraphicsContext& owner_)
: owner (owner_), currentBrush (0),
fontScaling (1.0f), currentFontFace (0),
fontHeightToEmSizeFactor (1.0f), currentFontFace (0),
clipsRect (false), shouldClipRect (false),
clipsRectList (false), shouldClipRectList (false),
clipsComplex (false), shouldClipComplex (false),
@@ -572,35 +539,11 @@ public:
void createFont()
{
// xxx The font shouldn't be managed by the graphics context.
// The correct way to handle font lifetimes is to use a subclass of Typeface - see
// OSXTypeface and WindowsTypeface classes. D2D support could probably just be added to the
// WindowsTypeface class.
if (currentFontFace == 0)
if (currentFontFace == nullptr)
{
WindowsTypeface* systemType = dynamic_cast<WindowsTypeface*> (font.getTypeface());
fontScaling = systemType->getAscent();
BOOL fontFound;
uint32 fontIndex;
IDWriteFontCollection* fonts = SharedD2DFactory::getInstance()->systemFonts;
fonts->FindFamilyName (systemType->getName(), &fontIndex, &fontFound);
if (! fontFound)
fontIndex = 0;
ComSmartPtr <IDWriteFontFamily> fontFam;
fonts->GetFontFamily (fontIndex, fontFam.resetAndGetPointerAddress());
ComSmartPtr <IDWriteFont> font;
DWRITE_FONT_WEIGHT weight = this->font.isBold() ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_NORMAL;
DWRITE_FONT_STYLE style = this->font.isItalic() ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
fontFam->GetFirstMatchingFont (weight, DWRITE_FONT_STRETCH_NORMAL, style, font.resetAndGetPointerAddress());
font->CreateFontFace (localFontFace.resetAndGetPointerAddress());
currentFontFace = localFontFace;
WindowsDirectWriteTypeface* typeface = dynamic_cast<WindowsDirectWriteTypeface*> (font.getTypeface());
currentFontFace = typeface->getIDWriteFontFace();
fontHeightToEmSizeFactor = typeface->getFontHeightToEmSizeFactor();
}
}
@@ -676,7 +619,7 @@ public:
for (int i = fillType.gradient->getNumColours(); --i >= 0;)
{
stops[i].color = colourToD2D (fillType.gradient->getColour(i));
stops[i].position = fillType.gradient->getColourPosition(i);
stops[i].position = (FLOAT) fillType.gradient->getColourPosition(i);
}
owner.renderingTarget->CreateGradientStopCollection (stops.getData(), numColors, gradientStops.resetAndGetPointerAddress());
@@ -724,7 +667,7 @@ public:
Point<int> origin;
Font font;
float fontScaling;
float fontHeightToEmSizeFactor;
IDWriteFontFace* currentFontFace;
ComSmartPtr <IDWriteFontFace> localFontFace;
@@ -787,7 +730,7 @@ private:
static const D2D1_POINT_2F pointTransformed (int x, int y, const AffineTransform& transform = AffineTransform::identity)
{
transform.transformPoint (x, y);
return D2D1::Point2F (x, y);
return D2D1::Point2F ((FLOAT) x, (FLOAT) y);
}
static void rectToGeometrySink (const Rectangle<int>& rect, ID2D1GeometrySink* sink)
@@ -802,7 +745,7 @@ private:
static ID2D1PathGeometry* rectListToPathGeometry (const RectangleList& clipRegion)
{
ID2D1PathGeometry* p = nullptr;
SharedD2DFactory::getInstance()->d2dFactory->CreatePathGeometry (&p);
Direct2DFactories::getInstance().d2dFactory->CreatePathGeometry (&p);
ComSmartPtr <ID2D1GeometrySink> sink;
HRESULT hr = p->Open (sink.resetAndGetPointerAddress()); // xxx handle error
@@ -880,7 +823,7 @@ private:
static ID2D1PathGeometry* pathToPathGeometry (const Path& path, const AffineTransform& transform, const Point<int>& point)
{
ID2D1PathGeometry* p = nullptr;
SharedD2DFactory::getInstance()->d2dFactory->CreatePathGeometry (&p);
Direct2DFactories::getInstance().d2dFactory->CreatePathGeometry (&p);
ComSmartPtr <ID2D1GeometrySink> sink;
HRESULT hr = p->Open (sink.resetAndGetPointerAddress());
@@ -905,4 +848,4 @@ private:
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Direct2DLowLevelGraphicsContext);
};
};

+ 11
- 7
modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp View File

@@ -166,18 +166,19 @@ public:
DWRITE_FONT_METRICS dwFontMetrics;
dwFontFace->GetMetrics (&dwFontMetrics);
// All Font Metrics are in design units so we need to get designUnitsPerEm value to get the metrics
// into Em/Design Independent Pixels
// All Font Metrics are in design units so we need to get designUnitsPerEm value
// to get the metrics into Em/Design Independent Pixels
designUnitsPerEm = dwFontMetrics.designUnitsPerEm;
ascent = std::abs ((float) dwFontMetrics.ascent);
const float totalSize = ascent + std::abs ((float) dwFontMetrics.descent);
ascent /= totalSize;
unitsToHeightScaleFactor = 1.0f / (totalSize / designUnitsPerEm);
const float pathAscent = (((float) dwFontMetrics.ascent) / ((float) designUnitsPerEm)) * 1024.0f;
const float pathDescent = (((float) dwFontMetrics.descent) / ((float) designUnitsPerEm)) * 1024.0f;
const float pathTotalSize = std::abs (pathAscent) + std::abs (pathDescent);
pathTransform = AffineTransform::identity.scale (1.0f / pathTotalSize, 1.0f / pathTotalSize);
unitsToHeightScaleFactor = designUnitsPerEm / totalSize;
const float pathAscent = (1024.0f * dwFontMetrics.ascent) / designUnitsPerEm;
const float pathDescent = (1024.0f * dwFontMetrics.descent) / designUnitsPerEm;
const float pathScale = 1.0f / (std::abs (pathAscent) + std::abs (pathDescent));
pathTransform = AffineTransform::scale (pathScale, pathScale);
}
float getAscent() const { return ascent; }
@@ -248,6 +249,9 @@ public:
return true;
}
IDWriteFontFace* getIDWriteFontFace() const noexcept { return dwFontFace; }
float getFontHeightToEmSizeFactor() const noexcept { return unitsToHeightScaleFactor; }
private:
ComSmartPtr<IDWriteFontFace> dwFontFace;
float unitsToHeightScaleFactor, ascent;


Loading…
Cancel
Save