ftfonts.cpp File Reference

(r1785/r1535)

#include "camtypes.h"
#include "ftfonts.h"
#include "fontman.h"
#include "textfuns.h"
#include "oilpanse.h"
#include <pango/pango.h>
#include <pango/pangofc-font.h>
#include <ft2build.h>
#include <FT_FREETYPE_H>
#include <FT_OUTLINE_H>
#include <FT_TRUETYPE_TABLES_H>
#include <FT_TYPE1_TABLES_H>

Go to the source code of this file.

Classes

class  ClosestFontEnumerator
class  MyFontEnumerator
struct  OutlineDecompositionState

Defines

#define new   CAM_DEBUG_NEW

Typedefs

typedef OutlineDecompositionState DecompState

Functions

 DECLARE_SOURCE ("$Revision: 1535 $")
static PangoContext * GetPangoContext ()
 Get access to the application's PangoContext - as wxWidgets does it.
static BOOL ToASCII (TCHAR *src, char *buffer, UINT32 len)
 Convert a possibly unicoded ASCII string into a plain ASCII string.
static BOOL GetPangoFcFontAndFreeTypeFaceForFaceName (String_64 *pFaceName, PangoFcFont **ppPangoFcFont, FT_Face *ppFreeTypeFace)
 Get a PangoFc font and a FreeType face for a particular font face.
bool operator< (const ENUMLOGFONT &e1, const ENUMLOGFONT &e2)
bool operator== (const ENUMLOGFONT &e1, const ENUMLOGFONT &e2)
static void DumpString64User (char *user, TCHAR *msg, const String_64 *pString)
static String_64GetFacenameFromCharDesc (CharDescription &ChDesc)
 Extract the name of the font referenced by a Kernel character description.
static PangoFont * GetPangoFontForFaceName (String_64 *pFaceName, BOOL IsBold, BOOL IsItalic)
 return a PangoFont for a particular font face
static PangoFont * GetPangoFontForCharDesc (CharDescription &ChDesc)
 return a PangoFont for the font referenced by ChDesc
static INT32 ScaleToDefaultHeight (INT32 coord, INT32 DesignSize)
 Scale a coordinate according to the font's design size.
static BOOL GetPangoFcFontAndFreeTypeFaceForPangoFont (PangoFont *pFont, PangoFcFont **ppPangoFcFont, FT_Face *ppFreeTypeFace)
 Get a PangoFc font and a FreeType face for a Pango font.
static BOOL GetPangoFcFontAndFreeTypeFaceForCharDesc (CharDescription &ChDesc, PangoFcFont **ppPangoFcFont, FT_Face *ppFreeTypeFace)
 Get a PangoFc font and a FreeType face for a char description.
static int AddMoveTo (FREETYPE_CALLBACK_CONST FT_Vector *to, void *user)
 Callback to emit a move command.
static int AddLineTo (FREETYPE_CALLBACK_CONST FT_Vector *to, void *user)
 Callback to emit a line command.
static int AddConicTo (FREETYPE_CALLBACK_CONST FT_Vector *control, FREETYPE_CALLBACK_CONST FT_Vector *to, void *user)
 Callback to deal with a quadratic Bezier curve.
static int AddCubicTo (FREETYPE_CALLBACK_CONST FT_Vector *control1, FREETYPE_CALLBACK_CONST FT_Vector *control2, FREETYPE_CALLBACK_CONST FT_Vector *to, void *user)
 Callback to deal with a cubic Bezier curve.


Define Documentation

#define new   CAM_DEBUG_NEW
 

Definition at line 132 of file ftfonts.cpp.


Typedef Documentation

typedef struct OutlineDecompositionState DecompState
 


Function Documentation

static int AddConicTo FREETYPE_CALLBACK_CONST FT_Vector *  control,
FREETYPE_CALLBACK_CONST FT_Vector *  to,
void *  user
[static]
 

Callback to deal with a quadratic Bezier curve.

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
28/03/06
Parameters:
control - control point of quadratic Bezier curve [INPUTS] to - endpoint of curve user - pointer to our decomposition state
- [OUTPUTS]
Returns:
0 for success, non-0 for failure

Definition at line 1124 of file ftfonts.cpp.

01124                                                                                          : Correct - FreeType callback interface
01125                       FREETYPE_CALLBACK_CONST FT_Vector* to, void* user)
01126 {
01127     DecompState* state = (DecompState*)user;
01128 
01129     // OK, we got a quadratic curve but we can only handle cubic ones, so convert
01130     // from quadratic to cubic - fortunately, this is lossless. The following
01131     // algorithm (with a major error) was found in an article in comp.lang.postscript
01132     // and, corrected, reads as follows:
01133     //
01134     // Let (xb, yb) and (xe, ye) be the beginning and ending coordinates of
01135     // the Bezier curve, respectively.  Let (xq1, yq1) be the interior control
01136     // point for the quadratric Bezier curve. Our task is to determine
01137     // (xc1, yc1) and (xc2, yc), the interior control points of the cubic
01138     // Bezier segment which matches the quadratic segment.
01139     // 
01140     // Solving the algebra led to this conversion:
01141     //   xc1 = (xb + 2 * xq1) / 3        yc1 = (yb + 2 * yq1) / 3
01142     //   xc2 = (2 * xq1 + xe) / 3        yc2 = (2 * yq1 + ye) / 3
01143 
01144     POINT p1;
01145     POINT p2;
01146     POINT p3;
01147     p3.x = ScaleToDefaultHeight(to->x, state->DesignSize);
01148     p3.y = ScaleToDefaultHeight(to->y, state->DesignSize);
01149 
01150     // we need the starting point, which we can find in the current state
01151     p1.x = ScaleToDefaultHeight((state->CurrentPoint.x + 2 * control->x) / 3, state->DesignSize);
01152     p1.y = ScaleToDefaultHeight((state->CurrentPoint.y + 2 * control->y) / 3, state->DesignSize);
01153 
01154     p2.x = ScaleToDefaultHeight((2 * control->x + to->x) / 3, state->DesignSize);
01155     p2.y = ScaleToDefaultHeight((2 * control->y + to->y) / 3, state->DesignSize);
01156     // TRACEUSER("wuerthne", _T("q calling BezierTo(%d,%d)(%d,%d)(%d,%d)"), p1.x, p1.y, p2.x, p2.y, p3.x ,p3.y);
01157     OILFontMan::AddBezierTo(p1, p2, p3);
01158     state->CurrentPoint = *to;
01159     return 0;
01160 }

static int AddCubicTo FREETYPE_CALLBACK_CONST FT_Vector *  control1,
FREETYPE_CALLBACK_CONST FT_Vector *  control2,
FREETYPE_CALLBACK_CONST FT_Vector *  to,
void *  user
[static]
 

Callback to deal with a cubic Bezier curve.

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
28/03/06
Parameters:
control1,control2 - control points of cubic Bezier curve [INPUTS] to - endpoint of curve user - pointer to our decomposition state
- [OUTPUTS]
Returns:
0 for success, non-0 for failure

Definition at line 1179 of file ftfonts.cpp.

01179                                                                                        : Correct
01180                       FREETYPE_CALLBACK_CONST FT_Vector *control2,
01181                       FREETYPE_CALLBACK_CONST FT_Vector* to, void* user)
01182 {
01183     DecompState* state = (DecompState*)user;
01184     POINT p1;
01185     POINT p2;
01186     POINT p3;
01187     p1.x = ScaleToDefaultHeight(control1->x, state->DesignSize);
01188     p1.y = ScaleToDefaultHeight(control1->y, state->DesignSize);
01189     p2.x = ScaleToDefaultHeight(control2->x, state->DesignSize);
01190     p2.y = ScaleToDefaultHeight(control2->y, state->DesignSize);
01191     p3.x = ScaleToDefaultHeight(to->x, state->DesignSize);
01192     p3.y = ScaleToDefaultHeight(to->y, state->DesignSize);
01193     // TRACEUSER("wuerthne", _T("c calling BezierTo(%d,%d)(%d,%d)(%d,%d)"), p1.x, p1.y, p2.x, p2.y, p3.x ,p3.y);
01194     OILFontMan::AddBezierTo(p1, p2, p3);
01195     state->CurrentPoint = *to;
01196     return 0;
01197 }

static int AddLineTo FREETYPE_CALLBACK_CONST FT_Vector *  to,
void *  user
[static]
 

Callback to emit a line command.

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
28/03/06
Parameters:
to - endpoint of line [INPUTS] user - pointer to our decomposition state
- [OUTPUTS]
Returns:
0 for success, non-0 for failure

Definition at line 1096 of file ftfonts.cpp.

01096                                                                                          : Correct - FreeType callback interface
01097 {
01098     DecompState* state = (DecompState*)user;
01099     POINT p;
01100     p.x = ScaleToDefaultHeight(to->x, state->DesignSize);
01101     p.y = ScaleToDefaultHeight(to->y, state->DesignSize);
01102     // TRACEUSER("wuerthne", _T("calling LineTo(%d,%d)"), p.x, p.y);
01103     OILFontMan::AddLineTo(p);
01104     state->CurrentPoint = *to;
01105     return 0;
01106 }

static int AddMoveTo FREETYPE_CALLBACK_CONST FT_Vector *  to,
void *  user
[static]
 

Callback to emit a move command.

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
28/03/06
Parameters:
to - target point of move [INPUTS] user - pointer to our decomposition state
- [OUTPUTS]
Returns:
0 for success, non-0 for failure

Definition at line 1063 of file ftfonts.cpp.

01063                                                                                     : Correct - FreeType callback interface
01064 {
01065     DecompState* state = (DecompState*)user;
01066     if (!state->IsFirstMove) {
01067         // this is the beginning of a subsequent contour (subpath), so close the current one
01068         // TRACEUSER("wuerthne", _T("calling ClosePath()"));
01069         OILFontMan::ClosePath();
01070     }
01071     POINT p;
01072     p.x = ScaleToDefaultHeight(to->x, state->DesignSize);
01073     p.y = ScaleToDefaultHeight(to->y, state->DesignSize);
01074     // TRACEUSER("wuerthne", _T("calling MoveTo(%d,%d)"), p.x, p.y);
01075     OILFontMan::AddMoveTo(p);
01076     state->CurrentPoint = *to;
01077     state->IsFirstMove = FALSE;
01078     return 0;
01079 }

DECLARE_SOURCE "$Revision: 1535 $"   ) 
 

static void DumpString64User char *  user,
TCHAR msg,
const String_64 pString
[static]
 

Definition at line 236 of file ftfonts.cpp.

00237 {
00238     TRACEUSER(user, msg);
00239     TRACEUSER(user, (const TCHAR*)(*pString));  // use TCHAR* conversion operator
00240 }

static String_64* GetFacenameFromCharDesc CharDescription ChDesc  )  [static]
 

Extract the name of the font referenced by a Kernel character description.

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
06/03/06
Parameters:
ChDesc - a Kernel character description [INPUTS]
- [OUTPUTS]
Returns:
The Facename of the referenced font NULL if the found could not be found (e.g., not cached - should not happen)

Definition at line 727 of file ftfonts.cpp.

00728 {
00729     // get LogFont from face handle in char descriptor
00730     WORD            FaceHandle    = ChDesc.GetTypefaceHandle();
00731     CachedFontItem* pFontDataItem = FONTMANAGER->GetFont(FaceHandle);
00732     ERROR2IF(pFontDataItem==NULL,FALSE,"FTFontMan::GetCharOutline could not find cached font");
00733     ENUMLOGFONT*    pEnumLogFont  = pFontDataItem->GetEnumLogFont();
00734     ERROR2IF(pEnumLogFont==NULL,FALSE,"FTFontMan::GetCharOutline could not find cached EnumLogFont");
00735     // DumpString64User("wuerthne", _T("GetFacenameFromCharDesc returning"), &pEnumLogFont->elfLogFont.FaceName);
00736     return &pEnumLogFont->elfLogFont.FaceName;
00737 }

static PangoContext * GetPangoContext  )  [static]
 

Get access to the application's PangoContext - as wxWidgets does it.

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
06/03/06
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
the PangoContext of the application

Definition at line 860 of file ftfonts.cpp.

00861 {
00862     // The magic code to get the Pango context for wxGTK2 and below is copied
00863     // from wxWidgets/unix/fontenum.cpp
00864     PangoContext *pPangoContext =
00865 #ifdef __WXGTK20__
00866         gtk_widget_get_pango_context( wxGetRootWindow() );
00867 #elif defined(__WXGTK__)
00868         wxTheApp->GetPangoContext();
00869 #else
00870         #error "Sorry, this source file can only be compiled for wxGTK"
00871 #endif
00872         return pPangoContext;
00873 }

static BOOL GetPangoFcFontAndFreeTypeFaceForCharDesc CharDescription ChDesc,
PangoFcFont **  ppPangoFcFont,
FT_Face *  ppFreeTypeFace
[static]
 

Get a PangoFc font and a FreeType face for a char description.

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
06/03/06
Parameters:
ChDesc - a Kernel character description [INPUTS]
a pointer to the PangoFcFont is stored in ppPangoFcFont [OUTPUTS] a pointer to the FreeType font is stored in ppFreeTypeFace When finished with the font and face, the client has to call pango_fc_font_unlock_face(*ppPangoFcFont) to free the font
Returns:
TRUE if the font descriptors have been returned correctly FALSE if not.

Definition at line 989 of file ftfonts.cpp.

00991 {
00992     // We extract the font description from ChDesc and find a PangoFont for it
00993     PangoFont* pFont = GetPangoFontForCharDesc(ChDesc);
00994     return GetPangoFcFontAndFreeTypeFaceForPangoFont(pFont, ppPangoFcFont, ppFreeTypeFace);
00995 }

static BOOL GetPangoFcFontAndFreeTypeFaceForFaceName String_64 pFaceName,
PangoFcFont **  ppPangoFcFont,
FT_Face *  ppFreeTypeFace
[static]
 

Get a PangoFc font and a FreeType face for a particular font face.

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
19/04/06
Parameters:
pFaceName - pointer to a face name [INPUTS]
a pointer to the PangoFcFont is stored in ppPangoFcFont [OUTPUTS] a pointer to the FreeType font is stored in ppFreeTypeFace When finished with the font and face, the client has to call pango_fc_font_unlock_face(*ppPangoFcFont) to free the font
Returns:
TRUE if the font descriptors have been returned correctly FALSE if not.

Definition at line 1015 of file ftfonts.cpp.

01017 {
01018     PangoFont* pFont = GetPangoFontForFaceName(pFaceName, FALSE, FALSE);
01019     return GetPangoFcFontAndFreeTypeFaceForPangoFont(pFont, ppPangoFcFont, ppFreeTypeFace);
01020 }

static BOOL GetPangoFcFontAndFreeTypeFaceForPangoFont PangoFont *  pFont,
PangoFcFont **  ppPangoFcFont,
FT_Face *  ppFreeTypeFace
[static]
 

Get a PangoFc font and a FreeType face for a Pango font.

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
19/04/06
Parameters:
pFont - pointer to a PangoFont [INPUTS]
a pointer to the PangoFcFont is stored in ppPangoFcFont [OUTPUTS] a pointer to the FreeType font is stored in ppFreeTypeFace When finished with the font and face, the client has to call pango_fc_font_unlock_face(*ppPangoFcFont) to free the font
Returns:
TRUE if the font descriptors have been returned correctly FALSE if not.

Definition at line 912 of file ftfonts.cpp.

00913 {
00914     if (!pFont) return FALSE;
00915 
00916     // We need to get at the underlying FreeType information, which only works for
00917     // Pango backends that are based on FreeType. The common factor for those
00918     // backends is that they are based on FontConfig, so we check whether the font
00919     // we got is indeed managed by a FontConfig-based backend (Xft or Cairo).
00920     if (!PANGO_IS_FC_FONT(pFont))
00921     {
00922         ERROR2(FALSE, "FTFontMan: font is not a PangoFcFont!");
00923     }
00924 
00925     // OK, so we can safely cast to PangoFcFont
00926     PangoFcFont* pFcFont = (PangoFcFont*)pFont;
00927 
00928     // The magic call to get at the underlying FreeType data
00929     // We must unlock this before returning!
00930     FT_Face pFreeTypeFace = pango_fc_font_lock_face(pFcFont);
00931     if (!pFreeTypeFace) {
00932         pango_fc_font_unlock_face(pFcFont);
00933         return FALSE;
00934     }
00935 
00936     // The default charmap is always unicode if present, but we may
00937     // have a symbol font which we may want to drive in symbol mode.
00938     // Check whether there is just an Adobe custom or MS Symbol encoding
00939     // in addition to the synthesized unicode charmap and if so, use that
00940     // instead.
00941     FT_CharMap pCustomCharmap = NULL;
00942     for (INT32 mapnum = 0; mapnum < pFreeTypeFace->num_charmaps; mapnum++)
00943     {
00944         FT_CharMap pThisMap = pFreeTypeFace->charmaps[mapnum];
00945         if (pThisMap->encoding == FT_ENCODING_ADOBE_CUSTOM
00946             || pThisMap->encoding == FT_ENCODING_MS_SYMBOL) {
00947             pCustomCharmap = pThisMap;
00948             // we go on checking the other encodings
00949         }
00950         else if (pThisMap->encoding != FT_ENCODING_UNICODE) {
00951             // there is an encoding that is neither a custom one
00952             // nor a Unicode encoding, so this is a language font
00953             pCustomCharmap = NULL;
00954             break;
00955         }
00956     }
00957     if (pCustomCharmap) FT_Set_Charmap(pFreeTypeFace, pCustomCharmap);
00958     
00959     // We do not support non-scalable fonts - do not report an error, this routine
00960     // is called during font enumeration and simply returns FALSE in this case
00961     if (!FT_IS_SCALABLE(pFreeTypeFace))
00962     {
00963         pango_fc_font_unlock_face(pFcFont);
00964         return FALSE;
00965     }
00966     *ppPangoFcFont = pFcFont;
00967     *ppFreeTypeFace = pFreeTypeFace;
00968     return TRUE;
00969 }

static PangoFont* GetPangoFontForCharDesc CharDescription ChDesc  )  [static]
 

return a PangoFont for the font referenced by ChDesc

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
06/03/06
Parameters:
ChDesc - a Kernel character description [INPUTS]
- [OUTPUTS]
Returns:
a pointer to the corresponding PangoFont structure may return NULL if the font could not be loaded the Pango documentation does not state anything about how to or having to free the PangoFont object, so we assume it is managed by the FontMap

Definition at line 838 of file ftfonts.cpp.

00839 {
00840     String_64* pFaceName = GetFacenameFromCharDesc(ChDesc);
00841     return GetPangoFontForFaceName(pFaceName, ChDesc.GetBold(), ChDesc.GetItalic());
00842 }

static PangoFont* GetPangoFontForFaceName String_64 pFaceName,
BOOL  IsBold,
BOOL  IsItalic
[static]
 

return a PangoFont for a particular font face

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
19/04/06
Parameters:
pFaceName - pointer to a face name [INPUTS]
- [OUTPUTS]
Returns:
a pointer to the corresponding PangoFont structure may return NULL if the font could not be loaded the Pango documentation does not state anything about how to or having to free the PangoFont object, so we assume it is managed by the FontMap

Definition at line 798 of file ftfonts.cpp.

00799 {
00800     // DumpString64User("wuerthne", _T("FTFontMan::GetPangoFontForFaceName"), pFaceName);
00801 
00802     char ASCIIFaceName[64]; // TYPENOTE: correct (needed as parameter to Pango)
00803     if (!ToASCII(*pFaceName, ASCIIFaceName, 64)) return NULL;
00804 
00805     PangoContext* pPangoContext = GetPangoContext();
00806     ERROR2IF(pPangoContext==NULL,NULL,"FTFontMan::GetPangoFontForCharDesc failed to get PangoContext");
00807     PangoFontMap* pFontMap = pango_context_get_font_map(pPangoContext);
00808     ERROR2IF(pPangoContext==NULL,NULL,"FTFontMan::GetPangoFontForCharDesc failed to get PangoFontMan");
00809 
00810     PangoFontDescription* pDescription = pango_font_description_new();
00811     pango_font_description_set_family_static(pDescription, ASCIIFaceName);
00812     pango_font_description_set_style(pDescription, IsItalic ? PANGO_STYLE_ITALIC :  PANGO_STYLE_NORMAL);
00813     pango_font_description_set_weight(pDescription, IsBold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
00814     pango_font_description_set_size(pDescription, 12 * PANGO_SCALE);  // arbitrary, we get unscaled outlines later
00815 
00816     PangoFont* pFont = pango_font_map_load_font(pFontMap, pPangoContext, pDescription);
00817     pango_font_description_free(pDescription);
00818     if (!PANGO_IS_FONT(pFont)) return NULL;
00819     return pFont;
00820 }

bool operator< const ENUMLOGFONT e1,
const ENUMLOGFONT e2
 

Definition at line 144 of file ftfonts.cpp.

00145 {
00146     return e1.elfLogFont.FaceName.CompareTo(e2.elfLogFont.FaceName, FALSE) < 0;
00147 }

bool operator== const ENUMLOGFONT e1,
const ENUMLOGFONT e2
 

Definition at line 149 of file ftfonts.cpp.

00150 {
00151     return e1.elfLogFont.FaceName.CompareTo(e2.elfLogFont.FaceName, FALSE) == 0;
00152 }

static INT32 ScaleToDefaultHeight INT32  coord,
INT32  DesignSize
[static]
 

Scale a coordinate according to the font's design size.

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
06/03/06
Parameters:
coord - the coordinate to scale [INPUTS] DesignSize - the design size of the font
- [OUTPUTS]
Returns:
the scaled size

Definition at line 889 of file ftfonts.cpp.

00890 {
00891     return coord * TextManager::GetDefaultHeight() / DesignSize;
00892 }

static BOOL ToASCII TCHAR src,
char *  buffer,
UINT32  len
[static]
 

Convert a possibly unicoded ASCII string into a plain ASCII string.

Author:
Martin Wuerthner <xara@mw-software.com>
Date:
06/03/06
Parameters:
src - a pointer to a TCHAR* string [INPUTS]
The converted string in the char* buffer [OUTPUTS]
Returns:
TRUE if the string was converted OK FALSE if not (e.g., buffer overflow, invalid character found)

Definition at line 755 of file ftfonts.cpp.

00755                                                                         : correct - we need to use char
00756 {
00757     char* dest = buffer;
00758     while(*src >= 32 && len)
00759     {
00760         TCHAR b = *src++;
00761         if (b > 127)
00762         {
00763             // outside ASCII range, so fail
00764             *dest = '\0';
00765             return FALSE;
00766         }
00767         *dest++ = b;
00768         len--;
00769     }
00770     if (!len)
00771     {
00772         // buffer overflow, so fail
00773         dest[-1] = '\0';
00774         return FALSE;
00775     }
00776     else {
00777         *dest = '\0';
00778         return TRUE;
00779     }
00780 }


Generated on Sat Nov 10 03:49:31 2007 for Camelot by  doxygen 1.4.4