I am using below code but this is not working its show only one line in bottom while I want a paragraph in bottom in every page.
public void onEndPage(PdfWriter writer, Document document) {
Rectangle rect = writer.getBoxSize("art");
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_LEFT, new Phrase(ActivityWaTestamentInput.pDFHeaderText,headerFont),
rect.getLeft(), rect.getTop(), 0);
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_LEFT, new Paragraph(ActivityWaTestamentInput.pDFFooterText,footerFont),
rect.getLeft() , rect.getBottom() - 18, 0);
As documented, ColumnText.showTextAligned() will only show one line. If you need multiple lines, then you can also use ColumnText, but you need to use it in a different way.
Please download the free ebook The Best iText Questions on StackOverflow. In the section "Absolute positioning of text", you'll find several examples that involve ColumnText.
These are some questions and answers you should check:
How to fit a String inside a rectangle?
How to draw a rectangle around multiline text
iText placement of Phrase within ColumnText
This is a code snippet from one of the answers to these questions:
ColumnText ct = new ColumnText(cb);
ct.setSimpleColumn(120f, 500f, 250f, 780f);
Paragraph p = new Paragraph("This is a long paragraph that doesn't"
+ "fit the width we defined for the simple column of the"
+ "ColumnText object, so it will be distributed over several"
+ "lines (and we don't know in advance how many).");
ct.addElement(p);
ct.go();
I hardcoded the position:
llx = 120;
lly = 500;
urx = 250;
ury = 780;
This is a rectangle with lower left corner (120, 500), a width of 130 and a height of 380. You will need to adapt these values if you want the text to appear at the bottom of the page.
Related
I've an Android app that needs to generate a PDF document with various data fetched from a database. Everything is working fine, included tables and checkboxes, that I generate with this snipped of code :
private PdfFormField WriteCheckbox(ref PdfContentByte pcb, float xPos, float yPos, string fldName, bool cbState)
{
yPos = yPos - 2f;
float cbDist = 1f;
Rectangle cbRect = new Rectangle(xPos, yPos, xPos + DEFAULT_CHECKBOX_SIZE, yPos + DEFAULT_CHECKBOX_SIZE);
RadioCheckField checkbox = new RadioCheckField(pcb.PdfWriter, cbRect, "", "");
checkbox.CheckType = RadioCheckField.TYPE_SQUARE;
checkbox.BorderColor = BaseColor.BLACK;
checkbox.BorderStyle = PdfBorderDictionary.STYLE_SOLID;
checkbox.BorderWidth = 0.5f;
checkbox.FieldName = fldName;
if(cbState)
{
pcb.SetLineWidth(1.2f);
pcb.MoveTo(xPos + DEFAULT_CHECKBOX_DISTANCE, yPos + cbDist);
pcb.LineTo(xPos + DEFAULT_CHECKBOX_SIZE - cbDist - 1, yPos + DEFAULT_CHECKBOX_SIZE - cbDist - 1);
pcb.MoveTo(xPos + DEFAULT_CHECKBOX_SIZE - cbDist - 1, yPos + cbDist);
pcb.LineTo(xPos + DEFAULT_CHECKBOX_DISTANCE, yPos + DEFAULT_CHECKBOX_SIZE - cbDist - 1);
}
pcb.Stroke();
return(checkbox.RadioField);
}
The resulting PDF is visualize correctly on the tablet (Nexus 7), but when I copy it con my PC and open if with Acrobat Reader all is at the correct place except the squares I draw to show the checkboxes. I can se the cross I draw inside the squares, but not the surrounding square. What is happening ?
This is the link to the pdf generated :
https://www.dropbox.com/s/p388bw7egjsbi80/curit_2015_2.pdf?dl=0
This is the link to the Nexus 7 screenshot showing the very same file :
Any hint would be very appreciated.
the squares I draw to show the checkboxes
Your code doesn't draw any squares.
What your code does, actually is surprising,
it creates numerous checkbox AcroForm form fields, none of them checked, none of them named, with a square visualization selection, and
it draws a cross in the page content in positions you seem to want to have appear checked.
So even if the created PDF was valid, it could irritate people, as they apparently could not de-select the pre-selected entries, merely select them a second time resulting in two overlapping crosses.
The reason why your checkbox borders only appear on some PDF viewers and not on others, is the same as explained in this answer to the question "iText - Java Android - Adding fields to existing pdf":
AcroForm form fields need to have a non-empty name. AcroForm forms contents are meant to be sent to some service for automatic evaluation, so they must be named and they must be distinguishable by their respective names.
Some PDF viewers recognize early that they couldn't properly handle fields with empty names and, therefore, don't even show them while other viewers recognize that later when trying to save or post the form, or don't recognize it at all, producing broken outputs.
But even after naming the boxes individually, you should decide whether you want to have AcroForm form fields or not. In the former case you would merely add properly named form fields and set them selected or not, and in the latter case you would draw complete checkbox appearances (not merely the check marks) in the page content and not use form fields at all.
I am creating a PDF document with images and text in Android using iText. Each page has an image at the top followed by some text. On the first page the image is correctly aligned to the top margin of the page, but on subsequent pages there is a gap of approximately 10 points between the top margin and the top of the image.
Here's my code:
// Create PDF document object
float pageMargin = 72;
document = new com.itextpdf.text.Document(PageSize.A4, pageMargin, pageMargin, pageMargin, pageMargin);
PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(myFile.getAbsoluteFile()));
document.open();
PdfContentByte cb = pdfWriter.getDirectContent();
for (PicturePage picPage : picPageList)
{
// Draw a border on the page
cb.moveTo(pageMargin, pageMargin);
cb.lineTo(pageMargin, (pageHeight - pageMargin));
cb.lineTo((pageWidth - pageMargin), (pageHeight - pageMargin));
cb.lineTo((pageWidth - pageMargin), pageMargin);
cb.lineTo(pageMargin, pageMargin);
cb.stroke();
// Get an image from the file system and scale to required size
String imgFileName = picPage.getImagePath();
image = Image.getInstance(imgFileName);
float fitWidth = 400;
float fitHeight = 300;
image.scaleToFit(fitWidth, fitHeight);
image.setAlignment(Image.ALIGN_CENTER | Image.ALIGN_TOP);
document.add(image);
// Add the text to the page.
String theText = picPage.getText();
String[] arrParagraphs = theText.split("\n");
for (int i=0; i<arrParagraphs.length; i++)
{
String paragraphText = arrParagraphs[i];
Paragraph p = new Paragraph(paragraphText);
document.add(p);
}
// Start a new page
document.newPage();
}
I have tried various combinations of Image.ALIGN... and Image.TEXTWRAP but none of them remove the gap. I tried changing the order of placing the image and the border but no change. I have also tried removing the text and the border but the placement of the image is still the same.
Any ideas how to fix this?
Thanks,
Declan
I hope you won't mind if I share my opinion, but I don't like your code. There are much better ways to render images followed by a caption than the way you do it.
Now let me explain what causes the small gap to appear.
When you first create your document, the value of the leading is zero. (The leading is the distance between the baselines of two consecutive lines). This value changes as soon as you add the first object that defines a leading. In your case, this object is a Paragraph.
Although you do not define a leading explicitly, your paragraph uses a default font (Helvetica) and a default font size (12). The default leading is 1.5 times the font size (18).
Now when you go to the next page, that leading is used, introducing a small gap preceding the image. You could solve this by adding an empty Paragraph with leading 0 before triggering a new page:
document.add(new Paragraph(0));
(Add this before document.newPage();.)
However: if I were you, I'd throw away my code, and I'd add my image and my caption using a PdfPTable with a fixed width and fixed heights for the cells. You can add this table either using document.add(), or using the writeSelectedRows() method. Alternatively I could add the image at an absolute position and add the caption using a ColumnText object. There are many different ways to achieve what you want. The way you do it may work, but it's not optimal.
WHAT I WANT: I want my text to appear character by character and when entire text is visible, I want entire text to blink.
WHAT I HAVE DONE:
Text displayText = new TickerText(WIDTH / 2 - ((displayTxt.length() / 2)
* FONT_SIZE_LARGE) / 2 - FONT_SIZE_LARGE, HEIGHT / 2, mPlokFontLarge,
displayTxt, new TickerTextOptions(HorizontalAlign.CENTER, 4),
vertexBufferObjectManager);
scene.attachChild(displayText);
This code adds the text which is in string displayTxt and then make it appear character by character. Now to make it blinking i made a LoopEntityModifier
final LoopEntityModifier blinkModifier = new LoopEntityModifier(
new SequenceEntityModifier(new FadeOutModifier(0.25f), new FadeInModifier(0.25f)));
But i can't add this to displayText.
Also i checked out this link which tells how to do so, but the problem is, it is for GLES1.0
Any help is appreciated. Also, I am very new to AndEngine, so please forgive it I am going wrong and guide me. Also if you can point me to relevant tutorials, it will be appreciated
you should be able to add any modifier to your text using something like
displayText.registerEntityModifier(yourModifierHere)
I would like to be able to know the total area covered by a region (e.g. a double integral over this said area).
I cannot find any method for that, and I wonder will I have to go pixel-by-pixel.
Thanks in advance!
You should be able to use a RegionIterator and sum the areas of the rectangles returned.
Reasoning: The Andriod docs imply that when boolean ops are done on regions, the result region is a new set of non-overlapping rectangles with the desired union. In other words, A - B, where A and B are rectangles, may produce 0, 1, 2, 3, or 4 rectangles as a result.
I have not tested, but the source at the Android xRef site shows that a validated region consists of rectangles with no overlaps.
It seems, i have the same problem like your problem.
I'm not sure, if it is a "real" solution. But i post my code. The values looks ok.
private void calculateArea(Region region) {
RegionIterator regionIterator = new RegionIterator(region);
int size = 0; // amount of Rects
float area = 0; // units of area
Rect tmpRect= new Rect();
while (regionIterator.next(tmpRect)) {
size++;
area += tmpRect.width() * tmpRect.height();
}
log.d("Rect amount=" + size);
log.d("Area Size / units of area=" + area);
}
}
My Problem is: I want to get the area size of some drawn pathes. To recognize touches on the pathes i added a Region too.
The Android TextView clips off my text subscripts (see image below) even when I use android:layout_height="wrap_content" for the TextView.
Is there a fix/work-around for this?
P/S: Superscripts work fine
Note: padding doesn't work.
I tried even adding a padding of 50dip but it did not help.
I can use an absolute height such as 50dip but that messes everything up when I need text to wrap around.
Sample Code:
mtTextView.setText(Html.fromHtml("HC0<sub>3</sub>"));
Most answers suggest to add paddings or to use smaller sub/superscripts. These might be serviceable workarounds, but they don't really solve the problem. Ideally, we want Android to take the sub/superscript into account when calculating line height. I think I found how to do it, and I'm sharing it for people googling this issue.
SpannableStringBuilder sb = new SpannableStringBuilder("X2");
sb.setSpan(new SuperscriptSpan(), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(sb, BufferType.SPANNABLE);
The trick is in BufferType.SPANNABLE. Apparently it makes TextView pay more attention to the markup and calculate line heights properly.
This solution worked for me.
Superscripted text is usually made smaller when the browser renders it, that doesn't seem to happen here so you can replicate that (and solve this problem) by doing this:
someTextView.setText(Html.fromHtml("Some text<sup><small>1</small></sup>"));
For subscript a slight variation to the above suggestion is needed, two small tags:
textView.setText(Html.fromHtml(
"HCO<sub><small><small>3</small></small></sub>));
android:lineSpacingExtra="4dp" should solve it
this will add extra line spacing below your text, and keep subscript from getting cutoff. I haven't tried it with superscript so it might now fix that.
I had the same issue, so after reading the posts, I found this to be working.
Example : H2O
simply use :
textView.setText(Html.fromHtml("H<sub>2</sub>O"),BufferType.SPANNABLE);
BufferType.SPANNABLE is important as it will tell textview to consider the superscript span.
If you are using custom tag handler for HTML you can also use it like this:
textView.setText(Html.fromHtml(data, null, new CustomHtmlTagHandler(),BufferType.SPANNABLE);
Hope it helps someone looking for same problem.
I'm displaying fractions and mixed numbers so I'm using both super and subscripting together. The Html.fromHtml didn't work for me, it either clipped the top or the bottom.
Oddly, mixed numbers worked correctly, but fractions by themselves did not.
I ended up using a SpannableString with a SubscriptSpan or a SuperscriptSpan, then setting the font size in a TextAppearanceSpan.
Once I had done that I had to expand the height of the TextView as well.
TextView number = (TextView)findViewById(R.id.number);
String temp = "1 1/2";
SpannableString s = new SpannableString(temp);
// if the string has a fraction in it, superscript the numerator and subscript the denominator
if (temp.indexOf('/') != -1)
{
int len = temp.length();
s.setSpan(new SuperscriptSpan(), len - 3, len - 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new TextAppearanceSpan(null, 0, fractionFontSize, null, null), len - 3, len - 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new TextAppearanceSpan(null, 0, fractionFontSize, null, null), len - 2, len - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new SubscriptSpan(), len - 1, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new TextAppearanceSpan(null, 0, fractionFontSize, null, null), len - 1, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
number.setText(s);
Then I had to expand the height:
RelativeLayout.LayoutParams parms = (RelativeLayout.LayoutParams)number.getLayoutParams();
Rect frame = CalcSize(number.getTextSize(), quantityMaxString);
parms.height = frame.height() + fractionAdjustment;
number.setLayoutParams(parms);
CalcSize returns a bounding rectangle of the largest string in the array of display elements.
fractionAdjustment is an emperically selected value that works for the selected font size adjusted for screen geometry.
Note: This is TextView is inside a ListView, so that might have some impact as well.
// calculate the field dimensions, given the font size and longest string
private static Rect CalcSize(float fontSize, String maxString)
{
Rect bounds = new Rect();
paint.setTypeface(Typeface.DEFAULT);
paint.setTextSize(fontSize);
paint.getTextBounds(maxString, 0, maxString.length(), bounds);
return bounds;
}
Empirical values:
fractionAdjustment = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, resources.getDisplayMetrics());
fractionFontSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 11, resources.getDisplayMetrics());
I have faced the same issue in ICS and below android versions. I fixed the issue by a simple step
Give a minimum height to the Text View . It will fix the problem.
You can set minimum height through xml .
android:minHeight="30dp"
Or dynamically
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
tv.setMinHeight(52);
}
This worked for me along with the Small tag.
Inside the TextView add
android:paddingBottom="1dp"
Use the small Tag after the subscript
yourTextView.setText(Html.fromHtml("" +" Hey< sub >< small >2< /small > < /sub >"));
Note Please note , step 1 is important , My text was still cutting down in some case,using paddingBottom resolved it.
Don't forget to remove the spaces in sub and small tags that are present in my answer :)
The More number of <small> </small> tags in there, the smaller the subscript will get and you should be able to see it without being clipped.
Eg: H2O
Html.fromHtml("H<sub><small><small><small>2</small></small></small></sub>O");