wine/objects/font.c
Alexandre Julliard 401710d757 Release 0.3.0
Fri Sep  3 11:52:18 1993  Bob Amstadt

	* [windows/timer.c]
	Changed to use CallWindowProc() rather directly calling callback.

	* [windows/event.c]
	Implemented SetCapture() and ReleaseCapture()

	* [windows/keyboard.c]
	Created stub for GetKeyState()

	* [objects/linedda.c]
	Created stub for LineDDA()

	* [if1632/callback.c]
	Created callback handler for LineDDA callback procedure.

	* [if1632/callback.c]
	Created FreeProcInstance()

Fri Sep  3 08:36:52 1993  David Metcalfe

	* [loader/signal.c]
	Patch to and code for INT 1A

Thu Sep  2 00:31:54 1993  Alexandre Julliard

	* [objects/font.c] [objects/text.c]
	More text support: implemented justification and underlining.

	* [windows/clipping.c] [objects/clipping.c]
	Moved low-level clipping functions to objects/clipping.c.

	* [windows/clipping.c] [windows/event.c] [windows/message.c]
	Implemented window update regions.

	* [windows/dc.c] [objects/dcvalues.c]
	Moved some device-independent DC functions to objects/dcvalues.c.

	* [windows/graphics.c]
	Implemented InvertRect() and GetPixel().

Sat Aug 28 08:40:23 1993  Eric Youngdale

	* [include/neexe.h] [loader/wine.c]
	Added code to handle relocation type 4.

	* [loader/signal.h] [loader/wine.c] [loader/selector.c]
	Added support for dos interrupts.

Thu 26 Aug 19:15:00 1993  Eric Youngdale

	* [loader/selector.c]
	Fixed bug dealing with loading DLLs.

Thu Aug 26 19:22:40 1993  Alexandre Julliard

        * [include/gdi.h] [objects/font.c] [windows/dc.c]
        Beginning of real font support.

        * [windows/graphics.c]
        Implemented PatBlt().

        * [memory/global.c]
        Corrected a bug with linked list handling in GlobalAlloc().

        * [objects/bitmap.c]
        Corrected a bug in BITMAP_SelectObject().

Tue Aug 24 19:22:40 1993  David Metcalfe

        * [controls/Command*] [controls/Label*] [controls[MenuButto*]
	  [controls/SmeMenuButt*]
	Change code to support & as a special character in menu item text.

Tue Aug 24 19:22:40 1993  Alexandre Julliard

	* [include/gdi.h] [windows/dc.c]
	Heavily modified the DC structure for better device-independence.

	* [objects/bitmap.c]
	Implemented bitmap dimensions.

	* [windows/dc.c] [windows/dce.c]
	Implemented DC state saving and restoring.

	* [windows/dc.c]
	Implemented ROP mode.

	* [windows/graphics.c]
	Implemented FillRect().

Mon Aug 23 22:08:34 1993  Bob Amstadt  (bob at pooh)

	* [misc/xt.c]
	Fixed bug in InvalidateRect().  Solitaire attempted to
	clear window before it was realized.

	* [loader/resource.c]
	Began rewrite of LoadBitmap().

	* [loader/wine.c]
	Fixed code which set Argv and Argc global variables.

	* [loader/selector.c]
	Added code to set up command line arguments.

	* [include/neexe.h]
	Fixed error in PSP structure.

Tue Aug 17 20:41:12 1993  Alexandre Julliard

	* [include/gdi.h] [windows/dc.c]
	Implemented device capabilities.

	* [objects/region.c]
	Implemented EqualRgn() and CombineRgn().

	* [windows/clipping.c]
	Implemented Save/RestoreVisRgn().

	* [windows/graphics.c]
	Implemented PaintRgn() and FillRgn().

	* [windows/mapping.c]
	Implemented mapping modes.

Tue Aug 10 14:07:38 1993  Alexandre Julliard

	* [if1632/user.spec] [misc/rect.c]
	Implemented rectangle API functions.

	* [if1632/gdi.spec] [include/gdi.h] [objects/region.c]
	Implemented regions.

	* [windows/class.c]
	Corrected a typo in UnregisterClass().

	* [windows/clipping.c] [windows/dc.c]
	Implemented DC clipping and visible region.

Tue Aug 10 20:57:56 1993  Bob Amstadt  (bob at pooh)

	* [controls/menu.c] [windows/win.c]
	SetMenu(), GetMenu(), CheckMenuItem() implemented

Thu Aug  5 22:33:22 1993  Bob Amstadt  (bob at pooh)

	* [controls/menu.c] [windows/win.c]
	Many improvements menus.  LoadMenu() should work.

Wed Aug  4 14:55:36 1993  Alexandre Julliard

        * [objects/dib.c]
        Started the implementation of device-independent bitmaps.

        * [objects/bitmap.c]
        Added support for multiple bitmap depths.

        * [objects/brush.c]
        Implemented pattern brushes.

        * [windows/dc.c] [windows/graphics.c]
        Implemented some GDI graphics primitives.

Tue Aug  3 21:16:47 1993  Bob Amstadt  (bob at pooh)

	* [controls/menu.c] [windows/win.c] [include/menu.h]
	Code to load class menus from executable file.

	* [if1632/user.spec]
	Fixed specification of SendMessage() and PostMessage.

Mon Jul 26 21:53:24 1993  Alexandre Julliard

	* [if1632/call.S]
	Corrected a bug in KERNEL_InitTask().

	* [include/windows.h]
	Added a lot of constants.

	* [loader/selector.c]
	Corrected a bug in segment allocation in CreateSelectors().

	* [objects/bitmap.c]
	Implemented SelectObject() for bitmaps.

	* [objects/brush.c]
	Implemented hatched brushes and SelectObject().

	* [objects/gdiobj.c]
	Removed linked list (not needed).

	* [objects/palette.c]
	Implemented system palette creation and misc. palette API functions.

	* [windows/timer.c]
	Implemented timers.

	* [windows/dc.c]
	Implemented memory device contexts.

Tue Jul 20 10:38:59 1993  Bob Amstadt  (bob at pooh)

        * [dos.c]
	Split DOS3Call() out of kernel.c.  Added support for get date
	and time functions.

	* [call.S]
	Added function ReturnFromRegisterFunc() to allow DOS calls
	to return values in registers.

	* [regfunc.h]
	Macros to access registers saved on stack.

Tue Jul 20 10:38:59 1993  Alexandre Julliard

        * [win.c]
        Corrected allocation of the WM_CREATE data structure.

        * [dce.c] [dce.h]
        Implemented DCE handling.

        * [bitmap.c] [brush.c] [dc.c] [font.c] [gdi.h] [gdi.spec] 
          [gdiobj.c] [palette.c] [pen.c]
        Implemented the GDI objects data structures and allocation.

        * [windows.h]
        Added several structures and constants for GDI objects.

Mon Jul 19 12:51:10 1993  Bob Amstadt  (bob at pooh)

	* [ldtlib.c]
	Modified system calls to match Linus' new interface for
	the LDT modification.

	* [win.c]
	Fixed bug with WM_CREATE message.

	* [heap.c] [kernel.spec]
	Completed local heap allocation functions.

	* [global.c]
	Created function GlobalQuickAlloc() for easy allocation from DLLs
1993-09-04 10:09:32 +00:00

333 lines
9.8 KiB
C

/*
* GDI font objects
*
* Copyright 1993 Alexandre Julliard
*/
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xatom.h>
#include "gdi.h"
extern Display * XT_display;
extern Screen * XT_screen;
/***********************************************************************
* FONT_MatchFont
*
* Find a X font matching the logical font.
*/
XFontStruct * FONT_MatchFont( DC * dc, LOGFONT * font )
{
char pattern[100];
char *family, *weight, *charset;
char **names;
char slant, spacing;
int width, height, count;
XFontStruct * fontStruct;
weight = (font->lfWeight > 550) ? "bold" : "medium";
slant = font->lfItalic ? 'i' : 'r';
height = font->lfHeight * 10;
width = font->lfWidth * 10;
spacing = (font->lfPitchAndFamily & FIXED_PITCH) ? 'm' :
(font->lfPitchAndFamily & VARIABLE_PITCH) ? 'p' : '*';
charset = (font->lfCharSet == ANSI_CHARSET) ? "iso8859-1" : "*";
family = font->lfFaceName;
if (!*family) switch(font->lfPitchAndFamily & 0xf0)
{
case FF_ROMAN: family = "times"; break;
case FF_SWISS: family = "helvetica"; break;
case FF_MODERN: family = "courier"; break;
case FF_SCRIPT: family = "*"; break;
case FF_DECORATIVE: family = "*"; break;
default: family = "*"; break;
}
sprintf( pattern, "-*-%s-%s-%c-normal--*-%d-*-*-%c-%d-%s",
family, weight, slant, height, spacing, width, charset );
#ifdef DEBUG_FONT
printf( "FONT_MatchFont: '%s'\n", pattern );
#endif
names = XListFonts( XT_display, pattern, 1, &count );
if (!count)
{
#ifdef DEBUG_FONT
printf( " No matching font found\n" );
#endif
return NULL;
}
#ifdef DEBUG_FONT
printf( " Found '%s'\n", *names );
#endif
fontStruct = XLoadQueryFont( XT_display, *names );
XFreeFontNames( names );
return fontStruct;
}
/***********************************************************************
* FONT_GetMetrics
*/
void FONT_GetMetrics( LOGFONT * logfont, XFontStruct * xfont,
TEXTMETRIC * metrics )
{
int average, i;
unsigned long prop;
metrics->tmAscent = xfont->ascent;
metrics->tmDescent = xfont->descent;
metrics->tmHeight = xfont->ascent + xfont->descent;
metrics->tmInternalLeading = 0;
if (XGetFontProperty( xfont, XA_X_HEIGHT, &prop ))
metrics->tmInternalLeading = xfont->ascent - (short)prop;
metrics->tmExternalLeading = 0;
metrics->tmMaxCharWidth = xfont->max_bounds.width;
metrics->tmWeight = logfont->lfWeight;
metrics->tmItalic = logfont->lfItalic;
metrics->tmUnderlined = logfont->lfUnderline;
metrics->tmStruckOut = logfont->lfStrikeOut;
metrics->tmFirstChar = xfont->min_char_or_byte2;
metrics->tmLastChar = xfont->max_char_or_byte2;
metrics->tmDefaultChar = xfont->default_char;
metrics->tmBreakChar = ' ';
metrics->tmPitchAndFamily = logfont->lfPitchAndFamily;
metrics->tmCharSet = logfont->lfCharSet;
metrics->tmOverhang = 0;
metrics->tmDigitizedAspectX = 1;
metrics->tmDigitizedAspectY = 1;
if (xfont->per_char) average = metrics->tmMaxCharWidth;
else
{
XCharStruct * charPtr = xfont->per_char;
average = 0;
for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
{
average += charPtr->width;
charPtr++;
}
average /= metrics->tmLastChar - metrics->tmFirstChar + 1;
}
metrics->tmAveCharWidth = average;
}
/***********************************************************************
* CreateFontIndirect (GDI.57)
*/
HFONT CreateFontIndirect( LOGFONT * font )
{
FONTOBJ * fontPtr;
HFONT hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
if (!hfont) return 0;
fontPtr = (FONTOBJ *) GDI_HEAP_ADDR( hfont );
memcpy( &fontPtr->logfont, font, sizeof(LOGFONT) );
return hfont;
}
/***********************************************************************
* CreateFont (GDI.56)
*/
HFONT CreateFont( int height, int width, int esc, int orient, int weight,
BYTE italic, BYTE underline, BYTE strikeout, BYTE charset,
BYTE outpres, BYTE clippres, BYTE quality, BYTE pitch,
LPSTR name )
{
LOGFONT logfont = { height, width, esc, orient, weight, italic, underline,
strikeout, charset, outpres, clippres, quality, pitch, };
strncpy( logfont.lfFaceName, name, LF_FACESIZE );
return CreateFontIndirect( &logfont );
}
/***********************************************************************
* FONT_GetObject
*/
int FONT_GetObject( FONTOBJ * font, int count, LPSTR buffer )
{
if (count > sizeof(LOGFONT)) count = sizeof(LOGFONT);
memcpy( buffer, &font->logfont, count );
return count;
}
/***********************************************************************
* FONT_SelectObject
*/
HFONT FONT_SelectObject( DC * dc, HFONT hfont, FONTOBJ * font )
{
static X_PHYSFONT stockFonts[LAST_STOCK_FONT-FIRST_STOCK_FONT+1];
X_PHYSFONT * stockPtr;
HFONT prevHandle = dc->w.hFont;
XFontStruct * fontStruct;
/* Load font if necessary */
if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT))
stockPtr = &stockFonts[hfont - FIRST_STOCK_FONT];
else stockPtr = NULL;
if (!stockPtr || !stockPtr->fstruct)
{
fontStruct = FONT_MatchFont( dc, &font->logfont );
}
else
{
fontStruct = stockPtr->fstruct;
#ifdef DEBUG_FONT
printf( "FONT_SelectObject: Loaded font from cache %x %p\n",
hfont, fontStruct );
#endif
}
if (!fontStruct) return 0;
/* Free previous font */
if ((prevHandle < FIRST_STOCK_FONT) || (prevHandle > LAST_STOCK_FONT))
{
if (dc->u.x.font.fstruct)
XFreeFont( XT_display, dc->u.x.font.fstruct );
}
/* Store font */
dc->w.hFont = hfont;
if (stockPtr)
{
if (!stockPtr->fstruct)
{
stockPtr->fstruct = fontStruct;
FONT_GetMetrics( &font->logfont, fontStruct, &stockPtr->metrics );
}
memcpy( &dc->u.x.font, stockPtr, sizeof(*stockPtr) );
}
else
{
dc->u.x.font.fstruct = fontStruct;
FONT_GetMetrics( &font->logfont, fontStruct, &dc->u.x.font.metrics );
}
return prevHandle;
}
/***********************************************************************
* GetTextCharacterExtra (GDI.89)
*/
short GetTextCharacterExtra( HDC hdc )
{
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return 0;
return abs( (dc->w.charExtra * dc->w.WndExtX + dc->w.VportExtX / 2)
/ dc->w.VportExtX );
}
/***********************************************************************
* SetTextCharacterExtra (GDI.8)
*/
short SetTextCharacterExtra( HDC hdc, short extra )
{
short prev;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return 0;
extra = (extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX;
prev = dc->w.charExtra;
dc->w.charExtra = abs(extra);
return (prev * dc->w.WndExtX + dc->w.VportExtX / 2) / dc->w.VportExtX;
}
/***********************************************************************
* SetTextJustification (GDI.10)
*/
short SetTextJustification( HDC hdc, short extra, short breaks )
{
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return 0;
extra = abs((extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX);
if (!extra) breaks = 0;
dc->w.breakTotalExtra = extra;
dc->w.breakCount = breaks;
if (breaks)
{
dc->w.breakExtra = extra / breaks;
dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
}
else
{
dc->w.breakExtra = 0;
dc->w.breakRem = 0;
}
return 1;
}
/***********************************************************************
* GetTextExtent (GDI.91)
*/
DWORD GetTextExtent( HDC hdc, LPSTR str, short count )
{
SIZE size;
if (!GetTextExtentPoint( hdc, str, count, &size )) return 0;
return size.cx | (size.cy << 16);
}
/***********************************************************************
* GetTextExtentPoint (GDI.471)
*/
BOOL GetTextExtentPoint( HDC hdc, LPSTR str, short count, LPSIZE size )
{
int dir, ascent, descent;
XCharStruct info;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return FALSE;
XTextExtents( dc->u.x.font.fstruct, str, count, &dir,
&ascent, &descent, &info );
size->cx = abs((info.width + dc->w.breakRem + count * dc->w.charExtra)
* dc->w.WndExtX / dc->w.VportExtX);
size->cy = abs((dc->u.x.font.fstruct->ascent+dc->u.x.font.fstruct->descent)
* dc->w.WndExtY / dc->w.VportExtY);
#ifdef DEBUG_FONT
printf( "GetTextExtentPoint(%d '%s' %d %p): returning %d,%d\n",
hdc, str, count, size, size->cx, size->cy );
#endif
return TRUE;
}
/***********************************************************************
* GetTextMetrics (GDI.93)
*/
BOOL GetTextMetrics( HDC hdc, LPTEXTMETRIC metrics )
{
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return FALSE;
memcpy( metrics, &dc->u.x.font.metrics, sizeof(*metrics) );
metrics->tmAscent = abs( metrics->tmAscent
* dc->w.WndExtY / dc->w.VportExtY );
metrics->tmDescent = abs( metrics->tmDescent
* dc->w.WndExtY / dc->w.VportExtY );
metrics->tmHeight = metrics->tmAscent + metrics->tmDescent;
metrics->tmInternalLeading = abs( metrics->tmInternalLeading
* dc->w.WndExtY / dc->w.VportExtY );
metrics->tmExternalLeading = abs( metrics->tmExternalLeading
* dc->w.WndExtY / dc->w.VportExtY );
metrics->tmMaxCharWidth = abs( metrics->tmMaxCharWidth
* dc->w.WndExtX / dc->w.VportExtX );
metrics->tmAveCharWidth = abs( metrics->tmAveCharWidth
* dc->w.WndExtX / dc->w.VportExtX );
return TRUE;
}