Skip to content

Commit

Permalink
lvdrawbuf: handle border colors with alpha (koreader#476)
Browse files Browse the repository at this point in the history
lvdrawbuf: also handle alpha in DrawLine() (forgotten
in ada7342).
Handle alpha in lvrend.cpp DrawBorder().
Behave as Firefox with "border-color: black" for border-style
outset/inset/groove/ridge, using some fixed values of gray.
Also fix parsing of 8-digits hex color values.
  • Loading branch information
poire-z authored Apr 14, 2022
1 parent a0dfc0a commit e6de204
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 26 deletions.
40 changes: 31 additions & 9 deletions crengine/src/lvdrawbuf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -905,9 +905,10 @@ void LVGrayDrawBuf::FillRect( int x0, int y0, int x1, int y1, lUInt32 color32 )
if (x0>=x1 || y0>=y1)
return;
lUInt8 color = rgbToGrayMask( color32, _bpp );
const lUInt8 opacity = ~color32 >> 24;
if (opacity == 0) // Fully transparent color
const lUInt8 alpha = (color32 >> 24) & 0xFF;
if (alpha == 0xFF) // Fully transparent color
return;
const lUInt8 opacity = alpha ^ 0xFF;
#if (GRAY_INVERSE==1)
color ^= 0xFF;
#endif
Expand All @@ -934,7 +935,6 @@ void LVGrayDrawBuf::FillRect( int x0, int y0, int x1, int y1, lUInt32 color32 )
line[x] = color;
}
else {
const lUInt8 alpha = opacity ^ 0xFF;
for (int x=x0; x<x1; x++)
ApplyAlphaGray8( line[x], color, alpha, opacity );
}
Expand Down Expand Up @@ -1174,6 +1174,10 @@ void LVGrayDrawBuf::DrawLine(int x0, int y0, int x1, int y1, lUInt32 color0, int
if (x0>=x1 || y0>=y1)
return;
lUInt8 color = rgbToGrayMask( color0, _bpp );
const lUInt8 alpha = (color0 >> 24) & 0xFF;
if (alpha == 0xFF) // Fully transparent color
return;
const lUInt8 opacity = alpha ^ 0xFF;
#if (GRAY_INVERSE==1)
color ^= 0xFF;
#endif
Expand All @@ -1198,8 +1202,13 @@ void LVGrayDrawBuf::DrawLine(int x0, int y0, int x1, int y1, lUInt32 color0, int
for (int x=x0; x<x1; x++)
{
lUInt8 * __restrict line = GetScanLine(y);
if (direction==0 &&x%(length1+length2)<length1)line[x] = color;
if (direction==1 &&y%(length1+length2)<length1)line[x] = color;
if ( (direction==0 &&x%(length1+length2)<length1) ||
(direction==1 &&y%(length1+length2)<length1) ) {
if ( opacity == 0xFF )
line[x] = color;
else
ApplyAlphaGray8( line[x], color, alpha, opacity );
}
}
}
}
Expand Down Expand Up @@ -1719,15 +1728,23 @@ void LVColorDrawBuf::DrawLine(int x0, int y0, int x1, int y1, lUInt32 color0, in
y1 = _clip.bottom;
if (x0>=x1 || y0>=y1)
return;
const lUInt8 alpha = (color0 >> 24) & 0xFF;
if (alpha == 0xFF) // Fully transparent color
return;
if ( _bpp==16 ) {
const lUInt16 cl16 = rgb888to565(color0);
for (int y=y0; y<y1; y++)
{
lUInt16 * __restrict line = (lUInt16 *)GetScanLine(y);
for (int x=x0; x<x1; x++)
{
if (direction==0 &&x%(length1+length2)<length1)line[x] = cl16;
if (direction==1 &&y%(length1+length2)<length1)line[x] = cl16;
if ( (direction==0 &&x%(length1+length2)<length1) ||
(direction==1 &&y%(length1+length2)<length1) ) {
if (alpha)
ApplyAlphaRGB565(line[x], cl16, alpha);
else
line[x] = cl16;
}
}
}
} else {
Expand All @@ -1737,8 +1754,13 @@ void LVColorDrawBuf::DrawLine(int x0, int y0, int x1, int y1, lUInt32 color0, in
lUInt32 * __restrict line = (lUInt32 *)GetScanLine(y);
for (int x=x0; x<x1; x++)
{
if (direction==0 &&x%(length1+length2)<length1)line[x] = cl32;
if (direction==1 &&y%(length1+length2)<length1)line[x] = cl32;
if ( (direction==0 &&x%(length1+length2)<length1) ||
(direction==1 &&y%(length1+length2)<length1) ) {
if (alpha)
ApplyAlphaRGB(line[x], cl32, alpha);
else
line[x] = cl32;
}
}
}
}
Expand Down
52 changes: 36 additions & 16 deletions crengine/src/lvrend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8595,13 +8595,18 @@ void DrawBorder(ldomNode *enode,LVDrawBuf & drawbuf,int x0,int y0,int doc_x,int
leftBorderwidth=lbw;
if (style->border_color[0].type==css_val_color)
{
lUInt32 r,g,b;
r=g=b=topBordercolor;
r=r>>16;
lUInt32 r,g,b,o;
r=g=b=o=topBordercolor;
r=r>>16&0xff;
g=g>>8&0xff;
b=b&0xff;
shadecolor=(r*160/255)<<16|(g*160/255)<<8|b*160/255;
o=o&0xFF000000;
shadecolor=o|(r*160/255)<<16|(g*160/255)<<8|b*160/255;
lightcolor=topBordercolor;
if ( (topBordercolor & 0xFFFFFF) == 0 ) {
shadecolor = o|0x4c4c4c; // Firefox uses these values when color is real black 0x000000 (but not if 0x010101)
lightcolor = o|0xb2b2b2;
}
}
int left=1,right=1;
left=(hasleftBorder)?0:1;
Expand Down Expand Up @@ -8700,13 +8705,18 @@ void DrawBorder(ldomNode *enode,LVDrawBuf & drawbuf,int x0,int y0,int doc_x,int
// leftBorderwidth=lbw; // (not used)
if (style->border_color[1].type==css_val_color)
{
lUInt32 r,g,b;
r=g=b=rightBordercolor;
r=r>>16;
lUInt32 r,g,b,o;
r=g=b=o=rightBordercolor;
r=r>>16&0xff;
g=g>>8&0xff;
b=b&0xff;
shadecolor=(r*160/255)<<16|(g*160/255)<<8|b*160/255;
o=o&0xFF000000;
shadecolor=o|(r*160/255)<<16|(g*160/255)<<8|b*160/255;
lightcolor=rightBordercolor;
if ( (rightBordercolor & 0xFFFFFF) == 0 ) {
shadecolor = o|0x4c4c4c;
lightcolor = o|0xb2b2b2;
}
}
int up=1,down=1;
up=(hastopBorder)?0:1;
Expand Down Expand Up @@ -8807,13 +8817,18 @@ void DrawBorder(ldomNode *enode,LVDrawBuf & drawbuf,int x0,int y0,int doc_x,int
leftBorderwidth=lbw;
if (style->border_color[2].type==css_val_color)
{
lUInt32 r,g,b;
r=g=b=bottomBordercolor;
r=r>>16;
lUInt32 r,g,b,o;
r=g=b=o=bottomBordercolor;
r=r>>16&0xff;
g=g>>8&0xff;
b=b&0xff;
shadecolor=(r*160/255)<<16|(g*160/255)<<8|b*160/255;
o=o&0xFF000000;
shadecolor=o|(r*160/255)<<16|(g*160/255)<<8|b*160/255;
lightcolor=bottomBordercolor;
if ( (bottomBordercolor & 0xFFFFFF) == 0 ) {
shadecolor = o|0x4c4c4c;
lightcolor = o|0xb2b2b2;
}
}
int left=1,right=1;
left=(hasleftBorder)?0:1;
Expand Down Expand Up @@ -8903,13 +8918,18 @@ void DrawBorder(ldomNode *enode,LVDrawBuf & drawbuf,int x0,int y0,int doc_x,int
leftBorderwidth=lbw;
if (style->border_color[3].type==css_val_color)
{
lUInt32 r,g,b;
r=g=b=leftBordercolor;
r=r>>16;
lUInt32 r,g,b,o;
r=g=b=o=leftBordercolor;
r=r>>16&0xff;
g=g>>8&0xff;
b=b&0xff;
shadecolor=(r*160/255)<<16|(g*160/255)<<8|b*160/255;
o=o&0xFF000000;
shadecolor=o|(r*160/255)<<16|(g*160/255)<<8|b*160/255;
lightcolor=leftBordercolor;
if ( (leftBordercolor & 0xFFFFFF) == 0 ) {
shadecolor = o|0x4c4c4c;
lightcolor = o|0xb2b2b2;
}
}
int up=1,down=1;
up=(hastopBorder)?0:1;
Expand Down
2 changes: 1 addition & 1 deletion crengine/src/lvstsheet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,7 @@ bool parse_color_value( const char * & str, css_length_t & value )
int a = hexDigit( *str++ ) * 16;
a += hexDigit( *str++ );
// cre color upper byte is inverted alpha
value.value |= ((a + a*16)^0xFF)<<24;
value.value |= (a^0xFF)<<24;
}
return true;
} else {
Expand Down

0 comments on commit e6de204

Please sign in to comment.