fontbase.cpp

Go to the documentation of this file.
00001 // $Id: fontbase.cpp 1642 2006-08-02 10:15:44Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 // implementation file for 'OILfontman' font manager which supports all
00099 // other forms of derived font managers (currently ATM and TrueType)
00100 
00101 /*
00102 */
00103 
00104 #include "camtypes.h"
00105 #ifdef __WXGTK__
00106 #include "ftfonts.h"
00107 #endif
00108 #include "textfuns.h"
00109 #include "fontman.h"        // includes fontbase.h
00110 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 //#include "doccoord.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 //#include "pathtype.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00113 //#include "txtattr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00114 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00115 
00116 #include "fontimpl.h"       // private definitions
00117 //#include "mike.h"
00118 
00119 DECLARE_SOURCE( "$Revision: 1642 $" );
00120 
00121 CC_IMPLEMENT_DYNCREATE( FontBase, CCObject )
00122 CC_IMPLEMENT_DYNCREATE( OILFontMan, CCObject )
00123 CC_IMPLEMENT_DYNCREATE( OILEnumFonts, CCObject )
00124 CC_IMPLEMENT_MEMDUMP( FontMetricsCacheEntry, CC_CLASS_MEMDUMP );
00125 CC_IMPLEMENT_MEMDUMP( FontMetricsCache, CC_CLASS_MEMDUMP );
00126 CC_IMPLEMENT_MEMDUMP( FontKerningPairsCacheEntry, CC_CLASS_MEMDUMP );
00127 CC_IMPLEMENT_MEMDUMP( FontKerningPairsCache, CC_CLASS_MEMDUMP );
00128 CC_IMPLEMENT_MEMDUMP( CharOutlineCache, CC_CLASS_MEMDUMP );
00129 
00130 #define new CAM_DEBUG_NEW
00131 
00132 // a macro to ignore a parameter without causing a warning
00133 #define IGNOREPARAM(x) x = x
00134 
00136 // Some outline cache constants
00137 UINT32 CharOutlineCache::CacheSize = 0;
00138 DocCoord CharOutlineCache::LastMoveTo;
00139 DocCoord CharOutlineCache::CacheCoords[OILFONTLIMIT];
00140 PathVerb CharOutlineCache::CacheVerbs[OILFONTLIMIT];
00141 
00142 // define some font metrics/kerning pairs cache statics
00143 FontMetricsCacheEntry       FontMetricsCache::mpFontMetricsData[FontMetricsCache::NUMENTRIES];
00144 FontKerningPairsCacheEntry  FontKerningPairsCache::m_FontKerningPairsCacheData[FontKerningPairsCache::NUMENTRIES];
00145 
00146 
00147 /********************************************************************************************
00148 
00149 >   OILFontMan::OILFontMan() 
00150 
00151     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00152     Created:    12/09/95                
00153     Purpose:    Default constructor
00154 
00155 ********************************************************************************************/
00156 
00157 OILFontMan::OILFontMan()
00158 {
00159 }
00160 
00161 /********************************************************************************************
00162 
00163 >   BOOL OILFontMan::LegalFontClass(INT32 Class, FontClass& RealClass)
00164 
00165     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00166     Created:    12/09/95                
00167     Inputs:     A INT32 describing the font class
00168     Outputs:    RealClass - holds the real FontClass typedef of the numeric class
00169     Returns:    TRUE if the font class is supported, FALSE if not
00170     Purpose:    Check whether a numeric value actually indicates a valid class of font
00171                 ie lies in the range of supported font types. This is used generally for
00172                 loading purpose where the font class is loaded as a numeric value.
00173                 The class given will be converted to RealClass on exit.
00174 
00175 ********************************************************************************************/
00176 
00177 BOOL OILFontMan::LegalFontClass(INT32 Class, FontClass& RealClass)
00178 {
00179     BOOL ok = ((Class>((INT32)FC_UNDEFINED)) && (Class<((INT32)FC_ILLEGAL)));
00180     (ok) ? (RealClass=(FontClass)(Class)) : (RealClass=FC_UNDEFINED);
00181     return ok;
00182 }
00183 
00184 
00185 
00186 /********************************************************************************************
00187 
00188 >   BOOL OILFontMan::IsOkToCall(FontClass Class)
00189 
00190     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00191     Created:    12/09/95                
00192                 Class  : The class of font
00193     Outputs:    TRUE if the font class is ok to make further calls to
00194                 FALSE if not.
00195     Purpose:    Check whether this particular font class manager is up and running.
00196     
00197 ********************************************************************************************/
00198 
00199 BOOL OILFontMan::IsOkToCall(FontClass Class)
00200 {
00201     switch (Class)
00202     {
00203         case FC_ATM:
00204 #ifndef EXCLUDE_FROM_XARALX
00205             return ATMFontMan::IsOkToCall();
00206 #elif defined(__WXGTK__)
00207             return FTFontMan::IsOkToCall();
00208 #else
00209             return FALSE;
00210 #endif
00211             break;
00212         case FC_TRUETYPE:
00213 #ifndef EXCLUDE_FROM_XARALX
00214             return TTFontMan::IsOkToCall();
00215 #elif defined(__WXGTK__)
00216             return FTFontMan::IsOkToCall();
00217 #else
00218             return FALSE;
00219 #endif
00220             break;
00221         default:
00222             ERROR3("Unknown font class passed to OILFontMan::IsOkToCall()");
00223             break;
00224     }
00225     return FALSE;
00226 }
00227 
00228 
00229 /********************************************************************************************
00230 
00231 >   static BOOL OILFontMan::CacheNamedFont(String_64* pFontName, FontClass Class=FC_UNDEFINED, INT32 Pass=1)
00232 
00233     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00234     Created:    12/9/95
00235     Inputs:     pFontName = a pointer to a fontname to find and cache
00236                 Class     : The class of font to cache
00237                             FC_UNDEFINED - then try to cache any font
00238                 Pass      : 1 - first pass, try to match the font exactly
00239                           : 2 - second pass, try to find a compatible font
00240     Outputs:    -
00241     Returns:    TRUE if the font has been cached
00242                 FALSE if not.
00243     Purpose:    This function attempts to cache a font of some variety. It asks each
00244                 fontmanager in turn to attempt to cache the font. So for something like
00245                 'Symbol' a true type font will be cached as this font manager is asked
00246                 first
00247 
00248 ********************************************************************************************/
00249 
00250 BOOL OILFontMan::CacheNamedFont(String_64* pFontName, FontClass Class, INT32 Pass)
00251 {
00252     // Sticks the font in a temporary cache
00253     switch (Pass)
00254     {
00255         // PASS1 - try to cache an exact match
00256         case 1:
00257         {
00258             switch (Class)
00259             {
00260                 case FC_UNDEFINED:
00261                 {
00262 #ifdef __WXGTK__
00263                     if (FTFontMan::CacheNamedFont(pFontName))
00264                         return TRUE;
00265 #endif
00266 PORTNOTE("text","We do not use TTFontMan in wxOil")
00267 #ifndef EXCLUDE_FROM_XARALX
00268                     if (TTFontMan::CacheNamedFont(pFontName))
00269                         return TRUE;
00270 #endif
00271 PORTNOTE("text","Never cache ATM font")
00272 #ifndef EXCLUDE_FROM_XARALX
00273                     return ATMFontMan::CacheNamedFont(pFontName);
00274 #else
00275                     return FALSE;
00276 #endif                  
00277                     break;
00278                 }
00279 
00280                 case FC_TRUETYPE:
00281                 {
00282 #ifndef EXCLUDE_FROM_XARALX
00283                     return TTFontMan::CacheNamedFont(pFontName);
00284 #elif defined(__WXGTK__)
00285                     return FTFontMan::CacheNamedFont(pFontName);
00286 #else
00287 PORTNOTE("text","We do not use TTFontMan in wxOil")
00288                     return FALSE;
00289 #endif
00290                     break;
00291                 }
00292 
00293                 case FC_ATM:
00294                 {
00295 #ifndef EXCLUDE_FROM_XARALX
00296                     return ATMFontMan::CacheNamedFont(pFontName);
00297 #elif defined(__WXGTK__)
00298                     return FTFontMan::CacheNamedFont(pFontName);
00299 #else
00300 PORTNOTE("text","Never cache ATM font")
00301                     return FALSE;
00302 #endif                  
00303                     break;
00304                 }
00305 
00306                 default:
00307                     ERROR3("Unknown font class passed to OILFontMan::CacheNamedFont()");
00308             }
00309             break;
00310         }
00311 
00312         // PASS2 - try to create a compatible font as a replacement
00313         case 2:
00314         {
00315             switch (Class)
00316             {
00317                 case FC_UNDEFINED:
00318                 {
00319 #ifdef __WXGTK__
00320                     if (FTFontMan::CacheCompatibleFont(pFontName))
00321                         return TRUE;
00322 #endif
00323 
00324 PORTNOTE("text","We do not use TTFontMan in wxOil")
00325 #ifndef EXCLUDE_FROM_XARALX
00326                     if (TTFontMan::CacheCompatibleFont(pFontName))
00327                         return TRUE;
00328 #endif
00329 PORTNOTE("text","Never cache ATM font")
00330 #ifndef EXCLUDE_FROM_XARALX
00331                     return ATMFontMan::CacheCompatibleFont(pFontName);
00332 #else
00333                     return FALSE;
00334 #endif                  
00335                     break;
00336                 }
00337 
00338                 case FC_TRUETYPE:
00339                 {
00340 #ifndef EXCLUDE_FROM_XARALX
00341                     return TTFontMan::CacheCompatibleFont(pFontName);
00342 #elif defined(__WXGTK__)
00343                     return FTFontMan::CacheCompatibleFont(pFontName);
00344 #else
00345 PORTNOTE("text","We do not use TTFontMan in wxOil")
00346                     return FALSE;
00347 #endif
00348                     break;
00349                 }
00350 
00351                 case FC_ATM:
00352                 {
00353 #ifndef EXCLUDE_FROM_XARALX
00354                     return ATMFontMan::CacheCompatibleFont(pFontName);
00355 #elif defined(__WXGTK__)
00356                     return FTFontMan::CacheCompatibleFont(pFontName);
00357 #else
00358 PORTNOTE("text","Never cache ATM font")
00359                     return FALSE;
00360 #endif                  
00361                 }
00362 
00363                 default:
00364                     ERROR3("Unknown font class passed to OILFontMan::CacheNamedFont()");
00365 
00366             }
00367             break;
00368         }
00369     
00370         default:
00371             ERROR3("Unknown pass selector passed to OILFontMan::CacheNamedFont()");
00372     }
00373 
00374     return FALSE;
00375 }
00376 
00377 /********************************************************************************************
00378 
00379 >   static void OILFontMan::ValidateCache()
00380 
00381     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00382     Created:    12/9/95
00383     Purpose:    This function attempts to recache all fonts of all varieties
00384 
00385 ********************************************************************************************/
00386 
00387 void OILFontMan::ValidateCache()
00388 {
00389 #ifdef __WXGTK__
00390     FTFontMan::ValidateCache();
00391 #endif
00392 PORTNOTE("text","We do not use TTFontMan in wxOil")
00393 #ifndef EXCLUDE_FROM_XARALX
00394     TTFontMan::ValidateCache();
00395 #endif
00396 PORTNOTE("text","ATM deactivated")
00397 #ifndef EXCLUDE_FROM_XARALX
00398     ATMFontMan::ValidateCache();
00399 #endif
00400 }
00401 
00402 /********************************************************************************************
00403 
00404 >   static void OILFontMan::FindClosestFont()
00405 
00406     Author:     Andy_Hayward (Xara Group Ltd) <camelotdev@xara.com>
00407     Created:    20/08/96
00408     Inputs:     -
00409     Returns:    -
00410     Purpose:    Calls each of the font managers, when searching for a match to a panose number
00411 
00412 ********************************************************************************************/
00413 
00414 void OILFontMan::FindClosestFont()
00415 {
00416 #ifdef __WXGTK__
00417     FTFontMan::FindClosestFont();
00418 #endif
00419 PORTNOTE("text","We do not use TTFontMan in wxOil")
00420 #ifndef EXCLUDE_FROM_XARALX
00421     TTFontMan::FindClosestFont();
00422 #endif
00423 PORTNOTE("text","ATM deactivated")
00424 #ifndef EXCLUDE_FROM_XARALX
00425     ATMFontMan::FindClosestFont();
00426 #endif
00427 }
00428 
00429 /********************************************************************************************
00430 
00431 >   FontBase* OILFontMan::CreateNewFont(FontClass Class, String_64* pFontName)
00432 
00433     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00434     Created:    12/9/95
00435     Inputs:     Class = the type of font item to create
00436                 pFontName = the name of the font to put in the created item
00437     Retruns:    A pointer to a font item (dependent on the class on entry)
00438     Purpose:    This function attempts to create a font instance and will be called by
00439                 the font manager when new fonts are added.
00440 
00441 ********************************************************************************************/
00442 
00443 FontBase* OILFontMan::CreateNewFont(FontClass Class, String_64* pFontName)
00444 {
00445     switch (Class)
00446     {
00447         case FC_TRUETYPE:
00448 #ifndef EXCLUDE_FROM_XARALX
00449             return TTFontMan::CreateNewFont(pFontName);
00450 #elif defined(__WXGTK__)
00451             return FTFontMan::CreateNewFont(pFontName, Class);
00452 #else
00453 PORTNOTE("text","We do not use TTFontMan in wxOil")
00454             return NULL;
00455 #endif
00456             break;
00457         case FC_ATM:
00458 #ifndef EXCLUDE_FROM_XARALX
00459             return ATMFontMan::CreateNewFont(pFontName);
00460 #elif defined(__WXGTK__)
00461             return FTFontMan::CreateNewFont(pFontName, Class);
00462 #else
00463 PORTNOTE("text","ATM deactivated")
00464             return NULL;
00465 #endif
00466             break;
00467         default:
00468             break;
00469     }
00470     ERROR3("OILFontMan::CreateNewFont() - Unknown font class");
00471     return NULL;
00472 }
00473 
00474 /********************************************************************************************
00475 
00476 >   OUTLINETEXTMETRIC *OILFontMan::GetOutlineTextMetric(FontClass Class, LOGFONT *pLogFont)
00477 
00478     Author:     Andy_Hayward (Xara Group Ltd) <camelotdev@xara.com>
00479     Created:    15/08/96
00480     Inputs:     Class       - class of font
00481                 pLogFont    - LOGFONT structure describing the font to retrieve the
00482                               OUTLINETEXTMETRIC from
00483     Returns:    Pointer to the OUTLINETEXTMETRIC structure for a font, or NULL if one
00484                 doesn't exist.
00485     Purpose:    Returns the OUTLINETEXTMETRIC structure for a font.
00486 
00487 ********************************************************************************************/
00488 
00489 OUTLINETEXTMETRIC *OILFontMan::GetOutlineTextMetric(FontClass Class, LOGFONT *pLogFont)
00490 {
00491     switch (Class)
00492     {
00493         case FC_TRUETYPE:
00494 #ifndef EXCLUDE_FROM_XARALX
00495             return TTFontMan::GetOutlineTextMetric(pLogFont);
00496 #elif defined(__WXGTK__)
00497             return FTFontMan::GetOutlineTextMetric(pLogFont);
00498 #else
00499 PORTNOTE("text","TT deactivated")
00500             return NULL;
00501 #endif
00502             break;
00503         case FC_ATM:
00504 #ifndef EXCLUDE_FROM_XARALX
00505             return ATMFontMan::GetOutlineTextMetric(pLogFont);
00506 #elif defined(__WXGTK__)
00507             return FTFontMan::GetOutlineTextMetric(pLogFont);
00508 #else
00509 PORTNOTE("text","ATM deactivated")
00510             return NULL;
00511 #endif
00512             break;
00513         default:
00514             ERROR3("OILFontMan::CreateNewFont() - Unknown font class");
00515             break;
00516     }
00517     return NULL;
00518 }
00519 
00520 /********************************************************************************************
00521 >   String_64* OILFontMan::GetNativeFontName(FontClass Class, LOGFONT *pLogFont)
00522 
00523     Author:     Martin Wuerthner <xara@mw-software.com>
00524     Created:    01/08/06
00525     Inputs:     Class - the font class of the font (not used in wxOil but supplied in analogy
00526                         to GetOutlineTextMetrics)
00527                 pLogFont - a pointer to it's LOGFONT structure
00528     Returns:    A pointer to the underlying native font name
00529     Purpose:    Return the underlying native font name for a font
00530 
00531 ********************************************************************************************/
00532 String_64* OILFontMan::GetNativeFontName(FontClass Class, LOGFONT *pLogFont)
00533 {
00534     IGNOREPARAM(Class);
00535     return &pLogFont->FaceName;
00536 }
00537 
00538 /********************************************************************************************
00539 >   OILFontMan::InvalidateCharMetrics()
00540 
00541     Author:     Martin Wuerthner <xara@mw-software.com>
00542     Created:    20/04/2006
00543     Purpose:    Facade routine for FontMetricsCache::InvalidateCharMetrics
00544 
00545 ********************************************************************************************/
00546 void OILFontMan::InvalidateCharMetrics()
00547 {
00548     FontMetricsCache::InvalidateCharMetrics();
00549 }
00550 
00551 /********************************************************************************************
00552 >   BOOL GetCharMetrics(wxDC* pDC, WCHAR ch, CharDescription& FontDesc, CharMetrics* pCharMetrics)
00553 
00554     Author:     Martin Wuerthner <xara@mw-software.com>
00555     Created:    20/04/2006
00556     Purpose:    Facade routine for FontMetricsCache::GetCharMetrics
00557 
00558 ********************************************************************************************/
00559 BOOL OILFontMan::GetCharMetrics(wxDC* pDC, WCHAR ch, CharDescription& FontDesc, CharMetrics* pCharMetrics)
00560 {
00561     return FontMetricsCache::GetCharMetrics(pDC, ch, FontDesc, pCharMetrics);
00562 }
00563 
00564 /********************************************************************************************
00565 >   MILLIPOINT GetCharsKerning(wxDC* pDC, WCHAR chLeft, WCHAR chRight, CharDescription& FontDesc)
00566 
00567     Author:     Martin Wuerthner <xara@mw-software.com>
00568     Created:    20/04/2006
00569     Purpose:    Facade routine for FontKerningPairsCache::GetCharsKerning
00570 
00571 ********************************************************************************************/
00572 MILLIPOINT OILFontMan::GetCharsKerning(wxDC* pDC, WCHAR chLeft, WCHAR chRight, CharDescription& FontDesc)
00573 {
00574     return FontKerningPairsCache::GetCharsKerning(pDC, chLeft, chRight, FontDesc);
00575 }
00576 
00577 /********************************************************************************************
00578 
00579 >   static UINT32 OILFontMan::GetOutlineCache(DocCoord** pCoords, PathVerb** pVerbs);
00580 
00581     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00582     Created:    12/9/95
00583     Inputs:     -
00584     Outputs;    pCoords, a pointer to the coordinate cache
00585                 pVerbs, a pointer to the verb cache
00586     Returns:    The number of elements in the path cache.
00587     Purpose:    The function returns pointers to a statically allocated cache consiting of
00588                 a verb and coordinate array. The cache is generally used by the font manager
00589                 gen outline routines to temporarily store outlines of characters.
00590 
00591 ********************************************************************************************/
00592 
00593 UINT32 OILFontMan::GetOutlineCache(DocCoord** pCoords, PathVerb** pVerbs)
00594 {
00595     if (pCoords!=NULL)
00596         (*pCoords)=(CharOutlineCache::CacheCoords);
00597     if (pVerbs!=NULL)
00598         (*pVerbs)=(CharOutlineCache::CacheVerbs);
00599     return (CharOutlineCache::CacheSize);
00600 }
00601 
00602 /********************************************************************************************
00603 
00604 >   static void OILFontMan::InitialiseOutlineCache()
00605 
00606     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00607     Created:    26/9/95
00608     Inputs:     -
00609     returns:    -
00610     Purpose:    Resets the OILFontMan CharOutlineCache to zero. Must be called before
00611                 any calls to AddMoveTo, AddLineTo, AddBezierTo, ClosePath.
00612 
00613 ********************************************************************************************/
00614 
00615 void OILFontMan::InitialiseOutlineCache()
00616 {
00617     CharOutlineCache::CacheSize=0;
00618     CharOutlineCache::LastMoveTo.x = 0x7FFFFFFF;
00619 }
00620 
00621 /********************************************************************************************
00622 
00623 >   BOOL OILFontMan::AddMoveTo(POINT& p0)
00624 
00625     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00626     Created:    12/9/95
00627     Inputs:     p0 = a coordinate
00628     Returns:    TRUE if the coordinate was added to the outline cache
00629                 FALSE if not
00630     Purpose:    Adds a new moveto element and point to the character outline cache at
00631                 the insert position.
00632 
00633 ********************************************************************************************/
00634 
00635 BOOL OILFontMan::AddMoveTo(POINT& p0)
00636 {
00637     if ((CharOutlineCache::CacheSize)<OILFONTLIMIT)
00638     {
00639         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize].x = p0.x;
00640         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize].y = p0.y;
00641         CharOutlineCache::CacheVerbs[CharOutlineCache::CacheSize] = PT_MOVETO;
00642         CharOutlineCache::CacheSize++;
00643         CharOutlineCache::LastMoveTo.x = p0.x;
00644         CharOutlineCache::LastMoveTo.y = p0.y;
00645         return TRUE;
00646     }
00647     ERROR3("CharOutlineCache overflow");
00648     return FALSE;
00649 }
00650 
00651 BOOL OILFontMan::AddMoveTo(DocCoord& p0)
00652 {
00653     if ((CharOutlineCache::CacheSize)<OILFONTLIMIT)
00654     {
00655         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize] = p0;
00656         CharOutlineCache::CacheVerbs[CharOutlineCache::CacheSize] = PT_MOVETO;
00657         CharOutlineCache::CacheSize++;
00658         CharOutlineCache::LastMoveTo = p0;
00659         return TRUE;
00660     }
00661     ERROR3("CharOutlineCache overflow");
00662     return FALSE;
00663 }
00664 
00665 /********************************************************************************************
00666 
00667 >   BOOL OILFontMan::AddLineTo(POINT& p0)
00668 
00669     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00670     Created:    12/9/95
00671     Inputs:     p0 = a coordinate
00672     Returns:    TRUE if the coordinate was added to the outline cache
00673                 FALSE if not
00674     Purpose:    Adds a new lineto element and point to the character outline cache at
00675                 the insert position.
00676 
00677 ********************************************************************************************/
00678 
00679 BOOL OILFontMan::AddLineTo(POINT& p0)
00680 {
00681     if ((CharOutlineCache::CacheSize)<OILFONTLIMIT)
00682     {
00683         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize].x = p0.x;
00684         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize].y = p0.y;
00685         CharOutlineCache::CacheVerbs[CharOutlineCache::CacheSize] = PT_LINETO;
00686         CharOutlineCache::CacheSize++;
00687         return TRUE;
00688     }
00689     ERROR3("CharOutlineCache overflow");
00690     return FALSE;
00691 }
00692 
00693 BOOL OILFontMan::AddLineTo(DocCoord& p0)
00694 {
00695     if ((CharOutlineCache::CacheSize)<OILFONTLIMIT)
00696     {
00697         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize] = p0;
00698         CharOutlineCache::CacheVerbs[CharOutlineCache::CacheSize] = PT_LINETO;
00699         CharOutlineCache::CacheSize++;
00700         return TRUE;
00701     }
00702     ERROR3("CharOutlineCache overflow");
00703     return FALSE;
00704 }
00705 
00706 /********************************************************************************************
00707 
00708 >   BOOL OILFontMan::AddBezierTo(POINT& p0, POINT& p1, POINT& p2)
00709 
00710     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00711     Created:    12/9/95
00712     Inputs:     p0,p1,p2 = a set of coordinates
00713     Returns:    TRUE if the coordinates were added to the outline cache
00714                 FALSE if not
00715     Purpose:    Adds a new bezierto element to the character outline cache at the insert
00716                 position.
00717 
00718 ********************************************************************************************/
00719 
00720 BOOL OILFontMan::AddBezierTo(POINT& p0, POINT& p1, POINT& p2)
00721 {
00722     if ((CharOutlineCache::CacheSize)<(OILFONTLIMIT-3))
00723     {
00724         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize].x = p0.x;
00725         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize].y = p0.y;
00726         CharOutlineCache::CacheVerbs[CharOutlineCache::CacheSize] = PT_BEZIERTO;
00727         CharOutlineCache::CacheSize++;
00728         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize].x = p1.x;
00729         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize].y = p1.y;
00730         CharOutlineCache::CacheVerbs[CharOutlineCache::CacheSize] = PT_BEZIERTO;
00731         CharOutlineCache::CacheSize++;
00732         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize].x = p2.x;
00733         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize].y = p2.y;
00734         CharOutlineCache::CacheVerbs[CharOutlineCache::CacheSize] = PT_BEZIERTO;
00735         CharOutlineCache::CacheSize++;
00736         return TRUE;
00737     }
00738     ERROR3("CharOutlineCache overflow");
00739     return FALSE;
00740 }
00741 
00742 BOOL OILFontMan::AddBezierTo(DocCoord& p0, DocCoord& p1, DocCoord& p2)
00743 {
00744     if ((CharOutlineCache::CacheSize)<(OILFONTLIMIT-3))
00745     {
00746         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize] = p0;
00747         CharOutlineCache::CacheVerbs[CharOutlineCache::CacheSize] = PT_BEZIERTO;
00748         CharOutlineCache::CacheSize++;
00749         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize] = p1;
00750         CharOutlineCache::CacheVerbs[CharOutlineCache::CacheSize] = PT_BEZIERTO;
00751         CharOutlineCache::CacheSize++;
00752         CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize] = p2;
00753         CharOutlineCache::CacheVerbs[CharOutlineCache::CacheSize] = PT_BEZIERTO;
00754         CharOutlineCache::CacheSize++;
00755         return TRUE;
00756     }
00757     ERROR3("CharOutlineCache overflow");
00758     return FALSE;
00759 }
00760 
00761 /********************************************************************************************
00762 
00763 >   BOOL OILFontMan::ClosePath()
00764 
00765     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00766     Created:    12/9/95
00767     Inputs:     -
00768     Retruns:    TRUE if the current path has been closed
00769                 FALSE if there is no valid path in the cache
00770     Purpose:    To close the cached path
00771 
00772 ********************************************************************************************/
00773 
00774 BOOL OILFontMan::ClosePath()
00775 {
00776     if ((CharOutlineCache::CacheSize)<1)
00777         return FALSE;
00778 
00779     // Just check the initialised value of LastMoveto for sanity
00780     if (CharOutlineCache::LastMoveTo.x == 0x7FFFFFFF)
00781     {
00782         ERROR3("No moveto in outline cache");
00783         return FALSE;
00784     }
00785     
00786     // find the last coordinate visited
00787     DocCoord LastCoord = CharOutlineCache::CacheCoords[CharOutlineCache::CacheSize-1];
00788 
00789     // if last coord does not close the path then add an extra element
00790     if (LastCoord != CharOutlineCache::LastMoveTo)
00791         if (!AddLineTo(CharOutlineCache::LastMoveTo))
00792             return FALSE;
00793 
00794     // finally close the element and record its position
00795     CharOutlineCache::CacheVerbs[CharOutlineCache::CacheSize-1] |= PT_CLOSEFIGURE;
00796 
00797     return TRUE;
00798 }
00799 
00800 /********************************************************************************************
00801 
00802 >   static void OILFontMan::FinaliseOutlineCache()
00803 
00804     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00805     Created:    26/9/95
00806     Inputs:     -
00807     returns:    -
00808     Purpose:    Tidies what is left by a series of calls to AddMoveTo, AddLineTo, AddCurveTo
00809                 to make sure the path format is correct for our internal processors.
00810 
00811 ********************************************************************************************/
00812 
00813 void OILFontMan::FinaliseOutlineCache()
00814 {
00815 }
00816 
00817 /********************************************************************************************
00818 
00819 >   static BOOL OILFontMan::GetCharPath(CharDescription& ChDesc,
00820                                         DocCoord** ppCoords,
00821                                         PathVerb** ppVerbs,
00822                                         UINT32* pNumCoords,
00823                                         wxDC* pDC=NULL)
00824 
00825     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00826     Created:    28/9/95
00827     Inputs:     ChDesc  = description of char
00828                 pDC     = (possible) pointer to a DC (for optimisation) defaults to NULL
00829     Outputs:    ppCoords    = pointer to path coords buffer
00830                 ppVerbs     = pointer to path verbs buffer
00831                 pNumCoords  = number of elements in path
00832     Returns:    FALSE if fails
00833     Purpose:    Get the path associated with a given char
00834 
00835 ********************************************************************************************/
00836 
00837 BOOL OILFontMan::GetCharPath(FontClass fclass,
00838                              CharDescription& ChDesc,
00839                              DocCoord** ppCoords,
00840                              PathVerb** ppVerbs,
00841                              UINT32* pNumCoords,
00842                              wxDC *pDC)
00843 {
00844     // TRACEUSER("wuerthne",_T("OILFontMan::GetCharPath"));
00845     BOOL Success=FALSE;
00846     switch (fclass)
00847     {
00848         case FC_TRUETYPE:
00849 #ifndef EXCLUDE_FROM_XARALX
00850             Success = TextManager::GetTTCharPath(ChDesc, ppCoords, ppVerbs, pNumCoords, pDC);
00851 #elif defined(__WXGTK__)
00852             Success = FTFontMan::GetCharOutline(ChDesc, ppCoords, ppVerbs, pNumCoords, pDC);
00853 #else
00854             PORTNOTE("text","TrueType deactivated")
00855 #endif
00856             ERROR1IF(Success==FALSE, FALSE, _R(IDE_FONTMAN_NOTTOUTLINE));
00857             break;
00858 
00859         case FC_ATM:
00860 #ifndef EXCLUDE_FROM_XARALX
00861             Success = ATMFontMan::GetCharOutline(ChDesc, ppCoords, ppVerbs, pNumCoords, pDC);
00862 #elif defined(__WXGTK__)
00863             Success = FTFontMan::GetCharOutline(ChDesc, ppCoords, ppVerbs, pNumCoords, pDC);
00864 #else
00865             PORTNOTE("text","ATM deactivated")
00866 #endif
00867             ERROR1IF(Success==FALSE, FALSE, _R(IDE_FONTMAN_NOATMOUTLINE));
00868             break;
00869 
00870         default:
00871             ERROR3("Unknown font class in OILFontMan::GetCharPath");
00872             break;
00873     }
00874     return Success;
00875 }
00876 
00877 
00879 // FontMetricsCacheEntry
00880 
00881 /********************************************************************************************
00882 >   FontMetricsCacheEntry::FontMetricsCacheEntry()
00883 
00884     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00885     Created:    15/1/96
00886     Purpose:    Default constructor
00887 
00888 ********************************************************************************************/
00889 
00890 FontMetricsCacheEntry::FontMetricsCacheEntry()
00891 {
00892     for (INT32 i=0; i<NUMCHARS; i++)
00893         pCharWidths[i] = 0;
00894 
00895     FontEmWidth = 0;
00896     FontAscent  = 0;
00897     FontDescent = 0;
00898     CharDescription emptyCharDesc(0, 0, 0, 0);
00899     FontDesc    = emptyCharDesc;
00900 }
00901 
00902 
00903 /********************************************************************************************
00904 >   BOOL FontMetricsCacheEntry::CacheFontMetrics(wxDC* pDC, CharDescription FontDesc,
00905                                                 MILLIPOINT DefaultHeight, INT32 DesignSize)
00906 
00907     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00908     Created:    15/1/96
00909     Inputs:     pDC           - DC with design size font selected
00910                 FontDesc      - descriptor of font which is being cached
00911                 DefaultHeight - default height of char (ie size of font for which char widths are cached)
00912                 DesignSize    - size of font selected in DC (in Logical units - pixels)
00913     Returns:    FALSE if fails
00914     Purpose:    Refill the font cache entry
00915 ********************************************************************************************/
00916 
00917 BOOL FontMetricsCacheEntry::CacheFontMetrics( wxDC* pDC, CharDescription FontDesc,
00918                                                 MILLIPOINT DefaultHeight, INT32 DesignSize )
00919 {
00920 #ifdef __WXGTK__
00921     INT32 Ascent;
00922     INT32 Descent;
00923 #endif
00924 
00925     // these values are ignored - the DesignSize needs to be read from the font, so the
00926     // scaling needs to be done by FTFontMan itself
00927     IGNOREPARAM(DefaultHeight);
00928     IGNOREPARAM(DesignSize);
00929 
00930 #ifdef __WXGTK__
00931     // TRACEUSER("wuerthne", _T("CacheFontMetrics DesignSize = %d"), DesignSize);
00932     if (FTFontMan::GetAscentDescent(FontDesc, &Ascent, &Descent) == FALSE) return FALSE;
00933     // scaling to DefaultHeight was done in GetAscentDescent already
00934     SetFontAscent( Ascent );
00935     SetFontDescent( -Descent );
00936 
00937     // get char widths and convert form design size in pixels to default height in millipoints
00938     static INT32 pTempCharWidthBuf[NUMCHARS];
00939     if (FTFontMan::GetCharWidth(FontDesc, FIRSTCHAR, LASTCHAR, pTempCharWidthBuf)==FALSE)
00940         return FALSE;
00941     // scaling to DefaultHeight was done in GetCharWidth already
00942     for (INT32 i=0; i<NUMCHARS; i++)
00943         pCharWidths[i] = pTempCharWidthBuf[i];
00944 
00945     // if 'em' char in cache, get it from the cache else calculate its width separately
00946     if (CharInCacheRange(FONTEMCHAR))
00947         SetFontEmWidth( GetCharWidthFromCache(FONTEMCHAR) );
00948     else
00949     {
00950         ERROR3("FontMetricsCache::GetCharMetrics() - 'FONTEMCHAR' not in cache!");
00951         INT32 TempCharWidth = 0;
00952         if (FTFontMan::GetCharWidth(FontDesc, FONTEMCHAR, FONTEMCHAR, &TempCharWidth)==FALSE)
00953             return FALSE;
00954         // scaling to DefaultHeight was done in GetCharWidth already
00955         SetFontEmWidth( TempCharWidth );
00956     }
00957 
00958     // update cache tag
00959     SetFontDesc(FontDesc);
00960 #else // !wxGTK
00961     return FALSE;
00962 #endif
00963 
00964 #ifndef EXCLUDE_FROM_XARALX
00965     // debug test
00966     CheckCharWidthsSameAsABCWidths(pDC,FontDesc);
00967 #endif
00968     return TRUE;
00969 }
00970 
00971 
00972 /********************************************************************************************
00973 >   static void FontMetricsCacheEntry::CheckCharWidthsSameAsABCWidths(wxDC* pDC, CharDescription FontDesc)
00974 
00975     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00976     Created:    15/1/96
00977     Inputs:     pDC      - 
00978                 FontDesc - 
00979     Purpose:    Test to see if ::GetCharWidth() with design size font is as accurate as ::GetCharABCWidths()
00980 ********************************************************************************************/
00981 
00982 void FontMetricsCacheEntry::CheckCharWidthsSameAsABCWidths(wxDC* pDC, CharDescription FontDesc)
00983 {
00984 #ifdef _DEBUG
00985 #ifndef EXCLUDE_FROM_XARALX
00986     // ensure that the char widths are the same as the sum of the ABC widths
00987 
00988     // do nothing if its an ATM font (or an error)
00989     CachedFontItem* pItem = FONTMANAGER->GetFont(FontDesc.GetTypefaceHandle());
00990     if (pItem->GetFontClass()==FC_ATM || pItem==NULL || pItem->IsCorrupt())
00991         return;
00992 
00993     INT32 pTempCharWidthBuf[NUMCHARS];
00994     ABC pTempCharABCBuf[NUMCHARS];
00995     BOOL    ok = TextManager::GetCharWidth(    pDC, FIRSTCHAR, LASTCHAR, pTempCharWidthBuf);
00996     if (ok) ok = TextManager::GetCharABCWidths(pDC, FIRSTCHAR, LASTCHAR, pTempCharABCBuf);
00997     ERROR3IF(!ok,"FontMetricsCache::CheckCharWidthsSameAsABCWidths() - TextManager::GetCharWidth()/GetCharABCWidths() failed!\n");
00998 
00999     for (INT32 i=0; i<NUMCHARS; i++)
01000     {
01001         ABC* pABC     = &pTempCharABCBuf[i];
01002         INT32 SumABC    = pABC->abcA+pABC->abcB+pABC->abcC;
01003         INT32 CharWidth = pTempCharWidthBuf[i];
01004         ERROR3IF_PF(SumABC!=CharWidth,("FontMetricsCache::CheckCharWidthsSameAsABCWidths() - sum of ABCwidths (%d) differs from CharWidths (%d)",SumABC,CharWidth));
01005     }
01006 #endif
01007 
01008 //#ifdef _DEBUG
01009 #if 0
01010     // test accuracy of old and new methods of calculating metrics
01011 
01012     INT32 DesignSizeInPixels = TextManager::GetDesignSize(pDC);
01013     INT32 DefaultSizeInMP    = TextManager::GetDefaultHeight();
01014     INT32 dpi                = pDC->GetDeviceCaps(LOGPIXELSY);
01015     for (MILLIPOINT FontSizeInMP=4000; FontSizeInMP<=72000; FontSizeInMP+=4000)
01016     {
01017         double SumNewMetrics      = 0;
01018         double SumOldMetrics      = 0;
01019         double SumAccurateMetrics = 0;
01020         for (WCHAR ch=0; ch<256; ch++)
01021         {
01022             INT32 DesignSizeMetricInPixels = 500;
01023             BOOL ok = TextManager::GetCharWidth(pDC,ch,ch,&DesignSizeMetricInPixels);
01024             ERROR3IF(!ok,"FontMetricsCache::CheckCharWidthsSameAsABCWidths() - TextManager::GetCharWidth() failed!\n");
01025 
01026             // new calc
01027             MILLIPOINT InchMetricInMP                  = MulDiv(DesignSizeMetricInPixels, DefaultSizeInMP, DesignSizeInPixels);
01028             FIXED16    InchMetricToFontSizeMetricRatio = Div32By32(FontSizeInMP, DefaultSizeInMP);
01029             MILLIPOINT NewFontSizeMetricInMP           = InchMetricInMP * InchMetricToFontSizeMetricRatio;
01030             SumNewMetrics += NewFontSizeMetricInMP;
01031 
01032             // old calc
01033             MILLIPOINT DesignSizeMetricInMP                  = MulDiv(DesignSizeMetricInPixels, 72000, dpi);
01034             MILLIPOINT DesignSizeInMP                        = MulDiv(DesignSizeInPixels, 72000, dpi);
01035             FIXED16    DesignSizeMetricToFontSizeMetricRatio = Div32By32(FontSizeInMP, DesignSizeInMP);
01036             MILLIPOINT OldFontSizeMetricInMP                 = DesignSizeMetricInMP * DesignSizeMetricToFontSizeMetricRatio;
01037             SumOldMetrics += OldFontSizeMetricInMP;
01038 
01039             // accurate calc
01040             double AccurateFontSizeMetricInMP = (double) DesignSizeMetricInPixels / DesignSizeInPixels * FontSizeInMP;
01041             SumAccurateMetrics += AccurateFontSizeMetricInMP;
01042         }
01043         TRACEUSER( "Ed", _T("Sum of CharWidths (%5dMP): new=%8.0f (e=%6.2f), old=%8.0f (e=%6.2f), accrutate=%8.2f\n"), FontSizeInMP, SumNewMetrics, SumNewMetrics-SumAccurateMetrics, SumOldMetrics, SumOldMetrics-SumAccurateMetrics, SumAccurateMetrics);
01044     }
01045 #endif // EXCLUDE_FROM_XARALX
01046 #endif // _DEBUG
01047 }
01048 
01049 
01051 // FontMetricsCache
01052 
01053 /********************************************************************************************
01054 >   static BOOL FontMetricsCache::GetCharMetrics(wxDC* pDC, WCHAR ch, CharDescription& FontDesc,
01055                                                     CharMetrics* pCharMetrics)
01056 
01057     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
01058     Created:    14/1/96
01059     Inputs:     pDC         = a pointer to a device context
01060                 ch          = a character code
01061                 FontDesc    = a font description
01062     Outputs:    pCharMetrics = metrics of char requested
01063     Returns:    FALSE if fails
01064     Purpose:    Get the metrics of a given char for the font selected in the DC,
01065     Note:       Uses a single entry cache for speed
01066 ********************************************************************************************/
01067 
01068 BOOL FontMetricsCache::GetCharMetrics(wxDC* pDC, WCHAR ch, CharDescription& FontDesc, CharMetrics* pCharMetrics)
01069 {
01070     // TRACEUSER("wuerthne", _T("FontMetricsCache::GetCharMetrics %04x"), ch);
01071     IGNOREPARAM(pDC);
01072     ERROR2IF(pCharMetrics==NULL,FALSE,"FontMetricsCache::GetCharMetrics() - pCharMetrics==NULL");
01073     ERROR2IF(FontDesc.GetCharCode()!=FONTEMCHAR,FALSE,"FontMetricsCache::GetCharMetrics() - FontDesc char should be 'FONTEMCHAR'");
01074 
01075     // find if font is in cache (and if so which entry)
01076     INT32 CacheEntry = 0;
01077     while (CacheEntry<NUMENTRIES && mpFontMetricsData[CacheEntry].GetFontDesc()!=FontDesc)
01078         CacheEntry +=1;
01079 
01080     // if font not in cache, recache it, or if char not in cached range, get it explicitly
01081     MILLIPOINT CharWidth  = 0;
01082     BOOL CharInCacheRange = FontMetricsCacheEntry::CharInCacheRange(ch);
01083     if (CacheEntry>=NUMENTRIES || !CharInCacheRange)
01084     {
01085         // get design size of font, and default heigh
01086         INT32 DesignSize    = TextManager::GetDesignSize(pDC);  // ignores pDC
01087         INT32 DefaultHeight = TextManager::GetDefaultHeight();
01088 
01089         CachedFontItem* pItem = FONTMANAGER->GetFont(FontDesc.GetTypefaceHandle());
01090         if (pItem==NULL || pItem->IsCorrupt())
01091             return FALSE;
01092 
01093         // get a LogFont, create a font and select it into the DC
01094         LOGFONT CharLogFont;
01095         if (TextManager::GetLogFontFromCharDescriptor(pDC, FontDesc, &CharLogFont, DesignSize)==FALSE)
01096             return FALSE;
01097 
01098         // if font not in cache, cache its metrics throwing out a random entry
01099         if (CacheEntry>=NUMENTRIES)
01100         {
01101             CacheEntry = rand() % NUMENTRIES;
01102             if (mpFontMetricsData[CacheEntry].CacheFontMetrics(pDC, FontDesc, DefaultHeight, DesignSize) == FALSE)
01103                 return FALSE;
01104         }
01105 
01106         // if char not in cache, find it's width separately (unless it is FONTEMCHAR - eg for kern code, blank line)
01107         if (!CharInCacheRange)
01108         {
01109             if (ch==FONTEMCHAR)
01110                 CharWidth = mpFontMetricsData[CacheEntry].GetFontEmWidth();
01111             else
01112             {
01113 #ifdef __WXGTK__
01114                 // FTFontMan returns the scaled character width already
01115                 if (FTFontMan::GetCharWidth(FontDesc, ch, ch, &CharWidth)==FALSE)
01116 #endif
01117                     return FALSE;
01118             }
01119         }
01120     }
01121 
01122     if (CharInCacheRange)
01123         CharWidth = mpFontMetricsData[CacheEntry].GetCharWidthFromCache(ch);
01124 
01125     pCharMetrics->CharWidth   = CharWidth;
01126     pCharMetrics->FontAscent  = mpFontMetricsData[CacheEntry].GetFontAscent();
01127     pCharMetrics->FontEmWidth = mpFontMetricsData[CacheEntry].GetFontEmWidth();
01128     pCharMetrics->FontDescent = mpFontMetricsData[CacheEntry].GetFontDescent();
01129     return TRUE;
01130 }
01131 
01132 
01133 /********************************************************************************************
01134 >   static void FontMetricsCache::InvalidateCharMetrics()
01135 
01136     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
01137     Created:    15/1/96
01138     Purpose:    Invalidate the FontMetricsCache
01139 ********************************************************************************************/
01140 
01141 void FontMetricsCache::InvalidateCharMetrics()
01142 {
01143     CharDescription emptyCharDesc(0, 0, 0, 0);
01144     for (INT32 i=0; i<NUMENTRIES; i++)
01145         mpFontMetricsData[i].SetFontDesc( emptyCharDesc );
01146 }
01147 
01149 // FontKerningPairsCache
01150 
01151 /********************************************************************************************
01152 >   static MILLIPOINT FontKerningPairsCache::GetCharsKerning(wxDC* pDC, WCHAR chLeft,
01153                                                     WCHAR chRight, CharDescription& FontDesc);
01154 
01155     Author:     Jonathan_Payne (Xara Group Ltd) <camelotdev@xara.com>
01156     Created:    16/20/2000
01157     Inputs:     pDC         = a pointer to a device context
01158                 chLeft      = a character code of the left char of a kerning pair
01159                 chRight     = a character code of the right char of a kerning pair
01160                 FontDesc    = a font description
01161     Returns:    Kern in millipoints (or zero if no kern or error)
01162     Purpose:    Get the kern between two chars of a font
01163     Note:       The kern pairs are cached (see FontKerningPairsCacheEntry::GetCharsKerning)
01164 ********************************************************************************************/
01165 
01166 MILLIPOINT FontKerningPairsCache::GetCharsKerning(wxDC* pDC, WCHAR chLeft, WCHAR chRight,
01167                                                   CharDescription& FontDesc)
01168 {
01169     // TRACEUSER("wuerthne", _T("GetCharsKerning %04x %04x"), chLeft, chRight);
01170     ERROR2IF(pDC==NULL, 0, "FontKerningPairsCache::GetCharsKerning() - pDC==NULL");
01171     ERROR2IF(FontDesc.GetCharCode() != FONTEMCHAR, FALSE,
01172         "FontKerningPairsCache::GetCharsKerning() - FontDesc char should be 'FONTEMCHAR'");
01173 #ifndef DISABLE_TEXT_RENDERING
01174     // find out whether the font is in the cache (and if so which entry)
01175     INT32 CacheEntry = 0;
01176     while (CacheEntry < NUMENTRIES && m_FontKerningPairsCacheData[CacheEntry].GetFontDesc() != FontDesc)
01177         CacheEntry++;
01178 
01179     if (CacheEntry >= NUMENTRIES)
01180     {
01181         // TRACEUSER("wuerthne", _T("did not find cache entry, so allocate new one"));
01182         // the font is not in the cache, so throw out a random cache entry and prepare
01183         // the cache entry so we can start caching the kerning data for the new font
01184         CacheEntry = rand() % NUMENTRIES;
01185         m_FontKerningPairsCacheData[CacheEntry].Reinitialise(FontDesc);
01186     }
01187     return m_FontKerningPairsCacheData[CacheEntry].GetCharsKerning(chLeft, chRight);
01188 #else
01189     return 0;
01190 #endif
01191 }
01192 
01193 #ifdef _DEBUG
01194 /********************************************************************************************
01195 
01196 >   void FontKerningPairsCache::Dump()
01197 
01198     Author:     Jonathan_Payne (Xara Group Ltd) <camelotdev@xara.com>
01199     Created:    16/10/2000
01200     Purpose:    Dumps the class's data
01201 
01202 ********************************************************************************************/
01203 void FontKerningPairsCache::Dump()
01204 {
01205     TRACE( _T(">>> Font kerning data start >>>\n"));
01206     for (INT32 i=0; i<NUMENTRIES; ++i)
01207     {
01208         TRACE( _T("Entry %d:\n"), i);
01209         m_FontKerningPairsCacheData[i].Dump();
01210     }
01211     TRACE( _T("<<< Font kerning data end <<<\n"));
01212 }
01213 #endif // _DEBUG
01214 
01216 // FontKerningPairsCacheEntry
01217 
01218 /********************************************************************************************
01219 >   FontKerningPairsCacheEntry::FontKerningPairsCacheEntry()
01220 
01221     Author:     Martin Wuerthner <xara@mw-software.com>
01222     Created:    20/04/2006
01223     Purpose:    Default constructor
01224 
01225 ********************************************************************************************/
01226 FontKerningPairsCacheEntry::FontKerningPairsCacheEntry()
01227 {
01228     CharDescription emptyCharDesc(0, 0, 0, 0);
01229     FontDesc = emptyCharDesc;
01230     m_pPairsCacheMap = NULL;
01231 }
01232 
01233 /********************************************************************************************
01234 >   FontKerningPairsCacheEntry::FontKerningPairsCacheEntry()
01235 
01236     Author:     Martin Wuerthner <xara@mw-software.com>
01237     Created:    20/04/2006
01238     Purpose:    Destructor
01239 
01240 ********************************************************************************************/
01241 FontKerningPairsCacheEntry::~FontKerningPairsCacheEntry()
01242 {
01243     if (m_pPairsCacheMap) delete m_pPairsCacheMap;
01244 }
01245 
01246 /********************************************************************************************
01247 >   FontKerningPairsCacheEntry::Reinitialise(CharDescription& NewFontDesc)
01248 
01249     Author:     Martin Wuerthner <xara@mw-software.com>
01250     Created:    20/04/2006
01251     Inputs:     NewFontDesc = a font descriptor specifying the font to which this cache
01252                               entry should refer from now on
01253     Purpose:    Clears the cache entry and initialises it for a new font
01254 
01255 ********************************************************************************************/
01256 void FontKerningPairsCacheEntry::Reinitialise(CharDescription& NewFontDesc)
01257 {
01258     FontDesc = NewFontDesc;
01259     if (m_pPairsCacheMap) delete m_pPairsCacheMap;
01260     m_pPairsCacheMap = new std::map<UINT32,INT32>;
01261     // we do not check whether the new has succeeded - in case it has not,
01262     // we will not fall over later but caching will be disabled for this entry
01263 }
01264 
01265 /********************************************************************************************
01266 >   FontKerningPairsCacheEntry::GetCharsKerning(WCHAR chLeft, WCHAR chRight)
01267 
01268     Author:     Martin Wuerthner <xara@mw-software.com>
01269     Created:    20/04/2006
01270     Inputs:     chLeft      = a character code of the left char of a kerning pair
01271                 chRight     = a character code of the right char of a kerning pair
01272     Returns:    Kern in millipoints (or zero if no kern or error)
01273     Purpose:    Gets the kerning for a character pair (and caches it if not cached yet)
01274     Note:       The cache uses an STL map, which means logarithmic access time. Maybe
01275                 a hash_map could do better.
01276 
01277 ********************************************************************************************/
01278 MILLIPOINT FontKerningPairsCacheEntry::GetCharsKerning(WCHAR chLeft, WCHAR chRight)
01279 {
01280     UINT32 key;
01281     // we cache the kerning for characters in the range 0x0 - 0xFFFF only
01282     // we also need the map set up - if it could not be allocated, we simply bypass the cache
01283     if (chLeft > 0x10000 || chRight > 0x10000 || m_pPairsCacheMap == NULL)
01284     {
01285         // TRACEUSER("wuerthne", _T("Bypass cache"));
01286 #ifdef __WXGTK__
01287         return FTFontMan::GetCharsKerning(FontDesc, chLeft, chRight);
01288 #else
01289         return 0;
01290 #endif
01291     }
01292 
01293     key = (chLeft << 16) | chRight;
01294     std::map<UINT32,INT32>::iterator it = m_pPairsCacheMap->find(key);
01295     if (it != m_pPairsCacheMap->end()) {
01296         // we found a cached entry
01297         // TRACEUSER("wuerthne", _T("kern pair found"));
01298         return it->second;
01299     }
01300     else {
01301         // we did not find an entry, so get the kerning from the underlying font system
01302 #ifdef __WXGTK__
01303         INT32 kerning = FTFontMan::GetCharsKerning(FontDesc, chLeft, chRight);
01304 #else
01305         INT32 kerning = 0;
01306 #endif
01307         // and cache it
01308         // TRACEUSER("wuerthne", _T("cache kern pair"));
01309         (*m_pPairsCacheMap)[key] = kerning;
01310         return kerning;
01311     }
01312 }
01313 
01314 #if _DEBUG
01315 
01316 /********************************************************************************************
01317 
01318 >   void FontKerningPairsCacheEntry::Dump()
01319 
01320     Author:     Martin Wuerthner <xara@mw-software.com>
01321     Created:    21/04/2006
01322     Purpose:    Dumps the class data
01323 
01324 ********************************************************************************************/
01325 void FontKerningPairsCacheEntry::Dump()
01326 {
01327     // dump the map
01328     if (m_pPairsCacheMap != NULL) {
01329         for (std::map<UINT32,INT32>::iterator it = m_pPairsCacheMap->begin(); it != m_pPairsCacheMap->end(); ++it)
01330         {
01331             UINT32 key = (*it).first;
01332             TRACE(_T("cached kern pair %04x/%04x = %d"), key >> 16, key & 0xffff, (*it).second);
01333         }
01334     }
01335 }
01336 
01337 #endif // _DEBUG
01338 
01340 // some debug stuff
01341 
01342 
01343 #if _DEBUG
01344 
01345 /********************************************************************************************
01346 
01347 >   static void CharOutlineCache::Dump()
01348 
01349     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01350     Created:    26/9/95
01351     Purpose:    Dump out the contents of the character outline cache
01352 
01353 ********************************************************************************************/
01354 
01355 void CharOutlineCache::Dump()
01356 {
01357     UINT32 i=0;
01358 
01359     TRACE( _T("CHAROUTLINECACHE DUMP\n"));
01360 
01361     while (i < CacheSize)
01362     {
01363         switch ((CacheVerbs[i]) & ~PT_CLOSEFIGURE)
01364         {
01365             case PT_MOVETO:
01366                 TRACE( _T("MoveTo "));
01367                 TRACE( _T("(%d,"),CacheCoords[i].x);
01368                 TRACE( _T("%d)\n"),CacheCoords[i].y);
01369                 i++;
01370                 break;
01371             case PT_LINETO:
01372                 TRACE( _T("LineTo "));
01373                 TRACE( _T("(%d,"),CacheCoords[i].x);
01374                 TRACE( _T("%d)\n"),CacheCoords[i].y);
01375                 i++;
01376                 break;
01377             case PT_BEZIERTO:
01378                 TRACE( _T("CurveTo "));
01379                 TRACE( _T("(%d,"),CacheCoords[i].x);
01380                 TRACE( _T("%d) "),CacheCoords[i].y);
01381                 TRACE( _T("(%d,"),CacheCoords[i+1].x);
01382                 TRACE( _T("%d) "),CacheCoords[i+1].y);
01383                 TRACE( _T("(%d,"),CacheCoords[i+2].x);
01384                 TRACE( _T("%d)\n"),CacheCoords[i+2].y);
01385                 i+=3;
01386                 break;
01387         }
01388     }   
01389 }
01390 
01391 #endif
01392 
01393 #if _DEBUG
01394 
01395 /********************************************************************************************
01396 
01397 >   void OILFontMan::DumpEnumLogFont(ENUMLOGFONT* lpelf)
01398 
01399     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01400     Created:    18/4/95
01401     Purpose:    Dump out the contents of a log font.
01402 
01403 ********************************************************************************************/
01404 
01405 void OILFontMan::DumpEnumLogFont(ENUMLOGFONT* lpelf)
01406 {
01407     TRACE( _T("DumpELogFont at %ld\n"),lpelf);
01408     if (lpelf!=NULL)
01409     {
01410         TRACE( _T(" ---------------- \n"));
01411         TRACE( _T("Enum Log font structure:\n"));
01412 #ifndef EXCLUDE_FROM_XARALX
01413         TRACE( _T(" Full name = %s\n"), lpelf->elfFullName);
01414         TRACE( _T(" Style     = %s\n"), lpelf->elfStyle);
01415 #endif
01416         DumpLogFont(&(lpelf->elfLogFont));
01417         TRACE( _T(" ---------------- \n"));
01418     }
01419 }
01420 
01421 void OILFontMan::DumpLogFont(LOGFONT* lplf)
01422 {
01423     if (lplf!=NULL)
01424     {
01425         TRACE( _T("Log font structure:\n"));
01426 #ifndef EXCLUDE_FROM_XARALX
01427         TRACE( _T(" Height          = %d\n"), lplf->lfHeight);
01428         TRACE( _T(" Width           = %d\n"), lplf->lfWidth);
01429         TRACE( _T(" Escapement      = %d\n"), lplf->lfEscapement);
01430         TRACE( _T(" Orientation     = %d\n"), lplf->lfOrientation);
01431         TRACE( _T(" Weight          = %d\n"), lplf->lfWeight);
01432         TRACE( _T(" Italic          = %d\n"), lplf->lfItalic);
01433         TRACE( _T(" Underline       = %d\n"), lplf->lfUnderline);
01434         TRACE( _T(" StrikeOut       = %d\n"), lplf->lfStrikeOut);
01435         TRACE( _T(" CharSet         = %d\n"), lplf->lfCharSet);
01436         TRACE( _T(" OutPrecision    = %d\n"), lplf->lfOutPrecision);
01437         TRACE( _T(" ClipPrecision   = %d\n"), lplf->lfClipPrecision);
01438         TRACE( _T(" Quality         = %d\n"), lplf->lfQuality);
01439         TRACE( _T(" PitchAndFamily  = %d\n"), lplf->lfPitchAndFamily);
01440         TRACE( _T(" FaceName        = %s\n"), lplf->lfFaceName);
01441 #endif
01442     }
01443 }
01444 
01445 #endif
01446 
01447 // ------------------------ End of OilFontMan functions -------------------------------------
01448 
01449 
01450 /********************************************************************************************
01451 
01452 >   FontBase::FontBase()
01453 
01454     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01455     Created:    12/09/95                
01456     Purpose:    Default constructor
01457 
01458 ********************************************************************************************/
01459 
01460 FontBase::FontBase()
01461 {
01462 }
01463 
01464 
01465 /********************************************************************************************
01466 
01467 >   BOOL FontBase::Initialise(String_64 *pFontName)
01468 
01469     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01470     Created:    12/09/95                
01471     Inputs:     pFontName = A pointer to a font name
01472     Purpose:    Initialises the OILFont font class
01473 
01474 ********************************************************************************************/
01475 
01476 BOOL FontBase::Initialise(String_64 *pFontName)
01477 {
01478     TheFontName = *pFontName;
01479     return TRUE;
01480 }
01481 
01482 
01483 /********************************************************************************************
01484 
01485 >   virtual void FontBase::Delete()
01486 
01487     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01488     Created:    12/09/95
01489     Inputs:     -
01490     Returns:    -               
01491     Purpose:    Deletes the contents of a OILFont font class
01492 
01493 ********************************************************************************************/
01494 
01495 void FontBase::Delete()
01496 {
01497     ERROR3("Error Error, FontBase::Delete() called - bad derivation / v-table corrupted");
01498 }
01499 
01500 
01501 /********************************************************************************************
01502 
01503 >   virtual BOOL FontBase::Compare(String_64* pFontName)
01504 
01505     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01506     Created:    12/09/95
01507     Inputs:     pFontName = A pointer to a font name
01508                 Class     = The font class
01509     Returns:    TRUE if the font name on entry matchs that of this cached font
01510     Purpose:    Compare one font item name with an other
01511 
01512 ********************************************************************************************/
01513 
01514 BOOL FontBase::Compare(String_64* pFontName)
01515 {
01516     return ((TheFontName.CompareTo(*pFontName)) == 0);
01517 }
01518 
01519 
01520 
01521 /********************************************************************************************
01522 
01523 >   virtual void FontBase::Dump()
01524 
01525     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01526     Created:    13/09/95
01527     Inputs:     -
01528     Returns:    -
01529     Purpose:    -
01530 
01531 ********************************************************************************************/
01532 
01533 void FontBase::Dump()
01534 {
01535     TRACE( _T(" Font name = %s\n"),((TCHAR*)TheFontName));
01536 }
01537 
01538 
01539 // ------------------------ End of FontBase functions -------------------------------------
01540 
01541 /********************************************************************************************
01542 
01543 >   void EnumFonts()
01544 
01545     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01546     Created:    12/9/95
01547     Purpose:    This function allows kernel routines to enumerate all the installed fonts
01548                 in the system. It is currently used to build menus
01549 
01550 ********************************************************************************************/
01551 
01552 OILEnumFonts::OILEnumFonts()
01553 {
01554 }
01555 
01556 void OILEnumFonts::Execute()
01557 {
01558 PORTNOTE("text","We do not use TTFontMan in wxOil")
01559 #ifndef EXCLUDE_FROM_XARALX
01560     TTFontMan::EnumAllFonts(this);
01561 #endif
01562 PORTNOTE("text","We do not use ATMFontMan in wxOil")
01563 #ifndef EXCLUDE_FROM_XARALX
01564     ATMFontMan::EnumAllFonts(this);
01565 #endif
01566 #ifdef __WXGTK__
01567     FTFontMan::EnumAllFonts(this);
01568 #endif
01569     // Add any further OIL Level font managers here
01570 }
01571 
01572 // Kernel routines using this class override this method
01573 BOOL OILEnumFonts::NewFont(FontClass Class, ENUMLOGFONT *lpelf)
01574 {
01575     return FALSE;
01576 }

Generated on Sat Nov 10 03:48:28 2007 for Camelot by  doxygen 1.4.4