Getting a Font's EXTLOGFONT

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Getting a Font's EXTLOGFONT

Mikael Svane
For the RichText extensions that I have asked about in previous posts, I
need to get the EXTLOGFONT of a Dolphin Font in order to get the PANOSE
structure from the EXTLOGFONT. The PANOSE structure information is needed
when creating the font table of a rich text document. I have defined the
EXTLOGFONT external structure class from the information on
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/fontext_04tu.asp
but how shall I proceed to get the EXTLOGFONT structure from the Font in
Dolphin?

Best regards,
Mikael Svane


Reply | Threaded
Open this post in threaded view
|

Re: Getting a Font's EXTLOGFONT

Blair McGlashan
Mikael

You wrote in message news:bmpqkh$pi479$[hidden email]...
> For the RichText extensions that I have asked about in previous posts, I
> need to get the EXTLOGFONT of a Dolphin Font in order to get the PANOSE
> structure from the EXTLOGFONT. The PANOSE structure information is needed
> when creating the font table of a rich text document. I have defined the
> EXTLOGFONT external structure class from the information on
>
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/fontext_04tu.asp
> but how shall I proceed to get the EXTLOGFONT structure from the Font in
> Dolphin?

I'm not sure that you can. However there is another way to enquire the
PANOSE information through the GetOutlineTextMetrics() API. Please see the
attached package, and refer to the package comment for an example.

Regards

Blair
-------------------
| package |
package := Package name: 'OutlineTextMetrics'.
package paxVersion: 0;
 basicComment: 'Dolphin Outline Text Metrics Package
Copyright (c) Object Arts Ltd, 2003.

This package includes the necessary class and method definitions to allow
one to enquire for OUTLINETEXTMETRIC information for a font, including the
PANOSE information.

Example:

font := Font name: ''Comic Sans MS'' pointSize: 22.
canvas := Canvas forDisplay.
canvas font: font.
"Get the outline text metrics"
otm := canvas outlineTextMetrics.
"Canvas is no longer needed"
canvas free.
"Finally get the panose info"
otm otmPanoseNumber
'.

package basicScriptAt: #postinstall put: 'PANOSE compileDefinition!!
OUTLINETEXTMETRIC compileDefinition!!'.
package basicScriptAt: #preinstall put: 'Win32Constants at:
''ELF_VENDOR_SIZE'' put: 4; at: ''LF_FULLFACESIZE'' put: 64'.

package classNames
 add: #OUTLINETEXTMETRIC;
 add: #PANOSE;
 yourself.

package methodNames
 add: #Canvas -> #outlineTextMetrics;
 add: #GDILibrary -> #getOutlineTextMetrics:cbData:lpotm:;
 yourself.

package binaryGlobalNames: (Set new
 yourself).

package globalAliases: (Set new
 yourself).

package allResourceNames: (Set new
 yourself).

package setPrerequisites: (IdentitySet new
 add: 'Object Arts\Dolphin\Base\Dolphin';
 add: 'Object Arts\Dolphin\MVP\Base\Dolphin MVP Base';
 yourself).

package!

"Class Definitions"!

Win32Structure subclass: #OUTLINETEXTMETRIC
 instanceVariableNames: ''
 classVariableNames: ''
 poolDictionaries: ''
 classInstanceVariableNames: ''!
Win32Structure subclass: #PANOSE
 instanceVariableNames: ''
 classVariableNames: ''
 poolDictionaries: ''
 classInstanceVariableNames: ''!

"Global Aliases"!


"Loose Methods"!

!Canvas methodsFor!

outlineTextMetrics
 "Answer the standard Win32 OUTLINETEXTMETRICs for the currently selected
font."

 "Implementation Note: See the MSDN article KB84132"

 | answer size lib |
 lib := GDILibrary default.
 size := lib
    getOutlineTextMetrics: self asParameter
    cbData: 0
    lpotm: nil.
 size == 0 ifTrue: [lib systemError].
 answer := OUTLINETEXTMETRIC new: size.
 (lib
  getOutlineTextMetrics: self asParameter
  cbData: size
  lpotm: answer) == 0
  ifTrue: [lib systemError].
 ^answer! !
!Canvas categoriesFor: #outlineTextMetrics!accessing!public! !

!GDILibrary methodsFor!

getOutlineTextMetrics: anExternalHandle cbData: anInteger lpotm:
anOUTLINETEXTMETRIC
 <stdcall: dword GetOutlineTextMetricsA handle dword OUTLINETEXTMETRIC*>
 ^self invalidCall! !
!GDILibrary categoriesFor: #getOutlineTextMetrics:cbData:lpotm:!public!win32
functions-font and text! !

"End of package definition"!

"Source Globals"!

"Classes"!

OUTLINETEXTMETRIC guid: (GUID fromString:
'{52831A87-901F-4A84-894B-AB539352B71F}')!
OUTLINETEXTMETRIC comment: '<OUTLINETEXTMETRIC> is an <ExternalStructure>
class to wrap the struct ''Win.OUTLINETEXTMETRIC'' from type information in
the ''Windows API (ANSI)'' library.'!
!OUTLINETEXTMETRIC categoriesForClass!Win-Structs! !
!OUTLINETEXTMETRIC methodsFor!

faceName
 "Answer the receiver's <readableString> font face name."

 ^String fromAddress: bytes yourAddress + self otmpFaceName!

familyName
 "Answer the receiver's <readableString> font family name."

 ^String fromAddress: bytes yourAddress + self otmpFamilyName!

fullName
 "Answer the receiver's <readableString> full font name."

 ^String fromAddress: bytes yourAddress + self otmpFullName!

styleName
 "Answer the receiver's <readableString> style name.
 This is the name that appears in the font dialog as the 'Font style',
 e.g. regular, bold, italic, etc"

 ^String fromAddress: bytes yourAddress + self otmpStyleName! !
!OUTLINETEXTMETRIC categoriesFor: #faceName!accessing!public! !
!OUTLINETEXTMETRIC categoriesFor: #familyName!accessing!public! !
!OUTLINETEXTMETRIC categoriesFor: #fullName!accessing!public! !
!OUTLINETEXTMETRIC categoriesFor: #styleName!accessing!public! !

!OUTLINETEXTMETRIC class methodsFor!

defineFields
 "Define the fields of the OUTLINETEXTMETRIC structure.
  OUTLINETEXTMETRIC compileDefinition

  typedef
  struct tagOUTLINETEXTMETRIC {
   int otmSize;
   TEXTMETRIC otmTextMetrics;
   BYTE otmFiller;
   PANOSE otmPanoseNumber;
   UINT otmfsSelection;
   UINT otmfsType;
   int otmsCharSlopeRise;
   int otmsCharSlopeRun;
   int otmItalicAngle;
   UINT otmEMSquare;
   int otmAscent;
   int otmDescent;
   UINT otmLineGap;
   UINT otmsCapEmHeight;
   UINT otmsXHeight;
   RECT otmrcFontBox;
   int otmMacAscent;
   int otmMacDescent;
   UINT otmMacLineGap;
   UINT otmusMinimumPPEM;
   POINTL otmptSubscriptSize;
   POINTL otmptSubscriptOffset;
   POINTL otmptSuperscriptSize;
   POINTL otmptSuperscriptOffset;
   UINT otmsStrikeoutSize;
   int otmsStrikeoutPosition;
   int otmsUnderscoreSize;
   int otmsUnderscorePosition;
   LPSTR otmpFamilyName;
   LPSTR otmpFaceName;
   LPSTR otmpStyleName;
   LPSTR otmpFullName;
  } OUTLINETEXTMETRIC;
"


 self
  defineField: #dwSize type: DWORDField writeOnly beOverride;
  defineField: #otmTextMetrics type: (StructureField type: TEXTMETRIC)
beReadOnly offset: 4;
  defineField: #otmFiller type: BYTEField filler offset: 60;
  defineField: #otmPanoseNumber type: (StructureField type: PANOSE)
beReadOnly offset: 61;
  defineField: #otmfsSelection type: DWORDField readOnly offset: 72;
  defineField: #otmfsType type: DWORDField readOnly offset: 76;
  defineField: #otmsCharSlopeRise type: SDWORDField readOnly offset: 80;
  defineField: #otmsCharSlopeRun type: SDWORDField readOnly offset: 84;
  defineField: #otmItalicAngle type: SDWORDField readOnly offset: 88;
  defineField: #otmEMSquare type: DWORDField readOnly offset: 92;
  defineField: #otmAscent type: SDWORDField readOnly offset: 96;
  defineField: #otmDescent type: SDWORDField readOnly offset: 100;
  defineField: #otmLineGap type: DWORDField readOnly offset: 104;
  defineField: #otmsCapEmHeight type: DWORDField readOnly offset: 108;
  defineField: #otmsXHeight type: DWORDField readOnly offset: 112;
  defineField: #otmrcFontBox type: (StructureField type: RECT) beReadOnly
offset: 116;
  defineField: #otmMacAscent type: SDWORDField readOnly offset: 132;
  defineField: #otmMacDescent type: SDWORDField readOnly offset: 136;
  defineField: #otmMacLineGap type: DWORDField readOnly offset: 140;
  defineField: #otmusMinimumPPEM type: DWORDField readOnly offset: 144;
  defineField: #otmptSubscriptSize type: (StructureField type: POINTL)
beReadOnly offset: 148;
  defineField: #otmptSubscriptOffset type: (StructureField type: POINTL)
beReadOnly offset: 156;
  defineField: #otmptSuperscriptSize type: (StructureField type: POINTL)
beReadOnly offset: 164;
  defineField: #otmptSuperscriptOffset type: (StructureField type: POINTL)
beReadOnly offset: 172;
  defineField: #otmsStrikeoutSize type: DWORDField readOnly offset: 180;
  defineField: #otmsStrikeoutPosition type: SDWORDField readOnly offset:
184;
  defineField: #otmsUnderscoreSize type: SDWORDField readOnly offset: 188;
  defineField: #otmsUnderscorePosition type: SDWORDField readOnly offset:
192;
  "See MSDN article KB84132"
  defineField: #otmpFamilyName type: DWORDField readOnly offset: 196;
  defineField: #otmpFaceName type: DWORDField readOnly offset: 200;
  defineField: #otmpStyleName type: DWORDField readOnly offset: 204;
  defineField: #otmpFullName type: DWORDField readOnly offset: 208.
 self byteSize: 212! !
!OUTLINETEXTMETRIC class categoriesFor: #defineFields!initializing!public! !

PANOSE guid: (GUID fromString: '{AB0B82A7-5304-49C0-9937-E7474BC1A82F}')!
PANOSE comment: '<PANOSE> is an <ExternalStructure> class to wrap the struct
''Win.PANOSE'' from type information in the ''Windows API (ANSI)'' library.
'!
!PANOSE categoriesForClass!Win-Structs! !
!PANOSE class methodsFor!

defineFields
 "Define the fields of the PANOSE structure.
  PANOSE compileDefinition

  typedef
  struct tagPANOSE {
   BYTE bFamilyType;
   BYTE bSerifStyle;
   BYTE bWeight;
   BYTE bProportion;
   BYTE bContrast;
   BYTE bStrokeVariation;
   BYTE bArmStyle;
   BYTE bLetterform;
   BYTE bMidline;
   BYTE bXHeight;
  } PANOSE;
"

 self
  defineField: #bFamilyType type: BYTEField readOnly offset: 0;
  defineField: #bSerifStyle type: BYTEField readOnly offset: 1;
  defineField: #bWeight type: BYTEField readOnly offset: 2;
  defineField: #bProportion type: BYTEField readOnly offset: 3;
  defineField: #bContrast type: BYTEField readOnly offset: 4;
  defineField: #bStrokeVariation type: BYTEField readOnly offset: 5;
  defineField: #bArmStyle type: BYTEField readOnly offset: 6;
  defineField: #bLetterform type: BYTEField readOnly offset: 7;
  defineField: #bMidline type: BYTEField readOnly offset: 8;
  defineField: #bXHeight type: BYTEField readOnly offset: 9.
 self byteSize: 10! !
!PANOSE class categoriesFor: #defineFields!**auto
generated**!initializing!public! !

"Binary Globals"!

"Resources"!


Reply | Threaded
Open this post in threaded view
|

Re: Getting a Font's EXTLOGFONT

Mikael Svane
Blair,

Thank you very much for this solution. I had not found the way you described
of getting the PANOSE information on msdn. The package that you wrote solved
my problems completely, and I now have a RichText subclass to which
instances of Font can be added and which then produces a rich text header
with the proper font table. I had to make one small change in
Canvas>>outlineTextMetrics:

> outlineTextMetrics
>  "Answer the standard Win32 OUTLINETEXTMETRICs for the currently selected
> font."
>
>  "Implementation Note: See the MSDN article KB84132"
>
>  | answer size lib |
>  lib := GDILibrary default.
>  size := lib
>     getOutlineTextMetrics: self asParameter
>     cbData: 0
>     lpotm: nil.
>  size == 0 ifTrue: [lib systemError].
>  answer := OUTLINETEXTMETRIC new: size.
>  (lib
>   getOutlineTextMetrics: self asParameter
>   cbData: size
>   lpotm: answer) == 0
>   ifTrue: [lib systemError].
>  ^answer! !

where I replaced the first "size == 0 ifTrue: [lib systemError]." with "size
== 0 ifTrue: [^ nil]." since only TrueType fonts have OUTLINETEXTMETRIC
structures and I needed to be able to handle other fonts too.

Again thank you very much!

Mikael Svane