BOOL nulldrv_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode ) { DC *dc = get_nulldrv_dc( dev ); switch (mode) { case MWT_IDENTITY: dc->xformWorld2Wnd.eM11 = 1.0f; dc->xformWorld2Wnd.eM12 = 0.0f; dc->xformWorld2Wnd.eM21 = 0.0f; dc->xformWorld2Wnd.eM22 = 1.0f; dc->xformWorld2Wnd.eDx = 0.0f; dc->xformWorld2Wnd.eDy = 0.0f; break; case MWT_LEFTMULTIPLY: CombineTransform( &dc->xformWorld2Wnd, xform, &dc->xformWorld2Wnd ); break; case MWT_RIGHTMULTIPLY: CombineTransform( &dc->xformWorld2Wnd, &dc->xformWorld2Wnd, xform ); break; default: return FALSE; } DC_UpdateXforms( dc ); return TRUE; }
COLORREF nulldrv_GetPixel( PHYSDEV dev, INT x, INT y ) { DC *dc = get_nulldrv_dc( dev ); char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *info = (BITMAPINFO *)buffer; struct bitblt_coords src; struct gdi_image_bits bits; COLORREF ret; src.visrect.left = x; src.visrect.top = y; LPtoDP( dev->hdc, (POINT *)&src.visrect, 1 ); src.visrect.right = src.visrect.left + 1; src.visrect.bottom = src.visrect.top + 1; src.x = src.visrect.left; src.y = src.visrect.top; src.width = src.height = 1; if (!clip_visrect( dc, &src.visrect, &src.visrect )) return CLR_INVALID; dev = GET_DC_PHYSDEV( dc, pGetImage ); if (dev->funcs->pGetImage( dev, info, &bits, &src )) return CLR_INVALID; ret = get_pixel_bitmapinfo( info, bits.ptr, &src ); if (bits.free) bits.free( &bits ); return ret; }
BOOL nulldrv_SetWorldTransform( PHYSDEV dev, const XFORM *xform ) { DC *dc = get_nulldrv_dc( dev ); dc->xformWorld2Wnd = *xform; DC_UpdateXforms( dc ); return TRUE; }
/* nulldrv fallback implementation using StretchDIBits */ BOOL CDECL nulldrv_StretchBlt( PHYSDEV dst_dev, INT xDst, INT yDst, INT widthDst, INT heightDst, PHYSDEV src_dev, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop ) { DC *dc = get_nulldrv_dc( dst_dev ); BITMAP bm; BITMAPINFOHEADER info_hdr; HBITMAP hbm; LPVOID bits; INT lines; POINT pts[2]; /* make sure we have a real implementation for StretchDIBits */ if (GET_DC_PHYSDEV( dc, pStretchDIBits ) == dst_dev) return 0; pts[0].x = xSrc; pts[0].y = ySrc; pts[1].x = xSrc + widthSrc; pts[1].y = ySrc + heightSrc; LPtoDP( src_dev->hdc, pts, 2 ); xSrc = pts[0].x; ySrc = pts[0].y; widthSrc = pts[1].x - pts[0].x; heightSrc = pts[1].y - pts[0].y; if (GetObjectType( src_dev->hdc ) != OBJ_MEMDC) return FALSE; if (!GetObjectW( GetCurrentObject( src_dev->hdc, OBJ_BITMAP ), sizeof(bm), &bm )) return FALSE; info_hdr.biSize = sizeof(info_hdr); info_hdr.biWidth = bm.bmWidth; info_hdr.biHeight = bm.bmHeight; info_hdr.biPlanes = 1; info_hdr.biBitCount = 32; info_hdr.biCompression = BI_RGB; info_hdr.biSizeImage = 0; info_hdr.biXPelsPerMeter = 0; info_hdr.biYPelsPerMeter = 0; info_hdr.biClrUsed = 0; info_hdr.biClrImportant = 0; if (!(bits = HeapAlloc(GetProcessHeap(), 0, bm.bmHeight * bm.bmWidth * 4))) return FALSE; /* Select out the src bitmap before calling GetDIBits */ hbm = SelectObject( src_dev->hdc, GetStockObject(DEFAULT_BITMAP) ); lines = GetDIBits( src_dev->hdc, hbm, 0, bm.bmHeight, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS ); SelectObject( src_dev->hdc, hbm ); if (lines) lines = StretchDIBits( dst_dev->hdc, xDst, yDst, widthDst, heightDst, xSrc, bm.bmHeight - heightSrc - ySrc, widthSrc, heightSrc, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS, rop ); HeapFree( GetProcessHeap(), 0, bits ); return (lines == heightSrc); }
INT nulldrv_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) { DC *dc = get_nulldrv_dc( dev ); RECT rect = get_clip_rect( dc, left, top, right, bottom ); INT ret; HRGN rgn; if (!(rgn = CreateRectRgnIndirect( &rect ))) return ERROR; if (!dc->hClipRgn) create_default_clip_region( dc ); ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, rgn, RGN_DIFF ); DeleteObject( rgn ); if (ret != ERROR) update_dc_clipping( dc ); return ret; }
BOOL nulldrv_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) { DC *dc = get_nulldrv_dc( dev ); if (pt) { pt->x = dc->wndOrgX; pt->y = dc->wndOrgY; } dc->wndOrgX += x; dc->wndOrgY += y; DC_UpdateXforms( dc ); return TRUE; }
BOOL nulldrv_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) { DC *dc = get_nulldrv_dc( dev ); if (pt) { pt->x = dc->vportOrgX; pt->y = dc->vportOrgY; } dc->vportOrgX = x; dc->vportOrgY = y; DC_UpdateXforms( dc ); return TRUE; }
BOOL nulldrv_PolyBezierTo( PHYSDEV dev, const POINT *points, DWORD count ) { DC *dc = get_nulldrv_dc( dev ); BOOL ret = FALSE; POINT *pts = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT) * (count + 1) ); if (pts) { pts[0] = dc->cur_pos; memcpy( pts + 1, points, sizeof(POINT) * count ); ret = PolyBezier( dev->hdc, pts, count + 1 ); HeapFree( GetProcessHeap(), 0, pts ); } return ret; }
INT nulldrv_OffsetClipRgn( PHYSDEV dev, INT x, INT y ) { DC *dc = get_nulldrv_dc( dev ); INT ret = NULLREGION; if (dc->hClipRgn) { x = MulDiv( x, dc->vport_ext.cx, dc->wnd_ext.cx ); y = MulDiv( y, dc->vport_ext.cy, dc->wnd_ext.cy ); if (dc->layout & LAYOUT_RTL) x = -x; ret = OffsetRgn( dc->hClipRgn, x, y ); update_dc_clipping( dc ); } return ret; }
DWORD nulldrv_BlendImage( PHYSDEV dev, BITMAPINFO *info, const struct gdi_image_bits *bits, struct bitblt_coords *src, struct bitblt_coords *dst, BLENDFUNCTION blend ) { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *dst_info = (BITMAPINFO *)buffer; struct gdi_image_bits dst_bits; struct bitblt_coords orig_dst; DWORD *masks = (DWORD *)info->bmiColors; DC *dc = get_nulldrv_dc( dev ); DWORD err; if (info->bmiHeader.biPlanes != 1) goto update_format; if (info->bmiHeader.biBitCount != 32) goto update_format; if (info->bmiHeader.biCompression == BI_BITFIELDS) { if (blend.AlphaFormat & AC_SRC_ALPHA) return ERROR_INVALID_PARAMETER; if (masks[0] != 0xff0000 || masks[1] != 0x00ff00 || masks[2] != 0x0000ff) goto update_format; } if (!bits) return ERROR_SUCCESS; if ((src->width != dst->width) || (src->height != dst->height)) return ERROR_TRANSFORM_NOT_SUPPORTED; dev = GET_DC_PHYSDEV( dc, pGetImage ); orig_dst = *dst; err = dev->funcs->pGetImage( dev, dst_info, &dst_bits, dst ); if (err) return err; dev = GET_DC_PHYSDEV( dc, pPutImage ); err = blend_bits( info, bits, src, dst_info, &dst_bits, dst, blend ); if (!err) err = dev->funcs->pPutImage( dev, 0, dst_info, &dst_bits, dst, &orig_dst, SRCCOPY ); if (dst_bits.free) dst_bits.free( &dst_bits ); return err; update_format: if (blend.AlphaFormat & AC_SRC_ALPHA) /* source alpha requires A8R8G8B8 format */ return ERROR_INVALID_PARAMETER; info->bmiHeader.biPlanes = 1; info->bmiHeader.biBitCount = 32; info->bmiHeader.biCompression = BI_BITFIELDS; info->bmiHeader.biClrUsed = 0; masks[0] = 0xff0000; masks[1] = 0x00ff00; masks[2] = 0x0000ff; return ERROR_BAD_FORMAT; }
INT nulldrv_ExtSelectClipRgn( PHYSDEV dev, HRGN rgn, INT mode ) { DC *dc = get_nulldrv_dc( dev ); INT ret; if (!rgn) { switch (mode) { case RGN_COPY: if (dc->hClipRgn) DeleteObject( dc->hClipRgn ); dc->hClipRgn = 0; ret = SIMPLEREGION; break; case RGN_DIFF: return ERROR; default: FIXME("Unimplemented: hrgn NULL in mode: %d\n", mode); return ERROR; } } else { HRGN mirrored = 0; if (dc->layout & LAYOUT_RTL) { if (!(mirrored = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR; mirror_region( mirrored, rgn, dc->vis_rect.right - dc->vis_rect.left ); rgn = mirrored; } if (!dc->hClipRgn) create_default_clip_region( dc ); if (mode == RGN_COPY) ret = CombineRgn( dc->hClipRgn, rgn, 0, mode ); else ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, rgn, mode); if (mirrored) DeleteObject( mirrored ); } update_dc_clipping( dc ); return ret; }
BOOL nulldrv_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size ) { DC *dc = get_nulldrv_dc( dev ); if (size) { size->cx = dc->vportExtX; size->cy = dc->vportExtY; } if (dc->MapMode != MM_ISOTROPIC && dc->MapMode != MM_ANISOTROPIC) return TRUE; if (!cx || !cy) return FALSE; dc->vportExtX = cx; dc->vportExtY = cy; if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc ); DC_UpdateXforms( dc ); return TRUE; }
BOOL nulldrv_ScaleViewportExtEx( PHYSDEV dev, INT x_num, INT x_denom, INT y_num, INT y_denom, SIZE *size ) { DC *dc = get_nulldrv_dc( dev ); if (size) { size->cx = dc->vportExtX; size->cy = dc->vportExtY; } if (dc->MapMode != MM_ISOTROPIC && dc->MapMode != MM_ANISOTROPIC) return TRUE; if (!x_num || !x_denom || !y_num || !y_denom) return FALSE; dc->vportExtX = (dc->vportExtX * x_num) / x_denom; dc->vportExtY = (dc->vportExtY * y_num) / y_denom; if (dc->vportExtX == 0) dc->vportExtX = 1; if (dc->vportExtY == 0) dc->vportExtY = 1; if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc ); DC_UpdateXforms( dc ); return TRUE; }
BOOL nulldrv_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size ) { DC *dc = get_nulldrv_dc( dev ); if (size) { size->cx = dc->wndExtX; size->cy = dc->wndExtY; } if (dc->MapMode != MM_ISOTROPIC && dc->MapMode != MM_ANISOTROPIC) return TRUE; if (!cx || !cy) return FALSE; dc->wndExtX = cx; dc->wndExtY = cy; /* The API docs say that you should call SetWindowExtEx before SetViewportExtEx. This advice does not imply that Windows doesn't ensure the isotropic mapping after SetWindowExtEx! */ if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc ); DC_UpdateXforms( dc ); return TRUE; }
INT nulldrv_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) { DC *dc = get_nulldrv_dc( dev ); RECT rect = get_clip_rect( dc, left, top, right, bottom ); INT ret; HRGN rgn; if (!dc->hClipRgn) { dc->hClipRgn = CreateRectRgnIndirect( &rect ); ret = SIMPLEREGION; } else { if (!(rgn = CreateRectRgnIndirect( &rect ))) return ERROR; ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, rgn, RGN_AND ); DeleteObject( rgn ); } if (ret != ERROR) update_dc_clipping( dc ); return ret; }
BOOL nulldrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst, PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION func ) { DC *dc_src, *dc_dst = get_nulldrv_dc( dst_dev ); char src_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; char dst_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *src_info = (BITMAPINFO *)src_buffer; BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer; DWORD err; struct gdi_image_bits bits; if (!(dc_src = get_dc_ptr( src_dev->hdc ))) return FALSE; src_dev = GET_DC_PHYSDEV( dc_src, pGetImage ); err = src_dev->funcs->pGetImage( src_dev, src_info, &bits, src ); if (err) goto done; dst_dev = GET_DC_PHYSDEV( dc_dst, pBlendImage ); copy_bitmapinfo( dst_info, src_info ); err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func ); if (err == ERROR_BAD_FORMAT) { err = convert_bits( src_info, src, dst_info, &bits ); if (!err) err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func ); } if (err == ERROR_TRANSFORM_NOT_SUPPORTED && ((src->width != dst->width) || (src->height != dst->height))) { copy_bitmapinfo( src_info, dst_info ); err = stretch_bits( src_info, src, dst_info, dst, &bits, COLORONCOLOR ); if (!err) err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func ); } if (bits.free) bits.free( &bits ); done: release_dc_ptr( dc_src ); if (err) SetLastError( err ); return !err; }
BOOL nulldrv_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert, void * grad_array, ULONG ngrad, ULONG mode ) { DC *dc = get_nulldrv_dc( dev ); char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *info = (BITMAPINFO *)buffer; struct bitblt_coords src, dst; struct gdi_image_bits bits; unsigned int i; POINT *pts; BOOL ret = FALSE; DWORD err; HRGN rgn; if (!(pts = HeapAlloc( GetProcessHeap(), 0, nvert * sizeof(*pts) ))) return FALSE; for (i = 0; i < nvert; i++) { pts[i].x = vert_array[i].x; pts[i].y = vert_array[i].y; } LPtoDP( dev->hdc, pts, nvert ); /* compute bounding rect of all the rectangles/triangles */ reset_bounds( &dst.visrect ); for (i = 0; i < ngrad * (mode == GRADIENT_FILL_TRIANGLE ? 3 : 2); i++) { ULONG v = ((ULONG *)grad_array)[i]; dst.visrect.left = min( dst.visrect.left, pts[v].x ); dst.visrect.top = min( dst.visrect.top, pts[v].y ); dst.visrect.right = max( dst.visrect.right, pts[v].x ); dst.visrect.bottom = max( dst.visrect.bottom, pts[v].y ); } dst.x = dst.visrect.left; dst.y = dst.visrect.top; dst.width = dst.visrect.right - dst.visrect.left; dst.height = dst.visrect.bottom - dst.visrect.top; if (!clip_visrect( dc, &dst.visrect, &dst.visrect )) goto done; /* query the bitmap format */ info->bmiHeader.biSize = sizeof(info->bmiHeader); info->bmiHeader.biPlanes = 1; info->bmiHeader.biBitCount = 0; info->bmiHeader.biCompression = BI_RGB; info->bmiHeader.biXPelsPerMeter = 0; info->bmiHeader.biYPelsPerMeter = 0; info->bmiHeader.biClrUsed = 0; info->bmiHeader.biClrImportant = 0; info->bmiHeader.biWidth = dst.visrect.right - dst.visrect.left; info->bmiHeader.biHeight = dst.visrect.bottom - dst.visrect.top; info->bmiHeader.biSizeImage = 0; dev = GET_DC_PHYSDEV( dc, pPutImage ); err = dev->funcs->pPutImage( dev, 0, info, NULL, NULL, NULL, 0 ); if (err && err != ERROR_BAD_FORMAT) goto done; info->bmiHeader.biSizeImage = get_dib_image_size( info ); if (!(bits.ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage ))) goto done; bits.is_copy = TRUE; bits.free = free_heap_bits; /* make src and points relative to the bitmap */ src = dst; src.x -= dst.visrect.left; src.y -= dst.visrect.top; offset_rect( &src.visrect, -dst.visrect.left, -dst.visrect.top ); for (i = 0; i < nvert; i++) { pts[i].x -= dst.visrect.left; pts[i].y -= dst.visrect.top; } rgn = CreateRectRgn( 0, 0, 0, 0 ); gradient_bitmapinfo( info, bits.ptr, vert_array, nvert, grad_array, ngrad, mode, pts, rgn ); OffsetRgn( rgn, dst.visrect.left, dst.visrect.top ); ret = !dev->funcs->pPutImage( dev, rgn, info, &bits, &src, &dst, SRCCOPY ); if (bits.free) bits.free( &bits ); DeleteObject( rgn ); done: HeapFree( GetProcessHeap(), 0, pts ); return ret; }
BOOL nulldrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst, PHYSDEV src_dev, struct bitblt_coords *src, DWORD rop ) { DC *dc_src, *dc_dst = get_nulldrv_dc( dst_dev ); char src_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; char dst_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *src_info = (BITMAPINFO *)src_buffer; BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer; DWORD err; struct gdi_image_bits bits; if (!(dc_src = get_dc_ptr( src_dev->hdc ))) return FALSE; src_dev = GET_DC_PHYSDEV( dc_src, pGetImage ); if (src_dev->funcs->pGetImage( src_dev, src_info, &bits, src )) { release_dc_ptr( dc_src ); return FALSE; } dst_dev = GET_DC_PHYSDEV( dc_dst, pPutImage ); copy_bitmapinfo( dst_info, src_info ); err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &bits, src, dst, rop ); if (err == ERROR_BAD_FORMAT) { DWORD dst_colors = dst_info->bmiHeader.biClrUsed; /* 1-bpp source without a color table uses the destination DC colors */ if (src_info->bmiHeader.biBitCount == 1 && !src_info->bmiHeader.biClrUsed) get_mono_dc_colors( dst_dev->hdc, src_info, 2 ); if (dst_info->bmiHeader.biBitCount == 1 && !dst_colors) { /* 1-bpp destination without a color table requires a fake 1-entry table * that contains only the background color; except with a 1-bpp source, * in which case it uses the source colors */ if (src_info->bmiHeader.biBitCount > 1) get_mono_dc_colors( src_dev->hdc, dst_info, 1 ); else get_mono_dc_colors( src_dev->hdc, dst_info, 2 ); } if (!(err = convert_bits( src_info, src, dst_info, &bits ))) { /* get rid of the fake destination table */ dst_info->bmiHeader.biClrUsed = dst_colors; err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &bits, src, dst, rop ); } } if (err == ERROR_TRANSFORM_NOT_SUPPORTED && ((src->width != dst->width) || (src->height != dst->height))) { copy_bitmapinfo( src_info, dst_info ); err = stretch_bits( src_info, src, dst_info, dst, &bits, GetStretchBltMode( dst_dev->hdc )); if (!err) err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &bits, src, dst, rop ); } if (bits.free) bits.free( &bits ); release_dc_ptr( dc_src ); return !err; }
BOOL nulldrv_PolyDraw( PHYSDEV dev, const POINT *points, const BYTE *types, DWORD count ) { DC *dc = get_nulldrv_dc( dev ); POINT *line_pts = NULL, *bzr_pts = NULL, bzr[4]; DWORD i; INT num_pts, num_bzr_pts, space, size; /* check for valid point types */ for (i = 0; i < count; i++) { switch (types[i]) { case PT_MOVETO: case PT_LINETO | PT_CLOSEFIGURE: case PT_LINETO: break; case PT_BEZIERTO: if (i + 2 >= count) return FALSE; if (types[i + 1] != PT_BEZIERTO) return FALSE; if ((types[i + 2] & ~PT_CLOSEFIGURE) != PT_BEZIERTO) return FALSE; i += 2; break; default: return FALSE; } } space = count + 300; line_pts = HeapAlloc( GetProcessHeap(), 0, space * sizeof(POINT) ); num_pts = 1; line_pts[0] = dc->cur_pos; for (i = 0; i < count; i++) { switch (types[i]) { case PT_MOVETO: if (num_pts >= 2) Polyline( dev->hdc, line_pts, num_pts ); num_pts = 0; line_pts[num_pts++] = points[i]; break; case PT_LINETO: case (PT_LINETO | PT_CLOSEFIGURE): line_pts[num_pts++] = points[i]; break; case PT_BEZIERTO: bzr[0].x = line_pts[num_pts - 1].x; bzr[0].y = line_pts[num_pts - 1].y; memcpy( &bzr[1], &points[i], 3 * sizeof(POINT) ); if ((bzr_pts = GDI_Bezier( bzr, 4, &num_bzr_pts ))) { size = num_pts + (count - i) + num_bzr_pts; if (space < size) { space = size * 2; line_pts = HeapReAlloc( GetProcessHeap(), 0, line_pts, space * sizeof(POINT) ); } memcpy( &line_pts[num_pts], &bzr_pts[1], (num_bzr_pts - 1) * sizeof(POINT) ); num_pts += num_bzr_pts - 1; HeapFree( GetProcessHeap(), 0, bzr_pts ); } i += 2; break; } if (types[i] & PT_CLOSEFIGURE) line_pts[num_pts++] = line_pts[0]; } if (num_pts >= 2) Polyline( dev->hdc, line_pts, num_pts ); HeapFree( GetProcessHeap(), 0, line_pts ); return TRUE; }
INT nulldrv_SetMapMode( PHYSDEV dev, INT mode ) { DC *dc = get_nulldrv_dc( dev ); INT ret = dc->MapMode; INT horzSize, vertSize, horzRes, vertRes; if (mode == dc->MapMode && (mode == MM_ISOTROPIC || mode == MM_ANISOTROPIC)) return ret; horzSize = dc->virtual_size.cx; vertSize = dc->virtual_size.cy; horzRes = dc->virtual_res.cx; vertRes = dc->virtual_res.cy; switch (mode) { case MM_TEXT: dc->wndExtX = 1; dc->wndExtY = 1; dc->vportExtX = 1; dc->vportExtY = 1; break; case MM_LOMETRIC: case MM_ISOTROPIC: dc->wndExtX = horzSize * 10; dc->wndExtY = vertSize * 10; dc->vportExtX = horzRes; dc->vportExtY = -vertRes; break; case MM_HIMETRIC: dc->wndExtX = horzSize * 100; dc->wndExtY = vertSize * 100; dc->vportExtX = horzRes; dc->vportExtY = -vertRes; break; case MM_LOENGLISH: dc->wndExtX = MulDiv(1000, horzSize, 254); dc->wndExtY = MulDiv(1000, vertSize, 254); dc->vportExtX = horzRes; dc->vportExtY = -vertRes; break; case MM_HIENGLISH: dc->wndExtX = MulDiv(10000, horzSize, 254); dc->wndExtY = MulDiv(10000, vertSize, 254); dc->vportExtX = horzRes; dc->vportExtY = -vertRes; break; case MM_TWIPS: dc->wndExtX = MulDiv(14400, horzSize, 254); dc->wndExtY = MulDiv(14400, vertSize, 254); dc->vportExtX = horzRes; dc->vportExtY = -vertRes; break; case MM_ANISOTROPIC: break; default: return 0; } /* RTL layout is always MM_ANISOTROPIC */ if (!(dc->layout & LAYOUT_RTL)) dc->MapMode = mode; DC_UpdateXforms( dc ); return ret; }