summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/win/gdi/salfont.cxx167
1 files changed, 64 insertions, 103 deletions
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 0dfd4fdc62a1..56685cda8eb9 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -40,6 +40,7 @@
#include <o3tl/char16_t2wchar_t.hxx>
#include <tools/helpers.hxx>
#include <tools/stream.hxx>
+#include <tools/urlobj.hxx>
#include <unotools/fontcfg.hxx>
#include <vcl/settings.hxx>
#include <vcl/sysdata.hxx>
@@ -1105,111 +1106,71 @@ void ImplReleaseTempFonts(SalData& rSalData, bool bAll)
}
}
-static bool ImplGetFontAttrFromFile( const OUString& rFontFileURL,
- FontAttributes& rDFA )
+static OUString lcl_GetFontFamilyName(const OUString& rFontFileURL)
{
- OUString aUSytemPath;
- OSL_VERIFY( !osl::FileBase::getSystemPathFromFileURL( rFontFileURL, aUSytemPath ) );
-
- // get FontAttributes from a *fot file
- // TODO: use GetTTGlobalFontInfo() to access the font directly
- rDFA.SetQuality( 1000 );
- rDFA.SetFamilyType(FAMILY_DONTKNOW);
- rDFA.SetWidthType(WIDTH_DONTKNOW);
- rDFA.SetWeight(WEIGHT_DONTKNOW);
- rDFA.SetItalic(ITALIC_DONTKNOW);
- rDFA.SetPitch(PITCH_DONTKNOW);
-
// Create temporary file name
- wchar_t aResourceName[512];
- int nMaxLen = SAL_N_ELEMENTS(aResourceName) - 16;
- int nLen = GetTempPathW( nMaxLen, aResourceName );
- wcsncpy( aResourceName + nLen, L"soAAT.fot", std::max( 0, nMaxLen - nLen ));
- DeleteFileW( aResourceName );
-
- // Create font resource file (typically with a .fot file name extension).
- CreateScalableFontResourceW( 0, aResourceName, o3tl::toW(aUSytemPath.getStr()), nullptr );
+ OUString aTempFileURL;
+ if (osl::File::E_None != osl::File::createTempFile(nullptr, nullptr, &aTempFileURL))
+ return OUString();
+ osl::File::remove(aTempFileURL);
+ OUString aResSystemPath;
+ osl::FileBase::getSystemPathFromFileURL(aTempFileURL, aResSystemPath);
+
+ // Create font resource file (.fot)
+ // There is a limit of 127 characters for the full path passed via lpszFile, so we have to
+ // split the font URL and pass it as two parameters. As a result we can't use
+ // CreateScalableFontResource for renaming, as it now expects the font in the system path.
+ // But it's still good to use it for family name extraction, we're currently after.
+ // BTW: it doesn't help to prefix the lpszFile with \\?\ to support larger paths.
+ // TODO: use TTLoadEmbeddedFont (needs an EOT as input, so we have to add a header to the TTF)
+ // TODO: forward the EOT from the AddTempDevFont call side, if VCL supports it
+ INetURLObject aTTFUrl(rFontFileURL);
+ // GetBase() stripts the extension
+ OUString aFilename = aTTFUrl.GetLastName(INetURLObject::DecodeMechanism::WithCharset);
+ if (!CreateScalableFontResourceW(0, o3tl::toW(aResSystemPath.getStr()),
+ o3tl::toW(aFilename.getStr()), o3tl::toW(aTTFUrl.GetPath().getStr())))
+ {
+ sal_uInt32 nError = GetLastError();
+ SAL_WARN("vcl.fonts", "CreateScalableFontResource failed for " << aResSystemPath << " "
+ << aFilename << " " << aTTFUrl.GetPath() << " " << nError);
+ return OUString();
+ }
// Open and read the font resource file
- OUString aFotFileName = o3tl::toU( aResourceName );
- osl::FileBase::getFileURLFromSystemPath( aFotFileName, aFotFileName );
- osl::File aFotFile( aFotFileName );
- osl::FileBase::RC aError = aFotFile.open( osl_File_OpenFlag_Read );
- if( aError != osl::FileBase::E_None )
- return false;
+ osl::File aFotFile(aTempFileURL);
+ if (osl::FileBase::E_None != aFotFile.open(osl_File_OpenFlag_Read))
+ return OUString();
sal_uInt64 nBytesRead = 0;
char aBuffer[4096];
aFotFile.read( aBuffer, sizeof( aBuffer ), nBytesRead );
// clean up temporary resource file
aFotFile.close();
- DeleteFileW( aResourceName );
+ osl::File::remove(aTempFileURL);
// retrieve font family name from byte offset 0x4F6
- sal_uInt64 i = 0x4F6;
- sal_uInt64 nNameOfs = i;
- while( (i < nBytesRead) && (aBuffer[i++] != 0) );
- // skip full name
- while( (i < nBytesRead) && (aBuffer[i++] != 0) );
- // retrieve font style name
- int nStyleOfs = i;
- while( (i < nBytesRead) && (aBuffer[i++] != 0) );
- if( i >= nBytesRead )
- return false;
+ static const sal_uInt64 nNameOfs = 0x4F6;
+ sal_uInt64 nPos = nNameOfs;
+ for (; (nPos < nBytesRead) && (aBuffer[nPos] != 0); nPos++);
+ if (nPos >= nBytesRead || (nPos == nNameOfs))
+ return OUString();
- // convert byte strings to unicode
- char *pName = aBuffer + nNameOfs;
- rDFA.SetFamilyName(OUString(pName, strlen(pName), osl_getThreadTextEncoding()));
- char *pStyle = aBuffer + nStyleOfs;
- rDFA.SetStyleName(OUString(pStyle, strlen(pStyle), osl_getThreadTextEncoding() ));
-
- // byte offset 0x4C7: OS2_fsSelection
- const char nFSS = aBuffer[ 0x4C7 ];
- if( nFSS & 0x01 ) // italic
- rDFA.SetItalic(ITALIC_NORMAL);
- //if( nFSS & 0x20 ) // bold
- // rDFA.meWeight = WEIGHT_BOLD;
- if( nFSS & 0x40 ) // regular
- {
- rDFA.SetWeight(WEIGHT_NORMAL);
- rDFA.SetItalic(ITALIC_NONE);
- }
-
- // byte offsets 0x4D7/0x4D8: wingdi's FW_WEIGHT
- int nWinWeight = (aBuffer[0x4D7] & 0xFF) + ((aBuffer[0x4D8] & 0xFF) << 8);
- rDFA.SetWeight(ImplWeightToSal( nWinWeight ));
-
- rDFA.SetSymbolFlag(false); // TODO
- rDFA.SetPitch(PITCH_DONTKNOW); // TODO
-
- // byte offset 0x4DE: pitch&family
- rDFA.SetFamilyType(ImplFamilyToSal( aBuffer[0x4DE] ));
-
- // byte offsets 0x4C8/0x4C9: emunits
- // byte offsets 0x4CE/0x4CF: winascent
- // byte offsets 0x4D0/0x4D1: winascent+windescent-emunits
- // byte offsets 0x4DF/0x4E0: avgwidth
-
- return true;
+ return OUString(aBuffer + nNameOfs, nPos - nNameOfs, osl_getThreadTextEncoding());
}
bool WinSalGraphics::AddTempDevFont(PhysicalFontCollection* pFontCollection,
const OUString& rFontFileURL, const OUString& rFontName)
{
-
- FontAttributes aDFA;
- aDFA.SetFamilyName(rFontName);
- aDFA.SetQuality( 1000 );
-
- // Retrieve font name from font resource
- if( aDFA.GetFamilyName().isEmpty() )
+ OUString aFontFamily = lcl_GetFontFamilyName(rFontFileURL);
+ if (aFontFamily.isEmpty())
{
- ImplGetFontAttrFromFile( rFontFileURL, aDFA );
+ SAL_WARN("vcl.fonts", "error extracting font family from " << rFontFileURL);
+ return false;
}
- if ( aDFA.GetFamilyName().isEmpty() )
+ if (rFontName != aFontFamily)
{
- SAL_WARN("vcl.fonts", "error extracting font family from " << rFontFileURL);
+ SAL_WARN("vcl.fonts", "font family renaming not implemented; skipping embedded " << rFontName);
return false;
}
@@ -1217,26 +1178,26 @@ bool WinSalGraphics::AddTempDevFont(PhysicalFontCollection* pFontCollection,
if (nFonts <= 0)
return false;
- // create matching FontData struct
- aDFA.SetSymbolFlag(false); // TODO: how to know it without accessing the font?
- aDFA.SetFamilyType(FAMILY_DONTKNOW);
- aDFA.SetWidthType(WIDTH_DONTKNOW);
- aDFA.SetWeight(WEIGHT_DONTKNOW);
- aDFA.SetItalic(ITALIC_DONTKNOW);
- aDFA.SetPitch(PITCH_DONTKNOW);
-
- /*
- // TODO: improve FontAttributes using the "font resource file"
- aDFS.maName = // using "FONTRES:" from file
- if( rFontName != aDFS.maName )
- aDFS.maMapName = aFontName;
- */
-
- rtl::Reference<WinFontFace> pFontData = new WinFontFace(aDFA,
- sal::static_int_cast<BYTE>(DEFAULT_CHARSET),
- sal::static_int_cast<BYTE>(TMPF_VECTOR|TMPF_TRUETYPE) );
- pFontData->SetFontId( reinterpret_cast<sal_IntPtr>(pFontData.get()) );
- pFontCollection->Add( pFontData.get() );
+ ImplEnumInfo aInfo;
+ aInfo.mhDC = getHDC();
+ aInfo.mpList = pFontCollection;
+ aInfo.mpName = &aFontFamily;
+ aInfo.mbPrinter = mbPrinter;
+ aInfo.mnFontCount = pFontCollection->Count();
+ const int nExpectedFontCount = aInfo.mnFontCount + nFonts;
+
+ LOGFONTW aLogFont;
+ memset(&aLogFont, 0, sizeof(aLogFont));
+ aLogFont.lfCharSet = DEFAULT_CHARSET;
+ aInfo.mpLogFont = &aLogFont;
+
+ // add the font to the PhysicalFontCollection
+ EnumFontFamiliesExW(getHDC(), &aLogFont,
+ SalEnumFontsProcExW, reinterpret_cast<LPARAM>(&aInfo), 0);
+
+ SAL_WARN_IF(nExpectedFontCount != pFontCollection->Count(), "vcl.fonts",
+ "temp font was registered but is not in enumeration: " << rFontFileURL);
+
return true;
}