More text attributes on Windows, including the beginning of drawing effects for colors and underlines.
This commit is contained in:
parent
fb04feaebb
commit
b42250e3a9
|
@ -2,19 +2,42 @@
|
||||||
#include "uipriv_windows.hpp"
|
#include "uipriv_windows.hpp"
|
||||||
#include "draw.hpp"
|
#include "draw.hpp"
|
||||||
|
|
||||||
// we need to collect all the OpenType features and background blocks and add them all at once
|
// we need to combine color and underline style into one unit for IDWriteLayout::SetDrawingEffect()
|
||||||
|
// we also need to collect all the OpenType features and background blocks and add them all at once
|
||||||
// TODO(TODO does not seem to apply here) this is the wrong approach; it causes Pango to end runs early, meaning attributes like the ligature attributes never get applied properly
|
// TODO(TODO does not seem to apply here) this is the wrong approach; it causes Pango to end runs early, meaning attributes like the ligature attributes never get applied properly
|
||||||
// TODO contextual alternates override ligatures?
|
// TODO contextual alternates override ligatures?
|
||||||
// TODO rename this struct to something that isn't exclusively foreach-ing?
|
// TODO rename this struct to something that isn't exclusively foreach-ing?
|
||||||
struct foreachParams {
|
struct foreachParams {
|
||||||
const uint16_t *s;
|
const uint16_t *s;
|
||||||
IDWriteTextLayout *layout;
|
IDWriteTextLayout *layout;
|
||||||
|
std::map<size_t, textDrawingEffect *> *effects;
|
||||||
std::map<size_t, IDWriteTypography *> *features;
|
std::map<size_t, IDWriteTypography *> *features;
|
||||||
//TODO GPtrArray *backgroundClosures;
|
//TODO GPtrArray *backgroundClosures;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define isCodepointStart(w) ((((uint16_t) (w)) < 0xDC00) || (((uint16_t) (w)) >= 0xE000))
|
#define isCodepointStart(w) ((((uint16_t) (w)) < 0xDC00) || (((uint16_t) (w)) >= 0xE000))
|
||||||
|
|
||||||
|
static void ensureEffectsInRange(struct foreachParams *p, size_t start, size_t end, std::function<void(textDrawingEffect *)> f)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
size_t *key;
|
||||||
|
textDrawingEffect *t;
|
||||||
|
|
||||||
|
for (i = start; i < end; i++) {
|
||||||
|
// don't create redundant entries; see below
|
||||||
|
if (!isCodepointStart(p->s[i]))
|
||||||
|
continue;
|
||||||
|
t = (*(p->effects))[i];
|
||||||
|
if (t != NULL) {
|
||||||
|
f(t);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
t = new textDrawingEffect;
|
||||||
|
f(t);
|
||||||
|
(*(p->effects))[i] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ensureFeaturesInRange(struct foreachParams *p, size_t start, size_t end)
|
static void ensureFeaturesInRange(struct foreachParams *p, size_t start, size_t end)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -124,9 +147,8 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
#if 0 /* TODO */
|
#if 0 /* TODO */
|
||||||
GClosure *closure;
|
GClosure *closure;
|
||||||
PangoGravity gravity;
|
PangoGravity gravity;
|
||||||
PangoUnderline underline;
|
|
||||||
PangoLanguage *lang;
|
|
||||||
#endif
|
#endif
|
||||||
|
WCHAR *localeName;
|
||||||
struct otParam op;
|
struct otParam op;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -151,30 +173,38 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
logHRESULT(L"error applying size attribute", hr);
|
logHRESULT(L"error applying size attribute", hr);
|
||||||
break;
|
break;
|
||||||
#if 0 /* TODO */
|
|
||||||
case uiAttributeWeight:
|
case uiAttributeWeight:
|
||||||
// TODO reverse the misalignment from drawtext.c if it is corrected
|
// TODO reverse the misalignment from drawtext.cpp if it is corrected
|
||||||
addattr(p, start, end,
|
hr = p->layout->SetFontWeight(
|
||||||
pango_attr_weight_new((PangoWeight) (spec->Value)));
|
(DWRITE_FONT_WEIGHT) (spec->Value),
|
||||||
|
range);
|
||||||
|
if (hr != S_OK)
|
||||||
|
logHRESULT(L"error applying weight attribute", hr);
|
||||||
break;
|
break;
|
||||||
case uiAttributeItalic:
|
case uiAttributeItalic:
|
||||||
addattr(p, start, end,
|
hr = p->layout->SetFontStyle(
|
||||||
pango_attr_style_new(pangoItalics[(uiDrawTextItalic) (spec->Value)]));
|
dwriteItalics[(uiDrawTextItalic) (spec->Value)],
|
||||||
|
range);
|
||||||
|
if (hr != S_OK)
|
||||||
|
logHRESULT(L"error applying italic attribute", hr);
|
||||||
break;
|
break;
|
||||||
case uiAttributeStretch:
|
case uiAttributeStretch:
|
||||||
addattr(p, start, end,
|
hr = p->layout->SetFontStretch(
|
||||||
pango_attr_stretch_new(pangoStretches[(uiDrawTextStretch) (spec->Value)]));
|
dwriteStretches[(uiDrawTextStretch) (spec->Value)],
|
||||||
|
range);
|
||||||
|
if (hr != S_OK)
|
||||||
|
logHRESULT(L"error applying stretch attribute", hr);
|
||||||
break;
|
break;
|
||||||
case uiAttributeColor:
|
case uiAttributeColor:
|
||||||
addattr(p, start, end,
|
ensureEffectsInRange(p, start, end, [=](textDrawingEffect *t) {
|
||||||
pango_attr_foreground_new(
|
t->hasColor = true;
|
||||||
(guint16) (spec->R * 65535.0),
|
t->r = spec->R;
|
||||||
(guint16) (spec->G * 65535.0),
|
t->g = spec->G;
|
||||||
(guint16) (spec->B * 65535.0)));
|
t->b = spec->B;
|
||||||
addattr(p, start, end,
|
t->a = spec->A;
|
||||||
FUTURE_pango_attr_foreground_alpha_new(
|
});
|
||||||
(guint16) (spec->A * 65535.0)));
|
|
||||||
break;
|
break;
|
||||||
|
#if 0
|
||||||
case uiAttributeBackground:
|
case uiAttributeBackground:
|
||||||
closure = mkBackgroundClosure(start, end,
|
closure = mkBackgroundClosure(start, end,
|
||||||
spec->R, spec->G, spec->B, spec->A);
|
spec->R, spec->G, spec->B, spec->A);
|
||||||
|
@ -231,14 +261,15 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// language strings are specified as BCP 47: https://developer.gnome.org/pango/1.30/pango-Scripts-and-Languages.html#pango-language-from-string https://www.ietf.org/rfc/rfc3066.txt
|
|
||||||
case uiAttributeLanguage:
|
|
||||||
lang = pango_language_from_string((const char *) (spec->Value));
|
|
||||||
addattr(p, start, end,
|
|
||||||
pango_attr_language_new(lang));
|
|
||||||
// lang *cannot* be freed
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
// locale names are specified as BCP 47: https://msdn.microsoft.com/en-us/library/windows/desktop/dd373814(v=vs.85).aspx https://www.ietf.org/rfc/rfc4646.txt
|
||||||
|
case uiAttributeLanguage:
|
||||||
|
localeName = toUTF16((char *) (spec->Value));
|
||||||
|
hr = p->layout->SetLocaleName(localeName, range);
|
||||||
|
if (hr != S_OK)
|
||||||
|
logHRESULT(L"error applying locale name attribute", hr);
|
||||||
|
uiFree(localeName);
|
||||||
|
break;
|
||||||
// TODO
|
// TODO
|
||||||
default:
|
default:
|
||||||
// handle typographic features
|
// handle typographic features
|
||||||
|
@ -252,6 +283,25 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void applyAndFreeEffectsAttributes(struct foreachParams *p)
|
||||||
|
{
|
||||||
|
DWRITE_TEXT_RANGE range;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
for (auto iter = p->effects->begin(); iter != p->effects->end(); iter++) {
|
||||||
|
// make sure we cover an entire code point
|
||||||
|
range.startPosition = iter->first;
|
||||||
|
range.length = 1;
|
||||||
|
if (!isCodepointStart(p->s[iter->first]))
|
||||||
|
range.length = 2;
|
||||||
|
hr = p->layout->SetDrawingEffect(iter->second, range);
|
||||||
|
if (hr != S_OK)
|
||||||
|
logHRESULT(L"error applying drawing effects attributes", hr);
|
||||||
|
iter->second->Release();
|
||||||
|
}
|
||||||
|
delete p->effects;
|
||||||
|
}
|
||||||
|
|
||||||
static void applyAndFreeFeatureAttributes(struct foreachParams *p)
|
static void applyAndFreeFeatureAttributes(struct foreachParams *p)
|
||||||
{
|
{
|
||||||
DWRITE_TEXT_RANGE range;
|
DWRITE_TEXT_RANGE range;
|
||||||
|
@ -265,7 +315,7 @@ static void applyAndFreeFeatureAttributes(struct foreachParams *p)
|
||||||
range.length = 2;
|
range.length = 2;
|
||||||
hr = p->layout->SetTypography(iter->second, range);
|
hr = p->layout->SetTypography(iter->second, range);
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
logHRESULT(L"error applying typographic features", hr);
|
logHRESULT(L"error applying typographic features attributes", hr);
|
||||||
iter->second->Release();
|
iter->second->Release();
|
||||||
}
|
}
|
||||||
delete p->features;
|
delete p->features;
|
||||||
|
@ -284,9 +334,11 @@ void attrstrToIDWriteTextLayoutAttrs(uiDrawTextLayoutParams *p, IDWriteTextLayou
|
||||||
|
|
||||||
fep.s = attrstrUTF16(p->String);
|
fep.s = attrstrUTF16(p->String);
|
||||||
fep.layout = layout;
|
fep.layout = layout;
|
||||||
|
fep.effects = new std::map<size_t, textDrawingEffect *>;
|
||||||
fep.features = new std::map<size_t, IDWriteTypography *>;
|
fep.features = new std::map<size_t, IDWriteTypography *>;
|
||||||
//TODO fep.backgroundClosures = g_ptr_array_new_with_free_func(unrefClosure);
|
//TODO fep.backgroundClosures = g_ptr_array_new_with_free_func(unrefClosure);
|
||||||
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
|
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
|
||||||
|
applyAndFreeEffectsAttributes(&fep);
|
||||||
applyAndFreeFeatureAttributes(&fep);
|
applyAndFreeFeatureAttributes(&fep);
|
||||||
//TODO *backgroundClosures = fep.backgroundClosures;
|
//TODO *backgroundClosures = fep.backgroundClosures;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,3 +17,65 @@ extern void m2d(uiDrawMatrix *m, D2D1_MATRIX_3X2_F *d);
|
||||||
|
|
||||||
// attrstr.cpp
|
// attrstr.cpp
|
||||||
extern void attrstrToIDWriteTextLayoutAttrs(uiDrawTextLayoutParams *p, IDWriteTextLayout *layout/*TODO, GPtrArray **backgroundClosures*/);
|
extern void attrstrToIDWriteTextLayoutAttrs(uiDrawTextLayoutParams *p, IDWriteTextLayout *layout/*TODO, GPtrArray **backgroundClosures*/);
|
||||||
|
|
||||||
|
// drawtext.cpp
|
||||||
|
class textDrawingEffect : public IUnknown {
|
||||||
|
ULONG refcount;
|
||||||
|
public:
|
||||||
|
bool hasColor;
|
||||||
|
double r;
|
||||||
|
double g;
|
||||||
|
double b;
|
||||||
|
double a;
|
||||||
|
|
||||||
|
bool hasUnderline;
|
||||||
|
uiDrawUnderlineStyle u;
|
||||||
|
|
||||||
|
bool hasUnderlineColor;
|
||||||
|
double ur;
|
||||||
|
double ug;
|
||||||
|
double ub;
|
||||||
|
double ua;
|
||||||
|
|
||||||
|
textDrawingEffect()
|
||||||
|
{
|
||||||
|
this->refcount = 1;
|
||||||
|
this->hasColor = false;
|
||||||
|
this->hasUnderline = false;
|
||||||
|
this->hasUnderlineColor = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IUnknown
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
|
||||||
|
{
|
||||||
|
if (ppvObject == NULL)
|
||||||
|
return E_POINTER;
|
||||||
|
if (riid == IID_IUnknown) {
|
||||||
|
this->AddRef();
|
||||||
|
*ppvObject = this;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
*ppvObject = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ULONG STDMETHODCALLTYPE AddRef(void)
|
||||||
|
{
|
||||||
|
this->refcount++;
|
||||||
|
return this->refcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ULONG STDMETHODCALLTYPE Release(void)
|
||||||
|
{
|
||||||
|
this->refcount--;
|
||||||
|
if (this->refcount == 0) {
|
||||||
|
delete this;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return this->refcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
// TODO these should not be exported
|
||||||
|
extern std::map<uiDrawTextItalic, DWRITE_FONT_STYLE> dwriteItalics;
|
||||||
|
extern std::map<uiDrawTextStretch, DWRITE_FONT_STRETCH> dwriteStretches;
|
||||||
|
|
|
@ -28,14 +28,14 @@ struct uiDrawTextLayout {
|
||||||
#define pointSizeToDWriteSize(size) (size * (96.0 / 72.0))
|
#define pointSizeToDWriteSize(size) (size * (96.0 / 72.0))
|
||||||
|
|
||||||
// TODO should be const but then I can't operator[] on it; the real solution is to find a way to do designated array initializers in C++11 but I do not know enough C++ voodoo to make it work (it is possible but no one else has actually done it before)
|
// TODO should be const but then I can't operator[] on it; the real solution is to find a way to do designated array initializers in C++11 but I do not know enough C++ voodoo to make it work (it is possible but no one else has actually done it before)
|
||||||
static std::map<uiDrawTextItalic, DWRITE_FONT_STYLE> dwriteItalics = {
|
std::map<uiDrawTextItalic, DWRITE_FONT_STYLE> dwriteItalics = {
|
||||||
{ uiDrawTextItalicNormal, DWRITE_FONT_STYLE_NORMAL },
|
{ uiDrawTextItalicNormal, DWRITE_FONT_STYLE_NORMAL },
|
||||||
{ uiDrawTextItalicOblique, DWRITE_FONT_STYLE_OBLIQUE },
|
{ uiDrawTextItalicOblique, DWRITE_FONT_STYLE_OBLIQUE },
|
||||||
{ uiDrawTextItalicItalic, DWRITE_FONT_STYLE_ITALIC },
|
{ uiDrawTextItalicItalic, DWRITE_FONT_STYLE_ITALIC },
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO should be const but then I can't operator[] on it; the real solution is to find a way to do designated array initializers in C++11 but I do not know enough C++ voodoo to make it work (it is possible but no one else has actually done it before)
|
// TODO should be const but then I can't operator[] on it; the real solution is to find a way to do designated array initializers in C++11 but I do not know enough C++ voodoo to make it work (it is possible but no one else has actually done it before)
|
||||||
static std::map<uiDrawTextStretch, DWRITE_FONT_STRETCH> dwriteStretches = {
|
std::map<uiDrawTextStretch, DWRITE_FONT_STRETCH> dwriteStretches = {
|
||||||
{ uiDrawTextStretchUltraCondensed, DWRITE_FONT_STRETCH_ULTRA_CONDENSED },
|
{ uiDrawTextStretchUltraCondensed, DWRITE_FONT_STRETCH_ULTRA_CONDENSED },
|
||||||
{ uiDrawTextStretchExtraCondensed, DWRITE_FONT_STRETCH_EXTRA_CONDENSED },
|
{ uiDrawTextStretchExtraCondensed, DWRITE_FONT_STRETCH_EXTRA_CONDENSED },
|
||||||
{ uiDrawTextStretchCondensed, DWRITE_FONT_STRETCH_CONDENSED },
|
{ uiDrawTextStretchCondensed, DWRITE_FONT_STRETCH_CONDENSED },
|
||||||
|
@ -219,12 +219,10 @@ void uiDrawFreeTextLayout(uiDrawTextLayout *tl)
|
||||||
uiFree(tl);
|
uiFree(tl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ID2D1SolidColorBrush *mkSolidBrush(ID2D1RenderTarget *rt, double r, double g, double b, double a)
|
static HRESULT mkSolidBrush(ID2D1RenderTarget *rt, double r, double g, double b, double a, ID2D1SolidColorBrush **brush)
|
||||||
{
|
{
|
||||||
D2D1_BRUSH_PROPERTIES props;
|
D2D1_BRUSH_PROPERTIES props;
|
||||||
D2D1_COLOR_F color;
|
D2D1_COLOR_F color;
|
||||||
ID2D1SolidColorBrush *brush;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
ZeroMemory(&props, sizeof (D2D1_BRUSH_PROPERTIES));
|
ZeroMemory(&props, sizeof (D2D1_BRUSH_PROPERTIES));
|
||||||
props.opacity = 1.0;
|
props.opacity = 1.0;
|
||||||
|
@ -235,10 +233,18 @@ static ID2D1SolidColorBrush *mkSolidBrush(ID2D1RenderTarget *rt, double r, doubl
|
||||||
color.g = g;
|
color.g = g;
|
||||||
color.b = b;
|
color.b = b;
|
||||||
color.a = a;
|
color.a = a;
|
||||||
hr = rt->CreateSolidColorBrush(
|
return rt->CreateSolidColorBrush(
|
||||||
&color,
|
&color,
|
||||||
&props,
|
&props,
|
||||||
&brush);
|
brush);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ID2D1SolidColorBrush *mustMakeSolidBrush(ID2D1RenderTarget *rt, double r, double g, double b, double a)
|
||||||
|
{
|
||||||
|
ID2D1SolidColorBrush *brush;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = mkSolidBrush(rt, r, g, b, a, &brush);
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
logHRESULT(L"error creating solid brush", hr);
|
logHRESULT(L"error creating solid brush", hr);
|
||||||
return brush;
|
return brush;
|
||||||
|
@ -250,9 +256,9 @@ class textRenderer : public IDWriteTextRenderer {
|
||||||
ULONG refcount;
|
ULONG refcount;
|
||||||
ID2D1RenderTarget *rt;
|
ID2D1RenderTarget *rt;
|
||||||
BOOL snap;
|
BOOL snap;
|
||||||
IUnknown *black;
|
ID2D1SolidColorBrush *black;
|
||||||
public:
|
public:
|
||||||
textRenderer(ID2D1RenderTarget *rt, BOOL snap, IUnknown *black)
|
textRenderer(ID2D1RenderTarget *rt, BOOL snap, ID2D1SolidColorBrush *black)
|
||||||
{
|
{
|
||||||
this->refcount = 1;
|
this->refcount = 1;
|
||||||
this->rt = rt;
|
this->rt = rt;
|
||||||
|
@ -332,16 +338,26 @@ public:
|
||||||
virtual HRESULT STDMETHODCALLTYPE DrawGlyphRun(void *clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, DWRITE_MEASURING_MODE measuringMode, const DWRITE_GLYPH_RUN *glyphRun, const DWRITE_GLYPH_RUN_DESCRIPTION *glyphRunDescription, IUnknown *clientDrawingEffect)
|
virtual HRESULT STDMETHODCALLTYPE DrawGlyphRun(void *clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, DWRITE_MEASURING_MODE measuringMode, const DWRITE_GLYPH_RUN *glyphRun, const DWRITE_GLYPH_RUN_DESCRIPTION *glyphRunDescription, IUnknown *clientDrawingEffect)
|
||||||
{
|
{
|
||||||
D2D1_POINT_2F baseline;
|
D2D1_POINT_2F baseline;
|
||||||
|
textDrawingEffect *t = (textDrawingEffect *) clientDrawingEffect;
|
||||||
|
ID2D1SolidColorBrush *brush;
|
||||||
|
|
||||||
baseline.x = baselineOriginX;
|
baseline.x = baselineOriginX;
|
||||||
baseline.y = baselineOriginY;
|
baseline.y = baselineOriginY;
|
||||||
if (clientDrawingEffect == NULL)
|
brush = this->black;
|
||||||
clientDrawingEffect = black;
|
if (t != NULL && t->hasColor) {
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = mkSolidBrush(this->rt, t->r, t->g, t->b, t->a, &brush);
|
||||||
|
if (hr != S_OK)
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
this->rt->DrawGlyphRun(
|
this->rt->DrawGlyphRun(
|
||||||
baseline,
|
baseline,
|
||||||
glyphRun,
|
glyphRun,
|
||||||
(ID2D1Brush *) clientDrawingEffect,
|
brush,
|
||||||
measuringMode);
|
measuringMode);
|
||||||
|
if (t != NULL && t->hasColor)
|
||||||
|
brush->Release();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,12 +373,16 @@ public:
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE DrawStrikethrough(void *clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, const DWRITE_STRIKETHROUGH *strikethrough, IUnknown *clientDrawingEffect)
|
virtual HRESULT STDMETHODCALLTYPE DrawStrikethrough(void *clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, const DWRITE_STRIKETHROUGH *strikethrough, IUnknown *clientDrawingEffect)
|
||||||
{
|
{
|
||||||
|
textDrawingEffect *t = (textDrawingEffect *) clientDrawingEffect;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual HRESULT DrawUnderline(void *clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, const DWRITE_UNDERLINE *underline, IUnknown *clientDrawingEffect)
|
virtual HRESULT DrawUnderline(void *clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, const DWRITE_UNDERLINE *underline, IUnknown *clientDrawingEffect)
|
||||||
{
|
{
|
||||||
|
textDrawingEffect *t = (textDrawingEffect *) clientDrawingEffect;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -372,13 +392,13 @@ public:
|
||||||
void uiDrawText(uiDrawContext *c, uiDrawTextLayout *tl, double x, double y)
|
void uiDrawText(uiDrawContext *c, uiDrawTextLayout *tl, double x, double y)
|
||||||
{
|
{
|
||||||
D2D1_POINT_2F pt;
|
D2D1_POINT_2F pt;
|
||||||
ID2D1Brush *black;
|
ID2D1SolidColorBrush *black;
|
||||||
textRenderer *renderer;
|
textRenderer *renderer;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
// TODO document that fully opaque black is the default text color; figure out whether this is upheld in various scenarios on other platforms
|
// TODO document that fully opaque black is the default text color; figure out whether this is upheld in various scenarios on other platforms
|
||||||
// TODO figure out if this needs to be cleaned out
|
// TODO figure out if this needs to be cleaned out
|
||||||
black = mkSolidBrush(c->rt, 0.0, 0.0, 0.0, 1.0);
|
black = mustMakeSolidBrush(c->rt, 0.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
#define renderD2D 0
|
#define renderD2D 0
|
||||||
#define renderOur 1
|
#define renderOur 1
|
||||||
|
@ -395,7 +415,7 @@ void uiDrawText(uiDrawContext *c, uiDrawTextLayout *tl, double x, double y)
|
||||||
// draw ours semitransparent so we can check
|
// draw ours semitransparent so we can check
|
||||||
// TODO get the actual color Charles Petzold uses and use that
|
// TODO get the actual color Charles Petzold uses and use that
|
||||||
black->Release();
|
black->Release();
|
||||||
black = mkSolidBrush(c->rt, 1.0, 0.0, 0.0, 0.75);
|
black = mustMakeSolidBrush(c->rt, 1.0, 0.0, 0.0, 0.75);
|
||||||
#endif
|
#endif
|
||||||
#if renderOur
|
#if renderOur
|
||||||
renderer = new textRenderer(c->rt,
|
renderer = new textRenderer(c->rt,
|
||||||
|
|
|
@ -47,4 +47,5 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <functional>
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue