diff --git a/ChangeLog b/ChangeLog index d932b5c..90be89f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2003-12-23 Fred Kiefer + + * Source/winlib/WIN32GState.m (-copyBits:fromRect:toPoint:): Made + save against self and source being the same object and corrected + computation for flipped views. This code is copied over from xlib. + * Source/winlib/WIN32FontEnumerator.m Reimplemented the whole file. + * Source/winlib/WIN32FontInfo.m (-setupAttributes) assign font + family ivar and use common functions with font enumerator. + * Source/win32/WIN32ServerEvent.m (WIN32Server + -windowEventProc::::) flag that we handle erasing of the + background ourselves. (invalidateWindow) copy from backing store + if possible. + 2003-12-03 Adam Fedor * Headers/win32/WIN32Server.h: Add ivars currentFocus, desiredFocus. diff --git a/Source/win32/WIN32ServerEvent.m b/Source/win32/WIN32ServerEvent.m index 0b51209..38eed36 100755 --- a/Source/win32/WIN32ServerEvent.m +++ b/Source/win32/WIN32ServerEvent.m @@ -414,6 +414,8 @@ static void invalidateWindow(HWND hwnd, RECT rect); case WM_ERASEBKGND: NSDebugLLog(@"NSEvent", @"Got Message %s for %d", "ERASEBKGND", hwnd); + // Handle background painting ourselves. + return (LRESULT)1; break; case WM_PAINT: { @@ -860,15 +862,36 @@ process_mouse_event(HWND hwnd, WPARAM wParam, LPARAM lParam, static void invalidateWindow(HWND hwnd, RECT rect) { - NSWindow *window = GSWindowWithNumber((int)hwnd); - NSRect r = MSWindowRectToGS((HWND)hwnd, rect); + WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)hwnd, GWL_USERDATA); - /* - NSLog(@"Invalidated window %d %@ (%d, %d, %d, %d)", hwnd, - NSStringFromRect(r), rect.left, rect.top, rect.right, rect.bottom); - */ - // Repaint the window's client area. - [[window contentView] setNeedsDisplayInRect: r]; + if (win->useHDC) + { + HDC hdc = GetDC((HWND)hwnd); + WINBOOL result; + + result = BitBlt(hdc, rect.left, rect.top, + (rect.right - rect.left), (rect.bottom - rect.top), + win->hdc, rect.left, rect.top, SRCCOPY); + if (!result) + { + NSLog(@"validated window %d %@", hwnd, + NSStringFromRect(MSWindowRectToGS((HWND)hwnd, rect))); + NSLog(@"validateWindow failed %d", GetLastError()); + } + ReleaseDC((HWND)hwnd, hdc); + } + else + { + NSWindow *window = GSWindowWithNumber((int)hwnd); + NSRect r = MSWindowRectToGS((HWND)hwnd, rect); + + /* + NSLog(@"Invalidated window %d %@ (%d, %d, %d, %d)", hwnd, + NSStringFromRect(r), rect.left, rect.top, rect.right, rect.bottom); + */ + // Repaint the window's client area. + [[window contentView] setNeedsDisplayInRect: r]; + } } LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, diff --git a/Source/winlib/WIN32FontEnumerator.m b/Source/winlib/WIN32FontEnumerator.m index 260b68b..3dbf08b 100644 --- a/Source/winlib/WIN32FontEnumerator.m +++ b/Source/winlib/WIN32FontEnumerator.m @@ -22,59 +22,233 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "Foundation/NSValue.h" #include "Foundation/NSArray.h" +#include #include "Foundation/NSDictionary.h" +#include "Foundation/NSValue.h" #include "winlib/WIN32FontEnumerator.h" +#include "windows.h" @implementation WIN32FontEnumerator -- (void) enumerateFontsAndFamilies +int win32_font_weight(LONG tmWeight) { - /* - int CALLBACK EnumFontFamProc( - ENUMLOGFONT *lpelf, // logical-font data - NEWTEXTMETRIC *lpntm, // physical-font data - DWORD FontType, // type of font - LPARAM lParam // application-defined data -); + int weight; - EnumFontFamilies(hdc, (LPCTSTR) NULL, - (FONTENUMPROC) EnumFamCallBack, (LPARAM) aFontCount); - - if (cache == nil) + // The MS names are a bit different from the NS ones! + switch (tmWeight) { - if (load_cache(cache_name(), NO)) - { - allFontNames = [[cache objectForKey: @"AllFontNames"] allObjects]; - allFontFamilies = [cache objectForKey: @"AllFontFamilies"]; - // This dictionary stores the XLFD for each font - creationDictionary = [cache objectForKey: @"CreationDictionary"]; + case FW_THIN: + weight = 1; + break; + case FW_EXTRALIGHT: + weight = 2; + break; + case FW_LIGHT: + weight = 3; + break; + case FW_REGULAR: + weight = 5; + break; + case FW_MEDIUM: + weight = 6; + break; + case FW_DEMIBOLD: + weight = 7; + break; + case FW_BOLD: + weight = 9; + break; + case FW_EXTRABOLD: + weight = 10; + break; + case FW_BLACK: + weight = 12; + break; + default: + // Try to map the range 0 to 1000 into 1 to 14. + weight = (int)(tmWeight * 14 / 1000); + break; + } + + return weight; +} + +// FIXME +NSString *fontStyles[] = {@" Italic", @" Oblique", @" Bold", + @" BoldItalic", @" Demibold", + @" Normal", @" Kursiv", @" Fett"}; + +NSString *win32_font_family(NSString *fontName) +{ + NSString *fontFamily; + int i; + int max = sizeof(fontStyles) / sizeof(NSString*); + + fontFamily = fontName; + for (i = 0; i < max; i++) + { + if ([fontFamily hasSuffix: fontStyles[i]]) + { + fontFamily = [fontFamily substringToIndex: + ([fontFamily length] - + [fontStyles[i] length])]; } } - */ + + //NSLog(@"Font Family %@ for %@", fontFamily, fontName); + return fontFamily; +} + +static +void add_font(NSMutableArray *fontDefs, NSString *fontName, + ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme) +{ + NSArray *fontDef; + NSFontTraitMask traits = 0; + int weight; + + weight = win32_font_weight(lpntme->ntmTm.tmWeight); + if (weight >= 9) + traits |= NSBoldFontMask; + else + traits |= NSUnboldFontMask; + + if (lpntme->ntmTm.tmItalic) + traits |= NSItalicFontMask; + else + traits |= NSUnitalicFontMask; + + fontDef = [NSArray arrayWithObjects: fontName, + [NSString stringWithCString: lpelfe->elfStyle], + [NSNumber numberWithInt: weight], + [NSNumber numberWithUnsignedInt: traits], nil]; + [fontDefs addObject: fontDef]; +} + +int CALLBACK fontenum(ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, + DWORD FontType, LPARAM lParam) +{ + NSString *fontName; + + NSLog(@"Found font %s", lpelfe->elfFullName); + fontName = [NSString stringWithCString: lpelfe->elfFullName]; + add_font((NSMutableArray *)lParam, fontName, lpelfe, lpntme); + + return 1; +} + +static +void enumerate_font(NSMutableArray *fontDefs, NSString *fontFamily) +{ + HDC hdc; + LOGFONT logfont; + int res; + CREATE_AUTORELEASE_POOL(pool); + + NSLog(@"Enumerate font family %@", fontFamily); + hdc = GetDC(NULL); + logfont.lfCharSet = DEFAULT_CHARSET; + strncpy(logfont.lfFaceName, [fontFamily cString], LF_FACESIZE); + logfont.lfPitchAndFamily = 0; + res = EnumFontFamiliesEx(hdc, &logfont, (FONTENUMPROC)fontenum, + (LPARAM)fontDefs, 0); + ReleaseDC(NULL, hdc); + RELEASE(pool); +} + +int CALLBACK fontfamilyenum(ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, + DWORD FontType, LPARAM lParam) +{ + NSString *fontName; + NSString *familyName; + NSMutableArray *fontDefs; + WIN32FontEnumerator *enumer = (WIN32FontEnumerator*)lParam; + + //NSLog(@"Found font family %s", lpelfe->elfFullName); + fontName = [NSString stringWithCString: lpelfe->elfFullName]; + familyName = win32_font_family(fontName); + fontDefs = [enumer->allFontFamilies objectForKey: familyName]; + if (fontDefs == nil) + { + NSArray *fontDef; + + fontDefs = [NSMutableArray arrayWithCapacity: 10]; + [enumer->allFontFamilies setObject: fontDefs forKey: familyName]; + // FIXME: Need to loop over all fonts for this family + //add_font(fontDefs, fontName, lpelfe, lpntme); + //enumerate_font(fontDefs, familyName); + fontDef = [NSArray arrayWithObjects: familyName, + @"Normal", + [NSNumber numberWithInt: 6], + [NSNumber numberWithUnsignedInt: 0], nil]; + [fontDefs addObject: fontDef]; + fontDef = [NSArray arrayWithObjects: [familyName stringByAppendingString: @" Bold"], + @"Bold", + [NSNumber numberWithInt: 9], + [NSNumber numberWithUnsignedInt: NSBoldFontMask], nil]; + [fontDefs addObject: fontDef]; + fontDef = [NSArray arrayWithObjects: [familyName stringByAppendingString: @" Italic"], + @"Italic", + [NSNumber numberWithInt: 6], + [NSNumber numberWithUnsignedInt: NSItalicFontMask], nil]; + [fontDefs addObject: fontDef]; + fontDef = [NSArray arrayWithObjects: [familyName stringByAppendingString: @" Bold Italic"], + @"Bold Italic", + [NSNumber numberWithInt: 9], + [NSNumber numberWithUnsignedInt: NSBoldFontMask | NSItalicFontMask], nil]; + [fontDefs addObject: fontDef]; + + [(NSMutableArray*)(enumer->allFontNames) addObject: fontName]; + } + + return 1; +} + +- (void) enumerateFontsAndFamilies +{ static BOOL done = NO; if (!done) { - NSArray *fontDef; - NSMutableArray *fontDefs; + HDC hdc; + LOGFONT logfont; + int res; + CREATE_AUTORELEASE_POOL(pool); - ASSIGN(allFontNames, [NSArray arrayWithObject: @"Helvetica"]); allFontFamilies = [[NSMutableDictionary alloc] init]; + allFontNames = [[NSMutableArray alloc] init]; + + hdc = GetDC(NULL); + logfont.lfCharSet = DEFAULT_CHARSET; + logfont.lfFaceName[0] = '\0'; + logfont.lfPitchAndFamily = 0; + // This get ignored + logfont.lfItalic = 0; + logfont.lfWeight = FW_NORMAL; + res = EnumFontFamiliesEx(hdc, &logfont, (FONTENUMPROC)fontfamilyenum, + (LPARAM)self, 0); - fontDefs = [NSMutableArray arrayWithCapacity: 10]; - [allFontFamilies setObject: fontDefs forKey: @"Helvetica"]; - - - fontDef = [NSArray arrayWithObjects: @"Helvetica", @"", - [NSNumber numberWithInt: 6], - [NSNumber numberWithUnsignedInt: 0], nil]; - [fontDefs addObject: fontDef]; - + ReleaseDC(NULL, hdc); + RELEASE(pool); done = YES; } } +- (NSString*) defaultSystemFontName +{ + return @"Tahoma"; +} + +- (NSString*) defaultBoldSystemFontName +{ + return @"Tahoma Bold"; +} + +- (NSString*) defaultFixedPitchFontName +{ + return @"Courier New"; +} + @end diff --git a/Source/winlib/WIN32FontInfo.m b/Source/winlib/WIN32FontInfo.m index 23f7b24..3a39035 100644 --- a/Source/winlib/WIN32FontInfo.m +++ b/Source/winlib/WIN32FontInfo.m @@ -30,6 +30,9 @@ #include "winlib/WIN32FontInfo.h" +int win32_font_weight(LONG tmWeight); +NSString *win32_font_family(NSString *fontName); + @interface WIN32FontInfo (Private) - (BOOL) setupAttributes; @end @@ -214,9 +217,12 @@ NSRange range; //NSLog(@"Creating Font %@ of size %f", fontName, matrix[0]); + ASSIGN(familyName, win32_font_family(fontName)); memset(&logfont, 0, sizeof(LOGFONT)); + hdc = GetDC(NULL); // FIXME This hack gets the font size about right, but what is the real solution? logfont.lfHeight = (int)(matrix[0] * 4 / 3); + //logfont.lfHeight = -MulDiv(matrix[0], GetDeviceCaps(hdc, LOGPIXELSY), 72); range = [fontName rangeOfString: @"Bold"]; if (range.length) @@ -227,22 +233,21 @@ logfont.lfItalic = 1; logfont.lfQuality = ANTIALIASED_QUALITY; - strncpy(logfont.lfFaceName, [fontName cString], LF_FACESIZE); + strncpy(logfont.lfFaceName, [familyName cString], LF_FACESIZE); hFont = CreateFontIndirect(&logfont); if (!hFont) { NSLog(@"Could not create font %@", fontName); + ReleaseDC(NULL, hdc); return NO; } - hdc = GetDC(NULL); old = SelectObject(hdc, hFont); GetTextMetrics(hdc, &metric); SelectObject(hdc, old); ReleaseDC(NULL, hdc); // Fill the ivars - // NSAFMFamilyName isFixedPitch = TMPF_FIXED_PITCH & metric.tmPitchAndFamily; isBaseFont = NO; ascender = metric.tmAscent; @@ -254,42 +259,9 @@ (float)metric.tmMaxCharWidth, (float)metric.tmHeight); - // The MS names are a bit different from the NS ones! - switch (metric.tmWeight) - { - case FW_THIN: - weight = 1; - break; - case FW_EXTRALIGHT: - weight = 2; - break; - case FW_LIGHT: - weight = 3; - break; - case FW_REGULAR: - weight = 5; - break; - case FW_MEDIUM: - weight = 6; - break; - case FW_DEMIBOLD: - weight = 7; - break; - case FW_BOLD: - weight = 9; - break; - case FW_EXTRABOLD: - weight = 10; - break; - case FW_BLACK: - weight = 12; - break; - default: - // Try to map the range 0 to 1000 into 1 to 14. - weight = (int)(metric.tmWeight * 14 / 1000); - break; - } + weight = win32_font_weight(metric.tmWeight); + traits = 0; if (weight >= 9) traits |= NSBoldFontMask; else @@ -300,7 +272,7 @@ else traits |= NSUnitalicFontMask; - // Should come from metric.tmCharSet + // FIXME Should come from metric.tmCharSet mostCompatibleStringEncoding = NSISOLatin1StringEncoding; return YES; diff --git a/Source/winlib/WIN32GState.m b/Source/winlib/WIN32GState.m index c558570..02a3603 100644 --- a/Source/winlib/WIN32GState.m +++ b/Source/winlib/WIN32GState.m @@ -173,42 +173,57 @@ RECT GSViewRectToWin(WIN32GState *s, NSRect r) { HDC otherDC; HDC hDC; - POINT p; RECT rect; int h; - int y1; + int x; + int y; + NSRect r; + RECT rect2; - p = GSViewPointToWin(self, aPoint); rect = GSViewRectToWin(source, aRect); h = rect.bottom - rect.top; - if (viewIsFlipped) - y1 = p.y; - else - y1 = p.y - h; + r.size = aRect.size; + r.origin = aPoint; + rect2 = GSViewRectToWin(self, r); + x = rect2.left; + y = rect2.top; + if (source->ctm->matrix.m22 < 0 && ctm->matrix.m22 > 0) y += h; + if (source->ctm->matrix.m22 > 0 && ctm->matrix.m22 < 0) y -= h; otherDC = [source getHDC]; if (!otherDC) { return; - } - hDC = [self getHDC]; - if (!hDC) + } + if (self == source) { - [source releaseHDC: otherDC]; - return; + hDC = otherDC; } + else + { + hDC = [self getHDC]; + if (!hDC) + { + [source releaseHDC: otherDC]; + return; + } + } - if (!BitBlt(hDC, p.x, y1, (rect.right - rect.left), h, + if (!BitBlt(hDC, x, y, (rect.right - rect.left), h, otherDC, rect.left, rect.top, SRCCOPY)) { NSLog(@"Copy bitmap failed %d", GetLastError()); NSLog(@"Orig Copy Bits to %f, %f from %@", aPoint.x, aPoint.y, NSStringFromRect(aRect)); - NSLog(@"Copy Bits to %d %d from %d %d size %d %d", p.x , y1, + NSLog(@"Copy Bits to %d %d from %d %d size %d %d", x , y, rect.left, rect.top, (rect.right - rect.left), h); } - [self releaseHDC: hDC]; + + if (self != source) + { + [self releaseHDC: hDC]; + } [source releaseHDC: otherDC]; }