Background attribute rendering on Windows
This commit is contained in:
parent
24d802abc5
commit
e9f06c468a
|
@ -33,6 +33,7 @@ static std::hash<double> doubleHash;
|
|||
class combinedEffectsAttr : public IUnknown {
|
||||
ULONG refcount;
|
||||
uiAttribute *colorAttr;
|
||||
uiAttribute *backgroundAttr;
|
||||
uiAttribute *underlineAttr;
|
||||
uiAttribute *underlineColorAttr;
|
||||
|
||||
|
@ -46,6 +47,11 @@ class combinedEffectsAttr : public IUnknown {
|
|||
uiprivAttributeRelease(this->colorAttr);
|
||||
this->colorAttr = uiprivAttributeRetain(a);
|
||||
break;
|
||||
case uiAttributeTypeBackground:
|
||||
if (this->backgroundAttr != NULL)
|
||||
uiprivAttributeRelease(this->backgroundAttr);
|
||||
this->backgroundAttr = uiprivAttributeRetain(a);
|
||||
break;
|
||||
case uiAttributeTypeUnderline:
|
||||
if (this->underlineAttr != NULL)
|
||||
uiprivAttributeRelease(this->underlineAttr);
|
||||
|
@ -74,6 +80,7 @@ public:
|
|||
{
|
||||
this->refcount = 1;
|
||||
this->colorAttr = NULL;
|
||||
this->backgroundAttr = NULL;
|
||||
this->underlineAttr = NULL;
|
||||
this->underlineColorAttr = NULL;
|
||||
this->setAttribute(a);
|
||||
|
@ -83,6 +90,8 @@ public:
|
|||
{
|
||||
if (this->colorAttr != NULL)
|
||||
uiprivAttributeRelease(this->colorAttr);
|
||||
if (this->backgroundAttr != NULL)
|
||||
uiprivAttributeRelease(this->backgroundAttr);
|
||||
if (this->underlineAttr != NULL)
|
||||
uiprivAttributeRelease(this->underlineAttr);
|
||||
if (this->underlineColorAttr != NULL)
|
||||
|
@ -124,6 +133,7 @@ public:
|
|||
combinedEffectsAttr *b;
|
||||
|
||||
b = new combinedEffectsAttr(this->colorAttr);
|
||||
b->setAttribute(this->backgroundAttr);
|
||||
b->setAttribute(this->underlineAttr);
|
||||
b->setAttribute(this->underlineColorAttr);
|
||||
b->setAttribute(a);
|
||||
|
@ -144,6 +154,14 @@ public:
|
|||
ret ^= doubleHash(b);
|
||||
ret ^= doubleHash(a);
|
||||
}
|
||||
|
||||
if (this->backgroundAttr != NULL) {
|
||||
uiAttributeBackground(this->backgroundAttr, &r, &g, &b, &a);
|
||||
ret ^= doubleHash(r);
|
||||
ret ^= doubleHash(g);
|
||||
ret ^= doubleHash(b);
|
||||
ret ^= doubleHash(a);
|
||||
}
|
||||
if (this->underlineAttr != NULL)
|
||||
ret ^= (size_t) uiAttributeUnderline(this->underlineAttr);
|
||||
if (this->underlineColorAttr != NULL) {
|
||||
|
@ -162,6 +180,7 @@ public:
|
|||
if (b == NULL)
|
||||
return false;
|
||||
return combinedEffectsAttr::attrEqual(this->colorAttr, b->colorAttr) &&
|
||||
combinedEffectsAttr::attrEqual(this->backgroundAttr, b->backgroundAttr) &&
|
||||
combinedEffectsAttr::attrEqual(this->underlineAttr, b->underlineAttr) &&
|
||||
combinedEffectsAttr::attrEqual(this->underlineColorAttr, b->underlineColorAttr);
|
||||
}
|
||||
|
@ -177,6 +196,10 @@ public:
|
|||
uiAttributeColor(this->colorAttr, &r, &g, &b, &a);
|
||||
dea->setColor(r, g, b, a);
|
||||
}
|
||||
if (this->backgroundAttr != NULL) {
|
||||
uiAttributeBackground(this->backgroundAttr, &r, &g, &b, &a);
|
||||
dea->setBackground(r, g, b, a);
|
||||
}
|
||||
if (this->underlineAttr != NULL)
|
||||
dea->setUnderline(uiAttributeUnderline(this->underlineAttr));
|
||||
if (this->underlineColorAttr != NULL) {
|
||||
|
@ -338,14 +361,15 @@ static uiForEach processAttribute(const uiAttributedString *s, const uiAttribute
|
|||
// and fall through to set the underline style through the drawing effect
|
||||
case uiAttributeTypeColor:
|
||||
case uiAttributeTypeUnderlineColor:
|
||||
case uiAttributeTypeBackground:
|
||||
// TODO const-correct this properly
|
||||
hr = addEffectAttributeToRange(p, start, end, (uiAttribute *) attr);
|
||||
if (hr != S_OK)
|
||||
logHRESULT(L"error applying effect (color, underline, or underline color) attribute", hr);
|
||||
break;
|
||||
case uiAttributeTypeBackground:
|
||||
addBackgroundParams(p, start, end, attr);
|
||||
break;
|
||||
// case uiAttributeTypeBackground:
|
||||
// addBackgroundParams(p, start, end, attr);
|
||||
// break;
|
||||
case uiAttributeTypeFeatures:
|
||||
// only generate an attribute if not NULL
|
||||
// TODO do we still need to do this or not...
|
||||
|
|
|
@ -39,6 +39,12 @@ class drawingEffectsAttr : public IUnknown {
|
|||
double b;
|
||||
double a;
|
||||
|
||||
bool hasBackground;
|
||||
double br;
|
||||
double bg;
|
||||
double bb;
|
||||
double ba;
|
||||
|
||||
bool hasUnderline;
|
||||
uiUnderline u;
|
||||
|
||||
|
@ -56,9 +62,11 @@ public:
|
|||
virtual ULONG STDMETHODCALLTYPE Release(void);
|
||||
|
||||
void setColor(double r, double g, double b, double a);
|
||||
void setBackground(double r, double g, double b, double a);
|
||||
void setUnderline(uiUnderline u);
|
||||
void setUnderlineColor(double r, double g, double b, double a);
|
||||
HRESULT mkColorBrush(ID2D1RenderTarget *rt, ID2D1SolidColorBrush **b);
|
||||
HRESULT mkBackgroundBrush(ID2D1RenderTarget *rt, ID2D1SolidColorBrush **b);
|
||||
HRESULT underline(uiUnderline *u);
|
||||
HRESULT mkUnderlineBrush(ID2D1RenderTarget *rt, ID2D1SolidColorBrush **b);
|
||||
};
|
||||
|
|
|
@ -143,6 +143,7 @@ drawingEffectsAttr::drawingEffectsAttr(void)
|
|||
{
|
||||
this->refcount = 1;
|
||||
this->hasColor = false;
|
||||
this->hasBackground = false;
|
||||
this->hasUnderline = false;
|
||||
this->hasUnderlineColor = false;
|
||||
}
|
||||
|
@ -185,6 +186,15 @@ void drawingEffectsAttr::setColor(double r, double g, double b, double a)
|
|||
this->a = a;
|
||||
}
|
||||
|
||||
void drawingEffectsAttr::setBackground(double r, double g, double b, double a)
|
||||
{
|
||||
this->hasBackground = true;
|
||||
this->br = r;
|
||||
this->bg = g;
|
||||
this->bb = b;
|
||||
this->ba = a;
|
||||
}
|
||||
|
||||
void drawingEffectsAttr::setUnderline(uiUnderline u)
|
||||
{
|
||||
this->hasUnderline = true;
|
||||
|
@ -209,6 +219,15 @@ HRESULT drawingEffectsAttr::mkColorBrush(ID2D1RenderTarget *rt, ID2D1SolidColorB
|
|||
return mkSolidBrush(rt, this->r, this->g, this->b, this->a, b);
|
||||
}
|
||||
|
||||
HRESULT drawingEffectsAttr::mkBackgroundBrush(ID2D1RenderTarget *rt, ID2D1SolidColorBrush **b)
|
||||
{
|
||||
if (!this->hasBackground) {
|
||||
*b = NULL;
|
||||
return S_OK;
|
||||
}
|
||||
return mkSolidBrush(rt, this->br, this->bg, this->bb, this->ba, b);
|
||||
}
|
||||
|
||||
HRESULT drawingEffectsAttr::underline(uiUnderline *u)
|
||||
{
|
||||
if (u == NULL)
|
||||
|
@ -316,28 +335,57 @@ public:
|
|||
{
|
||||
D2D1_POINT_2F baseline;
|
||||
drawingEffectsAttr *dea = (drawingEffectsAttr *) clientDrawingEffect;
|
||||
ID2D1SolidColorBrush *brush;
|
||||
ID2D1SolidColorBrush *foregroundBrush;
|
||||
ID2D1SolidColorBrush *backgroundBrush;
|
||||
|
||||
baseline.x = baselineOriginX;
|
||||
baseline.y = baselineOriginY;
|
||||
brush = NULL;
|
||||
foregroundBrush = NULL;
|
||||
backgroundBrush = NULL;
|
||||
if (dea != NULL) {
|
||||
HRESULT hr;
|
||||
|
||||
hr = dea->mkColorBrush(this->rt, &brush);
|
||||
hr = dea->mkColorBrush(this->rt, &foregroundBrush);
|
||||
if (hr != S_OK)
|
||||
return hr;
|
||||
|
||||
hr = dea->mkBackgroundBrush(this->rt, &backgroundBrush);
|
||||
if (hr != S_OK)
|
||||
return hr;
|
||||
}
|
||||
if (brush == NULL) {
|
||||
brush = this->black;
|
||||
brush->AddRef();
|
||||
if (foregroundBrush == NULL) {
|
||||
foregroundBrush = this->black;
|
||||
foregroundBrush->AddRef();
|
||||
}
|
||||
if (backgroundBrush != nullptr) {
|
||||
// Get width of text
|
||||
float totalWidth = 0;
|
||||
|
||||
for (UINT32 index = 0; index < glyphRun->glyphCount; index++)
|
||||
{
|
||||
totalWidth += glyphRun->glyphAdvances[index];
|
||||
}
|
||||
|
||||
// Get height of text
|
||||
DWRITE_FONT_METRICS fontMetrics;
|
||||
glyphRun->fontFace->GetMetrics(&fontMetrics);
|
||||
float adjust = glyphRun->fontEmSize / fontMetrics.designUnitsPerEm;
|
||||
float ascent = adjust * fontMetrics.ascent;
|
||||
float descent = adjust * fontMetrics.descent;
|
||||
D2D1_RECT_F rect = D2D1::RectF(baselineOriginX,
|
||||
baselineOriginY - ascent,
|
||||
baselineOriginX + totalWidth,
|
||||
baselineOriginY + descent);
|
||||
|
||||
// Fill Rectangle
|
||||
this->rt->FillRectangle(rect, backgroundBrush);
|
||||
}
|
||||
this->rt->DrawGlyphRun(
|
||||
baseline,
|
||||
glyphRun,
|
||||
brush,
|
||||
foregroundBrush,
|
||||
measuringMode);
|
||||
brush->Release();
|
||||
foregroundBrush->Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue