/** * <summary>Ends the content row.</summary> * <param name="broken">Indicates whether this is the end of a paragraph.</param> */ private void EndRow( bool broken ) { if (rowEnded) { return; } rowEnded = true; float[] objectXOffsets = new float[currentRow.Objects.Count]; // Horizontal object displacements. float wordSpace = 0; // Exceeding space among words. float rowXOffset = 0; // Horizontal row offset. List <RowObject> objects = currentRow.Objects; // Horizontal alignment. AlignmentXEnum alignmentX = this.alignmentX; switch (alignmentX) { case AlignmentXEnum.Left: break; case AlignmentXEnum.Right: rowXOffset = frame.Width - currentRow.Width; break; case AlignmentXEnum.Center: rowXOffset = (frame.Width - currentRow.Width) / 2; break; case AlignmentXEnum.Justify: // Are there NO spaces? if (currentRow.SpaceCount == 0 || broken) // NO spaces. { /* NOTE: This situation equals a simple left alignment. */ alignmentX = AlignmentXEnum.Left; } else // Spaces exist. { // Calculate the exceeding spacing among the words! wordSpace = (frame.Width - currentRow.Width) / currentRow.SpaceCount; // Define the horizontal offsets for justified alignment. for ( int index = 1, count = objects.Count; index < count; index++ ) { /* * NOTE: The offset represents the horizontal justification gap inserted * at the left side of each object. */ objectXOffsets[index] = objectXOffsets[index - 1] + objects[index - 1].SpaceCount * wordSpace; } } break; } SetWordSpace wordSpaceOperation = new SetWordSpace(wordSpace); // Vertical alignment and translation. for ( int index = objects.Count - 1; index >= 0; index-- ) { RowObject obj = objects[index]; // Vertical alignment. float objectYOffset = 0; //TODO:IMPL image support!!! // switch(obj.Type) // { // case RowObjectTypeEnum.Text: objectYOffset = -(currentRow.Height - obj.Height); // Linebase-anchored vertical alignment. // break; // case RowObjectTypeEnum.Image: // objectYOffset = -(currentRow.Height - obj.Height) / 2; // Centered vertical alignment. // break; // } IList <ContentObject> containedGraphics = obj.Container.Objects; // Word spacing. containedGraphics.Insert(0, wordSpaceOperation); // Translation. containedGraphics.Insert( 0, new ModifyCTM( 1, 0, 0, 1, objectXOffsets[index] + rowXOffset, // Horizontal alignment. objectYOffset // Vertical alignment. ) ); } // Update the actual block height! boundBox.Height = currentRow.Y + currentRow.Height; // Update the actual block vertical location! float xOffset; switch (alignmentY) { case AlignmentYEnum.Bottom: xOffset = frame.Height - boundBox.Height; break; case AlignmentYEnum.Middle: xOffset = (frame.Height - boundBox.Height) / 2; break; case AlignmentYEnum.Top: default: xOffset = 0; break; } boundBox.Y = (float)(frame.Y + xOffset); // Discard the current row! currentRow = null; }
/** * <summary>Ends the content row.</summary> * <param name="broken">Indicates whether this is the end of a paragraph.</param> */ private void EndRow( bool broken ) { if (rowEnded) { return; } rowEnded = true; double[] objectXOffsets = new double[currentRow.Objects.Count]; // Horizontal object displacements. double wordSpace = 0; // Exceeding space among words. double rowXOffset = 0; // Horizontal row offset. List <RowObject> objects = currentRow.Objects; // Horizontal alignment. XAlignmentEnum xAlignment = this.xAlignment; switch (xAlignment) { case XAlignmentEnum.Left: break; case XAlignmentEnum.Right: rowXOffset = frame.Width - currentRow.Width; break; case XAlignmentEnum.Center: rowXOffset = (frame.Width - currentRow.Width) / 2; break; case XAlignmentEnum.Justify: // Are there NO spaces? if (currentRow.SpaceCount == 0 || broken) // NO spaces. { /* NOTE: This situation equals a simple left alignment. */ xAlignment = XAlignmentEnum.Left; } else // Spaces exist. { // Calculate the exceeding spacing among the words! wordSpace = (frame.Width - currentRow.Width) / currentRow.SpaceCount; // Define the horizontal offsets for justified alignment. for ( int index = 1, count = objects.Count; index < count; index++ ) { /* * NOTE: The offset represents the horizontal justification gap inserted * at the left side of each object. */ objectXOffsets[index] = objectXOffsets[index - 1] + objects[index - 1].SpaceCount * wordSpace; } } break; } SetWordSpace wordSpaceOperation = new SetWordSpace(wordSpace); // Vertical alignment and translation. for ( int index = objects.Count - 1; index >= 0; index-- ) { RowObject obj = objects[index]; // Vertical alignment. double objectYOffset = 0; { LineAlignmentEnum lineAlignment; double lineRise; { object objectLineAlignment = obj.LineAlignment; if (objectLineAlignment is Double) { lineAlignment = LineAlignmentEnum.BaseLine; lineRise = (double)objectLineAlignment; } else { lineAlignment = (LineAlignmentEnum)objectLineAlignment; lineRise = 0; } } switch (lineAlignment) { case LineAlignmentEnum.Top: /* NOOP */ break; case LineAlignmentEnum.Middle: objectYOffset = -(currentRow.Height - obj.Height) / 2; break; case LineAlignmentEnum.BaseLine: objectYOffset = -(currentRow.BaseLine - obj.BaseLine - lineRise); break; case LineAlignmentEnum.Bottom: objectYOffset = -(currentRow.Height - obj.Height); break; default: throw new NotImplementedException("Line alignment " + lineAlignment + " unknown."); } } IList <ContentObject> containedGraphics = obj.Container.Objects; // Word spacing. containedGraphics.Insert(0, wordSpaceOperation); // Translation. containedGraphics.Insert( 0, new ModifyCTM( 1, 0, 0, 1, objectXOffsets[index] + rowXOffset, // Horizontal alignment. objectYOffset // Vertical alignment. ) ); } // Update the actual block height! boundBox.Height = (float)(currentRow.Y + currentRow.Height); // Update the actual block vertical location! double yOffset; switch (yAlignment) { case YAlignmentEnum.Bottom: yOffset = frame.Height - boundBox.Height; break; case YAlignmentEnum.Middle: yOffset = (frame.Height - boundBox.Height) / 2; break; case YAlignmentEnum.Top: default: yOffset = 0; break; } boundBox.Y = (float)(frame.Y + yOffset); // Discard the current row! currentRow = null; }