[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]
[XaraXtreme-commits] Commit Complete
Commit by : alex
Repository : xara
Revision : 1642
Date : Wed Aug 2 11:15:45 BST 2006
Changed paths:
M /Trunk/XaraLX/Kernel/camfiltr.cpp
M /Trunk/XaraLX/Kernel/fontman.cpp
M /Trunk/XaraLX/Kernel/fontman.h
M /Trunk/XaraLX/wxOil/fontbase.cpp
M /Trunk/XaraLX/wxOil/fontbase.h
Commit MartinW's patch to fix current attributes for fonts that aren't installed
Diff:
Index: Trunk/XaraLX/Kernel/fontman.cpp
===================================================================
--- Trunk/XaraLX/Kernel/fontman.cpp (revision 1641)
+++ Trunk/XaraLX/Kernel/fontman.cpp (revision 1642)
@@ -102,6 +102,9 @@
#include "camtypes.h"
// #include "fontbase.h" - included in fontman.h
+#include "nodetxts.h"
+#include "nodetxtl.h"
+#include "nodetext.h"
#include "fontman.h"
//#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
//#include "txtattr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
@@ -333,7 +336,7 @@
{
PORTNOTE("text","CachedFontItem::IsFullyCached - do nothing");
#ifndef DISABLE_TEXT_RENDERING
- TRACEUSER("wuerthne", _T("CachedFontItem::IsFullyCached called") );
+ // TRACEUSER("wuerthne", _T("CachedFontItem::IsFullyCached called") );
ERROR2IF(pFontClass==NULL, FALSE, "A CachedFontItem structure exists without a FontClass!!!");
return (pEnumLogFont!=NULL);
#else
@@ -592,7 +595,7 @@
CachedFontItem* FontManager::AddFont(String_64* Name, FontClass fclass, WORD& retHandle)
{
-
+ TRACEUSER("wuerthne", _T("FontManager::AddFont %s"), (TCHAR*)*Name);
CachedFontItem* pItem = new CachedFontItem;
if (pItem==NULL)
return NULL;
@@ -610,6 +613,7 @@
TheFontList.AddTail(pItem);
retHandle = pItem->Handle;
+ TRACEUSER("wuerthne", _T("AddFont, returning %d"), retHandle);
return pItem;
}
@@ -656,6 +660,10 @@
NULL if unable to find the font
Purpose: Find the entry in the font managers font list which corresponds to this
fontname and font class
+ Note: One might be tempted to include the default font item in the comparison
+ and return the default font handle when the default font name is passed,
+ but this does not happen and this is by design. See OnDocumentLoaded for
+ further information.
********************************************************************************************/
@@ -963,6 +971,136 @@
/********************************************************************************************
+> BOOL FontManager::IsFontUsedInSiblings(Node* pNode, WORD Handle, WORD CurrentHandle, UINT32 Level)
+
+ Author: Martin Wuerthner <xara@xxxxxxxxxxxxxxx>
+ Created: 01/08/06
+ Inputs: pNode - the root node of the subtree to check
+ Handle - a font handle
+ CurrentHandle - the font handle applying to the current subtree
+ Level - level in the tree (level 0 is NodeDocument, level 1 are default attributes)
+ Returns: Returns TRUE if a font attribute with the given handle applies to a text
+ object.
+ Purpose: Find out whether a given font is used in a document.
+
+********************************************************************************************/
+
+BOOL FontManager::IsFontUsedInSiblings(Node* pNode, WORD Handle, WORD CurrentHandle, UINT32 Level)
+{
+ // perform a standard child-first recursion keeping track of the current font
+ while(pNode)
+ {
+ Node* pFirstChild = pNode->FindFirstChild();
+ if (pFirstChild && IsFontUsedInSiblings(pFirstChild, Handle, CurrentHandle, Level + 1)) return TRUE;
+ if (IS_A(pNode, AttrTxtFontTypeface))
+ {
+ AttrTxtFontTypeface* pAttr = (AttrTxtFontTypeface*)pNode;
+ CurrentHandle = pAttr->Value.HTypeface;
+ ENSURE(!(CurrentHandle == DEFAULTHANDLE && Level > 1), "FontManager::IsFontUsedInSiblings is based on the assumption that we do not have non-default attribute nodes referencing the default font");
+ }
+ if (CurrentHandle == Handle && (IS_A(pNode, TextStory) || IS_A(pNode, TextLine) || IS_A(pNode, TextChar)))
+ return TRUE;
+ pNode = pNode->FindNext();
+ }
+ return FALSE;
+}
+
+/********************************************************************************************
+
+> BOOL FontManager::IsFontUsedInDoc(WORD Handle, Document* pDocument)
+
+ Author: Martin Wuerthner <xara@xxxxxxxxxxxxxxx>
+ Created: 01/08/06
+ Inputs: Handle - a font handle
+ pDocument - pointer to a document
+ Returns: When called with Handle == DEFAULTHANDLE it returns TRUE if the default
+ attribute applies to a text object. Otherwise, it returns TRUE if the supplied
+ font handle is used in the document
+ Purpose: Find out whether a given font is used in a document.
+
+********************************************************************************************/
+
+BOOL FontManager::IsFontUsedInDoc(WORD Handle, Document* pDocument)
+{
+ Node* pNode = pDocument->GetFirstNode();
+ return IsFontUsedInSiblings(pNode, Handle, ILLEGALFHANDLE, 0);
+}
+
+/********************************************************************************************
+
+> void FontManager::OnDocumentLoaded(Document* pDocument)
+
+ Author: Martin Wuerthner <xara@xxxxxxxxxxxxxxx>
+ Created: 01/08/06
+ Inputs: pDocument - pointer to the newly created/loaded document
+ Purpose: Called after a document has been loaded - allows us to fix the current and
+ default fonts if they are not installed. They are only changed if they are
+ not used in the document.
+
+ Fixing the current font is useful because it stops "Arial (missing)" from
+ being displayed after start-up if Arial is not installed. The same happens
+ when loading a document with the current font set to Arial (or any other
+ font that is not installed). We do not touch the current font if it is
+ actually used in the document because then, it is possible that it was set
+ deliberately (maybe even in a template).
+
+ One might consider a similar approach for the default font, but by definition,
+ the default font is always installed (though it may or may not be Times New
+ Roman), so there is no need to change anything. The default attributes are not
+ saved with the document, so, in contrast to the current font, there cannot be
+ any surprises with fonts that are not installed. The font name referenced by
+ the default font does not matter because the default font attribute is never
+ inherited by any text object in the document.
+
+ This is down to the behaviour of FindFont(String_64*,FontClass), which never
+ returns the default font handle, so any font attribute created by the text tool
+ based on a font name (which involves calling FindFont at some stage) is always
+ different from the default attribute (even if it happens to be the same font as
+ the default font) and hence this attribute is not optimised away. Therefore, each
+ and every text object has a non-default font attribute applied to it.
+
+********************************************************************************************/
+
+void FontManager::OnDocumentLoaded(Document* pDocument)
+{
+ // check if the current font is installed and change it in case it is not (only if the font is not used)
+ NodeAttribute* pAttr = pDocument->GetAttributeMgr().GetCurrentAttribute(CC_RUNTIME_CLASS(BaseTextClass),
+ CC_RUNTIME_CLASS(AttrTxtFontTypeface));
+ if (pAttr)
+ {
+ AttrTxtFontTypeface* pTypeface = (AttrTxtFontTypeface*)pAttr;
+ WORD Handle = pTypeface->Value.HTypeface;
+ TRACEUSER("wuerthne", _T("found current font attribute, handle = %d"), Handle);
+ CachedFontItem *pItem = FindFont(Handle);
+ if (pItem)
+ {
+ String_64* SurfaceFontName = pItem->GetFontName();
+ TRACEUSER("wuerthne", _T("current font name is %s"), (TCHAR*)*SurfaceFontName);
+ ENUMLOGFONT *pEnumLogFont = pItem->GetEnumLogFont();
+ if (pEnumLogFont)
+ {
+ if (!IsFontInstalled(SurfaceFontName) && !IsFontUsedInDoc(Handle, pDocument))
+ {
+ // the current font is not installed and not used in the document,
+ // so find out what the replacement font is and use that instead
+ TRACEUSER("wuerthne", _T("font replaced and not used"));
+ String_64* NativeFontName = OILFontMan::GetNativeFontName(pItem->GetFontClass(),
+ &pEnumLogFont->elfLogFont);
+ WORD NewHandle = CacheNamedFont(NativeFontName, pItem->GetFontClass());
+ if (NewHandle != ILLEGALFHANDLE)
+ {
+ TRACEUSER("wuerthne", _T("change current font to handle %d"), NewHandle);
+ // modify the current attribute directly
+ pTypeface->Value.HTypeface = NewHandle;
+ }
+ }
+ }
+ }
+ }
+}
+
+/********************************************************************************************
+
> CachedFontItem* FontManager::GetFirstFontType(FontClass Class)
Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xxxxxxxx>
@@ -1552,7 +1690,8 @@
// we've done a search for it and it does not exist so we'll use the default
WORD hndle=ILLEGALFHANDLE;
AddTempFont(pFontName, Class, hndle);
-
+
+ TRACEUSER("wuerthne", _T("FontManager::CacheNamedFont = %d"), hndle);
return (hndle);
}
Index: Trunk/XaraLX/Kernel/fontman.h
===================================================================
--- Trunk/XaraLX/Kernel/fontman.h (revision 1641)
+++ Trunk/XaraLX/Kernel/fontman.h (revision 1642)
@@ -223,6 +223,9 @@
BOOL IsFontReplaced(WORD Handle);
BOOL IsFontReplaced(String_64* pFontName, FontClass Class=FC_UNDEFINED);
+ BOOL IsFontUsedInDoc(WORD Handle, Document* pDocument);
+ void OnDocumentLoaded(Document* pDocument);
+
void GetCompatibleFont(const String_64& EncodedName, String_64& CompatibleFont, INT32& Style);
void EncodeFontName(String_64& FontName, String_64& Encoded, INT32 Styles);
void EncodeAndMapFontName(String_64& FontName, String_64& Encoded, INT32 Styles);
@@ -286,6 +289,7 @@
CachedFontItem* AddTempFont(String_64* pFontName, FontClass Class, WORD& hndle);
void InvalidateCache();
void ResetDefaultFont();
+ BOOL IsFontUsedInSiblings(Node* pNode, WORD Handle, WORD CurrentHandle, UINT32 Level);
private:
WORD UniqueHandle;
Index: Trunk/XaraLX/Kernel/camfiltr.cpp
===================================================================
--- Trunk/XaraLX/Kernel/camfiltr.cpp (revision 1641)
+++ Trunk/XaraLX/Kernel/camfiltr.cpp (revision 1642)
@@ -3488,8 +3488,14 @@
// Flag this as a new format document
// But only flag it if we are opening the document rather than importing into an exisiting one
if (TheDocument && !TheDocument->IsImporting())
+ {
TheDocument->SetLoadedAsVersion1File(FALSE);
+ // allow the font manager to fix the current font
+ if (!TheDocument->IsAClipboard())
+ GetApplication()->GetFontManager()->OnDocumentLoaded(TheDocument);
+ }
+
#if !defined(EXCLUDE_FROM_RALPH)
BOOL UpdateBars = TheDocument ? !TheDocument->IsAClipboard() : TRUE;
#endif
Index: Trunk/XaraLX/wxOil/fontbase.cpp
===================================================================
--- Trunk/XaraLX/wxOil/fontbase.cpp (revision 1641)
+++ Trunk/XaraLX/wxOil/fontbase.cpp (revision 1642)
@@ -518,6 +518,24 @@
}
/********************************************************************************************
+> String_64* OILFontMan::GetNativeFontName(FontClass Class, LOGFONT *pLogFont)
+
+ Author: Martin Wuerthner <xara@xxxxxxxxxxxxxxx>
+ Created: 01/08/06
+ Inputs: Class - the font class of the font (not used in wxOil but supplied in analogy
+ to GetOutlineTextMetrics)
+ pLogFont - a pointer to it's LOGFONT structure
+ Returns: A pointer to the underlying native font name
+ Purpose: Return the underlying native font name for a font
+
+********************************************************************************************/
+String_64* OILFontMan::GetNativeFontName(FontClass Class, LOGFONT *pLogFont)
+{
+ IGNOREPARAM(Class);
+ return &pLogFont->FaceName;
+}
+
+/********************************************************************************************
> OILFontMan::InvalidateCharMetrics()
Author: Martin Wuerthner <xara@xxxxxxxxxxxxxxx>
Index: Trunk/XaraLX/wxOil/fontbase.h
===================================================================
--- Trunk/XaraLX/wxOil/fontbase.h (revision 1641)
+++ Trunk/XaraLX/wxOil/fontbase.h (revision 1642)
@@ -180,6 +180,7 @@
static void FindClosestFont();
static FontBase* CreateNewFont(FontClass Class, String_64* pFontName);
static OUTLINETEXTMETRIC *GetOutlineTextMetric(FontClass Class, LOGFONT *pLogFont);
+ static String_64* GetNativeFontName(FontClass Class, LOGFONT *pLogFont);
static void InvalidateCharMetrics();
static BOOL GetCharMetrics(wxDC* pDC, WCHAR ch, CharDescription& FontDesc, CharMetrics* pCharMetrics);
static MILLIPOINT GetCharsKerning(wxDC* pDC, WCHAR chLeft, WCHAR chRight,
Xara