| /* |
| * Enhanced MetaFile objects |
| * |
| * Copyright 1999 Huw D M Davies |
| */ |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| |
| #include "bitmap.h" |
| #include "brush.h" |
| #include "font.h" |
| #include "enhmetafiledrv.h" |
| #include "pen.h" |
| #include "debugtools.h" |
| #include "heap.h" |
| |
| DEFAULT_DEBUG_CHANNEL(enhmetafile) |
| |
| /*********************************************************************** |
| * EMFDRV_BITMAP_SelectObject |
| */ |
| static HBITMAP EMFDRV_BITMAP_SelectObject( DC * dc, HBITMAP hbitmap ) |
| { |
| return 0; |
| } |
| |
| |
| /*********************************************************************** |
| * EMFDRV_CreateBrushIndirect |
| */ |
| DWORD EMFDRV_CreateBrushIndirect( DC *dc, HBRUSH hBrush ) |
| { |
| DWORD index = 0; |
| BRUSHOBJ *brushObj = (BRUSHOBJ *)GDI_GetObjPtr( hBrush, BRUSH_MAGIC ); |
| |
| switch (brushObj->logbrush.lbStyle) { |
| case BS_SOLID: |
| case BS_HATCHED: |
| case BS_NULL: |
| { |
| EMRCREATEBRUSHINDIRECT emr; |
| emr.emr.iType = EMR_CREATEBRUSHINDIRECT; |
| emr.emr.nSize = sizeof(emr); |
| emr.ihBrush = index = EMFDRV_AddHandleDC( dc ); |
| emr.lb = brushObj->logbrush; |
| |
| if(!EMFDRV_WriteRecord( dc, &emr.emr )) |
| index = 0; |
| } |
| break; |
| case BS_DIBPATTERN: |
| { |
| EMRCREATEDIBPATTERNBRUSHPT *emr; |
| DWORD bmSize, biSize, size; |
| BITMAPINFO *info = GlobalLock16(brushObj->logbrush.lbHatch); |
| |
| if (info->bmiHeader.biCompression) |
| bmSize = info->bmiHeader.biSizeImage; |
| else |
| bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth, |
| info->bmiHeader.biHeight, |
| info->bmiHeader.biBitCount); |
| biSize = DIB_BitmapInfoSize(info, LOWORD(brushObj->logbrush.lbColor)); |
| size = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize + bmSize; |
| emr = HeapAlloc( GetProcessHeap(), 0, size ); |
| if(!emr) break; |
| emr->emr.iType = EMR_CREATEDIBPATTERNBRUSHPT; |
| emr->emr.nSize = size; |
| emr->ihBrush = index = EMFDRV_AddHandleDC( dc ); |
| emr->iUsage = LOWORD(brushObj->logbrush.lbColor); |
| emr->offBmi = sizeof(EMRCREATEDIBPATTERNBRUSHPT); |
| emr->cbBmi = biSize; |
| emr->offBits = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize; |
| memcpy((char *)emr + sizeof(EMRCREATEDIBPATTERNBRUSHPT), info, |
| biSize + bmSize ); |
| |
| if(!EMFDRV_WriteRecord( dc, &emr->emr )) |
| index = 0; |
| HeapFree( GetProcessHeap(), 0, emr ); |
| GlobalUnlock16(brushObj->logbrush.lbHatch); |
| } |
| break; |
| |
| case BS_PATTERN: |
| FIXME("Unsupported style %x\n", |
| brushObj->logbrush.lbStyle); |
| break; |
| default: |
| FIXME("Unknown style %x\n", brushObj->logbrush.lbStyle); |
| return FALSE; |
| } |
| GDI_HEAP_UNLOCK( hBrush ); |
| return index; |
| } |
| |
| |
| /*********************************************************************** |
| * EMFDRV_BRUSH_SelectObject |
| */ |
| static HBRUSH EMFDRV_BRUSH_SelectObject(DC *dc, HBRUSH hBrush ) |
| { |
| EMRSELECTOBJECT emr; |
| DWORD index; |
| HBRUSH hOldBrush; |
| |
| /* If the object is a stock brush object, do not need to create it. |
| * See definitions in wingdi.h for range of stock brushes. |
| * We do however have to handle setting the higher order bit to |
| * designate that this is a stock object. |
| */ |
| if (hBrush >= FIRST_STOCK_HANDLE && |
| hBrush <= FIRST_STOCK_HANDLE+HOLLOW_BRUSH ) |
| { |
| DWORD brush_index = hBrush - FIRST_STOCK_HANDLE; |
| index = brush_index | 0x80000000; |
| } |
| else |
| { |
| index = EMFDRV_CreateBrushIndirect(dc, hBrush ); |
| } |
| |
| if(!index) return FALSE; |
| |
| emr.emr.iType = EMR_SELECTOBJECT; |
| emr.emr.nSize = sizeof(emr); |
| emr.ihObject = index; |
| if(!EMFDRV_WriteRecord( dc, &emr.emr )) |
| return FALSE; |
| |
| hOldBrush = dc->w.hBrush; |
| dc->w.hBrush = hBrush; |
| return hOldBrush; |
| } |
| |
| |
| /****************************************************************** |
| * EMFDRV_CreateFontIndirect |
| */ |
| static BOOL EMFDRV_CreateFontIndirect(DC *dc, HFONT hFont ) |
| { |
| DWORD index = 0; |
| FONTOBJ *fontObj = (FONTOBJ *)GDI_GetObjPtr( hFont, FONT_MAGIC ); |
| EMREXTCREATEFONTINDIRECTW emr; |
| int i; |
| emr.emr.iType = EMR_EXTCREATEFONTINDIRECTW; |
| emr.emr.nSize = (sizeof(emr) + 3) / 4 * 4; |
| emr.ihFont = index = EMFDRV_AddHandleDC( dc ); |
| FONT_LogFont16To32W( &(fontObj->logfont), &(emr.elfw.elfLogFont) ); |
| emr.elfw.elfFullName[0] = '\0'; |
| emr.elfw.elfStyle[0] = '\0'; |
| emr.elfw.elfVersion = 0; |
| emr.elfw.elfStyleSize = 0; |
| emr.elfw.elfMatch = 0; |
| emr.elfw.elfReserved = 0; |
| for(i = 0; i < ELF_VENDOR_SIZE; i++) |
| emr.elfw.elfVendorId[i] = 0; |
| emr.elfw.elfCulture = PAN_CULTURE_LATIN; |
| emr.elfw.elfPanose.bFamilyType = PAN_NO_FIT; |
| emr.elfw.elfPanose.bSerifStyle = PAN_NO_FIT; |
| emr.elfw.elfPanose.bWeight = PAN_NO_FIT; |
| emr.elfw.elfPanose.bProportion = PAN_NO_FIT; |
| emr.elfw.elfPanose.bContrast = PAN_NO_FIT; |
| emr.elfw.elfPanose.bStrokeVariation = PAN_NO_FIT; |
| emr.elfw.elfPanose.bArmStyle = PAN_NO_FIT; |
| emr.elfw.elfPanose.bLetterform = PAN_NO_FIT; |
| emr.elfw.elfPanose.bMidline = PAN_NO_FIT; |
| emr.elfw.elfPanose.bXHeight = PAN_NO_FIT; |
| |
| if(!EMFDRV_WriteRecord( dc, &emr.emr )) |
| index = 0; |
| GDI_HEAP_UNLOCK( hFont ); |
| return index; |
| } |
| |
| |
| /*********************************************************************** |
| * EMFDRV_FONT_SelectObject |
| */ |
| static HFONT EMFDRV_FONT_SelectObject( DC * dc, HFONT hFont ) |
| { |
| EMRSELECTOBJECT emr; |
| DWORD index; |
| HFONT hOldFont; |
| |
| /* If the object is a stock font object, do not need to create it. |
| * See definitions in wingdi.h for range of stock fonts. |
| * We do however have to handle setting the higher order bit to |
| * designate that this is a stock object. |
| */ |
| |
| if (hFont >= STOCK_OEM_FIXED_FONT && |
| hFont <= STOCK_DEFAULT_GUI_FONT && |
| hFont != STOCK_DEFAULT_PALETTE) |
| { |
| DWORD font_index = hFont - FIRST_STOCK_HANDLE; |
| index = font_index | 0x80000000; |
| } |
| else |
| { |
| index = EMFDRV_CreateFontIndirect(dc, hFont ); |
| } |
| |
| if(!index) return FALSE; |
| |
| emr.emr.iType = EMR_SELECTOBJECT; |
| emr.emr.nSize = sizeof(emr); |
| emr.ihObject = index; |
| if(!EMFDRV_WriteRecord( dc, &emr.emr )) |
| return FALSE; |
| |
| hOldFont = dc->w.hFont; |
| dc->w.hFont = hFont; |
| return hOldFont; |
| } |
| |
| |
| |
| /****************************************************************** |
| * EMFDRV_CreatePenIndirect |
| */ |
| static HPEN EMFDRV_CreatePenIndirect(DC *dc, HPEN hPen ) |
| { |
| EMRCREATEPEN emr; |
| PENOBJ *penObj = (PENOBJ *)GDI_GetObjPtr( hPen, PEN_MAGIC ); |
| DWORD index = 0; |
| |
| emr.emr.iType = EMR_CREATEPEN; |
| emr.emr.nSize = sizeof(emr); |
| emr.ihPen = index = EMFDRV_AddHandleDC( dc ); |
| emr.lopn = penObj->logpen; |
| |
| if(!EMFDRV_WriteRecord( dc, &emr.emr )) |
| index = 0; |
| GDI_HEAP_UNLOCK( hPen ); |
| return index; |
| } |
| |
| /****************************************************************** |
| * EMFDRV_PEN_SelectObject |
| */ |
| static HPEN EMFDRV_PEN_SelectObject(DC *dc, HPEN hPen ) |
| { |
| EMRSELECTOBJECT emr; |
| DWORD index; |
| HFONT hOldPen; |
| |
| /* If the object is a stock pen object, do not need to create it. |
| * See definitions in wingdi.h for range of stock pens. |
| * We do however have to handle setting the higher order bit to |
| * designate that this is a stock object. |
| */ |
| |
| if (hPen >= STOCK_WHITE_PEN && |
| hPen <= STOCK_NULL_PEN ) |
| { |
| DWORD pen_index = hPen - FIRST_STOCK_HANDLE; |
| index = pen_index | 0x80000000; |
| } |
| else |
| { |
| index = EMFDRV_CreatePenIndirect(dc, hPen ); |
| } |
| |
| if(!index) return FALSE; |
| |
| emr.emr.iType = EMR_SELECTOBJECT; |
| emr.emr.nSize = sizeof(emr); |
| emr.ihObject = index; |
| if(!EMFDRV_WriteRecord( dc, &emr.emr )) |
| return FALSE; |
| |
| hOldPen = dc->w.hPen; |
| dc->w.hPen = hPen; |
| return hOldPen; |
| } |
| |
| |
| /*********************************************************************** |
| * EMFDRV_SelectObject |
| */ |
| HGDIOBJ EMFDRV_SelectObject( DC *dc, HGDIOBJ handle ) |
| { |
| GDIOBJHDR * ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ); |
| HGDIOBJ ret = 0; |
| |
| if (!ptr) return 0; |
| TRACE("hdc=%04x %04x\n", dc->hSelf, handle ); |
| |
| switch(ptr->wMagic) |
| { |
| case PEN_MAGIC: |
| ret = EMFDRV_PEN_SelectObject( dc, handle ); |
| break; |
| case BRUSH_MAGIC: |
| ret = EMFDRV_BRUSH_SelectObject( dc, handle ); |
| break; |
| case FONT_MAGIC: |
| ret = EMFDRV_FONT_SelectObject( dc, handle ); |
| break; |
| case BITMAP_MAGIC: |
| ret = EMFDRV_BITMAP_SelectObject( dc, handle ); |
| break; |
| } |
| GDI_HEAP_UNLOCK( handle ); |
| return ret; |
| } |
| |
| |