/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// aOperator is in the expanded format \uNNNN\uNNNN ... // First compress these Unicode points to the internal nsString format
int32_t i = 0;
nsAutoString name, value;
int32_t len = aOperator.Length();
char16_t c = aOperator[i++];
uint32_t state = 0;
char16_t uchar = 0; while (i <= len) { if (0 == state) { if (c != '\\') { returnfalse;
} if (i < len) {
c = aOperator[i];
}
i++; if (('u' != c) && ('U' != c)) { returnfalse;
} if (i < len) {
c = aOperator[i];
}
i++;
state++;
} else { if (('0' <= c) && (c <= '9')) {
uchar = (uchar << 4) | (c - '0');
} elseif (('a' <= c) && (c <= 'f')) {
uchar = (uchar << 4) | (c - 'a' + 0x0a);
} elseif (('A' <= c) && (c <= 'F')) {
uchar = (uchar << 4) | (c - 'A' + 0x0a);
} else { returnfalse;
} if (i < len) {
c = aOperator[i];
}
i++;
state++; if (5 == state) {
value.Append(uchar);
uchar = 0;
state = 0;
}
}
} if (0 != state) { returnfalse;
}
// Quick return when the caller doesn't care about the attributes and just // wants to know if this is a valid operator (this is the case at the first // pass of the parsing of the dictionary in InitOperators()) if (!aForm) { returntrue;
}
#ifdef DEBUG
NS_LossyConvertUTF16toASCII str(aAttributes); #endif // Loop over the space-delimited list of attributes to get the name:value // pairs
aAttributes.Append(kNullCh); // put an extra null at the end
char16_t* start = aAttributes.BeginWriting();
char16_t* end = start; while ((kNullCh != *start) && (kDashCh != *start)) {
name.SetLength(0);
value.SetLength(0); // skip leading space, the dash amounts to the end of the line while ((kNullCh != *start) && (kDashCh != *start) &&
nsCRT::IsAsciiSpace(*start)) {
++start;
}
end = start; // look for ':' while ((kNullCh != *end) && (kDashCh != *end) &&
!nsCRT::IsAsciiSpace(*end) && (kColonCh != *end)) {
++end;
} // If ':' is not found, then it's a boolean property bool IsBooleanProperty = (kColonCh != *end);
*end = kNullCh; // end segment here // this segment is the name if (start < end) {
name.Assign(start);
} if (IsBooleanProperty) {
SetBooleanProperty(aOperatorData, name);
} else {
start = ++end; // look for space or end of line while ((kNullCh != *end) && (kDashCh != *end) &&
!nsCRT::IsAsciiSpace(*end)) {
++end;
}
*end = kNullCh; // end segment here if (start < end) { // this segment is the value
value.Assign(start);
}
SetProperty(aOperatorData, name, value);
}
start = ++end;
} returntrue;
}
// 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";
} elseif (kNotFound != name.RFind(".postfix")) {
form = NS_MATHML_OPERATOR_FORM_POSTFIX;
len -= 8; // 8 is the length of ".postfix";
} elseif (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];
}
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;
}
/* static */
nsStretchDirection nsMathMLOperators::GetStretchyDirection( const nsString& aOperator) { // Search any entry for that operator and return the corresponding direction. // It is assumed that all the forms have same direction. for (constauto& form :
{NS_MATHML_OPERATOR_FORM_INFIX, NS_MATHML_OPERATOR_FORM_POSTFIX,
NS_MATHML_OPERATOR_FORM_PREFIX}) {
nsOperatorFlags flags; float dummy; if (nsMathMLOperators::LookupOperator(aOperator, form, &flags, &dummy,
&dummy)) { if (NS_MATHML_OPERATOR_IS_DIRECTION_VERTICAL(flags)) { return NS_STRETCH_DIRECTION_VERTICAL;
} if (NS_MATHML_OPERATOR_IS_DIRECTION_HORIZONTAL(flags)) { return NS_STRETCH_DIRECTION_HORIZONTAL;
}
}
} return NS_STRETCH_DIRECTION_UNSUPPORTED;
}
¤ Dauer der Verarbeitung: 0.35 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.