public override void Apply(ComputedStyle style, Value value) { // Get the text property: TextRenderingProperty text = style.Text; if (text == null) { // Create one - note that content is the only property that can create a TRP. style.Text = text = new TextRenderingProperty(style.Element); // Next, apply every textual style immediately. // Note: properties with multiple names are applied multiple times. // This is fine. It's expected to be such a rare case and it will work fine anyway. foreach (KeyValuePair <string, CssProperty> kvp in CssProperties.TextProperties) { SetValue(kvp.Value, style); } } // Set the actual text: if (value == null) { text.Text = ""; } else { text.Text = value.Text; } // And apply it: text.SetText(); // Flag it as having changed: text.Changed = true; }
/// <summary> /// Applies to text nodes. /// </summary> public override void ApplyText(TextRenderingProperty text, RenderableData data, ComputedStyle style, Value value) { // Get: TextShadowProperty tsp = data.GetProperty(typeof(TextShadowProperty)) as TextShadowProperty; // Apply the property: if (value != null && !(value.IsType(typeof(Css.Keywords.None))) && value.Type == ValueType.Set) { // The glow properties: float blur = 0; Color colour = Color.black; if (tsp == null) { // Required - Create: tsp = new TextShadowProperty(data); tsp.Text = text; // Add it: data.AddOrReplaceProperty(tsp, typeof(TextShadowProperty)); } tsp.HOffset = value[0].GetDecimal(data, this); tsp.VOffset = value[1].GetDecimal(data, this); // Grab the blur: Value innerValue = value[2]; if (innerValue.Type == ValueType.Set) { colour = innerValue.GetColour(data, this); } else { blur = innerValue.GetDecimal(data, this); // Grab the colour: innerValue = value[3]; if (innerValue.Type == ValueType.Set) { colour = innerValue.GetColour(data, this); } } if (colour.a == 1f) { // Default transparency: colour.a = 0.8f; } tsp.Colour = colour; tsp.Blur = blur; } else if (tsp != null) { // Remove: data.AddOrReplaceProperty(null, typeof(TextShadowProperty)); } }
public override void Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { return; } bool auto = (value == null || value.Text == "auto" || value.Text == "anti-alias"); if (auto) { text.Alias = float.MaxValue; } else if (value.PX != 0) { text.Alias = (float)value.PX; } else { text.Alias = value.Single; } // Set width/height directly to the computed style: text.SetDimensions(); // Request a redraw: style.RequestLayout(); }
public static void LoadInto(TextRenderingProperty trp, List <OpenTypeFeature> features, ComputedStyle cs) { Css.Value value = cs[GlobalProperty]; if (value == null) { return; } if (Features == null) { Features = new OpenTypeFeatureSet(); } switch (value.Text) { default: // Do nothing break; case "sub": features.Add(Features["subs"]); features.Add(Features["dnom"]); break; case "super": features.Add(Features["sups"]); features.Add(Features["numr"]); break; } }
public override void Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { return; } if (value == null) { // No extrude: text.Extrude = 0f; } else { if (value.Single < 0f) { text.Extrude = 0f; } else { text.Extrude = value.Single; } } // Apply the changes: text.SetText(); }
public override void Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { return; } if (text.TextLine == null) { return; } // Apply the property: if (value == null || value.Text == "initial") { // No longer custom: text.TextLine.ColourOverride = false; } else { // Set the colour: text.TextLine.SetColour(value.ToColor()); } // Let it know a colour changed: text.ColourChanged(); }
public override void Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { return; } // Apply the property: if (value == null || value.Text == "normal") { text.Weight = 400; } else if (value.Text == "bold") { text.Weight = 700; } else if (value.PX != 0) { text.Weight = value.PX; } else { text.Weight = 400; } // Apply the changes: text.SetText(); }
/// <summary>Looks up the user-defined parameter in the documents available @ rules.</summary> public void LookupParameter(List <OpenTypeFeature> features, TextRenderingProperty trp, string atProperty, string keyword) { RenderableData rd = trp.RenderData; // Get the host at rule(s): string fontName = trp.FontToDraw.FamilyName; FontFeatureValuesRule hostRule = rd.Document.FontFeatures[fontName]; if (hostRule == null) { return; } // Get the feature (e.g. @styleset): CssFontFeatureSubRule feature = hostRule.FeatureLookup[atProperty]; if (feature == null) { return; } List <OpenTypeFeature> feats = feature.Properties[keyword]; // Add each into features: for (int f = 0; f < feats.Count; f++) { // Add it: features.Add(feats[f]); } }
public override void Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { return; } // Apply the property: string fontName = value.Text; if (fontName == null) { return; } Find(fontName, text); if (text.FontToDraw == null) { // No fonts at all. // We're going to load and use the default one: text.FontToDraw = DynamicFont.GetDefaultFamily(); } // Apply the changes: text.SetText(); }
public static void LoadInto(TextRenderingProperty trp, List <OpenTypeFeature> features, ComputedStyle cs) { Css.Value value = cs[GlobalProperty]; if (value == null) { return; } if (Features == null) { Features = new OpenTypeFeatureSet(); } switch (value.Text) { default: case "normal": // Do nothing break; case "small-caps": features.Add(Features["smcp"]); break; case "all-small-caps": features.Add(Features["smcp"]); features.Add(Features["c2sc"]); break; case "petite-caps": features.Add(Features["pcap"]); break; case "all-petite-caps": features.Add(Features["pcap"]); features.Add(Features["c2pc"]); break; case "unicase": features.Add(Features["unic"]); break; case "titling-caps": features.Add(Features["titl"]); break; } }
public override ApplyState Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { // Ok! return(ApplyState.Ok); } float adjust = -1f; if (value != null && value.Text != "none") { adjust = (float)value.GetDecimal(style.RenderData, this); } text.FontSizeAdjust = adjust; // Clear dimensions so they get re-computed: text.ClearDimensions(); // Request a redraw: style.RequestLayout(); // Ok! return(ApplyState.Ok); }
public override ApplyState Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { // Ok! return(ApplyState.Ok); } bool auto = (value == null || value.IsAuto || value.Text == "anti-alias"); if (auto) { text.Alias = float.MaxValue; } else { text.Alias = value.GetDecimal(style.RenderData, this); } // Clear dimensions so they get re-computed: text.ClearDimensions(); // Request a redraw: style.RequestLayout(); // Ok! return(ApplyState.Ok); }
public override void Apply(ComputedStyle style,Value value){ // Get the text property: TextRenderingProperty text=style.Text; if(text==null){ // Create one - note that content is the only property that can create a TRP. style.Text=text=new TextRenderingProperty(style.Element); // Next, apply every textual style immediately. // Note: properties with multiple names are applied multiple times. // This is fine. It's expected to be such a rare case and it will work fine anyway. foreach(KeyValuePair<string,CssProperty> kvp in CssProperties.TextProperties){ SetValue(kvp.Value,style); } } // Set the actual text: if(value==null){ text.Text=""; }else{ text.Text=value.Text; } // And apply it: text.SetText(); // Flag it as having changed: text.Changed=true; }
/// <summary> /// Applies to text nodes. /// </summary> public override void ApplyText(TextRenderingProperty trp, RenderableData data, ComputedStyle style, Value value) { // Do nothing if the node is totally empty. Dom.TextNode tn = (data.Node as Dom.TextNode); if (tn != null && tn.IsSpaces) { return; } if (value == null || value.IsType(typeof(Css.Keywords.None))) { if (trp.Background != null && trp.Background.Image != null) { trp.Background.Image.GoingOffDisplay(); trp.Background = null; } // Reverse any isolation: trp.Include(); } else if (value.Type == Css.ValueType.Image) { if (trp.Background == null) { trp.Background = new BackgroundOverlay(trp); } // Pull the image from the CSS value and create the package now: ImageFormat fmt = value.GetImage(style.RenderData, GlobalProperty); trp.Background.Image = new ImagePackage(fmt); // Instantly call ready: trp.Background.ImageReady(); } else { if (trp.Background == null) { trp.Background = new BackgroundOverlay(trp); } // Load it now! trp.Background.Image = new ImagePackage(value.Text, trp.RenderData.Document.basepath); trp.Background.Image.onload = delegate(UIEvent e){ // Call image ready now: if (trp.Background != null) { trp.Background.ImageReady(); } }; // Send: trp.Background.Image.send(); } }
public override void GetOpenTypeFeatures(TextRenderingProperty trp, List <OpenTypeFeature> features) { // For each parameter to this function.. for (int i = 0; i < Count; i++) { // Lookup the param via the @ declaration with the same name as this function: LookupParameter(features, trp, Name, this[i].Text); } }
public override void GetOpenTypeFeatures(TextRenderingProperty trp, List <OpenTypeFeature> features) { // The 'hist' feature: if (Hist == null) { Hist = new OpenTypeFeature("hist"); } features.Add(Hist); }
public static void LoadInto(TextRenderingProperty trp, List <OpenTypeFeature> features, ComputedStyle cs) { Css.Value value = cs[GlobalProperty]; if (value == null) { return; } if (Features == null) { Features = new OpenTypeFeatureSet(); } for (int i = 0; i < value.Count; i++) { Css.Value current = value[i]; // The feature name: string name; if (current is Css.ValueSet) { // E.g. "swsh" 2 name = current[0].Text; // Get the value (may be 'on' or 'off'): Css.Value par = current[1]; if (par.Type == ValueType.Text) { if (par.Text == "off") { continue; } // name followed by 'on'. features.Add(Features[name]); } else { int param = (int)current[1].GetRawDecimal(); features.Add(new OpenTypeFeature(name, param)); } } else { // It's just a feature name: name = current.Text; features.Add(Features[name]); } } }
/// <summary>Gets the next/previous suitable newline index.</summary> public int FindNewline(int direction) { // Get the text content: RenderableTextNode htn = TextHolder; if (htn == null || htn.RenderData.Text == null || htn.RenderData.Text.Characters == null) { return(CaretIndex); } // Get the renderer so we can access the chars: TextRenderingProperty trp = htn.RenderData.Text; // First index to check is.. int index = CaretIndex + direction; // Safety check: int max = trp.Characters.Length; if (index >= max) { index = max - 1; } else if (index < 0) { index = 0; } while (index > 0 && index < max) { // Check if char[index] is a newline: InfiniText.Glyph glyph = trp.Characters[index]; if (glyph != null && glyph.Charcode == (int)'\n') { // Got it! if (direction == 1) { index++; } break; } // Next one: index += direction; } return(index); }
public override void Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { return; } // Apply the property: if (value == null) { text.FontSize = 12f; } else { if (value.Type == ValueType.Text) { if (string.IsNullOrEmpty(value.Text)) { text.FontSize = 12f; } else { text.FontSize = float.Parse(value.Text); } } else { text.FontSize = (float)value.PX; } } // Got any letter spacing that needs updating? Css.Value spacing = style["letter-spacing"]; if (spacing != null && spacing.Single != 0f) { // Apply a relative %: text.LetterSpacing = text.FontSize * (value.Single - 1f); } // Set width/height directly to the computed style: text.SetDimensions(); // Request a redraw: style.RequestLayout(); }
public override ApplyState Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null || value == null) { // Ok! return(ApplyState.Ok); } int synthMode = 0; for (int i = 0; i < value.Count; i++) { switch (value[i].Text) { case "none": synthMode = FontSynthesisFlags.None; break; case "weight": synthMode |= FontSynthesisFlags.Weight; break; case "style": synthMode |= FontSynthesisFlags.Style; break; case "stretch": synthMode |= FontSynthesisFlags.Stretch; break; } } if (synthMode == FontSynthesisFlags.All) { // Delete: style.Properties.Remove(GlobalProperty); } else { // Write the value to the style: style[GlobalProperty] = new Css.Units.CachedIntegerUnit(value, synthMode); } // Ok! return(ApplyState.ReloadValue); }
/// <summary>Finds the index of the nearest character to x pixels.</summary> /// <param name="x">The number of pixels from the left edge of the screen.</param> public int LetterIndex(float x, LayoutBox box) { if (box == null) { // Nope! return(0); } // Get the text renderer: TextRenderingProperty trp = RenderData_.Text; if (trp == null) { // It's not been rendered at all yet. return(0); } // Walk the characters in the box until we've walked at least x units. float left = box.X; float fontSize = trp.FontSize; for (int i = box.TextStart; i < box.TextEnd; i++) { // Get the char: InfiniText.Glyph glyph = trp.Characters[i]; if (glyph == null) { continue; } // Move width along: left += glyph.AdvanceWidth * fontSize; if (left >= x) { // Got it! return(i); } // Advance over spacing: left += trp.LetterSpacing; } // End of the box. return(box.TextEnd); }
public static void LoadInto(TextRenderingProperty trp, List <OpenTypeFeature> features, ComputedStyle cs) { Css.Value value = cs[GlobalProperty]; if (value == null) { return; } if (Features == null) { Features = new OpenTypeFeatureSet(); } if (value is CssFunction) { value.GetOpenTypeFeatures(trp, features); return; } for (int i = 0; i < value.Count; i++) { Css.Value current = value[i]; if (current is CssFunction) { // E.g. stylistic(..) current.GetOpenTypeFeatures(trp, features); } else { switch (current.Text) { default: case "normal": // Do nothing break; case "historical-forms": features.Add(Features["hist"]); break; } } } }
public static void LoadInto(TextRenderingProperty trp, List <OpenTypeFeature> features, ComputedStyle cs) { Css.Value value = cs[GlobalProperty]; if (value == null) { return; } if (Features == null) { Features = new OpenTypeFeatureSet(); } switch (value.Text) { default: // Do nothing break; case "common-ligatures": features.Add(Features["clig"]); features.Add(Features["liga"]); break; case "discretionary-ligatures": features.Add(Features["dlig"]); break; case "historical-ligatures": features.Add(Features["hlig"]); break; case "contextual": features.Add(Features["calt"]); break; } }
/// <summary>Use this to build all font-variant features.</summary> public static List <OpenTypeFeature> GetAllFeatures(TextRenderingProperty trp) { // Feature set: List <OpenTypeFeature> features = new List <OpenTypeFeature>(); // Get the cs: ComputedStyle cs = trp.RenderData.computedStyle; // Load each variant property into features: FontVariantCaps.LoadInto(trp, features, cs); FontVariantAlternates.LoadInto(trp, features, cs); FontVariantEastAsian.LoadInto(trp, features, cs); FontVariantLigatures.LoadInto(trp, features, cs); FontVariantNumeric.LoadInto(trp, features, cs); FontVariantPosition.LoadInto(trp, features, cs); FontFeatureSettings.LoadInto(trp, features, cs); return(features); }
public override ApplyState Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { // Ok! return(ApplyState.Ok); } // Apply the changes: text.ClearText(); // Request a layout: style.RequestLayout(); // Ok! return(ApplyState.Ok); }
public override void Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { return; } // Get the standard space size for this text property: float standardSize = text.StandardSpaceSize(); // Apply the property: if (value == null) { // Standard space size: text.SpaceSize = standardSize; } else if (value.Single != 0f) { // Relative, e.g. 200% text.SpaceSize = standardSize * value.Single; } else if (value.PX != 0) { // Straight pixel size: text.SpaceSize = (float)value.PX; } else { // Standard space size (will be overwritten): text.SpaceSize = standardSize; } // Prompt the renderer to recalculate the width of the words: text.SetDimensions(); // Apply: text.RequestLayout(); }
/// <summary>Finds and connects the font(s) for the given text renderer.</summary> private void Find(string fontName,TextRenderingProperty text){ fontName=fontName.Replace("\"",""); string[] pieces=fontName.Split(','); DynamicFont current=null; // Grab the doc: Document doc=text.Element.Document; for(int i=0;i<pieces.Length;i++){ // Trim the name: fontName=pieces[i].Trim(); // Get the font from this DOM: DynamicFont backup=doc.GetOrCreateFont(fontName); if(backup==null){ // Font not described in the HTML at all or isn't available in the project. continue; } if(current!=null){ // Hook up the fallback: current.Fallback=backup; } current=backup; if(text.FontToDraw==null){ text.FontToDraw=current; } } }
/// <summary> /// Applies to text nodes. /// </summary> public override void ApplyText(TextRenderingProperty text, RenderableData data, ComputedStyle style, Value value) { // Get: TextStrokeProperty tsp = data.GetProperty(typeof(TextStrokeProperty)) as TextStrokeProperty; // Apply the property: if (value != null && !(value.IsType(typeof(Css.Keywords.None)))) { // The stroke properties: float thickness = value[0].GetDecimal(style.RenderData, this); if (thickness != 0) { if (tsp == null) { // Required - Create: tsp = new TextStrokeProperty(data); tsp.Text = text; // Add it: data.AddOrReplaceProperty(tsp, typeof(TextStrokeProperty)); } tsp.Thickness = thickness; tsp.Colour = value[1].GetColour(style.RenderData, this); return; } } // Remove if it falls down here: if (tsp != null) { // Remove: data.AddOrReplaceProperty(null, typeof(TextStrokeProperty)); } }
/// <summary>Finds and connects the font(s) for the given text renderer.</summary> private void Find(string fontName, TextRenderingProperty text) { fontName = fontName.Replace("\"", ""); string[] pieces = fontName.Split(','); DynamicFont current = null; // Grab the doc: Document doc = text.Element.Document; for (int i = 0; i < pieces.Length; i++) { // Trim the name: fontName = pieces[i].Trim(); // Get the font from this DOM: DynamicFont backup = doc.GetOrCreateFont(fontName); if (backup == null) { // Font not described in the HTML at all or isn't available in the project. continue; } if (current != null) { // Hook up the fallback: current.Fallback = backup; } current = backup; if (text.FontToDraw == null) { text.FontToDraw = current; } } }
public override void Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { return; } if (value == null || value.Text == "normal") { text.LineGap = 0.2f; } else { text.LineGap = value.Single - 1f; } // Apply the changes: text.SetDimensions(); }
public override void Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { return; } // Apply the property: if (value == null) { // No spacing: text.LetterSpacing = 0; } else if (value.Type == ValueType.Pixels) { // Fixed space: text.LetterSpacing = value.PX; } else if (value.Single != 0f) { // Apply a relative %: text.LetterSpacing = text.FontSize * (value.Single - 1f); } else { // Default no spacing: text.LetterSpacing = 0; } // Apply: text.RequestLayout(); // Recalc size: text.SetDimensions(); }
public override void Apply(ComputedStyle style, Value value) { // Get the text: TextRenderingProperty text = GetText(style); if (text == null) { return; } // Apply the property: if (value == null) { text.BaseColour = Color.black; } else { text.BaseColour = value.ToColor(); } // Let it know a colour changed: text.ColourChanged(); }