New font handling and some bug fixing for MS Windows backend.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@18257 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2003-12-23 16:42:40 +00:00
parent bd5ac3f8dd
commit 0ec87c9c05
5 changed files with 291 additions and 94 deletions

View file

@ -1,3 +1,16 @@
2003-12-23 Fred Kiefer <FredKiefer@gmx.de>
* 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 <fedor@gnu.org>
* Headers/win32/WIN32Server.h: Add ivars currentFocus, desiredFocus.

View file

@ -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,

View file

@ -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 <Foundation/NSAutoreleasePool.h>
#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

View file

@ -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;

View file

@ -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];
}