Commit 5735c58e authored by Dave Belanger's avatar Dave Belanger Committed by Alexandre Julliard

Improved the bounding box calculation for the EMF driver ExtTextOut

metarecord. It takes the text alignment into account.
parent 96118aea
...@@ -656,19 +656,18 @@ BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, ...@@ -656,19 +656,18 @@ BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
DWORD nSize; DWORD nSize;
BOOL ret; BOOL ret;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev; EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
int textHeight = 0;
int textWidth = 0;
const UINT textAlign = GetTextAlign(physDev->hdc);
nSize = sizeof(*pemr) + ((count+1) & ~1) * sizeof(WCHAR) + count * sizeof(INT); nSize = sizeof(*pemr) + ((count+1) & ~1) * sizeof(WCHAR) + count * sizeof(INT);
TRACE("%s count %d nSize = %ld\n", debugstr_wn(str, count), count, nSize); TRACE("%s count %d nSize = %ld\n", debugstr_wn(str, count), count, nSize);
pemr = HeapAlloc(GetProcessHeap(), 0, nSize); pemr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nSize);
pemr->emr.iType = EMR_EXTTEXTOUTW; pemr->emr.iType = EMR_EXTTEXTOUTW;
pemr->emr.nSize = nSize; pemr->emr.nSize = nSize;
/* FIXME: Calculation of these requires honouring alignment mode, escapement etc. */
pemr->rclBounds.left = pemr->rclBounds.right = x;
pemr->rclBounds.top = pemr->rclBounds.bottom = y;
pemr->iGraphicsMode = GetGraphicsMode(physDev->hdc); pemr->iGraphicsMode = GetGraphicsMode(physDev->hdc);
pemr->exScale = pemr->eyScale = 1.0; /* FIXME */ pemr->exScale = pemr->eyScale = 1.0; /* FIXME */
...@@ -688,19 +687,67 @@ BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, ...@@ -688,19 +687,67 @@ BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
pemr->emrtext.rcl.bottom = lprect->bottom; pemr->emrtext.rcl.bottom = lprect->bottom;
} }
pemr->emrtext.offDx = pemr->emrtext.offString + count * sizeof(WCHAR); pemr->emrtext.offDx = pemr->emrtext.offString + ((count+1) & ~1) * sizeof(WCHAR);
if(lpDx) if(lpDx) {
memcpy((char*)pemr + pemr->emrtext.offDx, lpDx, count * sizeof(INT)); UINT i;
else SIZE strSize;
{ memcpy((char*)pemr + pemr->emrtext.offDx, lpDx, count * sizeof(INT));
for (i = 0; i < count; i++) {
textWidth += lpDx[i];
}
GetTextExtentPoint32W(physDev->hdc, str, count, &strSize);
textHeight = strSize.cy;
}
else {
UINT i; UINT i;
INT *dx = (INT *)((char*)pemr + pemr->emrtext.offDx); INT *dx = (INT *)((char*)pemr + pemr->emrtext.offDx);
for (i = 0; i < count; i++) SIZE charSize;
{ for (i = 0; i < count; i++) {
GetCharWidth32W(physDev->hdc, str[i], str[i], &dx[i]); GetTextExtentPoint32W(physDev->hdc, str + i, 1, &charSize);
dx[i] = charSize.cx;
textWidth += charSize.cx;
textHeight = max(textHeight, charSize.cy);
} }
} }
switch (textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER)) {
case TA_CENTER: {
pemr->rclBounds.left = x - (textWidth / 2) - 1;
pemr->rclBounds.right = x + (textWidth / 2) + 1;
break;
}
case TA_RIGHT: {
pemr->rclBounds.left = x - textWidth - 1;
pemr->rclBounds.right = x;
break;
}
default: { /* TA_LEFT */
pemr->rclBounds.left = x;
pemr->rclBounds.right = x + textWidth + 1;
}
}
switch (textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE)) {
case TA_BASELINE: {
TEXTMETRICW tm;
GetTextMetricsW(physDev->hdc, &tm);
/* Play safe here... it's better to have a bounding box */
/* that is too big than too small. */
pemr->rclBounds.top = y - textHeight - 1;
pemr->rclBounds.bottom = y + tm.tmDescent + 1;
break;
}
case TA_BOTTOM: {
pemr->rclBounds.top = y - textHeight - 1;
pemr->rclBounds.bottom = y;
break;
}
default: { /* TA_TOP */
pemr->rclBounds.top = y;
pemr->rclBounds.bottom = y + textHeight + 1;
}
}
ret = EMFDRV_WriteRecord( dev, &pemr->emr ); ret = EMFDRV_WriteRecord( dev, &pemr->emr );
if(ret) if(ret)
EMFDRV_UpdateBBox( dev, &pemr->rclBounds ); EMFDRV_UpdateBBox( dev, &pemr->rclBounds );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment