mirror of
https://github.com/gnustep/libs-back.git
synced 2025-02-23 20:01:22 +00:00
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:
parent
bd5ac3f8dd
commit
0ec87c9c05
5 changed files with 291 additions and 94 deletions
13
ChangeLog
13
ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue