Line spacing and paragraph alignment in CoreText - iphone

I am using CoreText to render multiple columns of text. However, when I set the first letter of the 1st paragraph to a bold, larger font than the rest of the text, I incur 2 issues (both visible in the attached image):
The spacing underneath the first line is too big (I understand that this is because the 1st character could be a g,y,p,q etc.
Lines below the first line now do not line up with corresponding lines in the next column.
Any advice on how to overcome these 2 issues would be greatly appreciated, thank you.

According to the documentation kCTParagraphStyleSpecifierMaximumLineHeight should have solved the problem, but unfortunately does not seem to work at least on IOS 4.3.
CTParagraphStyleSetting theSettings[5] =
{
{ kCTParagraphStyleSpecifierParagraphSpacing, sizeof(CGFloat), &spaceBetweenParaghraphs },
{ kCTParagraphStyleSpecifierParagraphSpacingBefore, sizeof(CGFloat), &topSpacing },
{ kCTParagraphStyleSpecifierLineSpacing, sizeof(CGFloat), &spaceBetweenLines },
{ kCTParagraphStyleSpecifierMinimumLineHeight, sizeof(CGFloat), &lineHeight},
{ kCTParagraphStyleSpecifierMaximumLineHeight, sizeof(CGFloat), &lineHeight}
};
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(theSettings, 5);
To be fair documentation says it's available in OS v10.5 and later.
kCTParagraphStyleSpecifierMaximumLineHeight:
The maximum height that any line in the frame will occupy, regardless of the font size or size of any attached graphic. Glyphs and graphics exceeding this height will overlap neighboring lines. A maximum height of 0 implies no line height limit. This value is always nonnegative.Type: CGFloat.
Default: 0.0.
Application: CTFramesetter.
Available in Mac OS X v10.5 and later.
Declared in CTParagraphStyle.h.

It seems the only way to fix this is with a workaround, which is to create 3 frames for the first column,1 for the W, 1 for the rest of the first sentence and 1 for the rest of the first column.

Related

Line Spacing Inside the Table in Word Using Apache POI

https://support.content.office.net/en-us/media/fbe67397-658c-4b04-b295-b0d6759e1aaa.jpg
Hello Everyone I need to add Line spacing Before(Spacing about 6pt) effect inside the table.You can see the above image that has a paragraph spacing i need that effect. I am using 5.0.0 version. And checked on many sites. nothing useful. if someone help me that will be great. Thank You in advance :)
To set the paragraph spacing apache poi provides XWPFParagraph.setSpacingBefore and XWPFParagraph.setSpacingAfter. Measurement unit for the int is twentieths of a point. So 8*20 is 8 pt.
In a table one needs get the first paragraph of a XWPFTableCell to set spacing before:
...
XWPFTableRow tableRow = ...
...
XWPFTableCell cell = tableRow.getCell(1);
if (cell.getParagraphs().size() > 0) cell.getParagraphs().get(0).setSpacingBefore(8*20);
...
But if the requirement is vertical aligning in cell, then XWPFTableCell.setVerticalAlignment should be used. But this only can be rendered properly if there is no spacing after the last paragraph which pushs the paragraph upwards.
So
...
XWPFTableRow tableRow = ...
...
XWPFTableCell cell = tableRow.getCell(1);
cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
if (cell.getParagraphs().size() > 0) cell.getParagraphs().get(cell.getParagraphs().size()-1).setSpacingAfter(0);
...

ag-Grid: extend rows till right edge if columns don't occupy full width

In ag-Grid, if the columns occupy a smaller space than the width of the grid, a blank hole appears on the right of the last column. Please see below (example taken from ag-Grid docs):
The UX designers on my team don't like that. They would like to see the rows extended all the way to the right to balance out the look. Is this possible to do with ag-Grid?
Edit: We don't want to use the sizeColumnsToFit option, because on large monitors it produces very wide columns and the grid becomes unreadable. We want to use the autoSize option to compact the columns and fill the hole on the RHS with blank stripes as suggested above.
Yes it is possible. You can call the sizeColumnsToFit function on the ag-Grid api which will fill out the width of the table with the columns.
Take a look at documentation.
Here is a plunker example.
EDIT
Use the property suppressSizeToFit and set it to true to when you call sizeColumnsToFit, it won't have an affect. Apply this property to the defaultColDef and set it to false for the last column. This was, when you call sizeColumnsToFit, only the last column will be set to full width. See the updated plunker above.
this is how i do it:
/**
* if there is "dead space" present on the grid, the columns will be auto sized to fill the gap
* #param gridApi
* #param columnApi
*/
resizeColumnsToFit(gridApi: GridApi, columnApi: ColumnApi, allowShrink = false) {
if (allowShrink) {
gridApi.sizeColumnsToFit();
} else {
const gridBodyWidth = document.getElementsByClassName("ag-root-wrapper")[0].clientWidth; // todo: use grid's id instead of [0] to allow multiple grids on a page
const allColumnsWidth = columnApi.getAllDisplayedColumns().map(c => c.getActualWidth()).reduce((a, b) => a + b, 0);
if (gridBodyWidth > allColumnsWidth) {
gridApi.sizeColumnsToFit();
}
}
}
This method will size columns to fit only when there is "dead" space on the right. Optionaly set allowShrink to true to force resizing even if there is no dead space
I had the same situation and resolved with the following css override:
.ag-center-cols-container {
width: 100% !important;
}
One possible option I've been playing with is adding a fake column at the end to fill the remaining space. To do so, you just need to add a column with options similar to the following to the end of your list of columns:
{
flex: 1,
headerName: '',
}
See this plunker forked from #ViqMontana's example above.
It's not a perfect solution, but wanted to mention it here in case it helps.
This works like Craig Weston's answer but without the need for !important:
.ag-center-cols-container {
min-width: 100%;
}

How to display text in center if use verticalText?

My code
VerticalText vt = new VerticalText(writer.getDirectContent());
vt.setVerticalLayout(marginLeft + squareHeight, 1191.0f - marginTop, squareHeight, 3, 20);
vt.setAlignment(Element.ALIGN_CENTER);
Paragraph p = new Paragraph(imgr.getText(), fontV);
p.setLeading(10);
vt.addText(p);
vt.go();
The result : Text is middle in vertical mode.
I want to display text is center in horizontal mode as below link:
How to solve this problem ?
As documented, left, center and right align has a different meaning in the context of VerticalText. Left is top, center is middle and right is bottom.
With class VerticalText, you always write from right to left. There is currently no way to align the text as shown in the screen shot to the right.
However, you could work around this problem by adding the vertical text in simulation mode first and then calculate the number of lines that have been written.
See for instance the VerticalText1 example from my book. I have adapted the code of that example like this:
BaseFont bf = BaseFont.createFont(
"KozMinPro-Regular", "UniJIS-UCS2-V", BaseFont.NOT_EMBEDDED);
Font font = new Font(bf, 20);
VerticalText vt = new VerticalText(writer.getDirectContent());
vt.setVerticalLayout(390, 570, 540, 12, 30);
vt.addText(new Chunk(MOVIE, font));
vt.go();
System.out.println(vt.getMaxLines());
vt.addText(new Phrase(TEXT1, font));
vt.go();
System.out.println(vt.getMaxLines());
vt.setAlignment(Element.ALIGN_RIGHT);
vt.addText(new Phrase(TEXT2, font));
vt.go();
System.out.println(vt.getMaxLines());
The output of the System.out calls is:
11
4
1
These numbers are the number of lines that are available after each go().
We start with 12 lines as defined in the setVerticalLayout() method.
We add MOVIE and there are 11 lines left. We've defined a leading of 30, which means we've already consumed (12 - 11) x 30pt = 30pt.
Then we add TEXT1 which is distributed over 7 lines, which take 7 * 30pt in width. In total we now have consumed (12 - 4) x 30pt = 240pt.
Finally we add TEXT2 which is distributed over 3 lines. Only 1 line is left. The total horizontal width of all the text is 330pt (we had only 30pt left).
Now that you know this math, you can execute the go() method in simulation mode, calculate the width that was consumed and use that info to add your text for real at the desired position.

Changing text line spacing

I'm creating a PDF document consisting of text only, where all the text is the same point size and font family but each character could potentially be a different color. Everything seems to work fine using the code snippet below, but the default space between the lines is slightly greater than I consider ideal. Is there a way to control this? (FYI, type "ColoredText" in the code below merely contains a string and its color. Also, the reason I am treating the newline character separately is that for some reason it doesn't cause a newline if it's in a Chunk.)
Thanks,
Ray
List<byte[]> pdfFilesAsBytes = new List<byte[]>();
iTextSharp.text.Document document = new iTextSharp.text.Document();
MemoryStream memStream = new MemoryStream();
iTextSharp.text.pdf.PdfWriter.GetInstance(document, memStream);
document.SetPageSize(isLandscape ? iTextSharp.text.PageSize.LETTER.Rotate() : iTextSharp.text.PageSize.LETTER);
document.Open();
foreach (ColoredText coloredText in coloredTextList)
{
Font font = new Font(Font.FontFamily.COURIER, pointSize, Font.NORMAL, coloredText.Color);
if (coloredText.Text == "\n")
document.Add(new Paragraph("", font));
else
document.Add(new Chunk(coloredText.Text, font));
}
document.Close();
pdfFilesAsBytes.Add(memStream.ToArray());
According to the PDF specification, the distance between the baseline of two lines is called the leading. In iText, the default leading is 1.5 times the size of the font. For instance: the default font size is 12 pt, hence the default leading is 18.
You can change the leading of a Paragraph by using one of the other constructors. See for instance: public Paragraph(float leading, String string, Font font)
You can also change the leading using one of the methods that sets the leading:
paragraph.SetLeading(fixed, multiplied);
The first parameter is the fixed leading: if you want a leading of 15 no matter which font size is used, you can choose fixed = 15 and multiplied = 0.
The second parameter is a factor: for instance if you want the leading to be twice the font size, you can choose fixed = 0 and multiplied = 2. In this case, the leading for a paragraph with font size 12 will be 24, for a font size 10, it will be 20, and son on.
You can also combine fixed and multiplied leading.
private static Paragraph addSpace(int size = 1)
{
Font LineBreak = FontFactory.GetFont("Arial", size);
Paragraph paragraph = new Paragraph("\n\n", LineBreak);
return paragraph;
}

Split String at specific line for NSString

Hello ist there a way to split a String for UITableView at a specific line to put the "rest" (the second part of the data) in an own cell
NSString *data;
CGsize *size = [data sizeOfStringWithFont:[UIFont systemFontOfSize:14] constrainToWidth:280.0];
if the size.height e.g. is greater than 1500 i want to split the string at this line position!
thank you
Use "constrainedToSize" (instead of just to width) and render as much as you can.
If you really want to take exactly the text that would not fit, you're going to have to do essentially a search, adding a word at a time and then doing the size check to see how high you have gotten. You could start out with a rough estimate by doing the whole string constrained to something only one line high with boundless width (say 999999) and then divide up the width into however many rows you are wishing to allow to get a rough starting point for adding/removing words from the string (it will not be exact because of word wrapping).
Fundamentally though it seems wierd to take the leftover text and put it in another cell. Are you really sure you don't simply want to change the height of the cell with the text to allow it to fit the whole thing?
I think Kendall has the right idea, but the constrained sizes should be reversed to get the exact height based on word wrapping. Take a sample CGSize that is the same width as your cell, but with a height larger than the max height you expect. In the sample code below, textSize will contain the height of your string as it would appear in your cell with an unbounded height.
CGSize sz = CGSizeMake (
yourCellWidth,
999999.0f );
CGSize textSize = [yourString sizeWithFont:yourCellfont
constrainedToSize:sz
lineBreakMode:UILineBreakModeWordWrap];
If the height is greater than 1500, you could start picking off substrings (substringWithRange) from the end and measuring them like above until you get something >= the remainder above 1500 that was returned by textSize.