//============================================================= /// <summary> /// recalculate margin /// </summary> /// <param name="margin">marin side</param> /// <param name="cbWidth">width of containging block</param> /// <returns></returns> float RecalculateMargin(CssLength margin, float cbWidth) { //www.w3.org/TR/CSS2/box.html#margin-properties if (margin.IsAuto) { return(0); } return(CssValueParser.ConvertToPx(margin, cbWidth, this)); }
private static CssLength TranslateLength(CssLength len) { if (len.HasError) { //if unknown unit number return(CssLength.MakePixelLength(len.Number)); } return(len); }
internal EwfTableFieldOrItemSetup( ElementClassSet classes, CssLength size, TextAlignment textAlignment, TableCellVerticalAlignment verticalAlignment, ElementActivationBehavior activationBehavior) { Classes = classes ?? ElementClassSet.Empty; Size = size; TextAlignment = textAlignment; VerticalAlignment = verticalAlignment; ActivationBehavior = activationBehavior; }
/// <summary> /// Converts an HTML length into a Css length /// </summary> /// <param name="htmlLength"></param> /// <returns></returns> public static CssLength TranslateLength(string htmlLength) { CssLength len = ParseGenericLength(htmlLength); if (len.HasError) { return(CssLength.MakePixelLength(0)); } return(len); }
/// <summary> /// recalculate padding /// </summary> /// <param name="padding"></param> /// <param name="cbWidth"></param> /// <returns></returns> float RecalculatePadding(CssLength padding, float cbWidth) { //www.w3.org/TR/CSS2/box.html#padding-properties if (padding.IsAuto) { return(0); } return(CssValueParser.ConvertToPx(padding, cbWidth, this)); }
static CssLength SetLineHeight(this CssBox box, CssLength len) { //2014,2015, //from www.w3c.org/wiki/Css/Properties/line-height //line height in <percentage> : //The computed value if the property is percentage multiplied by the //element's computed font size. return(CssLength.MakePixelLength( CssValueParser.ConvertToPx(len, box.GetEmHeight(), box))); }
/// <summary> /// Converts an HTML length into a Css length /// </summary> /// <param name="htmlLength"></param> /// <returns></returns> private string TranslateLength(string htmlLength) { CssLength len = new CssLength(htmlLength); if (len.HasError) { return(htmlLength + "px"); } return(htmlLength); }
/// <summary> /// Converts an HTML length into a Css length /// </summary> /// <param name="htmlLength"></param> /// <returns></returns> private static string TranslateLength(string htmlLength) { CssLength len = new CssLength(htmlLength); if (len.HasError) { return(string.Format(NumberFormatInfo.InvariantInfo, "{0}px", htmlLength)); } return(htmlLength); }
private EwfTableItemSetup( ElementClassSet classes, CssLength size, TextAlignment textAlignment, TableCellVerticalAlignment verticalAlignment, ElementActivationBehavior activationBehavior, SpecifiedValue <int> id, int?rankId) : base( classes, size, textAlignment, verticalAlignment, activationBehavior, id, rankId) { }
/// <summary> /// Get top-left location to start drawing the image at depending on background-position value. /// </summary> /// <param name="backgroundPosition">the background-position value</param> /// <param name="rectangle">the rectangle to position image in</param> /// <param name="imgSize">the size of the image</param> /// <returns>the top-left location</returns> static Point GetLocation(CssLength posX, CssLength posY, RectangleF rectangle, Size imgSize) { int left = (int)rectangle.Left; int top = (int)rectangle.Top; if (posX.IsBackgroundPositionName) { switch (posX.UnitOrNames) { case CssUnitOrNames.LEFT: { left = (int)(rectangle.Left + .5f); } break; case CssUnitOrNames.RIGHT: { left = (int)rectangle.Right - imgSize.Width; } break; } } else { //not complete ! left = (int)(rectangle.Left + (rectangle.Width - imgSize.Width) / 2 + .5f); } if (posY.IsBackgroundPositionName) { switch (posY.UnitOrNames) { case CssUnitOrNames.TOP: { top = (int)rectangle.Top; } break; case CssUnitOrNames.BOTTOM: { top = (int)rectangle.Bottom - imgSize.Height; } break; } } else { //not complete ! top = (int)(rectangle.Top + (rectangle.Height - imgSize.Height) / 2 + .5f); } return(new Point(left, top)); }
public static string ToFontSizeString(this CssLength length) { if (length.IsFontSizeName) { switch (length.UnitOrNames) { case CssUnitOrNames.FONTSIZE_MEDIUM: return(CssConstants.Medium); case CssUnitOrNames.FONTSIZE_SMALL: return(CssConstants.Small); case CssUnitOrNames.FONTSIZE_X_SMALL: return(CssConstants.XSmall); case CssUnitOrNames.FONTSIZE_XX_SMALL: return(CssConstants.XXSmall); case CssUnitOrNames.FONTSIZE_LARGE: return(CssConstants.Large); case CssUnitOrNames.FONTSIZE_X_LARGE: return(CssConstants.XLarge); case CssUnitOrNames.FONTSIZE_XX_LARGE: return(CssConstants.XXLarge); case CssUnitOrNames.FONTSIZE_LARGER: return(CssConstants.Larger); case CssUnitOrNames.FONTSIZE_SMALLER: return(CssConstants.Smaller); default: return(""); } } else { return(length.ToString()); } }
public static float GetActualBorderWidth(CssLength borderValue, CssBox b) { //------------------------------ //plan: use extended cssunit //------------------------------ switch (borderValue.UnitOrNames) { case CssUnitOrNames.EmptyValue: //as medium case CssUnitOrNames.BorderMedium: return(2f); case CssUnitOrNames.BorderThin: return(1f); case CssUnitOrNames.BorderThick: return(4f); default: return(Math.Abs(ConvertToPx(borderValue, 1, b))); } }
public ActionResult UsingLayout() { var fileManager = new FileManager { Width = CssLength.Percentage(100), DisplayLanguage = "en" }; fileManager.RootFolders.Add(new FileManagerRootFolder { Name = "Root Folder 1", Location = "~/App_Data/RootFolder1" }); fileManager.RootFolders[0].AccessControls.Add(new FileManagerAccessControl { Path = @"\", AllowedPermissions = FileManagerPermissions.Full }); return(View(fileManager)); }
private FileManager GetFileManagerModel() { var fileManager = new FileManager { Width = CssLength.Percentage(100), DisplayLanguage = "en" }; fileManager.RootFolders.Add(new FileManagerRootFolder { Name = "Root Folder 1", Location = "~/App_Data/RootFolder1" }); fileManager.RootFolders[0].AccessControls.Add(new FileManagerAccessControl { Path = @"\", AllowedPermissions = FileManagerPermissions.Full }); return(fileManager); }
public static float ConvertToPx(CssLength length, ref ReEvaluateArgs args) { //Return zero if no length specified, zero specified switch (length.UnitOrNames) { case CssUnitOrNames.EmptyValue: return(0); case CssUnitOrNames.Percent: return((length.Number / 100f) * args.containerW); case CssUnitOrNames.Ems: return(length.Number * args.emHeight); case CssUnitOrNames.Ex: return(length.Number * (args.emHeight / 2)); case CssUnitOrNames.Pixels: //atodo: check support for hi dpi return(length.Number); case CssUnitOrNames.Milimeters: return(length.Number * 3.779527559f); //3 pixels per millimeter case CssUnitOrNames.Centimeters: return(length.Number * 37.795275591f); //37 pixels per centimeter case CssUnitOrNames.Inches: return(length.Number * 96f); //96 pixels per inch case CssUnitOrNames.Points: return(length.Number * (96f / 72f)); // 1 point = 1/72 of inch case CssUnitOrNames.Picas: return(length.Number * 16f); // 1 pica = 12 points default: return(0); } }
public static float ConvertToPxWithFontAdjust(CssLength length, float hundredPercent, CssBox box) { //Return zero if no length specified, zero specified switch (length.UnitOrNames) { case CssUnitOrNames.EmptyValue: return(0); case CssUnitOrNames.Percent: return((length.Number / 100f) * hundredPercent); case CssUnitOrNames.Ems: return(length.Number * box.GetEmHeight()); case CssUnitOrNames.Ex: return(length.Number * (box.GetEmHeight() / 2)); case CssUnitOrNames.Pixels: //atodo: check support for hi dpi return(length.Number * (72f / 96f)); //font adjust case CssUnitOrNames.Milimeters: return(length.Number * 3.779527559f); //3 pixels per millimeter case CssUnitOrNames.Centimeters: return(length.Number * 37.795275591f); //37 pixels per centimeter case CssUnitOrNames.Inches: return(length.Number * 96f); //96 pixels per inch case CssUnitOrNames.Points: return(length.Number * (96f / 72f)); // 1 point = 1/72 of inch case CssUnitOrNames.Picas: return(length.Number * 16f); // 1 pica = 12 points default: return(0); } }
public static CssLength AsTranslatedLength(this WebDom.CssCodeValueExpression value) { if (value.EvaluatedAs != WebDom.CssValueEvaluatedAs.TranslatedLength) { switch (value.Hint) { case WebDom.CssValueHint.Number: { if (value is WebDom.CssCodePrimitiveExpression) { WebDom.CssCodePrimitiveExpression prim = (WebDom.CssCodePrimitiveExpression)value; CssLength len = new CssLength(value.AsNumber(), GetCssUnit(prim.Unit)); if (len.HasError) { len = CssLength.MakePixelLength(0); } value.SetCssLength(len, WebDom.CssValueEvaluatedAs.TranslatedLength); return(len); } else { CssLength len = CssLength.MakePixelLength(value.AsNumber()); value.SetCssLength(len, WebDom.CssValueEvaluatedAs.TranslatedLength); return(len); } } default: { CssLength len = TranslateLength(value.ToString()); value.SetCssLength(len, WebDom.CssValueEvaluatedAs.TranslatedLength); return(len); } } } return(value.GetCacheCssLength()); }
public void Add(string text, float value, CssLength cssLength) { Add(text, new CssLenghtUnit(value, cssLength)); }
internal Tuple <ComponentListItem, FlowComponentOrNode> GetItemAndComponent( ElementClassSet classes, CssLength width, bool includeContentContainer = false) { return(Tuple.Create(this, componentGetter(includeContentContainer, classes, width))); }
/// <summary> /// Ensures that the specified length is converted to pixels if necessary /// </summary> /// <param name="length"></param> protected string NoEms(string length) { var len = new CssLength(length); if (len.Unit == CssUnit.Ems) { length = len.ConvertEmToPixels(GetEmHeight()).ToString(); } return length; }
// unique characters used in length units: a, b, c, d, e, h, i, l, m, n, p, Q, r, t, v, w, x public static CssLenghtUnit Parse(string text) { var state = State.NumberBeforeDot; string number = ""; string unitName = ""; foreach (char c in text) { if (state == State.NumberBeforeDot) { // e E if (c == '-' || c == '+' || char.IsDigit(c)) { number += c; continue; } if (c == '.') { number += c; state = State.NumberAfterDot; continue; } } if (state == State.NumberAfterDot) { if (char.IsDigit(c)) { number += c; continue; } if (c == 'e' || c == 'E') { number += c; state = State.NumberAfterExponent; continue; } } if (state == State.NumberAfterExponent) { if (char.IsDigit(c)) { number += c; continue; } } if (c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' || c == 'h' || c == 'i' || c == 'l' || c == 'm' || c == 'n' || c == 'p' || c == 'Q' || c == 'r' || c == 't' || c == 'v' || c == 'w' || c == 'x') { if (state != State.Unit) { state = State.Unit; } unitName += c; continue; } throw new ArgumentException(""); } if (!float.TryParse(number, out float value)) { throw new ArgumentException("incorrect number"); // TODO } if (!_unitByName.ContainsKey(unitName)) { throw new ArgumentException("incorrect unit"); // TODO } CssLength unit = _unitByName[unitName]; return(new CssLenghtUnit(value, unit, text)); }
public CssLenghtUnit(float value, CssLength unit, string text = null) { Value = value; Unit = unit; _text = text; }
/// <summary> /// Creates a table field. /// </summary> /// <param name="classes">The classes. When used on a column, sets the classes on every cell since most styles don't work on col elements.</param> /// <param name="size">The height or width. For an EWF table, this is the column width. For a column primary table, this is the row height. If you specify /// percentage widths for some or all columns in a table, these values need not add up to 100; they will be automatically scaled if necessary. The automatic /// scaling will not happen if there are any columns without a specified width.</param> /// <param name="textAlignment">The text alignment of the cells in this field.</param> /// <param name="verticalAlignment">The vertical alignment of the cells in this field.</param> /// <param name="activationBehavior">The activation behavior.</param> public EwfTableField( ElementClassSet classes = null, CssLength size = null, TextAlignment textAlignment = TextAlignment.NotSpecified, TableCellVerticalAlignment verticalAlignment = TableCellVerticalAlignment.NotSpecified, ElementActivationBehavior activationBehavior = null) { FieldOrItemSetup = new EwfTableFieldOrItemSetup(classes, size, textAlignment, verticalAlignment, activationBehavior); }
public void SetCssLength(CssLength len, WebDom.CssValueEvaluatedAs evalAs) { _cachedLength = len; _evaluatedAs = evalAs; }
/// <summary> /// Converts an HTML length into a Css length /// </summary> /// <param name="htmlLength"></param> /// <returns></returns> private static string TranslateLength(string htmlLength) { CssLength len = new CssLength(htmlLength); if (len.HasError) { return string.Format(NumberFormatInfo.InvariantInfo, "{0}px", htmlLength); } return htmlLength; }
/// <summary> /// Gets the available width for the whole table. /// It also sets the value of WidthSpecified /// </summary> /// <returns></returns> /// <remarks> /// The table's width can be larger than the result of this method, because of the minimum /// size that individual boxes. /// </remarks> private float GetMaxTableWidth() { var tblen = new CssLength(_tableBox.MaxWidth); if (tblen.Number > 0) { _widthSpecified = true; return tblen.IsPercentage ? CssValueParser.ParseNumber(tblen.Length, _tableBox.ParentBox.AvailableWidth) : tblen.Number; } else { return 9999f; } }
/// <summary> /// Measure image box size by the width\height set on the box and the actual rendered image size.<br/> /// If no image exists for the box error icon will be set. /// </summary> /// <param name="imageWord">the image word to measure</param> public static void MeasureImageSize(CssRectImage imageWord) { ArgChecker.AssertArgNotNull(imageWord, "imageWord"); ArgChecker.AssertArgNotNull(imageWord.OwnerBox, "imageWord.OwnerBox"); var width = new CssLength(imageWord.OwnerBox.Width); var height = new CssLength(imageWord.OwnerBox.Height); bool hasImageTagWidth = width.Number > 0 && width.Unit == CssUnit.Pixels; bool hasImageTagHeight = height.Number > 0 && height.Unit == CssUnit.Pixels; bool scaleImageHeight = false; if (hasImageTagWidth) { imageWord.Width = width.Number; } else if(width.Number > 0 && width.IsPercentage) { imageWord.Width = width.Number*imageWord.OwnerBox.ContainingBlock.Size.Width; scaleImageHeight = true; } else if (imageWord.Image != null) { imageWord.Width = imageWord.ImageRectangle == Rectangle.Empty ? imageWord.Image.Width : imageWord.ImageRectangle.Width; } else { imageWord.Width = hasImageTagHeight ? height.Number / 1.14f : 20; } var maxWidth = new CssLength(imageWord.OwnerBox.MaxWidth); if (maxWidth.Number > 0) { float maxWidthVal = -1; if (maxWidth.Unit == CssUnit.Pixels) { maxWidthVal = maxWidth.Number; } else if (maxWidth.IsPercentage) { maxWidthVal = maxWidth.Number * imageWord.OwnerBox.ContainingBlock.Size.Width; } if (maxWidthVal > -1 && imageWord.Width > maxWidthVal) { imageWord.Width = maxWidthVal; scaleImageHeight = !hasImageTagHeight; } } if (hasImageTagHeight) { imageWord.Height = height.Number; } else if (imageWord.Image != null) { imageWord.Height = imageWord.ImageRectangle == Rectangle.Empty ? imageWord.Image.Height : imageWord.ImageRectangle.Height; } else { imageWord.Height = imageWord.Width > 0 ? imageWord.Width * 1.14f : 22.8f; } if (imageWord.Image != null) { // If only the width was set in the html tag, ratio the height. if ((hasImageTagWidth && !hasImageTagHeight) || scaleImageHeight) { // Divide the given tag width with the actual image width, to get the ratio. float ratio = imageWord.Width / imageWord.Image.Width; imageWord.Height = imageWord.Image.Height * ratio; } // If only the height was set in the html tag, ratio the width. else if (hasImageTagHeight && !hasImageTagWidth) { // Divide the given tag height with the actual image height, to get the ratio. float ratio = imageWord.Height / imageWord.Image.Height; imageWord.Width = imageWord.Image.Width * ratio; } } imageWord.Height += imageWord.OwnerBox.ActualBorderBottomWidth + imageWord.OwnerBox.ActualBorderTopWidth + imageWord.OwnerBox.ActualPaddingTop + imageWord.OwnerBox.ActualPaddingBottom; }
/// <summary> /// Creates an item setup object with a specified ID type. /// </summary> /// <param name="classes">The classes. When used on a column, sets the classes on every cell since most styles don't work on col elements.</param> /// <param name="size">The height or width. For an EWF table, this is the row height. For a column primary table, this is the column width. If you specify /// percentage widths for some or all columns in a table, these values need not add up to 100; they will be automatically scaled if necessary. The automatic /// scaling will not happen if there are any columns without a specified width.</param> /// <param name="textAlignment">The text alignment of the cells in this item.</param> /// <param name="verticalAlignment">The vertical alignment of the cells in this item.</param> /// <param name="activationBehavior">The activation behavior.</param> /// <param name="id">A value that uniquely identifies this item in table-level and group-level item actions. If you specify this, the item will have a /// checkbox that enables it to be included in the actions.</param> /// <param name="rankId">The rank ID for this item, which is used for item reordering.</param> public static EwfTableItemSetup <IdType> CreateWithIdType <IdType>( ElementClassSet classes = null, CssLength size = null, TextAlignment textAlignment = TextAlignment.NotSpecified, TableCellVerticalAlignment verticalAlignment = TableCellVerticalAlignment.NotSpecified, ElementActivationBehavior activationBehavior = null, SpecifiedValue <IdType> id = null, int?rankId = null) => new EwfTableItemSetup <IdType>(classes, size, textAlignment, verticalAlignment, activationBehavior, id, rankId);
/// <summary> /// On image load process is complete with image or without update the image box. /// </summary> /// <param name="image">the image loaded or null if failed</param> /// <param name="rectangle">the source rectangle to draw in the image (empty - draw everything)</param> /// <param name="async">is the callback was called async to load image call</param> private void OnLoadImageComplete(Image image, Rectangle rectangle, bool async) { _imageWord.Image = image; _imageWord.ImageRectangle = rectangle; _imageLoadingComplete = true; _wordsSizeMeasured = false; if (_imageLoadingComplete && image == null) { SetErrorBorder(); } if (!HtmlContainer.AvoidImagesLateLoading || async) { var width = new CssLength(Width); var height = new CssLength(Height); var layout = (width.Number <= 0 || width.Unit != CssUnit.Pixels) || (height.Number <= 0 || height.Unit != CssUnit.Pixels); HtmlContainer.RequestRefresh(layout); } }
private bool IsLayoutRequired() { var width = new CssLength(Width); var height = new CssLength(Height); return (width.Number <= 0 || width.Unit != CssUnit.Pixels) || (height.Number <= 0 || height.Unit != CssUnit.Pixels); }
/// <summary> /// Converts an HTML length into a Css length /// </summary> /// <param name="htmlLength"></param> /// <returns></returns> private string TranslateLength(string htmlLength) { CssLength len = new CssLength(htmlLength); if (len.HasError) { return htmlLength + "px"; } return htmlLength; }
static void SetFontSize(this BoxSpec box, WebDom.CssCodeValueExpression value) { //number + value WebDom.CssCodePrimitiveExpression primValue = value as WebDom.CssCodePrimitiveExpression; if (primValue == null) { return; } switch (primValue.Hint) { case WebDom.CssValueHint.Number: { //has unit or not //? //or percent ? CssLength len = UserMapUtil.AsLength(primValue); if (len.HasError) { len = CssLength.FontSizeMedium; } box.FontSize = len; } break; case WebDom.CssValueHint.Iden: { switch (primValue.GetTranslatedStringValue()) { default: { throw new NotSupportedException(); } case CssConstants.Medium: box.FontSize = CssLength.FontSizeMedium; break; case CssConstants.Small: box.FontSize = CssLength.FontSizeSmall; break; case CssConstants.XSmall: box.FontSize = CssLength.FontSizeXSmall; break; case CssConstants.XXSmall: box.FontSize = CssLength.FontSizeXXSmall; break; case CssConstants.Large: box.FontSize = CssLength.FontSizeLarge; break; case CssConstants.XLarge: box.FontSize = CssLength.FontSizeLarge; break; case CssConstants.XXLarge: box.FontSize = CssLength.FontSizeLarger; break; case CssConstants.Smaller: box.FontSize = CssLength.FontSizeSmaller; break; case CssConstants.Larger: box.FontSize = CssLength.FontSizeLarger; break; } } break; } }
/// <summary> /// Analyzes the Table and assigns values to this CssTable object. /// To be called from the constructor /// </summary> private void Analyze(Graphics g) { #region Assign box kinds foreach (CssBox box in TableBox.Boxes) { switch (box.Display) { case CssConstants.TableCaption: _caption = box; break; case CssConstants.TableColumn: for (int i = 0; i < GetSpan(box); i++) { Columns.Add(CreateColumn(box)); } break; case CssConstants.TableColumnGroup: if (box.Boxes.Count == 0) { int gspan = GetSpan(box); for (int i = 0; i < gspan; i++) { Columns.Add(CreateColumn(box)); } } else { foreach (CssBox bb in box.Boxes) { int bbspan = GetSpan(bb); for (int i = 0; i < bbspan; i++) { Columns.Add(CreateColumn(bb)); } } } break; case CssConstants.TableFooterGroup: if (FooterBox != null) BodyRows.Add(box); else _footerBox = box; break; case CssConstants.TableHeaderGroup: if (HeaderBox != null) BodyRows.Add(box); else _headerBox = box; break; case CssConstants.TableRow: BodyRows.Add(box); break; case CssConstants.TableRowGroup: foreach (CssBox childBox in box.Boxes) if (childBox.Display == CssConstants.TableRow) BodyRows.Add(childBox); break; } } #endregion #region Gather AllRows if (HeaderBox != null) _allRows.AddRange(HeaderBox.Boxes); _allRows.AddRange(BodyRows); if (FooterBox != null) _allRows.AddRange(FooterBox.Boxes); #endregion #region Insert EmptyBoxes for vertical cell spanning if (!TableBox._tableFixed) { int currow = 0; int curcol = 0; List<CssBox> rows = BodyRows; foreach (CssBox row in rows) { curcol = 0; for(int k = 0; k < row.Boxes.Count ; k++) { CssBox cell = row.Boxes[k]; int rowspan = GetRowSpan(cell); int realcol = GetCellRealColumnIndex(row, cell); //Real column of the cell for (int i = currow + 1; i < currow + rowspan; i++) { int colcount = 0; for (int j = 0; j <= rows[i].Boxes.Count; j++) { if (colcount == realcol) { rows[i].Boxes.Insert(colcount, new CssSpacingBox(TableBox, ref cell, currow)); break; } colcount++; realcol -= GetColSpan(rows[i].Boxes[j]) - 1; } } curcol++; } currow++; } TableBox._tableFixed = true; } #endregion #region Determine Row and Column Count, and ColumnWidths //Rows _rowCount = BodyRows.Count + (HeaderBox != null ? HeaderBox.Boxes.Count : 0) + (FooterBox != null ? FooterBox.Boxes.Count : 0); //Columns if (Columns.Count > 0) { _columnCount = Columns.Count; } else { foreach (CssBox b in AllRows) //Check trhough rows _columnCount = Math.Max(_columnCount, b.Boxes.Count); } //Initialize column widths array _columnWidths = new float[_columnCount]; //Fill them with NaNs for (int i = 0; i < _columnWidths.Length; i++) _columnWidths[i] = float.NaN; float availCellSpace = GetAvailableCellWidth(); if (Columns.Count > 0) { #region Fill ColumnWidths array by scanning column widths for (int i = 0; i < Columns.Count; i++) { CssLength len = new CssLength(Columns[i].Width); //Get specified width if (len.Number > 0) //If some width specified { if (len.IsPercentage)//Get width as a percentage { ColumnWidths[i] = CssValueParser.ParseNumber(Columns[i].Width, availCellSpace); } else if (len.Unit == CssUnit.Pixels || len.Unit == CssUnit.None) { ColumnWidths[i] = len.Number; //Get width as an absolute-pixel value } } } #endregion } else { #region Fill ColumnWidths array by scanning width in table-cell definitions foreach (CssBox row in AllRows) { //Check for column width in table-cell definitions for (int i = 0; i < _columnCount; i++) { if (float.IsNaN(ColumnWidths[i]) && //Check if no width specified for column i < row.Boxes.Count && //And there's a box to check row.Boxes[i].Display == CssConstants.TableCell)//And the box is a table-cell { CssLength len = new CssLength(row.Boxes[i].Width); //Get specified width if (len.Number > 0) //If some width specified { int colspan = GetColSpan(row.Boxes[i]); float flen = 0f; if (len.IsPercentage)//Get width as a percentage { flen = CssValueParser.ParseNumber(row.Boxes[i].Width, availCellSpace); } else if (len.Unit == CssUnit.Pixels || len.Unit == CssUnit.None) { flen = len.Number; //Get width as an absolute-pixel value } flen /= Convert.ToSingle(colspan); for (int j = i; j < i + colspan; j++) { ColumnWidths[j] = flen; } } } } } #endregion } #endregion #region Determine missing Column widths if (WidthSpecified) //If a width was specified, { //Assign NaNs equally with space left after gathering not-NaNs int numberOfNans = 0; float occupedSpace = 0f; //Calculate number of NaNs and occuped space foreach (float t in ColumnWidths) { if (float.IsNaN(t)) numberOfNans++; else occupedSpace += t; } //Determine width that will be assigned to un asigned widths float nanWidth = (availCellSpace - occupedSpace) / Convert.ToSingle(numberOfNans); for (int i = 0; i < ColumnWidths.Length; i++) if (float.IsNaN(ColumnWidths[i])) ColumnWidths[i] = nanWidth; } else { //Assign NaNs using full width float[] maxFullWidths = new float[ColumnWidths.Length]; //Get the maximum full length of NaN boxes foreach (CssBox row in AllRows) { for (int i = 0; i < row.Boxes.Count; i++) { int col = GetCellRealColumnIndex(row, row.Boxes[i]); if (float.IsNaN(ColumnWidths[col]) && i < row.Boxes.Count && GetColSpan(row.Boxes[i]) == 1) { maxFullWidths[col] = Math.Max(maxFullWidths[col], row.Boxes[i].GetFullWidth(g)); } } } for (int i = 0; i < ColumnWidths.Length; i++) if (float.IsNaN(ColumnWidths[i])) ColumnWidths[i] = maxFullWidths[i]; } #endregion #region Reduce widths if necessary int curCol = 0; //While table width is larger than it should, and width is reductable while (GetWidthSum() > GetAvailableWidth() && CanReduceWidth()) { while (!CanReduceWidth(curCol)) curCol++; ColumnWidths[curCol] -= 1f; curCol++; if (curCol >= ColumnWidths.Length) curCol = 0; } #endregion #region Check for minimum sizes (increment widths if necessary) foreach (CssBox row in AllRows) { foreach (CssBox cell in row.Boxes) { int colspan = GetColSpan(cell); int col = GetCellRealColumnIndex(row, cell); int affectcol = col + colspan - 1; if (ColumnWidths[col] < ColumnMinWidths[col]) { float diff = ColumnMinWidths[col] - ColumnWidths[col]; ColumnWidths[affectcol] = ColumnMinWidths[affectcol]; if (col < ColumnWidths.Length - 1) { ColumnWidths[col + 1] -= diff; } } } } #endregion #region Set table padding //Ensure there's no padding TableBox.PaddingLeft = TableBox.PaddingTop = TableBox.PaddingRight = TableBox.PaddingBottom = "0"; #endregion #region Layout cells //Actually layout cells! float startx = TableBox.ClientLeft + HorizontalSpacing; float starty = TableBox.ClientTop + VerticalSpacing; float curx = startx; float cury = starty; float maxRight = startx; float maxBottom = 0f; int currentrow = 0; for (int i = 0; i < AllRows.Count; i++ ) { var row = AllRows[i]; curx = startx; curCol = 0; for (int j = 0; j < row.Boxes.Count; j++) { CssBox cell = row.Boxes[j]; if (curCol >= ColumnWidths.Length) break; int rowspan = GetRowSpan(cell); var columnIndex = GetCellRealColumnIndex(row, cell); float width = GetCellWidth(columnIndex, cell); cell.Location = new PointF(curx, cury); cell.Size = new SizeF(width, 0f); cell.MeasureBounds(g); //That will automatically set the bottom of the cell //Alter max bottom only if row is cell's row + cell's rowspan - 1 CssSpacingBox sb = cell as CssSpacingBox; if (sb != null) { if (sb.EndRow == currentrow) { maxBottom = Math.Max(maxBottom, sb.ExtendedBox.ActualBottom); } } else if (rowspan == 1) { maxBottom = Math.Max(maxBottom, cell.ActualBottom); } maxRight = Math.Max(maxRight, cell.ActualRight); curCol++; curx = cell.ActualRight + HorizontalSpacing; } foreach (CssBox cell in row.Boxes) { CssSpacingBox spacer = cell as CssSpacingBox; if (spacer == null && GetRowSpan(cell) == 1) { cell.ActualBottom = maxBottom; CssLayoutEngine.ApplyCellVerticalAlignment(g, cell); } else if (spacer != null && spacer.EndRow == currentrow) { spacer.ExtendedBox.ActualBottom = maxBottom; CssLayoutEngine.ApplyCellVerticalAlignment(g, spacer.ExtendedBox); } } cury = maxBottom + VerticalSpacing; currentrow++; } TableBox.ActualRight = maxRight + HorizontalSpacing + TableBox.ActualBorderRightWidth; TableBox.ActualBottom = maxBottom + VerticalSpacing + TableBox.ActualBorderBottomWidth; #endregion }
/// <summary> /// Creates a browsing-context setup object. /// </summary> /// <param name="width">The width of the iframe.</param> /// <param name="height">The height of the iframe.</param> public BrowsingContextSetup(ContentBasedLength width = null, ContentBasedLength height = null) { Width = width; Height = height; }
/// <summary> /// Gets the available width for the whole table. /// It also sets the value of <see cref="WidthSpecified"/> /// </summary> /// <returns></returns> /// <remarks> /// The table's width can be larger than the result of this method, because of the minimum /// size that individual boxes. /// </remarks> private float GetAvailableWidth() { CssLength tblen = new CssLength(TableBox.Width); if (tblen.Number > 0) { _widthSpecified = true; if (tblen.IsPercentage) { return CssValueParser.ParseNumber(tblen.Length, TableBox.ParentBox.AvailableWidth); } else { return tblen.Number; } } else { return TableBox.ParentBox.AvailableWidth; } }
/// <summary> /// Determine Row and Column Count, and ColumnWidths /// </summary> /// <returns></returns> private float CalculateCountAndWidth() { //Columns if (_columns.Count > 0) { _columnCount = _columns.Count; } else { foreach (CssBox b in _allRows) _columnCount = Math.Max(_columnCount, b.Boxes.Count); } //Initialize column widths array with NaNs _columnWidths = new float[_columnCount]; for (int i = 0; i < _columnWidths.Length; i++) _columnWidths[i] = float.NaN; float availCellSpace = GetAvailableCellWidth(); if (_columns.Count > 0) { // Fill ColumnWidths array by scanning column widths for (int i = 0; i < _columns.Count; i++) { CssLength len = new CssLength(_columns[i].Width); //Get specified width if (len.Number > 0) //If some width specified { if (len.IsPercentage) //Get width as a percentage { _columnWidths[i] = CssValueParser.ParseNumber(_columns[i].Width, availCellSpace); } else if (len.Unit == CssUnit.Pixels || len.Unit == CssUnit.None) { _columnWidths[i] = len.Number; //Get width as an absolute-pixel value } } } } else { // Fill ColumnWidths array by scanning width in table-cell definitions foreach (CssBox row in _allRows) { //Check for column width in table-cell definitions for (int i = 0; i < _columnCount; i++) { if (float.IsNaN(_columnWidths[i]) && //Check if no width specified for column i < row.Boxes.Count && //And there's a box to check row.Boxes[i].Display == CssConstants.TableCell) //And the box is a table-cell { CssLength len = new CssLength(row.Boxes[i].Width); //Get specified width if (len.Number > 0) //If some width specified { int colspan = GetColSpan(row.Boxes[i]); float flen = 0f; if (len.IsPercentage) //Get width as a percentage { flen = CssValueParser.ParseNumber(row.Boxes[i].Width, availCellSpace); } else if (len.Unit == CssUnit.Pixels || len.Unit == CssUnit.None) { flen = len.Number; //Get width as an absolute-pixel value } flen /= Convert.ToSingle(colspan); for (int j = i; j < i + colspan; j++) { _columnWidths[j] = flen; } } } } } } return availCellSpace; }