// implement base class pure virtuals
     virtual int GetPointSize() const;
-    virtual wxFontFamily GetFamily() const;
     virtual wxFontStyle GetStyle() const;
     virtual wxFontWeight GetWeight() const;
     virtual bool GetUnderlined() const;
     virtual wxGDIRefData *CreateGDIRefData() const;
     virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const;
 
+    virtual wxFontFamily DoGetFamily() const;
+
 private:
     DECLARE_DYNAMIC_CLASS(wxFont)
 };
 
 
     // implement base class pure virtuals
     virtual int GetPointSize() const;
-    virtual wxFontFamily GetFamily() const;
     virtual wxFontStyle GetStyle() const;
     virtual wxFontWeight GetWeight() const;
     virtual wxString GetFaceName() const;
     virtual wxGDIRefData *CreateGDIRefData() const;
     virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const;
 
+    virtual wxFontFamily DoGetFamily() const;
+
 private:
     DECLARE_DYNAMIC_CLASS(wxFont)
 };
 
     virtual int GetPointSize() const = 0;
     virtual wxSize GetPixelSize() const;
     virtual bool IsUsingSizeInPixels() const;
-    virtual wxFontFamily GetFamily() const = 0;
+    wxFontFamily GetFamily() const;
     virtual wxFontStyle GetStyle() const = 0;
     virtual wxFontWeight GetWeight() const = 0;
     virtual bool GetUnderlined() const = 0;
     // the function called by both overloads of SetNativeFontInfo()
     virtual void DoSetNativeFontInfo(const wxNativeFontInfo& info);
 
+    // The function called by public GetFamily(): it can return
+    // wxFONTFAMILY_UNKNOWN unlike the public method (see comment there).
+    virtual wxFontFamily DoGetFamily() const = 0;
+
 private:
     // the currently default encoding: by default, it's the default system
     // encoding, but may be changed by the application using
 
 
     // implement base class pure virtuals
     virtual int GetPointSize() const;
-    virtual wxFontFamily GetFamily() const;
     virtual wxFontStyle GetStyle() const;
     virtual wxFontWeight GetWeight() const;
     virtual wxString GetFaceName() const;
     virtual wxGDIRefData* CreateGDIRefData() const;
     virtual wxGDIRefData* CloneGDIRefData(const wxGDIRefData* data) const;
 
+    virtual wxFontFamily DoGetFamily() const;
+
 private:
     DECLARE_DYNAMIC_CLASS(wxFont)
 };
 
 
     // implement base class pure virtuals
     virtual int GetPointSize() const;
-    virtual wxFontFamily GetFamily() const;
     virtual wxFontStyle GetStyle() const;
     virtual wxFontWeight GetWeight() const;
     virtual wxString GetFaceName() const;
     virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const;
 
     virtual void DoSetNativeFontInfo( const wxNativeFontInfo& info );
+    virtual wxFontFamily DoGetFamily() const;
 
 private:
     DECLARE_DYNAMIC_CLASS(wxFont)
 
 
     // implement base class pure virtuals
     virtual int GetPointSize() const;
-    virtual wxFontFamily GetFamily() const;
     virtual wxFontStyle GetStyle() const;
     virtual wxFontWeight GetWeight() const;
     virtual wxString GetFaceName() const;
     virtual wxGDIRefData *CreateGDIRefData() const;
     virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const;
 
+    virtual wxFontFamily DoGetFamily() const;
+
 private:
     DECLARE_DYNAMIC_CLASS(wxFont)
 };
 
 
     // implement base class pure virtuals
     virtual int GetPointSize() const;
-    virtual wxFontFamily GetFamily() const;
     virtual wxFontStyle GetStyle() const;
     virtual wxFontWeight GetWeight() const;
     virtual bool GetUnderlined() const;
     virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const;
 
     virtual void DoSetNativeFontInfo( const wxNativeFontInfo& info );
+    virtual wxFontFamily DoGetFamily() const;
 
     void Unshare();
 
 
     virtual int GetPointSize() const;
     virtual wxSize GetPixelSize() const;
     virtual bool IsUsingSizeInPixels() const;
-    virtual wxFontFamily GetFamily() const;
     virtual wxFontStyle GetStyle() const;
     virtual wxFontWeight GetWeight() const;
     virtual bool GetUnderlined() const;
                   wxFontEncoding encoding = wxFONTENCODING_DEFAULT);
 
     virtual void DoSetNativeFontInfo(const wxNativeFontInfo& info);
+    virtual wxFontFamily DoGetFamily() const;
 
     // implement wxObject virtuals which are used by AllocExclusive()
     virtual wxGDIRefData *CreateGDIRefData() const;
 
     // Implement base class pure virtuals
     //
     virtual int               GetPointSize(void) const;
-    virtual wxFontFamily GetFamily() const;
     virtual wxFontStyle GetStyle() const;
     virtual wxFontWeight GetWeight() const;
     virtual bool              GetUnderlined(void) const;
 
 protected:
     virtual void DoSetNativeFontInfo(const wxNativeFontInfo& rInfo);
+    virtual wxFontFamily DoGetFamily() const;
 
     // implement wxObject virtuals which are used by AllocExclusive()
     virtual wxGDIRefData *CreateGDIRefData() const;
 
     // implement base class pure virtuals
     virtual int GetPointSize() const;
     virtual wxSize GetPixelSize() const;
-    virtual wxFontFamily GetFamily() const;
     virtual wxFontStyle GetStyle() const;
     virtual wxFontWeight GetWeight() const;
     virtual bool GetUnderlined() const;
 
 protected:
     virtual void DoSetNativeFontInfo(const wxNativeFontInfo& info);
+    virtual wxFontFamily DoGetFamily() const;
 
     virtual wxGDIRefData *CreateGDIRefData() const;
     virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const;
 
     virtual int GetPointSize() const;
     virtual wxSize GetPixelSize() const;
     virtual bool IsUsingSizeInPixels() const;
-    virtual wxFontFamily GetFamily() const;
     virtual wxFontStyle GetStyle() const;
     virtual wxFontWeight GetWeight() const;
     virtual bool GetUnderlined() const;
                   wxFontEncoding encoding = wxFONTENCODING_DEFAULT);
 
     virtual void DoSetNativeFontInfo(const wxNativeFontInfo& info);
+    virtual wxFontFamily DoGetFamily() const;
 
     // implement wxObject virtuals which are used by AllocExclusive()
     virtual wxGDIRefData *CreateGDIRefData() const;
 
 
     // implement base class pure virtuals
     virtual int GetPointSize() const;
-    virtual wxFontFamily GetFamily() const;
     virtual wxFontStyle GetStyle() const;
     virtual wxFontWeight GetWeight() const;
     virtual bool GetUnderlined() const;
     virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const;
 
     virtual void DoSetNativeFontInfo( const wxNativeFontInfo& info );
+    virtual wxFontFamily DoGetFamily() const;
 
     void Unshare();
 
 
     /// See also wxFont::IsFixedWidth() for an easy way to test for monospace property.
     wxFONTFAMILY_TELETYPE = wxTELETYPE,
 
-    /// Returned by wxFont::GetFamily() when the face name of the font cannot
-    /// be classified into one of the previous wxFontFamily values.
-    wxFONTFAMILY_UNKNOWN = wxFONTFAMILY_MAX,
-
-    wxFONTFAMILY_MAX
+    /// Invalid font family value, returned by wxFont::GetFamily() when the
+    /// font is invalid for example.
+    wxFONTFAMILY_UNKNOWN
 };
 
 /**
     virtual wxString GetFaceName() const;
 
     /**
-        Gets the font family.
+        Gets the font family if possible.
+
         As described in ::wxFontFamily docs the returned value acts as a rough,
         basic classification of the main font properties (look, spacing).
 
         If the current font face name is not recognized by wxFont or by the
-        underlying system, @c wxFONTFAMILY_UNKNOWN is returned.
+        underlying system, @c wxFONTFAMILY_DEFAULT is returned.
 
-        Note that currently this function is rather unreliable (@c wxFONTFAMILY_UNKNOWN
-        is returned in too many cases) and not particularly useful.
-        Font families mostly make sense only for font creation; see SetFamily().
+        Note that currently this function is not very precise and so not
+        particularly useful. Font families mostly make sense only for font
+        creation, see SetFamily().
 
         @see SetFamily()
     */
 
     return M_FONTDATA->m_info.style;
 }
 
-wxFontFamily wxFont::GetFamily() const
+wxFontFamily wxFont::DoGetFamily() const
 {
-    wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
     return M_FONTDATA->m_info.family;
 }
 
 
            );
 }
 
+wxFontFamily wxFontBase::GetFamily() const
+{
+    wxCHECK_MSG( IsOk(), wxFONTFAMILY_UNKNOWN, wxS("invalid font") );
+
+    // Don't return wxFONTFAMILY_UNKNOWN from here because it prevents the code
+    // like wxFont(size, wxNORMAL_FONT->GetFamily(), ...) from working (see
+    // #12330). This is really just a hack but it allows to keep compatibility
+    // and doesn't really have any bad drawbacks so do this until someone comes
+    // up with a better idea.
+    const wxFontFamily family = DoGetFamily();
+
+    return family == wxFONTFAMILY_UNKNOWN ? wxFONTFAMILY_DEFAULT : family;
+}
+
 wxString wxFontBase::GetFamilyString() const
 {
     wxCHECK_MSG( IsOk(), "wxFONTFAMILY_DEFAULT", "invalid font" );
 
     return M_FONTDATA->GetFaceName();
 }
 
-wxFontFamily wxFont::GetFamily() const
+wxFontFamily wxFont::DoGetFamily() const
 {
-    wxCHECK_MSG( Ok(), wxFONTFAMILY_MAX, wxT("invalid font") );
-
     return M_FONTDATA->GetFamily();
 }
 
 
     return M_FONTDATA->m_nativeFontInfo.GetFaceName();
 }
 
-wxFontFamily wxFont::GetFamily() const
+wxFontFamily wxFont::DoGetFamily() const
 {
-    wxCHECK_MSG( IsOk(), wxFONTFAMILY_MAX, wxT("invalid font") );
-
     return M_FONTDATA->m_nativeFontInfo.GetFamily();
 }
 
 
     return M_FONTDATA->m_faceName;
 }
 
-wxFontFamily wxFont::GetFamily() const
+wxFontFamily wxFont::DoGetFamily() const
 {
-    wxCHECK_MSG( Ok(), wxFONTFAMILY_MAX, wxT("invalid font") );
-
     return M_FONTDATA->m_family;
 }
 
 
     return M_FONTDATA->GetFaceName();
 }
 
-wxFontFamily wxFont::GetFamily() const
+wxFontFamily wxFont::DoGetFamily() const
 {
-    wxCHECK_MSG( Ok(), wxFONTFAMILY_MAX, wxT("invalid font") );
-
     return M_FONTDATA->GetFamily();
 }
 
 
     return M_FONTDATA->m_faceName ;
 }
 
-wxFontFamily wxFont::GetFamily() const
+wxFontFamily wxFont::DoGetFamily() const
 {
-    wxCHECK_MSG( Ok(), wxFONTFAMILY_MAX, wxT("invalid font") );
-
     return M_FONTDATA->m_family;
 }
 
 
     return M_FONTDATA->IsUsingSizeInPixels();
 }
 
-wxFontFamily wxFont::GetFamily() const
+wxFontFamily wxFont::DoGetFamily() const
 {
-    wxCHECK_MSG( IsOk(), wxFONTFAMILY_MAX, wxT("invalid font") );
-
     return M_FONTDATA->GetFamily();
 }
 
 
     return M_FONTDATA->GetPointSize();
 } // end of wxFont::GetPointSize
 
-wxFontFamily wxFont::GetFamily() const
+wxFontFamily wxFont::DoGetFamily() const
 {
-    wxCHECK_MSG( Ok(), wxFONTFAMILY_MAX, wxT("invalid font") );
-
     return M_FONTDATA->GetFamily();
-} // end of wxFont::GetFamily
+} // end of wxFont::DoGetFamily
 
 wxFontStyle wxFont::GetStyle() const
 {
 
 #endif
 }
 
-wxFontFamily wxFont::GetFamily() const
+wxFontFamily wxFont::DoGetFamily() const
 {
-    wxCHECK_MSG( M_FONTDATA != NULL , wxFONTFAMILY_MAX, wxT("invalid font") );
-
     return M_FONTDATA->GetFamily();
 }
 
 
     return false;
 }
 
-wxFontFamily wxFont::GetFamily() const
+wxFontFamily wxFont::DoGetFamily() const
 {
     return wxFONTFAMILY_ROMAN;
 }
 
     return M_FONTDATA->m_faceName;
 }
 
-wxFontFamily wxFont::GetFamily() const
+wxFontFamily wxFont::DoGetFamily() const
 {
-    wxCHECK_MSG( Ok(), wxFONTFAMILY_MAX, wxT("invalid font") );
-
     return M_FONTDATA->m_family;
 }