diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/BmpPicture.cs | 36 | ||||
| -rw-r--r-- | src/Cairo/IFill.cs | 11 | ||||
| -rw-r--r-- | src/Colors.cs | 18 | ||||
| -rw-r--r-- | src/Fill/Fill.cs | 32 | ||||
| -rw-r--r-- | src/Gradient.cs | 130 | ||||
| -rw-r--r-- | src/GraphicObjects/AnalogMeter.cs | 2 | ||||
| -rw-r--r-- | src/GraphicObjects/Border.cs | 8 | ||||
| -rw-r--r-- | src/GraphicObjects/GraduatedSlider.cs | 2 | ||||
| -rw-r--r-- | src/GraphicObjects/GraphicObject.cs | 49 | ||||
| -rw-r--r-- | src/GraphicObjects/Group.cs | 10 | ||||
| -rw-r--r-- | src/GraphicObjects/Label.cs | 24 | ||||
| -rw-r--r-- | src/GraphicObjects/ProgressBar.cs | 6 | ||||
| -rw-r--r-- | src/GraphicObjects/Slider.cs | 40 | ||||
| -rw-r--r-- | src/GraphicObjects/TextBox.cs | 4 | ||||
| -rw-r--r-- | src/GraphicObjects/TextRun.cs | 2 | ||||
| -rw-r--r-- | src/Picture.cs | 2 | ||||
| -rw-r--r-- | src/Point.cs | 15 | ||||
| -rw-r--r-- | src/Rectangle.cs | 5 | ||||
| -rw-r--r-- | src/SolidColor.cs | 96 | ||||
| -rw-r--r-- | src/SvgPicture.cs | 36 |
20 files changed, 437 insertions, 91 deletions
diff --git a/src/BmpPicture.cs b/src/BmpPicture.cs index 879329aa..fc227747 100644 --- a/src/BmpPicture.cs +++ b/src/BmpPicture.cs @@ -61,6 +61,42 @@ namespace Crow bitmap.UnlockBits (data); } + #region implemented abstract members of Fill + + public override void SetAsSource (Context ctx, Rectangle bounds = default(Rectangle)) + { + float widthRatio = 1f; + float heightRatio = 1f; + + if (Scaled){ + widthRatio = (float)bounds.Width / Dimensions.Width; + heightRatio = (float)bounds.Height / Dimensions.Height; + } + + if (KeepProportions) { + if (widthRatio < heightRatio) + heightRatio = widthRatio; + else + widthRatio = heightRatio; + } + + using (ImageSurface tmp = new ImageSurface (Format.Argb32, bounds.Width, bounds.Height)) { + using (Cairo.Context gr = new Context (tmp)) { + gr.Translate (bounds.Left, bounds.Top); + gr.Scale (widthRatio, heightRatio); + gr.Translate ((bounds.Width/widthRatio - Dimensions.Width)/2, (bounds.Height/heightRatio - Dimensions.Height)/2); + + using (ImageSurface imgSurf = new ImageSurface (image, Format.Argb32, + Dimensions.Width, Dimensions.Height, 4 * Dimensions.Width)) { + gr.SetSourceSurface (imgSurf, 0,0); + gr.Paint (); + } + } + ctx.SetSource (tmp); + } + } + #endregion + public override void Paint (Cairo.Context gr, Rectangle rect, string subPart = "") { float widthRatio = 1f; diff --git a/src/Cairo/IFill.cs b/src/Cairo/IFill.cs deleted file mode 100644 index e3459bb0..00000000 --- a/src/Cairo/IFill.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Crow -{ - public interface ICairoFill - { - void SetAsSource (Cairo.Context ctx); - } -} - diff --git a/src/Colors.cs b/src/Colors.cs index c88e1729..ccc42493 100644 --- a/src/Colors.cs +++ b/src/Colors.cs @@ -10,7 +10,7 @@ using System.Diagnostics; namespace Crow { - public struct Color : ICairoFill + public struct Color { #region CTOR public Color(double _R, double _G, double _B, double _A) @@ -63,7 +63,6 @@ namespace Crow return cr; } } - return new Color( double.Parse(c[0]), double.Parse(c[1]), @@ -92,6 +91,10 @@ namespace Crow { return new Cairo.Color(c.R, c.G, c.B, c.A); } + public static implicit operator Fill(Color c){ + return new SolidColor (c) as Fill; + } + public static bool operator ==(Color left, Color right) { @@ -147,16 +150,7 @@ namespace Crow { return new Color (this.R, this.G, this.B, _A); } - - #region IFill implementation - - public void SetAsSource (Cairo.Context ctx) - { - ctx.SetSourceRGBA (R, G, B, A); - } - - #endregion - + #region Predefined colors public static readonly Color Transparent = new Color(0, 0, 0, 0, "Transparent"); public static readonly Color Clear = new Color(-1, -1, -1, -1, "Clear"); diff --git a/src/Fill/Fill.cs b/src/Fill/Fill.cs new file mode 100644 index 00000000..322fa5ae --- /dev/null +++ b/src/Fill/Fill.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +namespace Crow +{ + public abstract class Fill + { + public abstract void SetAsSource (Cairo.Context ctx, Rectangle bounds = default(Rectangle)); + public static object Parse (string s){ + if (string.IsNullOrEmpty (s)) + return null; + if (s.Substring (1).StartsWith ("gradient")) + return (Gradient)Gradient.Parse (s); + if (s.EndsWith (".svg", true, System.Globalization.CultureInfo.InvariantCulture)) + return SvgPicture.Parse (s); + if (s.EndsWith (".png", true, System.Globalization.CultureInfo.InvariantCulture) || + s.EndsWith (".jpg", true, System.Globalization.CultureInfo.InvariantCulture) || + s.EndsWith (".jpeg", true, System.Globalization.CultureInfo.InvariantCulture) || + s.EndsWith (".bmp", true, System.Globalization.CultureInfo.InvariantCulture) || + s.EndsWith (".gif", true, System.Globalization.CultureInfo.InvariantCulture)) + return BmpPicture.Parse (s); + + return (SolidColor)SolidColor.Parse (s); + } + + public static implicit operator Fill(Color c){ + return new SolidColor (c); + } + + } +} + diff --git a/src/Gradient.cs b/src/Gradient.cs new file mode 100644 index 00000000..c521fd67 --- /dev/null +++ b/src/Gradient.cs @@ -0,0 +1,130 @@ +// +// Gradient.cs +// +// Author: +// Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// Copyright (c) 2016 jp +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +using System; +using System.Collections.Generic; + +namespace Crow +{ + public class Gradient : Fill + { + public enum Type + { + Vertical, + Horizontal, + Oblic, + Radial + } + public class ColorStop + { + public double Offset; + public Color Color; + + public ColorStop(double offset, Color color){ + Offset = offset; + Color = color; + } + public static object Parse(string s) + { + if (string.IsNullOrEmpty (s)) + return null; + + string[] parts = s.Trim ().Split (':'); + + if (parts.Length > 2) + throw new Exception ("too many parameters in color stop: " + s); + + if (parts.Length == 2) + return new ColorStop (double.Parse (parts [0]), (Color)parts [1]); + + return new ColorStop (-1, (Color)parts [0]); + } + } + public Gradient.Type GradientType = Type.Vertical; +// public double x0; +// public double y0; +// public double x1; +// public double y1; +// public double Radius1; +// public double Radius2; + public List<ColorStop> Stops = new List<ColorStop>(); + public Gradient(Gradient.Type _type) + { + GradientType = _type; + } + + #region implemented abstract members of Fill + + public override void SetAsSource (Cairo.Context ctx, Rectangle bounds = default(Rectangle)) + { + Cairo.Gradient grad = null; + switch (GradientType) { + case Type.Vertical: + grad = new Cairo.LinearGradient (bounds.Left, bounds.Top, bounds.Left, bounds.Bottom); + break; + case Type.Horizontal: + grad = new Cairo.LinearGradient (bounds.Left, bounds.Top, bounds.Right, bounds.Top); + break; + case Type.Oblic: + grad = new Cairo.LinearGradient (bounds.Left, bounds.Top, bounds.Right, bounds.Bottom); + break; + case Type.Radial: + throw new NotImplementedException (); + } + + foreach (ColorStop cs in Stops) + grad.AddColorStop (cs.Offset, cs.Color); + + ctx.SetSource (grad); + grad.Dispose (); + } + #endregion + + public static object Parse(string s) + { + if (string.IsNullOrEmpty (s)) + return Color.White; + + Crow.Gradient tmp; + + string[] stops = s.Trim ().Split ('|'); + + switch (stops[0].Trim()) { + case "vgradient": + tmp = new Gradient (Type.Vertical); + break; + case "hgradient": + tmp = new Gradient (Type.Horizontal); + break; + case "ogradient": + tmp = new Gradient (Type.Oblic); + break; + default: + throw new Exception ("Unknown gradient type: " + stops [0]); + } + + for (int i = 1; i < stops.Length; i++) + tmp.Stops.Add((ColorStop)ColorStop.Parse(stops[i])); + + return tmp; + } + } +} + diff --git a/src/GraphicObjects/AnalogMeter.cs b/src/GraphicObjects/AnalogMeter.cs index 39e012dd..80e0e850 100644 --- a/src/GraphicObjects/AnalogMeter.cs +++ b/src/GraphicObjects/AnalogMeter.cs @@ -34,7 +34,7 @@ namespace Crow gr.Translate (-m.X, -m.Y); gr.LineWidth = 2; - gr.Color = Foreground; + Foreground.SetAsSource (gr); gr.MoveTo (m.X,0.0); gr.LineTo (m.X, -m.Y*0.5); gr.Stroke (); diff --git a/src/GraphicObjects/Border.cs b/src/GraphicObjects/Border.cs index c04a135e..58ccff33 100644 --- a/src/GraphicObjects/Border.cs +++ b/src/GraphicObjects/Border.cs @@ -25,7 +25,7 @@ namespace Crow } } [XmlAttributeAttribute()][DefaultValue("White")] - public override Color Foreground { + public override Fill Foreground { get { return base.Foreground;} set {base.Foreground = value;} } @@ -52,13 +52,13 @@ namespace Crow if (BorderWidth > 0) rBack.Inflate (-BorderWidth / 2); - gr.SetSourceColor(Background); - CairoHelpers.CairoRectangle(gr,rBack,CornerRadius); + Background.SetAsSource (gr, rBack); + CairoHelpers.CairoRectangle(gr, rBack, CornerRadius); gr.Fill (); if (BorderWidth > 0) { gr.LineWidth = BorderWidth; - gr.SetSourceColor(Foreground); + Foreground.SetAsSource (gr, rBack); CairoHelpers.CairoRectangle(gr, rBack, CornerRadius); gr.Stroke (); } diff --git a/src/GraphicObjects/GraduatedSlider.cs b/src/GraphicObjects/GraduatedSlider.cs index 3d916a8c..b7a181e0 100644 --- a/src/GraphicObjects/GraduatedSlider.cs +++ b/src/GraphicObjects/GraduatedSlider.cs @@ -25,7 +25,7 @@ namespace Crow protected override void DrawGraduations(Context gr, PointD pStart, PointD pEnd) { Rectangle r = ClientRectangle; - gr.SetSourceColor(Foreground); + Foreground.SetAsSource (gr); gr.LineWidth = 2; gr.MoveTo(pStart); diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index 5613c0c9..7fd0e1ca 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -66,8 +66,8 @@ namespace Crow #region private fields ILayoutable _parent; string _name = "unamed"; - Color _background = Color.Transparent; - Color _foreground = Color.White; + Fill _background = Color.Transparent; + Fill _foreground = Color.White; Font _font = "droid, 10"; double _cornerRadius = 0; int _margin = 0; @@ -79,9 +79,6 @@ namespace Crow HorizontalAlignment _horizontalAlignment = HorizontalAlignment.Center; Size _maximumSize = "0;0"; Size _minimumSize = "0;0"; - - Picture _backgroundImage; - string _backgroundImagePath; #endregion #region public fields @@ -278,7 +275,7 @@ namespace Crow } } [XmlAttributeAttribute()][DefaultValue("Transparent")] - public virtual Color Background { + public virtual Fill Background { get { return _background; } set { if (_background == value) @@ -289,7 +286,7 @@ namespace Crow } } [XmlAttributeAttribute()][DefaultValue("White")] - public virtual Color Foreground { + public virtual Fill Foreground { get { return _foreground; } set { if (_foreground == value) @@ -415,7 +412,6 @@ namespace Crow name = xaa.AttributeName; continue; } - XmlIgnoreAttribute xia = o as XmlIgnoreAttribute; if (xia != null) continue; @@ -707,7 +703,7 @@ namespace Crow { Rectangle rBack = new Rectangle (Slot.Size); - Background.SetAsSource (gr); + Background.SetAsSource (gr, rBack); CairoHelpers.CairoRectangle(gr,rBack,_cornerRadius); gr.Fill (); } @@ -747,12 +743,15 @@ namespace Crow Rectangle rb = Parent.ContextCoordinates(Slot); using (ImageSurface source = new ImageSurface(bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) { - if (this.Background == Color.Clear) { - ctx.Save (); - ctx.Operator = Operator.Clear; - ctx.Rectangle(rb); - ctx.Fill (); - ctx.Restore (); + //TODO:improve equality test for basic color and Fill + if (this.Background is SolidColor) { + if ((this.Background as SolidColor).Equals(Color.Clear)) { + ctx.Save (); + ctx.Operator = Operator.Clear; + ctx.Rectangle (rb); + ctx.Fill (); + ctx.Restore (); + } } ctx.SetSourceSurface (source, rb.X, rb.Y); ctx.Paint (); @@ -1146,16 +1145,16 @@ namespace Crow il.Emit(OpCodes.Ldstr,strcst); }else{ - //search for a static field in left operand type named 'rop name' - FieldInfo ropFi = lopT.GetField (rop, BindingFlags.Static|BindingFlags.Public); - if (ropFi != null) - { - il.Emit (OpCodes.Ldsfld, ropFi); - }else{ - //search if parsing methods are present - MethodInfo lopTryParseMi = lopT.GetMethod("TryParse"); - //TODO - } + if (lopT.IsEnum) + throw new NotImplementedException(); + + MethodInfo lopParseMi = lopT.GetMethod("Parse"); + if (lopParseMi == null) + throw new Exception (string.Format + ("GOML:no parse method found in: {0}", lopT.Name)); + il.Emit(OpCodes.Ldstr, rop); + il.Emit(OpCodes.Callvirt, lopParseMi); + il.Emit(OpCodes.Unbox_Any, lopT); } #endregion diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index e03399e9..087cd38d 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -188,8 +188,9 @@ namespace Crow protected override void onDraw (Context gr) { Rectangle rBack = new Rectangle (Slot.Size); - gr.SetSourceColor(Background); - CairoHelpers.CairoRectangle(gr,rBack,CornerRadius); + + Background.SetAsSource (gr, rBack); + CairoHelpers.CairoRectangle(gr, rBack, CornerRadius); gr.Fill (); foreach (GraphicObject g in Children) { @@ -225,9 +226,10 @@ namespace Crow clip.clearAndClip (gr); Rectangle rBack = Slot.Size; - gr.SetSourceColor(Background); - CairoHelpers.CairoRectangle(gr,rBack,CornerRadius); + Background.SetAsSource (gr, rBack); + CairoHelpers.CairoRectangle(gr, rBack, CornerRadius); gr.Fill (); + #if DEBUG_CLIP_RECTANGLE clip.stroke (gr, Color.Amaranth.AdjustAlpha (0.8)); #endif diff --git a/src/GraphicObjects/Label.cs b/src/GraphicObjects/Label.cs index 0b93924a..ee7dd045 100644 --- a/src/GraphicObjects/Label.cs +++ b/src/GraphicObjects/Label.cs @@ -106,7 +106,7 @@ namespace Crow this.registerForGraphicUpdate (); this.RegisterForLayouting ((int)LayoutingType.Sizing); - NotifyValueChanged ("Text", Text); + NotifyValueChanged ("Text", _text); } } [XmlAttributeAttribute()][DefaultValue(false)] @@ -122,7 +122,8 @@ namespace Crow registerForGraphicUpdate(); } } - [XmlIgnore]public int CurrentColumn{ + [XmlAttributeAttribute()][DefaultValue(0)] + public int CurrentColumn{ get { return _currentCol; } set { if (value == _currentCol) @@ -136,7 +137,8 @@ namespace Crow NotifyValueChanged ("CurrentColumn", _currentCol); } } - [XmlIgnore]public int CurrentLine{ + [XmlAttributeAttribute()][DefaultValue(0)] + public int CurrentLine{ get { return _currentLine; } set { if (value == _currentLine) @@ -150,7 +152,9 @@ namespace Crow NotifyValueChanged ("CurrentLine", _currentLine); } } - [XmlIgnore]public Point SelBegin { + //TODO:using HasFocus for drawing selection cause SelBegin and Release binding not to work + [XmlAttributeAttribute()][DefaultValue("-1")] + public Point SelBegin { get { return _selBegin; } @@ -158,10 +162,12 @@ namespace Crow if (value == _selBegin) return; _selBegin = value; + NotifyValueChanged ("SelBegin", _selBegin); NotifyValueChanged ("SelectedText", SelectedText); } } - [XmlIgnore]public Point SelRelease { + [XmlAttributeAttribute()][DefaultValue("-1")] + public Point SelRelease { get { return _selRelease; } @@ -169,6 +175,7 @@ namespace Crow if (value == _selRelease) return; _selRelease = value; + NotifyValueChanged ("SelRelease", _selRelease); NotifyValueChanged ("SelectedText", SelectedText); } } @@ -228,6 +235,7 @@ namespace Crow CurrentColumn = lines [CurrentLine].Count (); lines [CurrentLine] += lines [CurrentLine + 1]; lines.RemoveAt (CurrentLine + 1); + NotifyValueChanged ("Text", Text); return; } CurrentColumn--; @@ -251,6 +259,7 @@ namespace Crow SelBegin = -1; SelRelease = -1; } + NotifyValueChanged ("Text", Text); } /// <summary> /// Insert new string at caret position, should be sure no line break is inside. @@ -260,6 +269,7 @@ namespace Crow { lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, str); CurrentColumn += str.Length; + NotifyValueChanged ("Text", Text); } #region GraphicObject overrides @@ -483,7 +493,7 @@ namespace Crow if (HasFocus ) { - gr.SetSourceColor(Foreground); + Foreground.SetAsSource (gr); gr.LineWidth = 1.5; gr.MoveTo(new PointD(textCursorPos + rText.X, rText.Y + CurrentLine * fe.Height)); gr.LineTo(new PointD(textCursorPos + rText.X, rText.Y + (CurrentLine + 1) * fe.Height)); @@ -535,7 +545,7 @@ namespace Crow if (string.IsNullOrWhiteSpace (l)) continue; - gr.SetSourceColor(Foreground); + Foreground.SetAsSource (gr); gr.MoveTo (lineRect.X, rText.Y + fe.Ascent + fe.Height * i); #if _WIN32 || _WIN64 diff --git a/src/GraphicObjects/ProgressBar.cs b/src/GraphicObjects/ProgressBar.cs index c8dcbb77..c8165353 100644 --- a/src/GraphicObjects/ProgressBar.cs +++ b/src/GraphicObjects/ProgressBar.cs @@ -68,7 +68,7 @@ namespace Crow #region GraphicObject overrides [XmlAttributeAttribute()][DefaultValue("Gray")] - public override Color Background { + public override Fill Background { get { return base.Background; } set { base.Background = value; } } @@ -78,7 +78,7 @@ namespace Crow set { base.BorderWidth = value; } } [XmlAttributeAttribute()][DefaultValue("BlueCrayola")] - public override Color Foreground { + public override Fill Foreground { get { return base.Foreground; } set { base.Foreground = value; } } @@ -94,7 +94,7 @@ namespace Crow rBack.Width = (int)((double)rBack.Width / Maximum * Value); - gr.SetSourceColor(Foreground); + Foreground.SetAsSource (gr, rBack); CairoHelpers.CairoRectangle(gr,rBack,CornerRadius); gr.Fill(); diff --git a/src/GraphicObjects/Slider.cs b/src/GraphicObjects/Slider.cs index a931934a..f21202a8 100644 --- a/src/GraphicObjects/Slider.cs +++ b/src/GraphicObjects/Slider.cs @@ -32,7 +32,7 @@ namespace Crow #region private fields Rectangle cursor; int _cursorSize; - Color _cursorColor; + Fill _cursorColor; Orientation _orientation; bool holdCursor = false; #endregion @@ -40,33 +40,47 @@ namespace Crow protected double unity; #region Public properties - [XmlAttributeAttribute()][DefaultValue("BlueGray")] - public virtual Color CursorColor { + [XmlAttributeAttribute()][DefaultValue("vgradient|0:White|0,1:SteelBlue|0,9:SteelBlue|1:DimGray")] + public virtual Fill CursorColor { get { return _cursorColor; } set { + if (_cursorColor == value) + return; _cursorColor = value; registerForGraphicUpdate (); + NotifyValueChanged ("CursorColor", _cursorColor); } } [XmlAttributeAttribute()][DefaultValue(20)] public virtual int CursorSize { get { return _cursorSize; } set { + if (_cursorSize == value) + return; _cursorSize = value; + RegisterForLayouting ((int)LayoutingType.Sizing); registerForGraphicUpdate (); + NotifyValueChanged ("CursorSize", _cursorSize); } } [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)] public virtual Orientation Orientation { get { return _orientation; } - set { _orientation = value; } + set { + if (_orientation == value) + return; + _orientation = value; + + RegisterForLayouting ((int)LayoutingType.All); + NotifyValueChanged ("Orientation", _orientation); + } } #endregion [XmlAttributeAttribute()][DefaultValue(10.0)] public override double Maximum { get { return base.Maximum; } - set { + set { if (value == base.Maximum) return; base.Maximum = value; @@ -75,12 +89,18 @@ namespace Crow } } + #region GraphicObject Overrides - [XmlAttributeAttribute()][DefaultValue("Gray")] - public override Color Background { + [XmlAttributeAttribute()][DefaultValue("vgradient|0:Black|0,1:Gray|0,9:Gray|1:LightGray")] + public override Fill Background { get { return base.Background; } set { base.Background = value; } } + [XmlAttributeAttribute()][DefaultValue("Gray")] + public override Fill Foreground { + get { return base.Foreground; } + set { base.Foreground = value; } + } [XmlAttributeAttribute()][DefaultValue(true)] public override bool Focusable { @@ -120,7 +140,7 @@ namespace Crow protected virtual void DrawGraduations(Context gr, PointD pStart, PointD pEnd) { - gr.SetSourceColor(Foreground); + Foreground.SetAsSource (gr); gr.LineWidth = 1; gr.MoveTo(pStart); @@ -131,9 +151,9 @@ namespace Crow } protected virtual void DrawCursor(Context gr, Rectangle _cursor) { - gr.SetSourceColor(CursorColor); + CursorColor.SetAsSource (gr, _cursor); CairoHelpers.CairoRectangle (gr, _cursor, CornerRadius); - gr.FillPreserve(); + gr.Fill(); } void computeCursorPosition() diff --git a/src/GraphicObjects/TextBox.cs b/src/GraphicObjects/TextBox.cs index 6af75f1e..d9003b61 100644 --- a/src/GraphicObjects/TextBox.cs +++ b/src/GraphicObjects/TextBox.cs @@ -45,12 +45,12 @@ namespace Crow set { base.Focusable = value; } } [XmlAttributeAttribute()][DefaultValue("White")] - public override Color Background { + public override Fill Background { get { return base.Background; } set { base.Background = value; } } [XmlAttributeAttribute()][DefaultValue("Black")] - public override Color Foreground { + public override Fill Foreground { get { return base.Foreground; } set { base.Foreground = value; } } diff --git a/src/GraphicObjects/TextRun.cs b/src/GraphicObjects/TextRun.cs index 1c539c67..bee580b3 100644 --- a/src/GraphicObjects/TextRun.cs +++ b/src/GraphicObjects/TextRun.cs @@ -313,7 +313,7 @@ namespace Crow continue; } - gr.SetSourceColor (Foreground); + Foreground.SetAsSource (gr); gr.MoveTo (rText.X, rText.Y + fe.Ascent + fe.Height * curLineCount); #if _WIN32 || _WIN64 diff --git a/src/Picture.cs b/src/Picture.cs index c1d83061..6e928e6c 100644 --- a/src/Picture.cs +++ b/src/Picture.cs @@ -24,7 +24,7 @@ using Cairo; namespace Crow { - public abstract class Picture + public abstract class Picture : Fill { public string Path; public Size Dimensions; diff --git a/src/Point.cs b/src/Point.cs index 369cf01d..76beaa99 100644 --- a/src/Point.cs +++ b/src/Point.cs @@ -130,7 +130,7 @@ namespace Crow public override string ToString() { - return string.Format("({0},{1})", X, Y); + return string.Format("({0};{1})", X, Y); } public override bool Equals(object obj) @@ -141,6 +141,19 @@ namespace Crow { return base.GetHashCode(); } + public static Point Parse(string s) + { + if (string.IsNullOrEmpty (s)) + return default(Point); + string[] d = s.Trim().Split(';'); + if (d.Length == 2) + return new Point (int.Parse (d [0]), int.Parse (d [1])); + else if (d.Length == 1) { + int tmp = int.Parse (d [0]); + return new Point (tmp, tmp); + } + throw new Exception ("Crow.Point Parsing Error: " + s); + } } } diff --git a/src/Rectangle.cs b/src/Rectangle.cs index ea410ff3..c0b98520 100644 --- a/src/Rectangle.cs +++ b/src/Rectangle.cs @@ -233,10 +233,7 @@ namespace Crow } } - public static Rectangle Zero - { - get { return new Rectangle(0, 0, 0, 0); } - } + public static readonly Rectangle Zero = new Rectangle(0, 0, 0, 0); public static Rectangle Empty { get { return Zero; } diff --git a/src/SolidColor.cs b/src/SolidColor.cs new file mode 100644 index 00000000..7a1178cc --- /dev/null +++ b/src/SolidColor.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Serialization; +using System.Reflection; +using System.Diagnostics; + + + +namespace Crow +{ + public class SolidColor : Fill + { + Color color = Color.Transparent; + #region CTOR + public SolidColor(Color c) + { + color = c; + } + #endregion + + #region implemented abstract members of Fill + + public override void SetAsSource (Cairo.Context ctx, Rectangle bounds = default(Rectangle)) + { + ctx.SetSourceRGBA (color.R, color.G, color.B, color.A); + } + public static object Parse(string s) + { + return new SolidColor((Color)s); + } + #endregion + + #region Operators + public static implicit operator Color(SolidColor c) + { + return c.color; + } + public static implicit operator SolidColor(Color c) + { + return new SolidColor (c); + } + public static bool operator ==(SolidColor left, SolidColor right) + { + return left.color == right.color ? true : false; + } + public static bool operator !=(SolidColor left, SolidColor right) + { + return left.color == right.color ? false : true; + + } + public override bool Equals (object obj) + { + if (obj is Crow.Color) + return color == (Color)obj; + if (obj is SolidColor) + return color == (obj as SolidColor).color; + return false; + } +// public static bool operator ==(SolidColor c, string n) +// { +// return c.color.Name == n ? true : false; +// } +// public static bool operator !=(SolidColor c, string n) +// { +// return c.color.Name == n ? false : true; +// } +// public static bool operator ==(string n, SolidColor c) +// { +// return c.color.Name == n ? true : false; +// } +// public static bool operator !=(string n, SolidColor c) +// { +// return c.color.Name == n ? false : true; +// } + public static SolidColor operator *(SolidColor c, Double f) + { + return new SolidColor(new Color(c.color.R,c.color.G,c.color.B,c.color.A * f)); + } + public static SolidColor operator +(SolidColor c1, SolidColor c2) + { + return new SolidColor(new Color(c1.color.R + c2.color.R,c1.color.G + c2.color.G,c1.color.B + c2.color.B,c1.color.A + c2.color.A)); + } + public static SolidColor operator -(SolidColor c1, SolidColor c2) + { + return new SolidColor(new Color(c1.color.R - c2.color.R,c1.color.G - c2.color.G,c1.color.B - c2.color.B,c1.color.A - c2.color.A)); + } + #endregion + + public override string ToString() + { + return color.ToString (); + } + } +} diff --git a/src/SvgPicture.cs b/src/SvgPicture.cs index 38781a1c..19ace4db 100644 --- a/src/SvgPicture.cs +++ b/src/SvgPicture.cs @@ -41,6 +41,38 @@ namespace Crow Dimensions = new Size (hSVG.Dimensions.Width, hSVG.Dimensions.Height); } } + + #region implemented abstract members of Fill + + public override void SetAsSource (Context ctx, Rectangle bounds = default(Rectangle)) + { + float widthRatio = 1f; + float heightRatio = 1f; + + if (Scaled){ + widthRatio = (float)bounds.Width / Dimensions.Width; + heightRatio = (float)bounds.Height / Dimensions.Height; + } + + if (KeepProportions) { + if (widthRatio < heightRatio) + heightRatio = widthRatio; + else + widthRatio = heightRatio; + } + + using (ImageSurface tmp = new ImageSurface (Format.Argb32, bounds.Width, bounds.Height)) { + using (Cairo.Context gr = new Context (tmp)) { + gr.Translate (bounds.Left, bounds.Top); + gr.Scale (widthRatio, heightRatio); + gr.Translate ((bounds.Width/widthRatio - Dimensions.Width)/2, (bounds.Height/heightRatio - Dimensions.Height)/2); + + hSVG.RenderCairo (gr); + } + ctx.SetSource (tmp); + } + } + #endregion public override void Paint (Cairo.Context gr, Rectangle rect, string subPart = "") { @@ -64,10 +96,6 @@ namespace Crow gr.Scale (widthRatio, heightRatio); gr.Translate (((float)rect.Width/widthRatio - Dimensions.Width)/2f, ((float)rect.Height/heightRatio - Dimensions.Height)/2f); - if (string.IsNullOrEmpty (subPart)) - hSVG.RenderCairo (gr); - else - hSVG.RenderCairoSub (gr, "#" + subPart); gr.Restore (); } } |