public override void OnValueReady(CssLexer lexer) { int length = Count; if (length == 0) { return; } bool mapAll = true; // If any of the parameters are decimals or are just 0 and 1, remap them to INTS. for (int i = 0; i < length; i++) { // Get the decimal value [either a percentage or a 0-1 value]: DecimalUnit dec = this[i] as DecimalUnit; if (dec == null) { continue; } if (dec.RawValue > 1f) { // No remapping required. mapAll = false; break; } } // Re-map the parameters now: for (int i = 0; i < length; i++) { // Get the decimal value: DecimalUnit dec = this[i] as DecimalUnit; if (dec == null) { continue; } if (i == 3 || dec.RawValue < 1f || mapAll) { } else { dec.RawValue /= 255f; } } }
public Css.Value this[string property] { get{ Css.Value value; Features.TryGetValue(property, out value); return(value); } set{ DecimalUnit du = (value as DecimalUnit); if (du != null) { // Numeric - if it's zero, act as null: if (du.RawValue == 0f) { value = null; du = null; if (!Features.ContainsKey(property)) { // Don't add it. return; } } } // Apply the value: Features[property] = value; // Min/max too? if (value != null) { if (du != null) { // Numeric - it can therefore have min/max as well: Features["min-" + property] = value; Features["max-" + property] = value; } } if (Document != null) { // Run the change now: Changed(); } } }
/// <summary>Reads a single value from the stream.</summary> public Css.Value ReadSingleValue() { Css.Value result = null; // Skip whitespaces. SkipJunk(); char current = Peek(); if (SelectorMode && current == '.') { Read(); // Class selector. return(new TextUnit(".")); } int charCode = (int)current; CssUnitHandlers set; if (CssUnits.AllStart.TryGetValue(current, out set)) { // Match on the pretext: result = set.Handle(this, false); if (result != null) { // Read the value: result = result.ReadStartValue(this); if (result == null) { return(null); } // Call ready: result.OnValueReady(this); // Ok! return(result); } } // Number: int numberStart = Position; while (charCode == (int)'-' || charCode == '+' || (charCode >= (int)'0' && charCode <= (int)'9') || charCode == (int)'.') { if (numberStart == Position) { // Special case if it's just +, . or - // Prefixed keywords fall through here too. if (charCode == (int)'.') { // Must be 0-9 next: int next = (int)Peek(1); if (next < (int)'0' || next > (int)'9') { // Non-numeric. break; } } else if (charCode == (int)'+' || charCode == (int)'-') { // Peek the next char. It must be either . or 0-9: int next = (int)Peek(1); if (next != (int)'.' && (next < (int)'0' || next > (int)'9')) { // Non-numeric. break; } } } // Read off: Read(); // Go to the next one: current = Peek(); // Get the code: charCode = (int)current; } if (numberStart != Position) { // Read a number of some kind. Now look for the units, if there are any. string num = Input.Substring(numberStart, Position - numberStart); if (CssUnits.AllEnd.TryGetValue(current, out set) && !SelectorMode) { // Units handler is likely! result = set.Handle(this, true); if (result != null) { // Return the result: result = result.Copy(); // Apply the number: float flt; float.TryParse(num, out flt); // Set: result.SetRawDecimal(flt); // Call ready: result.OnValueReady(this); return(result); } } else { // Apply the number: float nFlt; float.TryParse(num, out nFlt); // Create: result = new DecimalUnit(); // Set: result.SetRawDecimal(nFlt); // Call ready: result.OnValueReady(this); return(result); } } if (charCode == '\\') { string characters = ""; while (true) { // Special case here; we have one or more unicode escaped characters. Read(); current = Peek(); charCode = (int)current; int res = 0; for (int i = 0; i < 6; i++) { if (charCode >= (int)'0' && charCode <= (int)'9') { Read(); // Apply to charcode: res = (res << 4) | (charCode - (int)'0'); // Move on: current = Peek(); charCode = (int)current; } else if (charCode >= (int)'a' && charCode <= (int)'f') { Read(); // Apply to charcode: res = (res << 4) | (charCode + 10 - (int)'a'); // Move on: current = Peek(); charCode = (int)current; } else { // No longer valid unicode. break; } } characters += char.ConvertFromUtf32(res); if (charCode != '\\') { // Go again otherwise! break; } } return(new TextUnit(characters)); } // E.g. textual keyword or function comes down here. // If we spot a (, call ReadValue() to get the parameter set. int textStart = Position; while (charCode != 0 && (charCode > 128 || charCode == 45 || charCode == 40 || (95 <= charCode && charCode <= 122) || (65 <= charCode && charCode <= 90) || (48 <= charCode && charCode <= 57)) ) { if (current == '(') { // Got a function name (if there is one). string name = Input.Substring(textStart, Position - textStart); result = ReadFunction(name); return(result); } Read(); current = Peek(); charCode = (int)current; } if (textStart == Position && charCode != 0) { // The only thing we've read is a delimiter. if (current == '\r' || current == '\n' || current == ')' || current == ' ' || current == '}' || current == '{' || current == ';' || current == ',' ) { // Handled elsewhere. Ignore these. // They all terminate upper level value readers (or are junk!). } else { // Add the single character into the buffer. Read(); if (current == '$' || current == '*' || current == '^' || current == '~' || current == '|') { // Followed by equals? if (Peek() == '=') { // Yep - include that in this same unit. Read(); return(new TextUnit(current + "=")); } } else if (current == '>') { // Followed by another? if (Peek() == '>') { // Yep - include that in this same unit. Read(); return(new TextUnit(">>")); } } return(new TextUnit(current.ToString())); } } // Text or keyword. string text = Input.Substring(textStart, Position - textStart); // Must not match keywords/ colours when in selector mode // (because keywords are always lowercase and colours act like *): if (SelectorMode) { // Just text: return(new TextUnit(text)); } // Keyword tests. string keyword = text.ToLower(); // Colour? bool wasColour; UnityEngine.Color32 col = Css.ColourMap.GetColourByName(keyword, out wasColour); if (wasColour) { // It's a colour: ColourUnit cResult = new ColourUnit(col); // Call ready: cResult.OnValueReady(this); return(cResult); } // Global keyword? result = CssKeywords.Get(keyword); if (result != null) { // Keyword! Can't share the global instance because of specifity. return(result.Copy()); } // Just treat as some text otherwise: return(new TextUnit(text)); }