private int AdjustCaret(FIGcharacter character, DrawingBoard drawingBoard, int columnOffset, int rowOffset, IDrawingElementBlender blender) { // this is the poor man's fix (again) // character does not have a visual, so we ignore it if (character.Width == 0) { return(columnOffset); } var previousHasNonBlanks = false; for (; ; columnOffset--) { if (!CanDraw(character, drawingBoard, columnOffset - 1, rowOffset, blender, out var hasNonBlanks) || previousHasNonBlanks) { return(columnOffset); } previousHasNonBlanks = hasNonBlanks; } }
/// <summary> /// Determines whether this instance can draw the specified character. /// </summary> /// <param name="character">The character.</param> /// <param name="drawingBoard">The drawing board.</param> /// <param name="columnOffset">The column offset.</param> /// <param name="rowOffset">The row offset.</param> /// <param name="blender">The blender.</param> /// <param name="hasNonBlanks">if set to <c>true</c> [has non spaces].</param> /// <returns> /// <c>true</c> if this instance can draw the specified character; otherwise, <c>false</c>. /// </returns> private bool CanDraw(FIGcharacter character, DrawingBoard drawingBoard, int columnOffset, int rowOffset, IDrawingElementBlender blender, out bool hasNonBlanks) { hasNonBlanks = false; foreach (var element in GetCharacterDrawingElements(character)) { var column = element.Column + columnOffset; var row = element.Row + rowOffset; if (column < 0 || row < 0) { return(false); } // this relies on the fact that element.DrawingElement is never null var under = drawingBoard[column, row]; if (blender.TryBlend(under, element.DrawingElement) is null) { return(false); } if (!(under is null) && !under.IsBlank && !element.DrawingElement.IsBlank) { hasNonBlanks = true; } } return(true); }
/// <summary> /// Initializes a new instance of the <see cref="InverseDrawingElementBlender"/> class. /// </summary> /// <param name="innerDrawingElementBlender">The inner drawing element blender.</param> public InverseDrawingElementBlender(IDrawingElementBlender innerDrawingElementBlender) { _innerDrawingElementBlender = innerDrawingElementBlender; }
/// <summary> /// Draws the specified <see cref="FIGcharacter" /> to <see cref="DrawingBoard" />. /// </summary> /// <param name="character">The character.</param> /// <param name="drawingBoard">The drawing board.</param> /// <param name="columnOffset">The column offset.</param> /// <param name="rowOffset">The row offset.</param> /// <param name="blender">The blender.</param> private void Draw(FIGcharacter character, DrawingBoard drawingBoard, int columnOffset, int rowOffset, IDrawingElementBlender blender) { foreach (var element in GetCharacterDrawingElements(character)) { var column = element.Column + columnOffset; var row = element.Row + rowOffset; drawingBoard[column, row] = blender.TryBlend(drawingBoard[column, row], element.DrawingElement) ?? element.DrawingElement; } }
private static void CheckRenderAsSmall(string literal, string expectedRendering, IDrawingElementBlender blender) { var d = new FIGdriver { Font = LoadSmallFIGfont(), Blender = blender }; d.Write(literal); var r = d.ToString(); Assert.IsTrue(Matches(expectedRendering, r)); }
/// <summary> /// Applies one or another blender (the first that works) /// </summary> /// <param name="a">a.</param> /// <param name="b">The b.</param> /// <returns></returns> public static IDrawingElementBlender Or(this IDrawingElementBlender a, IDrawingElementBlender b) { // TODO: optimize (if a or b is already a MultiDrawingElementBlender) return(new MultiDrawingElementBlender(a, b)); }
/// <summary> /// Inverses the specified blender. Allows to blend if inner blender refuses to. /// </summary> /// <param name="blender">The blender.</param> /// <returns></returns> public static IDrawingElementBlender Inverse(this IDrawingElementBlender blender) { return(new InverseDrawingElementBlender(blender)); }
/// <summary> /// Transforms a blender to a blender without priority (under=over). /// </summary> /// <param name="blender">The blender.</param> /// <returns></returns> public static IDrawingElementBlender WithoutPriority(this IDrawingElementBlender blender) { return(new FlatDrawingElementBlender(blender)); }
/// <summary> /// Initializes a new instance of the <see cref="FlatDrawingElementBlender"/> class. /// </summary> /// <param name="innerDrawingElementBlender">The inner drawing element blender.</param> public FlatDrawingElementBlender(IDrawingElementBlender innerDrawingElementBlender) { _innerDrawingElementBlender = innerDrawingElementBlender; }