FontPlayer XBAP

I thought it would be fun to update the UI (and some functionality) for the FontPlayer SDK sample. This app lets you to play with the fonts installed on your the machine. It also shows off the OpenType features of specific fonts.

Some of the interesting features that I added to this app:

  • Embedded fonts in XBAP
  • ComboBox bound to system fonts, displayed using font
  • New CheckBox template
  • Text “reflection” effect

FontPlayer works with RC 1. Run it here. Code found here.

Screen Shots – Details


custom font


font ComboBox


new CheckBox template

Embedded fonts in XBAP
Custom fonts are a great way to brand the look & feel for your app. WPF’s embedded font support means I can use a custom font in a web app without affecting/installing system fonts.

In this app, I’m using Robby’s custom font, Ingebretsen Neato. To accomplish this, I included “Ingebretsen Neato.ttf” in the project and then referenced it in this style:


  <Style x:Key="Heading" TargetType="{x:Type TextBlock}"  >
    <!– Custom font from http://notstatic.com -->
    <Setter Property=”FontFamily”
        Value=”./Resources/#Ingebretsen Neato” />
    <Setter Property=”FontSize” Value=”20″ />
    <Setter Property=”Foreground” Value=”#FFFFFFFF”/>
    <Setter Property=”HorizontalAlignment” Value=”Center”/>
  </Style>

The text team’s blog has a lot more info about fonts & typography if you’re interested.

ComboBox bound to system fonts

The XAML to create a ComboBox bound to the system’s font:


  <ComboBox Name="FontFamilyComboBox"
    ItemsSource=
       ”{Binding Source={x:Static media:Fonts.SystemFontFamilies}}”
    ItemTemplate=”{StaticResource FontFamilyTemplate}”
    SelectionChanged=”FontFamilySelectionChanged”
    Width=”150″ HorizontalAlignment=”Center”
  />

In order display the font names in the actual font, I used a data template w/ a type converter.


  <local:FontFamilyToStringConverter x:Key="FontFamilyToString" />
  ...
  <DataTemplate x:Key=”FontFamilyTemplate” >
    <TextBlock
      Text=
        ”{Binding Converter={StaticResource FontFamilyToString}}”
      FontFamily=”{Binding}”
    />
  </DataTemplate>

The type converter was defined in the code-behind file:


  public class FontFamilyToStringConverter : IValueConverter
  {
    public object Convert(object value, Type targetType,
                          object parameter, CultureInfo culture)
    {
       FontFamily fontFamily = value as FontFamily;
       return fontFamily.ToString();
    }
    ...  
  }

New CheckBox template

I thought that a new look & feel for the CheckBox would more sense for toggling the options. I based the control template on Robby’s SimpleStyles. I then animated the opacity of the OptionsGrid based on the CheckBox.Checked event.

To see it, look at ResourcesCheckBox.xaml.

7 comments

  1. I just thought I’d give some feedback that the User Experience for getting an account on scorbs.com is pretty week, and somewhat frustrating… just some points.

    1. When I registered for the account, it said that my password will be e-mailed to me. I went to my e-mail, and it wasn’t there. I kept checking, and it didn’t show up. I probably waited for 2 or 3 minutes, and it wouldn’t show up, finally I just closed the browser and went on to do other things.

    My expectation is that the e-mail would appear almost instantly because that’s how other sites behave. If there’s going to be even the slightest delay, other sites indicate that — something like, “please give 5 minutes” or “please wait 24 hours”… Setting expectation is important.

    2. When I got around to follow up, which was about three days later, the e-mail told me what my user name and password was, and a link to the site. I clicked on the link, and it presented to me the login screen, where I had to type in my username. I can’t recall the last time a site required me to type in my username during this process. Some just give you a link that you click on and then web site says, “you’re not registered”.. others ask you to retype your password. But for this site, I had to type in my user name. minor frustration.

    3. After I entered my user name and password, it complained that my user id is invalid. my user id is my last name, and I’m certain i typed it right. I checked the e-mail again, and typed it againt, but sure enough, it says that my user id is invalid.

    again.. not a very good user experience.

    All in all, this isn’t a major deal, and I doubt it’s going to make a difference in my overall online experience. But I feel that many people probably have the same experience that I have, and don’t bother providing feedback. So I thought I’d spend a few minutes of my time and help.

  2. I tried to run the XBAP app, but I got the following error:

    Startup URI: http://scorbs.com/workapps/fontplayer/FontPlayer.xbap
    Application Identity: http://scorbs.com/workapps/fontplayer/FontPlayer.xbap#FontPlayer.application, Version=1.2.0.0, Culture=neutral, PublicKeyToken=082204a7ace1afb0, processorArchitecture=msil/FontPlayer.exe, Version=1.2.0.0, Culture=neutral, PublicKeyToken=082204a7ace1afb0, processorArchitecture=msil, type=win32

    System.InvalidOperationException: Version mismatch. BAML stream has version number ‘0.94’ but parser can read only version ‘0.96’.
    at System.Windows.Markup.BamlVersionHeader.LoadVersion(BinaryReader bamlBinaryReader)
    at System.Windows.Markup.TreeBuilderBamlTranslator.ParseFragment()
    at System.Windows.Markup.TreeBuilder.Parse()
    at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
    at System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc)
    at MS.Internal.AppModel.AppModelKnownContentFactory.BamlConverter(Stream stream, Uri baseUri, Boolean canUseTopLevelBrowser, Boolean sandboxExternalContent, Boolean allowAsync, Boolean isJournalNavigation, XamlReader& asyncObjectConverter)
    at MS.Internal.AppModel.MimeObjectFactory.GetObjectAndCloseStream(Stream s, ContentType contentType, Uri baseUri, Boolean canUseTopLevelBrowser, Boolean sandboxExternalContent, Boolean allowAsync, Boolean isJournalNavigation, XamlReader& asyncObjectConverter)
    at System.Windows.Navigation.NavigationService.GetObjectFromResponse(WebRequest request, WebResponse response, Uri destinationUri, Object navState)
    at System.Windows.Navigation.NavigationService.DoNavigate(Uri source, NavigationMode f, Object navState)
    at System.Windows.Navigation.NavigateQueueItem.Dispatch(Object obj)
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
    at System.Windows.Threading.DispatcherOperation.InvokeImpl()
    at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
    at System.Threading.ExecutionContext.runTryCode(Object userData)
    at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Windows.Threading.DispatcherOperation.Invoke()
    at System.Windows.Threading.Dispatcher.ProcessQueue()
    at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
    at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
    at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
    at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
    at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
    at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
    at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
    at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
    at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
    at System.Windows.Threading.Dispatcher.Run()
    at System.Windows.Application.RunDispatcher(Object ignore)
    at System.Windows.Application.StartDispatcherInBrowser(Object unused)
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
    at System.Windows.Threading.DispatcherOperation.InvokeImpl()
    at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
    at System.Threading.ExecutionContext.runTryCode(Object userData)
    at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Windows.Threading.DispatcherOperation.Invoke()
    at System.Windows.Threading.Dispatcher.ProcessQueue()
    at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
    at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
    at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
    at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
    at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
    at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)

    ———————–

    PresentationHost.exe v3.0.6715.0 (winmain_oob/wap_rc1(avdrt).060815-1648) – C:WINDOWSsystem32PresentationHost.exe
    ntdll.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32ntdll.dll
    kernel32.dll v5.1.2600.2945 (xpsp_sp2_gdr.060704-2349) – C:WINDOWSsystem32kernel32.dll
    ADVAPI32.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32ADVAPI32.dll
    RPCRT4.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32RPCRT4.dll
    USER32.dll v5.1.2600.2622 (xpsp_sp2_gdr.050301-1519) – C:WINDOWSsystem32USER32.dll
    GDI32.dll v5.1.2600.2818 (xpsp_sp2_gdr.051228-1427) – C:WINDOWSsystem32GDI32.dll
    msvcrt.dll v7.0.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32msvcrt.dll
    ole32.dll v5.1.2600.2726 (xpsp_sp2_gdr.050725-1528) – C:WINDOWSsystem32ole32.dll
    SHELL32.dll v6.00.2900.2951 (xpsp_sp2_gdr.060713-0009) – C:WINDOWSsystem32SHELL32.dll
    SHLWAPI.dll v6.00.2900.2937 (xpsp.060623-0011) – C:WINDOWSsystem32SHLWAPI.dll
    urlmon.dll v7.00.5700.6 (winmain(wmbla).060822-2230) – C:WINDOWSsystem32urlmon.dll
    OLEAUT32.dll v5.1.2600.2180 – C:WINDOWSsystem32OLEAUT32.dll
    iertutil.dll v7.00.5700.6 (winmain(wmbla).060822-2230) – C:WINDOWSsystem32iertutil.dll
    WININET.dll v7.00.5700.6 (winmain(wmbla).060822-2230) – C:WINDOWSsystem32WININET.dll
    Normaliz.dll v6.0.5441.0 (winmain(wmbla).060628-1735) – C:WINDOWSsystem32Normaliz.dll
    IMM32.DLL v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32IMM32.DLL
    comctl32.dll v6.0 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSWinSxSx86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9comctl32.dll
    comctl32.dll v5.82 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32comctl32.dll
    uxtheme.dll v6.00.2900.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32uxtheme.dll
    MSCTF.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32MSCTF.dll
    tiptsf.dll v1.7.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:Program FilesCommon Filesmicrosoft sharedinktiptsf.dll
    OLEACC.dll v4.2.5406.0 (xpclient.010817-1148) – C:WINDOWSsystem32OLEACC.dll
    MSVCP60.dll v6.02.3104.0 – C:WINDOWSsystem32MSVCP60.dll
    VERSION.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32VERSION.dll
    PSAPI.DLL v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32PSAPI.DLL
    CLBCATQ.DLL v2001.12.4414.308 – C:WINDOWSsystem32CLBCATQ.DLL
    COMRes.dll v2001.12.4414.258 – C:WINDOWSsystem32COMRes.dll
    xpsp2res.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32xpsp2res.dll
    Secur32.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32Secur32.dll
    ws2_32.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32ws2_32.dll
    WS2HELP.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32WS2HELP.dll
    VetRedir.dll vVersion 8.0.5.0 – C:WINDOWSsystem32VetRedir.dll
    mswsock.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32mswsock.dll
    RASAPI32.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32RASAPI32.dll
    rasman.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32rasman.dll
    NETAPI32.dll v5.1.2600.2952 (xpsp_sp2_gdr.060714-0446) – C:WINDOWSsystem32NETAPI32.dll
    TAPI32.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32TAPI32.dll
    rtutils.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32rtutils.dll
    WINMM.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32WINMM.dll
    hnetcfg.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32hnetcfg.dll
    USERENV.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32USERENV.dll
    ISafeIf.dll vVersion 8.0.5.0 – C:WINDOWSsystem32ISafeIf.dll
    msv1_0.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32msv1_0.dll
    iphlpapi.dll v5.1.2600.2912 (xpsp_sp2_gdr.060519-0003) – C:WINDOWSsystem32iphlpapi.dll
    wshtcpip.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSSystem32wshtcpip.dll
    sensapi.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32sensapi.dll
    rasadhlp.dll v5.1.2600.2938 (xpsp_sp2_gdr.060626-0020) – C:WINDOWSsystem32rasadhlp.dll
    DNSAPI.dll v5.1.2600.2938 (xpsp_sp2_gdr.060626-0020) – C:WINDOWSsystem32DNSAPI.dll
    dfshim.dll v2.0.50727.42 (RTM.050727-4200) – C:WINDOWSsystem32dfshim.dll
    mscoree.dll v2.0.50727.42 (RTM.050727-4200) – C:WINDOWSsystem32mscoree.dll
    PresentationHostDLL.dll v3.0.6715.0 (winmain_oob/wap_rc1(avdrt).060815-1648) – C:WINDOWSMicrosoft.NetFrameworkv3.0WPFPresentationHostDLL.dll
    mscorwks.dll v2.0.50727.42 (RTM.050727-4200) – C:WINDOWSMicrosoft.NETFrameworkv2.0.50727mscorwks.dll
    MSVCR80.dll v8.00.50727.42 – C:WINDOWSWinSxSx86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acdMSVCR80.dll
    mscorlib.ni.dll v2.0.50727.42 (RTM.050727-4200) – C:WINDOWSassemblyNativeImages_v2.0.50727_32mscorlib7524066fbea68c47a734c3d217e95ecbmscorlib.ni.dll
    System.ni.dll v2.0.50727.42 (RTM.050727-4200) – C:WINDOWSassemblyNativeImages_v2.0.50727_32System9033388bdcad254c9329c852d0e18eafSystem.ni.dll
    WindowsBase.ni.dll v3.0.6715.0 (winmain_oob/wap_rc1(avdrt).060815-1648) – C:WINDOWSassemblyNativeImages_v2.0.50727_32WindowsBase74b584db0c2ef140a476b0a22b27b269WindowsBase.ni.dll
    PresentationCore.ni.dll v3.0.6715.0 (winmain_oob/wap_rc1(avdrt).060815-1648) – C:WINDOWSassemblyNativeImages_v2.0.50727_32PresentationCore791a43df3fb5b549ae63db67a0bf43f2PresentationCore.ni.dll
    PresentationFramework.ni.dll v3.0.6715.0 (winmain_oob/wap_rc1(avdrt).060815-1648) – C:WINDOWSassemblyNativeImages_v2.0.50727_32PresentationFramewo#feb913462c24be4784418080bf5c0128PresentationFramework.ni.dll
    msctfime.ime v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32msctfime.ime
    mslbui.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32mslbui.dll
    actxprxy.dll v6.00.2900.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32actxprxy.dll
    msi.dll v3.1.4000.2435 – C:WINDOWSsystem32msi.dll
    SXS.DLL v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32SXS.DLL
    ieproxy.dll v7.00.5700.6 (winmain(wmbla).060822-2230) – C:Program FilesInternet Explorerieproxy.dll
    nbmaptip.dll v1.0.2201.0 – C:Program Fileswindows journalnbmaptip.dll
    sptip.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSimesptip.dll
    SPGRMR.DLL v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSIMESPGRMR.DLL
    PresentationUI.ni.dll v3.0.6715.0 (winmain_oob/wap_rc1(avdrt).060815-1648) – C:WINDOWSassemblyNativeImages_v2.0.50727_32PresentationUI37dfafd7463be940bbfda415727e615ePresentationUI.ni.dll
    tipcomponentsps.dll v1.7.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:Program FilesCommon FilesMicrosoft SharedInktipcomponentsps.dll
    msctfp.dll v5.1.2600.2180 (xpsp_sp2_rtm.040803-2158) – C:WINDOWSsystem32msctfp.dll
    rsaenh.dll v5.1.2600.2161 (xpsp.040706-1629) – C:WINDOWSsystem32rsaenh.dll
    mscorjit.dll v2.0.50727.42 (RTM.050727-4200) – C:WINDOWSMicrosoft.NETFrameworkv2.0.50727mscorjit.dll
    PresentationFramework.Luna.ni.dll v3.0.6715.0 (winmain_oob/wap_rc1(avdrt).060815-1648) – C:WINDOWSassemblyNativeImages_v2.0.50727_32PresentationFramewo#a3e76164157563408e2bfbfca34f3d89PresentationFramework.Luna.ni.dll
    diasymreader.dll v8.0.50727.42 (RTM.050727-4200) – C:WINDOWSMicrosoft.NETFrameworkv2.0.50727diasymreader.dll

    Do you know how I can get your application to run on my PC? Thanks.

  3. I’m getting the same error as the previous commenter…I have RC1 installed (since the weekend), and I’m getting the “BAML stream has version number ‘0.94′ but parser can read only version ‘0.96′”.

    Is it possible the old version has been cached on the server?

  4. I haven’t had an problems… If you’ve run this app before, it’s possible that it’s cached on your side. (In hindsight, I probably should have bumped the Application version number.) Can you please try clearing your local cache by running:

    mage.exe -cc

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>