示例#1
0
 /// <summary>Set the calculated dimension to the manually set dimension in the passed float array</summary>
 /// <param name="dim">Dimension Container containing the manually set dimension</param>
 /// <param name="dimensions">array of calculated auto values for boxes in the given dimension</param>
 /// <param name="index">position in the array to replace</param>
 private void SetManualDimension(DimensionContainer dim, float[] dimensions, int index)
 {
     if (dim != null && !dim.IsAutoDimension())
     {
         dimensions[index] = dim.dimension;
     }
 }
示例#2
0
 /// <summary>Check if a calculated dimension value needs to be recalculated</summary>
 /// <param name="dim">Dimension container containing min and max dimension info</param>
 /// <param name="dimensions">array of calculated auto values for boxes in the given dimension</param>
 /// <param name="index">position in the array to look at</param>
 /// <returns><c>true</c> if the values in dimensions trigger a recalculation, <c>false</c> otherwise</returns>
 private bool RecalculateIfNecessary(DimensionContainer dim, float[] dimensions, int index)
 {
     if (dim != null)
     {
         if (dimensions[index] < dim.minDimension && dim.IsAutoDimension())
         {
             dim.dimension = dim.minDimension;
             return(true);
         }
         if (dimensions[index] > dim.maxDimension && dim.IsAutoDimension())
         {
             dim.dimension = dim.maxDimension;
             return(true);
         }
     }
     return(false);
 }
示例#3
0
        /// <summary>
        /// See the algorithm detailed at https://www.w3.org/TR/css3-page/#margin-dimension
        /// Divide the available dimension along the A,B and C according to their properties.
        /// </summary>
        /// <param name="dimA">object containing the dimension-related properties of A</param>
        /// <param name="dimB">object containing the dimension-related properties of B</param>
        /// <param name="dimC">object containing the dimension-related properties of C</param>
        /// <param name="availableDimension">maximum available dimension that can be taken up</param>
        /// <returns>float[3] containing the distributed dimensions of A at [0], B at [1] and C at [2]</returns>
        private float[] CalculatePageMarginBoxDimensions(DimensionContainer dimA, DimensionContainer dimB, DimensionContainer
                                                         dimC, float availableDimension)
        {
            float maxContentDimensionA = 0;
            float minContentDimensionA = 0;
            float maxContentDimensionB = 0;
            float minContentDimensionB = 0;
            float maxContentDimensionC = 0;
            float minContentDimensionC = 0;

            float[] dimensions = new float[3];
            if (IsContainerEmpty(dimA) && IsContainerEmpty(dimB) && IsContainerEmpty(dimC))
            {
                return(dimensions);
            }
            //Calculate widths
            //Check if B is present
            if (IsContainerEmpty(dimB))
            {
                //Single box present
                if (IsContainerEmpty(dimA))
                {
                    if (dimC.IsAutoDimension())
                    {
                        //Allocate everything to C
                        dimensions[2] = availableDimension;
                    }
                    else
                    {
                        dimensions[2] = dimC.dimension;
                    }
                }
                else
                {
                    if (IsContainerEmpty(dimC))
                    {
                        if (dimA.IsAutoDimension())
                        {
                            //Allocate everything to A
                            dimensions[0] = availableDimension;
                        }
                        else
                        {
                            dimensions[0] = dimA.dimension;
                        }
                    }
                    else
                    {
                        if (dimA.IsAutoDimension() && dimC.IsAutoDimension())
                        {
                            //Gather input
                            maxContentDimensionA = dimA.maxContentDimension;
                            minContentDimensionA = dimA.minContentDimension;
                            maxContentDimensionC = dimC.maxContentDimension;
                            minContentDimensionC = dimC.minContentDimension;
                            float[] distributedWidths = DistributeDimensionBetweenTwoBoxes(maxContentDimensionA, minContentDimensionA,
                                                                                           maxContentDimensionC, minContentDimensionC, availableDimension);
                            dimensions = new float[] { distributedWidths[0], 0f, distributedWidths[1] };
                        }
                        else
                        {
                            if (!dimA.IsAutoDimension())
                            {
                                dimensions[0] = dimA.dimension;
                            }
                            else
                            {
                                dimensions[0] = availableDimension - dimC.dimension;
                            }
                            if (!dimC.IsAutoDimension())
                            {
                                dimensions[2] = dimC.dimension;
                            }
                            else
                            {
                                dimensions[2] = availableDimension - dimA.dimension;
                            }
                        }
                    }
                }
            }
            else
            {
                //Check for edge cases
                if (!IsContainerEmpty(dimA))
                {
                    if (dimA.IsAutoDimension())
                    {
                        maxContentDimensionA = dimA.maxContentDimension;
                        minContentDimensionA = dimA.minContentDimension;
                    }
                    else
                    {
                        maxContentDimensionA = dimA.dimension;
                        minContentDimensionA = dimA.dimension;
                    }
                }
                if (!IsContainerEmpty(dimC))
                {
                    if (dimC.IsAutoDimension())
                    {
                        maxContentDimensionC = dimC.maxContentDimension;
                        minContentDimensionC = dimC.minContentDimension;
                    }
                    else
                    {
                        maxContentDimensionC = dimC.dimension;
                        minContentDimensionC = dimC.dimension;
                    }
                }
                if (dimB.IsAutoDimension())
                {
                    //Construct box AC
                    float maxContentWidthAC;
                    float minContentWidthAC;
                    maxContentWidthAC = 2 * Math.Max(maxContentDimensionA, maxContentDimensionC);
                    minContentWidthAC = 2 * Math.Max(minContentDimensionA, minContentDimensionC);
                    //Determine width box B
                    maxContentDimensionB = dimB.maxContentDimension;
                    minContentDimensionB = dimB.minContentDimension;
                    float[] distributedDimensions = DistributeDimensionBetweenTwoBoxes(maxContentDimensionB, minContentDimensionB
                                                                                       , maxContentWidthAC, minContentWidthAC, availableDimension);
                    //Determine width boxes A & C
                    float newAvailableDimension = (availableDimension - distributedDimensions[0]) / 2;
                    dimensions = new float[] { newAvailableDimension, distributedDimensions[0], newAvailableDimension };
                }
                else
                {
                    dimensions[1] = dimB.dimension;
                    float newAvailableDimension = (availableDimension - dimensions[1]) / 2;
                    if (newAvailableDimension > float.MaxValue - MinMaxWidthUtils.GetEps())
                    {
                        newAvailableDimension = float.MaxValue - MinMaxWidthUtils.GetEps();
                    }
                    dimensions[0] = Math.Min(maxContentDimensionA, newAvailableDimension) + MinMaxWidthUtils.GetEps();
                    dimensions[2] = Math.Min(maxContentDimensionC, newAvailableDimension) + MinMaxWidthUtils.GetEps();
                }
                SetManualDimension(dimA, dimensions, 0);
                SetManualDimension(dimC, dimensions, 2);
            }
            if (RecalculateIfNecessary(dimA, dimensions, 0) || RecalculateIfNecessary(dimB, dimensions, 1) || RecalculateIfNecessary
                    (dimC, dimensions, 2))
            {
                return(CalculatePageMarginBoxDimensions(dimA, dimB, dimC, availableDimension));
            }
            RemoveNegativeValues(dimensions);
            return(dimensions);
        }
示例#4
0
 private bool IsContainerEmpty(DimensionContainer container)
 {
     return(container == null || Math.Abs(container.maxContentDimension) < EPSILON);
 }
示例#5
0
        private void DetermineSizes(int side)
        {
            float[][] marginsBordersPaddingsWidths = new float[][] { new float[4], new float[4], new float[4] };
            for (int i = 0; i < 3; i++)
            {
                if (renderers[side * 4 + i + 1] != null)
                {
                    marginsBordersPaddingsWidths[i][0] = GetSizeOfOneSide(renderers[side * 4 + i + 1], Property.MARGIN_TOP, Property
                                                                          .BORDER_TOP, Property.PADDING_TOP);
                    marginsBordersPaddingsWidths[i][1] = GetSizeOfOneSide(renderers[side * 4 + i + 1], Property.MARGIN_RIGHT,
                                                                          Property.BORDER_RIGHT, Property.PADDING_RIGHT);
                    marginsBordersPaddingsWidths[i][2] = GetSizeOfOneSide(renderers[side * 4 + i + 1], Property.MARGIN_BOTTOM,
                                                                          Property.BORDER_BOTTOM, Property.PADDING_BOTTOM);
                    marginsBordersPaddingsWidths[i][3] = GetSizeOfOneSide(renderers[side * 4 + i + 1], Property.MARGIN_LEFT, Property
                                                                          .BORDER_LEFT, Property.PADDING_LEFT);
                }
            }
            Rectangle withoutMargins = pageSize.Clone().ApplyMargins(margins[0], margins[1], margins[2], margins[3], false
                                                                     );
            IDictionary <String, PageMarginBoxContextNode> resolvedPMBMap = new Dictionary <String, PageMarginBoxContextNode
                                                                                            >();

            for (int i = side * 4 + 1; i < side * 4 + 4; i++)
            {
                if (nodes[i] != null)
                {
                    resolvedPMBMap.Put(nodes[i].GetMarginBoxName(), nodes[i]);
                }
            }
            DimensionContainer[] dims         = new DimensionContainer[3];
            String[]             cssRuleName  = GetRuleNames(side);
            float withoutMarginsWidthOrHeight = side % 2 == 0 ? withoutMargins.GetWidth() : withoutMargins.GetHeight();

            for (int i = 0; i < 3; i++)
            {
                if (side % 2 == 0)
                {
                    dims[i] = RetrievePageMarginBoxWidths(resolvedPMBMap.Get(cssRuleName[i]), renderers[side * 4 + i + 1], withoutMarginsWidthOrHeight
                                                          , marginsBordersPaddingsWidths[i][1] + marginsBordersPaddingsWidths[i][3]);
                }
                else
                {
                    dims[i] = RetrievePageMarginBoxHeights(resolvedPMBMap.Get(cssRuleName[i]), renderers[side * 4 + i + 1], margins
                                                           [side], withoutMarginsWidthOrHeight, marginsBordersPaddingsWidths[i][0] + marginsBordersPaddingsWidths
                                                           [i][2]);
                }
            }
            float centerOrMiddleCoord;

            float[] widthOrHeightResults;
            widthOrHeightResults = CalculatePageMarginBoxDimensions(dims[0], dims[1], dims[2], withoutMarginsWidthOrHeight
                                                                    );
            if (side % 2 == 0)
            {
                centerOrMiddleCoord = GetStartCoordForCenterOrMiddleBox(withoutMarginsWidthOrHeight, widthOrHeightResults[
                                                                            1], withoutMargins.GetLeft());
            }
            else
            {
                centerOrMiddleCoord = GetStartCoordForCenterOrMiddleBox(withoutMarginsWidthOrHeight, widthOrHeightResults[
                                                                            1], withoutMargins.GetBottom());
            }
            Rectangle[] result = GetRectangles(side, withoutMargins, centerOrMiddleCoord, widthOrHeightResults);
            for (int i = 0; i < 3; i++)
            {
                if (nodes[side * 4 + i + 1] != null)
                {
                    nodes[side * 4 + i + 1].SetPageMarginBoxRectangle(new Rectangle(result[i]).IncreaseHeight(EPSILON));
                    UnitValue width = UnitValue.CreatePointValue(result[i].GetWidth() - marginsBordersPaddingsWidths[i][1] - marginsBordersPaddingsWidths
                                                                 [i][3]);
                    UnitValue height = UnitValue.CreatePointValue(result[i].GetHeight() - marginsBordersPaddingsWidths[i][0] -
                                                                  marginsBordersPaddingsWidths[i][2]);
                    if (Math.Abs(width.GetValue()) < EPSILON || Math.Abs(height.GetValue()) < EPSILON)
                    {
                        renderers[side * 4 + i + 1] = null;
                    }
                    else
                    {
                        renderers[side * 4 + i + 1].SetProperty(Property.WIDTH, width);
                        renderers[side * 4 + i + 1].SetProperty(Property.HEIGHT, height);
                    }
                }
            }
        }