Support the transparency in the KML Global Color.

This commit is contained in:
dgis 2019-11-12 00:16:38 +01:00
parent 577091db9e
commit fe3d8c4da0
3 changed files with 274 additions and 143 deletions

View file

@ -96,6 +96,134 @@ VOID CopyItemsToClipboard(HWND hWnd) // save selected Listbox Items to Clipboar
return;
}
#define WIDTHBYTES(bits) ((((bits) + 31) / 32) * 4)
static BOOL AbsColorCmp(DWORD dwColor1,DWORD dwColor2,DWORD dwTol)
{
DWORD dwDiff;
dwDiff = (DWORD) abs((INT) (dwColor1 & 0xFF) - (INT) (dwColor2 & 0xFF));
dwColor1 >>= 8;
dwColor2 >>= 8;
dwDiff += (DWORD) abs((INT) (dwColor1 & 0xFF) - (INT) (dwColor2 & 0xFF));
dwColor1 >>= 8;
dwColor2 >>= 8;
dwDiff += (DWORD) abs((INT) (dwColor1 & 0xFF) - (INT) (dwColor2 & 0xFF));
return dwDiff > dwTol; // FALSE = colors match
}
static BOOL LabColorCmp(DWORD dwColor1,DWORD dwColor2,DWORD dwTol)
{
DWORD dwDiff;
INT nDiffCol;
nDiffCol = (INT) (dwColor1 & 0xFF) - (INT) (dwColor2 & 0xFF);
dwDiff = (DWORD) (nDiffCol * nDiffCol);
dwColor1 >>= 8;
dwColor2 >>= 8;
nDiffCol = (INT) (dwColor1 & 0xFF) - (INT) (dwColor2 & 0xFF);
dwDiff += (DWORD) (nDiffCol * nDiffCol);
dwColor1 >>= 8;
dwColor2 >>= 8;
nDiffCol = (INT) (dwColor1 & 0xFF) - (INT) (dwColor2 & 0xFF);
dwDiff += (DWORD) (nDiffCol * nDiffCol);
dwTol *= dwTol;
return dwDiff > dwTol; // FALSE = colors match
}
static DWORD EncodeColorBits(DWORD dwColorVal,DWORD dwMask)
{
#define MAXBIT 32
UINT uLshift = MAXBIT;
UINT uRshift = 8;
DWORD dwBitMask = dwMask;
dwColorVal &= 0xFF; // the color component using the lowest 8 bit
// position of highest bit
while ((dwBitMask & (1<<(MAXBIT-1))) == 0 && uLshift > 0)
{
dwBitMask <<= 1; // next bit
--uLshift; // next position
}
if (uLshift > 24) // avoid overflow on 32bit mask
{
uLshift -= uRshift; // normalize left shift
uRshift = 0;
}
return ((dwColorVal << uLshift) >> uRshift) & dwMask;
#undef MAXBIT
}
extern JavaVM *java_machine;
extern jobject bitmapMainScreen;
extern AndroidBitmapInfo androidBitmapInfo;
static void MakeBitmapTransparent(HBITMAP hBmp,COLORREF color,DWORD dwTol) {
BOOL (*fnColorCmp)(DWORD dwColor1,DWORD dwColor2,DWORD dwTol);
if (dwTol >= 1000) { // use CIE L*a*b compare
fnColorCmp = LabColorCmp;
dwTol -= 1000; // remove L*a*b compare selector
} else { // use Abs summation compare
fnColorCmp = AbsColorCmp;
}
JNIEnv * jniEnv = NULL;
jint ret;
BOOL needDetach = FALSE;
ret = (*java_machine)->GetEnv(java_machine, (void **) &jniEnv, JNI_VERSION_1_6);
if (ret == JNI_EDETACHED) {
// GetEnv: not attached
ret = (*java_machine)->AttachCurrentThread(java_machine, &jniEnv, NULL);
if (ret == JNI_OK) {
needDetach = TRUE;
}
}
int destinationWidth = androidBitmapInfo.width;
int destinationHeight = androidBitmapInfo.height;
int destinationBitCount = 32;
int destinationStride = androidBitmapInfo.stride;
void * pixelsDestination = NULL;
if ((ret = AndroidBitmap_lockPixels(jniEnv, bitmapMainScreen, &pixelsDestination)) < 0) {
LOGD("AndroidBitmap_lockPixels() failed ! error=%d", ret);
return;
}
LPBYTE pbyBits = pixelsDestination;
// convert COLORREF to RGBQUAD color
DWORD dwRed = 0x00FF0000;
DWORD dwGreen = 0x0000FF00;
DWORD dwBlue = 0x000000FF;
color = EncodeColorBits((color >> 16), dwBlue)
| EncodeColorBits((color >> 8), dwGreen)
| EncodeColorBits((color >> 0), dwRed);
DWORD dwBpp = (DWORD) (destinationBitCount >> 3);
LPBYTE pbyColor = pbyBits + (destinationHeight - 1) * destinationStride;
for (LONG y = 0; y < destinationHeight; ++y) {
LPBYTE pbyLineStart = pbyColor;
for (LONG x = 0; x < destinationWidth; ++x) {
if(!fnColorCmp(*(LPDWORD)pbyColor,color,dwTol))
*(LPDWORD)pbyColor = 0x00000000;
pbyColor += dwBpp;
}
pbyColor = pbyLineStart - destinationStride;
}
if(jniEnv && (ret = AndroidBitmap_unlockPixels(jniEnv, bitmapMainScreen)) < 0)
LOGD("AndroidBitmap_unlockPixels() failed ! error=%d", ret);
}
//
// WM_PAINT
//
@ -127,6 +255,9 @@ static LRESULT OnPaint(HWND hWindow)
Paint.rcPaint.right-Paint.rcPaint.left, Paint.rcPaint.bottom-Paint.rcPaint.top,
hMainDC, rcMainPaint.left, rcMainPaint.top, SRCCOPY);
if (dwTColor != (DWORD) -1) // prepare background bitmap with transparency
MakeBitmapTransparent((HBITMAP)GetCurrentObject(hPaintDC, OBJ_BITMAP), dwTColor, dwTColorTol);
// CdB for HP: add apples display stuff
SetWindowOrgEx(hPaintDC, nBackgroundX, nBackgroundY, NULL);

View file

@ -2026,163 +2026,163 @@ void StretchBltInternal(int xDest, int yDest, int wDest, int hDest,
int dst_maxy = yDest + hDest;
if(xDest < 0) {
wDest += xDest;
xDest = 0;
}
wDest += xDest;
xDest = 0;
}
if(yDest < 0) {
hDest += yDest;
yDest = 0;
}
hDest += yDest;
yDest = 0;
}
if(dst_maxx > destinationWidth)
dst_maxx = destinationWidth;
dst_maxx = destinationWidth;
if(dst_maxy > destinationHeight)
dst_maxy = destinationHeight;
dst_maxy = destinationHeight;
for (int y = yDest; y < dst_maxy; y++) {
int src_cury = ySrc + (y - yDest) * hSrc / hDest;
if(!reverseHeight)
src_cury = sourceHeight - 1 - src_cury;
if (src_cury < 0 || src_cury >= sourceHeight)
int src_cury = ySrc + (y - yDest) * hSrc / hDest;
if(!reverseHeight)
src_cury = sourceHeight - 1 - src_cury;
if (src_cury < 0 || src_cury >= sourceHeight)
continue;
BYTE parity = (BYTE) xSrc;
for (int x = xDest; x < dst_maxx; x++, parity++) {
int src_curx = xSrc + (x - xDest) * wSrc / wDest;
if (src_curx < 0 || src_curx >= sourceWidth)
continue;
BYTE parity = (BYTE) xSrc;
for (int x = xDest; x < dst_maxx; x++, parity++) {
int src_curx = xSrc + (x - xDest) * wSrc / wDest;
if (src_curx < 0 || src_curx >= sourceWidth)
continue;
BYTE * sourcePixelBase = pixelsSource + sourceStride * src_cury;
BYTE * destinationPixelBase = pixelsDestination + destinationStride * y;
BYTE * sourcePixelBase = pixelsSource + sourceStride * src_cury;
BYTE * destinationPixelBase = pixelsDestination + destinationStride * y;
COLORREF sourceColor = 0xFF000000;
BYTE * sourceColorPointer = (BYTE *) &sourceColor;
COLORREF sourceColor = 0xFF000000;
BYTE * sourceColorPointer = (BYTE *) &sourceColor;
switch (sourceBitCount) {
case 1: {
//TODO https://devblogs.microsoft.com/oldnewthing/?p=29013
// When blitting from a monochrome DC to a color DC,
// the color black in the source turns into the destinations text color,
// and the color white in the source turns into the destinations background
// color.
BYTE * sourcePixel = sourcePixelBase + ((UINT)src_curx >> (UINT)3);
UINT bitNumber = (UINT) (src_curx % 8);
if(*sourcePixel & ((UINT)1 << bitNumber)) {
// Monochrome 1=White
sourceColorPointer[0] = 255;
sourceColorPointer[1] = 255;
sourceColorPointer[2] = 255;
} else {
// Monochrome 0=Black
sourceColorPointer[0] = 0;
sourceColorPointer[1] = 0;
sourceColorPointer[2] = 0;
}
sourceColorPointer[3] = 255;
break;
switch (sourceBitCount) {
case 1: {
//TODO https://devblogs.microsoft.com/oldnewthing/?p=29013
// When blitting from a monochrome DC to a color DC,
// the color black in the source turns into the destinations text color,
// and the color white in the source turns into the destinations background
// color.
BYTE * sourcePixel = sourcePixelBase + ((UINT)src_curx >> (UINT)3);
UINT bitNumber = (UINT) (src_curx % 8);
if(*sourcePixel & ((UINT)1 << bitNumber)) {
// Monochrome 1=White
sourceColorPointer[0] = 255;
sourceColorPointer[1] = 255;
sourceColorPointer[2] = 255;
} else {
// Monochrome 0=Black
sourceColorPointer[0] = 0;
sourceColorPointer[1] = 0;
sourceColorPointer[2] = 0;
}
case 4: {
int currentXBytes = ((sourceBitCount >> (UINT)2) * src_curx) >> (UINT)1;
BYTE * sourcePixel = sourcePixelBase + currentXBytes;
BYTE colorIndex = (parity & (BYTE)0x1 ? sourcePixel[0] & (BYTE)0x0F : sourcePixel[0] >> (UINT)4);
if (palPalEntry) {
sourceColorPointer[0] = palPalEntry[colorIndex].peBlue;
sourceColorPointer[1] = palPalEntry[colorIndex].peGreen;
sourceColorPointer[2] = palPalEntry[colorIndex].peRed;
sourceColorPointer[3] = 255;
} else {
sourceColorPointer[0] = colorIndex;
sourceColorPointer[1] = colorIndex;
sourceColorPointer[2] = colorIndex;
sourceColorPointer[3] = 255;
}
break;
}
case 8: {
BYTE * sourcePixel = sourcePixelBase + src_curx;
BYTE colorIndex = sourcePixel[0];
if (palPalEntry) {
sourceColorPointer[0] = palPalEntry[colorIndex].peBlue;
sourceColorPointer[1] = palPalEntry[colorIndex].peGreen;
sourceColorPointer[2] = palPalEntry[colorIndex].peRed;
sourceColorPointer[3] = 255;
} else {
sourceColorPointer[0] = colorIndex;
sourceColorPointer[1] = colorIndex;
sourceColorPointer[2] = colorIndex;
sourceColorPointer[3] = 255;
}
break;
}
case 24: {
BYTE * sourcePixel = sourcePixelBase + 3 * src_curx;
sourceColorPointer[0] = sourcePixel[2];
sourceColorPointer[1] = sourcePixel[1];
sourceColorPointer[2] = sourcePixel[0];
sourceColorPointer[3] = 255;
break;
}
case 32: {
BYTE *sourcePixel = sourcePixelBase + 4 * src_curx;
memcpy(sourceColorPointer, sourcePixel, 4);
break;
}
default:
break;
sourceColorPointer[3] = 255;
break;
}
switch (destinationBitCount) {
case 1: {
//TODO https://devblogs.microsoft.com/oldnewthing/?p=29013
// If you blit from a color DC to a monochrome DC,
// then all pixels in the source that are equal to the background color
// will turn white, and all other pixels will turn black.
// In other words, GDI considers a monochrome bitmap to be
// black pixels on a white background.
BYTE * destinationPixel = destinationPixelBase + (x >> 3);
UINT bitNumber = x % 8;
if(backgroundColor == sourceColor) {
*destinationPixel |= (1 << bitNumber); // 1 White
} else {
*destinationPixel &= ~(1 << bitNumber); // 0 Black
}
break;
case 4: {
int currentXBytes = ((sourceBitCount >> (UINT)2) * src_curx) >> (UINT)1;
BYTE * sourcePixel = sourcePixelBase + currentXBytes;
BYTE colorIndex = (parity & (BYTE)0x1 ? sourcePixel[0] & (BYTE)0x0F : sourcePixel[0] >> (UINT)4);
if (palPalEntry) {
sourceColorPointer[0] = palPalEntry[colorIndex].peBlue;
sourceColorPointer[1] = palPalEntry[colorIndex].peGreen;
sourceColorPointer[2] = palPalEntry[colorIndex].peRed;
sourceColorPointer[3] = 255;
} else {
sourceColorPointer[0] = colorIndex;
sourceColorPointer[1] = colorIndex;
sourceColorPointer[2] = colorIndex;
sourceColorPointer[3] = 255;
}
case 4: {
//TODO
break;
}
case 8: {
//TODO
break;
}
case 24: {
BYTE * destinationPixel = destinationPixelBase + 3 * x;
destinationPixel[0] = sourceColorPointer[0];
destinationPixel[1] = sourceColorPointer[1];
destinationPixel[2] = sourceColorPointer[2];
break;
}
case 32: {
BYTE * destinationPixel = destinationPixelBase + 4 * x;
// https://docs.microsoft.com/en-us/windows/desktop/gdi/ternary-raster-operations
// http://www.qnx.com/developers/docs/6.4.1/gf/dev_guide/api/gf_context_set_rop.html
if (rop == ROP_PDSPxax) { // P ^ (D & (S ^ P))
UINT destination = *((UINT *) destinationPixel);
*((UINT *)destinationPixel) = (brushColor ^ (destination & (sourceColor ^ brushColor))) | 0xFF000000;
} else if (rop == ROP_PSDPxax) { // P ^ (S & (D ^ P))
UINT destination = *((UINT *) destinationPixel);
*((UINT *)destinationPixel) = (brushColor ^ (sourceColor & (destination ^ brushColor))) | 0xFF000000;
} else if (rop == SRCAND) { // dest = source AND dest
UINT destination = *((UINT *) destinationPixel);
*((UINT *)destinationPixel) = (sourceColor & destination) | 0xFF000000;
} else
*((UINT *)destinationPixel) = sourceColor;
break;
}
default:
break;
break;
}
case 8: {
BYTE * sourcePixel = sourcePixelBase + src_curx;
BYTE colorIndex = sourcePixel[0];
if (palPalEntry) {
sourceColorPointer[0] = palPalEntry[colorIndex].peBlue;
sourceColorPointer[1] = palPalEntry[colorIndex].peGreen;
sourceColorPointer[2] = palPalEntry[colorIndex].peRed;
sourceColorPointer[3] = 255;
} else {
sourceColorPointer[0] = colorIndex;
sourceColorPointer[1] = colorIndex;
sourceColorPointer[2] = colorIndex;
sourceColorPointer[3] = 255;
}
break;
}
case 24: {
BYTE * sourcePixel = sourcePixelBase + 3 * src_curx;
sourceColorPointer[0] = sourcePixel[2];
sourceColorPointer[1] = sourcePixel[1];
sourceColorPointer[2] = sourcePixel[0];
sourceColorPointer[3] = 255;
break;
}
case 32: {
BYTE *sourcePixel = sourcePixelBase + 4 * src_curx;
memcpy(sourceColorPointer, sourcePixel, 4);
break;
}
default:
break;
}
switch (destinationBitCount) {
case 1: {
//TODO https://devblogs.microsoft.com/oldnewthing/?p=29013
// If you blit from a color DC to a monochrome DC,
// then all pixels in the source that are equal to the background color
// will turn white, and all other pixels will turn black.
// In other words, GDI considers a monochrome bitmap to be
// black pixels on a white background.
BYTE * destinationPixel = destinationPixelBase + (x >> 3);
UINT bitNumber = x % 8;
if(backgroundColor == sourceColor) {
*destinationPixel |= (1 << bitNumber); // 1 White
} else {
*destinationPixel &= ~(1 << bitNumber); // 0 Black
}
break;
}
case 4: {
//TODO
break;
}
case 8: {
//TODO
break;
}
case 24: {
BYTE * destinationPixel = destinationPixelBase + 3 * x;
destinationPixel[0] = sourceColorPointer[0];
destinationPixel[1] = sourceColorPointer[1];
destinationPixel[2] = sourceColorPointer[2];
break;
}
case 32: {
BYTE * destinationPixel = destinationPixelBase + 4 * x;
// https://docs.microsoft.com/en-us/windows/desktop/gdi/ternary-raster-operations
// http://www.qnx.com/developers/docs/6.4.1/gf/dev_guide/api/gf_context_set_rop.html
if (rop == ROP_PDSPxax) { // P ^ (D & (S ^ P))
UINT destination = *((UINT *) destinationPixel);
*((UINT *)destinationPixel) = (brushColor ^ (destination & (sourceColor ^ brushColor))) | 0xFF000000;
} else if (rop == ROP_PSDPxax) { // P ^ (S & (D ^ P))
UINT destination = *((UINT *) destinationPixel);
*((UINT *)destinationPixel) = (brushColor ^ (sourceColor & (destination ^ brushColor))) | 0xFF000000;
} else if (rop == SRCAND) { // dest = source AND dest
UINT destination = *((UINT *) destinationPixel);
*((UINT *)destinationPixel) = (sourceColor & destination) | 0xFF000000;
} else
*((UINT *)destinationPixel) = sourceColor;
break;
}
default:
break;
}
}
}
}
UINT SetDIBColorTable(HDC hdc, UINT iStart, UINT cEntries, CONST RGBQUAD *prgbq) {

View file

@ -7,7 +7,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.1'
classpath 'com.android.tools.build:gradle:3.5.2'
// NOTE: Do not place your application dependencies here; they belong