static nsresult InitOperators(void) { // Load the property file containing the Operator Dictionary nsresult rv; nsCOMPtr<nsIPersistentProperties> mathfontProp; rv = NS_LoadPersistentPropertiesFromURISpec(getter_AddRefs(mathfontProp), NS_LITERAL_CSTRING("resource://gre/res/fonts/mathfont.properties")); if (NS_FAILED(rv)) return rv; // Parse the Operator Dictionary in two passes. // The first pass is to count the number of operators; the second pass is to // allocate the necessary space for them and to add them in the hash table. for (int32_t pass = 1; pass <= 2; pass++) { OperatorData dummyData; OperatorData* operatorData = &dummyData; nsCOMPtr<nsISimpleEnumerator> iterator; if (NS_SUCCEEDED(mathfontProp->Enumerate(getter_AddRefs(iterator)))) { bool more; uint32_t index = 0; nsAutoCString name; nsAutoString attributes; while ((NS_SUCCEEDED(iterator->HasMoreElements(&more))) && more) { nsCOMPtr<nsISupports> supports; nsCOMPtr<nsIPropertyElement> element; if (NS_SUCCEEDED(iterator->GetNext(getter_AddRefs(supports)))) { element = do_QueryInterface(supports); if (NS_SUCCEEDED(element->GetKey(name)) && NS_SUCCEEDED(element->GetValue(attributes))) { // expected key: operator.\uNNNN.{infix,postfix,prefix} if ((21 <= name.Length()) && (0 == name.Find("operator.\\u"))) { name.Cut(0, 9); // 9 is the length of "operator."; int32_t len = name.Length(); nsOperatorFlags form = 0; if (kNotFound != name.RFind(".infix")) { form = NS_MATHML_OPERATOR_FORM_INFIX; len -= 6; // 6 is the length of ".infix"; } else if (kNotFound != name.RFind(".postfix")) { form = NS_MATHML_OPERATOR_FORM_POSTFIX; len -= 8; // 8 is the length of ".postfix"; } else if (kNotFound != name.RFind(".prefix")) { form = NS_MATHML_OPERATOR_FORM_PREFIX; len -= 7; // 7 is the length of ".prefix"; } else continue; // input is not applicable name.SetLength(len); if (2 == pass) { // allocate space and start the storage if (!gOperatorArray) { if (0 == gOperatorCount) return NS_ERROR_UNEXPECTED; gOperatorArray = new OperatorData[gOperatorCount]; if (!gOperatorArray) return NS_ERROR_OUT_OF_MEMORY; } operatorData = &gOperatorArray[index]; } else { form = 0; // to quickly return from SetOperator() at pass 1 } // See if the operator should be retained if (SetOperator(operatorData, form, name, attributes)) { index++; if (1 == pass) gOperatorCount = index; } } } } } } } return NS_OK; }
int mozilla_decoders_init(void) { static PRBool initialized = PR_FALSE; if (initialized) return 0; PangoContext* context = gdk_pango_context_get (); PangoFontMap* fontmap = pango_context_get_font_map (context); g_object_unref (context); if (!PANGO_IS_FC_FONT_MAP (fontmap)) return -1; encoder_hash = g_hash_table_new(g_str_hash, g_str_equal); cmap_hash = g_hash_table_new(g_str_hash, g_str_equal); wide_hash = g_hash_table_new(g_str_hash, g_str_equal); PRBool dumb = PR_FALSE; nsCOMPtr<nsIPersistentProperties> props; nsCOMPtr<nsISimpleEnumerator> encodeEnum; NS_LoadPersistentPropertiesFromURISpec(getter_AddRefs(props), NS_LITERAL_CSTRING("resource://gre/res/fonts/pangoFontEncoding.properties")); if (!props) goto loser; // Enumerate the properties in this file and figure out all of the // fonts for which we have custom encodings. props->Enumerate(getter_AddRefs(encodeEnum)); if (!encodeEnum) goto loser; while (encodeEnum->HasMoreElements(&dumb), dumb) { nsCOMPtr<nsIPropertyElement> prop; encodeEnum->GetNext(getter_AddRefs(prop)); if (!prop) goto loser; nsCAutoString name; prop->GetKey(name); nsAutoString value; prop->GetValue(value); if (!StringBeginsWith(name, NS_LITERAL_CSTRING("encoding."))) { printf("string doesn't begin with encoding?\n"); continue; } name = Substring(name, 9); if (StringEndsWith(name, NS_LITERAL_CSTRING(".ttf"))) { name = Substring(name, 0, name.Length() - 4); // Strip off a .wide if it's there. if (StringEndsWith(value, NS_LITERAL_STRING(".wide"))) { g_hash_table_insert(wide_hash, g_strdup(name.get()), g_strdup("wide")); value = Substring(value, 0, name.Length() - 5); } g_hash_table_insert(encoder_hash, g_strdup(name.get()), g_strdup(NS_ConvertUTF16toUTF8(value).get())); } else if (StringEndsWith(name, NS_LITERAL_CSTRING(".ftcmap"))) { name = Substring(name, 0, name.Length() - 7); g_hash_table_insert(cmap_hash, g_strdup(name.get()), g_strdup(NS_ConvertUTF16toUTF8(value).get())); } else { printf("unknown suffix used for mapping\n"); } } pango_fc_font_map_add_decoder_find_func(PANGO_FC_FONT_MAP(fontmap), mozilla_find_decoder, NULL, NULL); initialized = PR_TRUE; #ifdef DEBUG_CUSTOM_ENCODER printf("*** encoders\n"); g_hash_table_foreach(encoder_hash, (GHFunc)dump_hash, NULL); printf("*** cmaps\n"); g_hash_table_foreach(cmap_hash, (GHFunc)dump_hash, NULL); #endif return 0; loser: return -1; }