@@ -1921,7 +1921,7 @@ HRESULT MainWindow::SaveSelectedFontFile()
19211921 IFR (GetSelectedDrawableObject (OUT selectedDrawableObjectIndex));
19221922 IFR (GetFileOrFamilyName (selectedDrawableObjectIndex, OUT filePath));
19231923
1924- if (!GetSaveFileName (hwnd_, filePath. c_str (), filters, u" ttf " , OUT filePath))
1924+ if (!GetSaveFileName (hwnd_, filters, u" otf " , filePath. c_str () , OUT filePath))
19251925 return S_OK;
19261926
19271927 DrawingCanvasControl& drawingCanvas = *DrawingCanvasControl::GetClass (GetWindowFromId (hwnd_, IdcDrawingCanvas));
@@ -1948,6 +1948,61 @@ HRESULT MainWindow::SaveSelectedFontFile()
19481948}
19491949
19501950
1951+ HRESULT MainWindow::SaveUnpackedWoffFontFile ()
1952+ {
1953+ std::u16string openFilePath, saveFilePath;
1954+ auto const * openFilters = u" Fonts (*.woff *.woff2)\0 " u" *.woff;*.woff2\0 "
1955+ u" All files (*)\0 " u" *\0 " ;
1956+ auto const * saveFilters = u" Fonts (*.otf *.ttf)\0 " u" *.otf;*.ttf\0 "
1957+ u" All files (*)\0 " u" *\0 " ;
1958+
1959+ ComPtr<IDWriteFactory5> dwriteFactory;
1960+
1961+ IFR (ShowMessageIfError (
1962+ u" Operating system does not not support IDWriteFactory5. TextLayoutSampler uses DWrite to unpack WOFF files. Error = 0x%08X" ,
1963+ DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory5), reinterpret_cast <IUnknown**>(OUT &dwriteFactory))
1964+ ));
1965+
1966+ if (!GetOpenFileName (hwnd_, openFilters, OUT openFilePath, u" Open WOFF font file" ))
1967+ return S_FALSE;
1968+
1969+ saveFilePath = openFilePath;
1970+ RemoveFileNameExtension (IN OUT saveFilePath);
1971+ if (!GetSaveFileName (hwnd_, saveFilters, u" otf" , saveFilePath.c_str (), OUT saveFilePath))
1972+ return S_FALSE;
1973+
1974+ std::vector<uint8_t > fileData;
1975+ IFR (ShowMessageIfError (
1976+ u" Could not read file" ,
1977+ ReadBinaryFile (openFilePath.c_str (), OUT fileData)
1978+ ));
1979+
1980+ DWRITE_CONTAINER_TYPE containerType = dwriteFactory->AnalyzeContainerType (fileData.data (), static_cast <uint32_t >(fileData.size ()));
1981+ if (containerType == DWRITE_CONTAINER_TYPE_UNKNOWN)
1982+ {
1983+ ShowMessageAndAppendLog (u" Unknown container type for file '%s'" , openFilePath.c_str ());
1984+ return DWRITE_E_FILEFORMAT;
1985+ }
1986+
1987+ ComPtr<IDWriteFontFileStream> fontFileStream;
1988+ IFR (dwriteFactory->UnpackFontFile (
1989+ containerType,
1990+ fileData.data (),
1991+ static_cast <uint32_t >(fileData.size ()),
1992+ OUT &fontFileStream
1993+ ));
1994+
1995+ IFR (ShowMessageIfError (
1996+ u" Could not write font to file. Error = 0x%08X writing to '%s'." ,
1997+ SaveDWriteFontFile (fontFileStream, saveFilePath.c_str ()),
1998+ saveFilePath.c_str ()
1999+ ));
2000+
2001+ AppendLog (u" Wrote font to file '%s'.\r\n " , saveFilePath.c_str ());
2002+ return S_OK;
2003+ }
2004+
2005+
19512006HRESULT MainWindow::GetAllFontCharacters (bool copyToClipboardInstead, bool getOnlyColorFontCharacters)
19522007{
19532008 uint32_t selectedDrawableObjectIndex;
@@ -1999,12 +2054,10 @@ HRESULT MainWindow::ExportFontGlyphData()
19992054 IFR (GetFileOrFamilyName (selectedDrawableObjectIndex, OUT filePath));
20002055
20012056 // Remove any extension, appending underscore to separate.
2002- filePath.erase (FindFileNameExtension (filePath) - filePath.data ());
2003- if (!filePath.empty () && filePath.back () == ' .' )
2004- filePath.pop_back ();
2057+ RemoveFileNameExtension (IN OUT filePath);
20052058 filePath += u" _" ;
20062059
2007- if (!GetSaveFileName (hwnd_, filePath.c_str (), filters, nullptr , OUT filePath))
2060+ if (!GetSaveFileName (hwnd_, filters, nullptr , filePath.c_str (), OUT filePath))
20082061 return S_OK;
20092062
20102063 DrawingCanvasControl& drawingCanvas = *DrawingCanvasControl::GetClass (GetWindowFromId (hwnd_, IdcDrawingCanvas));
@@ -2096,7 +2149,7 @@ HRESULT MainWindow::StoreDrawableObjectsSettings()
20962149{
20972150 std::u16string filePath;
20982151
2099- if (!GetSaveFileName (hwnd_, previousSettingsFilePath_. c_str (), g_openSaveFiltersList, u" TextLayoutSamplerSettings" , OUT filePath))
2152+ if (!GetSaveFileName (hwnd_, g_openSaveFiltersList, u" TextLayoutSamplerSettings" , previousSettingsFilePath_. c_str () , OUT filePath))
21002153 return S_OK;
21012154
21022155 HRESULT hr = HRESULT_FROM_WIN32 (ERROR_BAD_FORMAT);
@@ -2895,7 +2948,8 @@ void MainWindow::Resize(int id)
28952948void MainWindow::OnAssortedActions (HWND anchorControl)
28962949{
28972950 TrackPopupMenu_Item constexpr static items[] = {
2898- {IdcSaveSelectedFontFile, u" Save font file..." },
2951+ {IdcSaveSelectedFontFile, u" Save font file..." },
2952+ {IdcSaveUnpackedWoffFontFile, u" Save unpacked WOFF font file..." },
28992953 {IdcExportGlyphImageData, u" Export all glyph image data..." },
29002954 { 0 , u" -" },
29012955 {IdcGetAllFontCharacters, u" Get all font characters" },
@@ -2915,6 +2969,7 @@ void MainWindow::OnAssortedActions(HWND anchorControl)
29152969 switch (menuId)
29162970 {
29172971 case IdcSaveSelectedFontFile: SaveSelectedFontFile (); break ;
2972+ case IdcSaveUnpackedWoffFontFile: SaveUnpackedWoffFontFile (); break ;
29182973 case IdcGetAllFontCharacters: GetAllFontCharacters (/* copyToClipboardInstead*/ false , /* getOnlyColorFontCharacters*/ false ); break ;
29192974 case IdcGetAllColorFontCharacters: GetAllFontCharacters (/* copyToClipboardInstead*/ false , /* getOnlyColorFontCharacters*/ true ); break ;
29202975 case IdcCopyAllFontCharacters: GetAllFontCharacters (/* copyToClipboardInstead*/ true , /* getOnlyColorFontCharacters*/ false ); break ;
@@ -2925,73 +2980,82 @@ void MainWindow::OnAssortedActions(HWND anchorControl)
29252980}
29262981
29272982
2928- void MainWindow::AppendLogCached (const char16_t * logMessage, ...)
2983+ void MainWindow::AppendLogCached (char16_t const * logMessage, ...)
29292984{
29302985 va_list argList;
29312986 va_start (argList, logMessage);
2932-
29332987 char16_t buffer[1000 ];
29342988 buffer[0 ] = 0 ;
2935- StringCchVPrintf (OUT ToWChar (buffer), countof (buffer), ToWChar (logMessage), argList);
29362989
2990+ StringCchVPrintf (OUT ToWChar (buffer), countof (buffer), ToWChar (logMessage), argList);
29372991 cachedLog_ += buffer;
29382992}
29392993
29402994
2941- void MainWindow::AppendLogDirect ( const char16_t * logMessage)
2995+ void MainWindow::AppendLogUnformatted ( char16_t const * logMessage)
29422996{
29432997 HWND hwndLog = GetWindowFromId (hwnd_, IdcLog);
29442998
2945- uint32_t textLength = Edit_GetTextLength (hwndLog);
29462999 if (!cachedLog_.empty ())
29473000 {
2948- Edit_SetSel (hwndLog, textLength, textLength);
2949- Edit_ReplaceSel (hwndLog, cachedLog_.c_str ());
2950- cachedLog_.clear ();
2951- textLength = Edit_GetTextLength (hwndLog);
3001+ cachedLog_ += logMessage;
3002+ logMessage = cachedLog_.data ();
29523003 }
2953- Edit_SetSel (hwndLog, textLength, textLength);
3004+ uint32_t previousTextLength = Edit_GetTextLength (hwndLog);
3005+ Edit_SetSel (hwndLog, previousTextLength, previousTextLength);
29543006 Edit_ReplaceSel (hwndLog, logMessage);
3007+ cachedLog_.clear ();
29553008}
29563009
29573010
2958- void MainWindow::AppendLog (const char16_t * logMessage, ...)
3011+ void MainWindow::AppendLog (char16_t const * logMessage, ...)
29593012{
29603013 va_list argList;
29613014 va_start (argList, logMessage);
2962-
29633015 char16_t buffer[1000 ];
29643016 buffer[0 ] = 0 ;
2965- StringCchVPrintf (OUT ToWChar (buffer), countof (buffer), ToWChar (logMessage), argList);
29663017
2967- AppendLogDirect (buffer);
3018+ StringCchVPrintf (OUT ToWChar (buffer), countof (buffer), ToWChar (logMessage), argList);
3019+ AppendLogUnformatted (buffer);
29683020}
29693021
29703022
2971- HRESULT MainWindow::ShowMessageIfError ( const char16_t * logMessage, HRESULT hr )
3023+ void MainWindow::ShowMessageAndAppendLogUnformatted ( char16_t const * logMessage)
29723024{
2973- if (FAILED (hr))
2974- {
2975- MainWindow::ShowMessageAndAppendLog (logMessage, hr);
2976- }
2977- return hr;
3025+ MessageBoxShaded::Show (hwnd_, logMessage, u" " , MB_OK | MB_ICONWARNING);
3026+
3027+ AppendLogUnformatted (logMessage);
3028+ size_t messageLength = wcslen (ToWChar (logMessage));
3029+ if (messageLength > 0 && logMessage[messageLength - 1 ] != ' \n ' )
3030+ AppendLogUnformatted (u" \r\n " );
29783031}
29793032
29803033
2981- void MainWindow::ShowMessageAndAppendLog (const char16_t * logMessage, ...)
3034+ void MainWindow::ShowMessageAndAppendLog (char16_t const * logMessage, ...)
29823035{
29833036 va_list argList;
29843037 va_start (argList, logMessage);
2985-
29863038 char16_t buffer[1000 ];
29873039 buffer[0 ] = 0 ;
3040+
29883041 StringCchVPrintf (OUT ToWChar (buffer), countof (buffer), ToWChar (logMessage), argList);
3042+ ShowMessageAndAppendLogUnformatted (buffer);
3043+ }
3044+
29893045
2990- MessageBoxShaded::Show (hwnd_, buffer, u" " , MB_OK|MB_ICONWARNING);
3046+ HRESULT MainWindow::ShowMessageIfError (char16_t const * logMessage, HRESULT hr, ...)
3047+ {
3048+ if (FAILED (hr))
3049+ {
3050+ va_list argList;
3051+ va_start (argList, logMessage);
3052+ char16_t buffer[1000 ];
3053+ buffer[0 ] = 0 ;
29913054
2992- AppendLogDirect (buffer);
2993- if (buffer[wcslen (ToWChar (buffer))] != ' \n ' )
2994- AppendLogDirect (u" \r\n " );
3055+ StringCchVPrintf (OUT ToWChar (buffer), countof (buffer), ToWChar (logMessage), argList);
3056+ MainWindow::ShowMessageAndAppendLogUnformatted (buffer);
3057+ }
3058+ return hr;
29953059}
29963060
29973061
0 commit comments