private Tuple <bool, IRenderEngine> GetRenderingEngine(string fontName, IVwGraphics vg, ILgWritingSystem ws) { // NB: Even if the ws claims graphite is enabled, this might not be a graphite font if (ws.IsGraphiteEnabled) { var graphiteEngine = GraphiteEngineClass.Create(); string fontFeatures = null; if (fontName == ws.DefaultFontName) { fontFeatures = GraphiteFontFeatures.ConvertFontFeatureCodesToIds(ws.DefaultFontFeatures); } graphiteEngine.InitRenderer(vg, fontFeatures); // check if the font is a valid Graphite font if (graphiteEngine.FontIsValid) { graphiteEngine.RenderEngineFactory = this; graphiteEngine.WritingSystemFactory = ws.WritingSystemFactory; return(new Tuple <bool, IRenderEngine>(ws.IsGraphiteEnabled, graphiteEngine)); } // It wasn't really a graphite font - release the graphite one and create a Uniscribe below Marshal.ReleaseComObject(graphiteEngine); } return(new Tuple <bool, IRenderEngine>(ws.IsGraphiteEnabled, GetUniscribeEngine(vg, ws))); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Raises the click event. /// </summary> /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param> /// ------------------------------------------------------------------------------------ protected override void OnClick(EventArgs e) { var menu = components.ContextMenu("ContextMenu"); int cfid; m_featureEngine.GetFeatureIDs(0, null, out cfid); // Get the list of features. using (ArrayPtr idsM = MarshalEx.ArrayToNative <int>(cfid)) { m_featureEngine.GetFeatureIDs(cfid, idsM, out cfid); m_ids = MarshalEx.NativeToArray <int>(idsM, cfid); } m_fontFeatures = GraphiteFontFeatures.ConvertFontFeatureCodesToIds(m_fontFeatures); m_values = ParseFeatureString(m_ids, m_fontFeatures); Debug.Assert(m_ids.Length == m_values.Length); for (int ifeat = 0; ifeat < m_ids.Length; ++ifeat) { int id = m_ids[ifeat]; if (id == kGrLangFeature) { continue; // Don't show Graphite built-in 'lang' feature. } string label; m_featureEngine.GetFeatureLabel(id, kUiCodePage, out label); if (label.Length == 0) { //Create backup default string, ie, "Feature #1". label = string.Format(FwCoreDlgControls.kstidFeature, id); } int cValueIds; int nDefault; int [] valueIds; using (ArrayPtr valueIdsM = MarshalEx.ArrayToNative <int>(kMaxValPerFeat)) { m_featureEngine.GetFeatureValues(id, kMaxValPerFeat, valueIdsM, out cValueIds, out nDefault); valueIds = MarshalEx.NativeToArray <int>(valueIdsM, cValueIds); } // If we know a value for this feature, use it. Otherwise init to default. int featureValue = nDefault; if (m_values[ifeat] != Int32.MaxValue) { featureValue = m_values[ifeat]; } // Decide whether to just use a check mark, or have a submenu. Default is sub. bool fBinary = false; if (cValueIds == 2 && (valueIds[0] == 0 || valueIds[1] == 0) && valueIds[0] + valueIds[1] == 1) { // Minimum requirement is that there are two states and the values have // ids of 0 and 1. We further require that the actual values belong to a // natural boolean set. string valueLabelT; // Label corresponding to 'true' etc, the checked value m_featureEngine.GetFeatureValueLabel(id, 1, kUiCodePage, out valueLabelT); string valueLabelF; // Label corresponding to 'false' etc, the unchecked val. m_featureEngine.GetFeatureValueLabel(id, 0, kUiCodePage, out valueLabelF); // Enhance: these should be based on a resource, or something that depends // on the code page, if the code page is ever not constant. switch (valueLabelT.ToLowerInvariant()) { case "true": case "yes": case "on": case "": { switch (valueLabelF.ToLowerInvariant()) { case "false": case "no": case "off": case "": fBinary = true; break; } } break; } } if (fBinary) { FontFeatureMenuItem item = new FontFeatureMenuItem(label, ifeat, this); item.Checked = featureValue == 1; menu.MenuItems.Add(item); } else if (cValueIds > 0) { FontFeatureMenuItem menuSub = new FontFeatureMenuItem(label, ifeat, this); for (int ival = 0; ival < valueIds.Length; ++ival) { string valueLabel; m_featureEngine.GetFeatureValueLabel(id, valueIds[ival], kUiCodePage, out valueLabel); if (valueLabel.Length == 0) { // Create backup default string. valueLabel = string.Format(FwCoreDlgControls.kstidFeatureValue, valueIds[ival]); } FontFeatureMenuItem itemSub = new FontFeatureMenuItem(valueLabel, valueIds[ival], this); itemSub.Checked = valueIds[ival] == featureValue; menuSub.MenuItems.Add(itemSub); } menu.MenuItems.Add(menuSub); } // if (fBinary) // { // ... // Assert(vnMenuMap.Size() == cItems); // vnMenuMap.Push((ifeat << 16) | 0x0000FFFF); // cItems++; // } // else if (cn > 0) // { // Assert(cn < 0x0000FFFF); // HMENU hmenuSub = ::CreatePopupMenu(); // ::AppendMenu(hmenu, MF_POPUP, (UINT_PTR)hmenuSub, strFeat.Chars()); // for (int in = 0; in < cn; in++) // { // // Assert(vnMenuMap.Size() == cItems); // vnMenuMap.Push((ifeat << 16) | in); // cItems++; // } // } // else // } } menu.Show(this, new Point(0, Height)); }