Windows XAML: LineCount in TextBlock? - xaml

I have a Text Block that I write on a Canvas. Since it is on a Canvas, I manually specify x-coord and y-coord.
My problem is, my y-coord is dependent on the LineCount of the wrapping on my TextBlock (due to limited width).
For example, the text "ADD Bananas" is written as:
ADD
Bananas
which has 2 line count.
Depending on the line count, I do something.
Right now, I am using this to determine the TextWidth and then do calculations from there. However, there are still some outliers (ex. instead of supposed to be 3 lines calculated, 2 in actual visual):
private double stringWidth(string s, double fontSize)
{
if(s==" ")
s = "\u00A0"; //this line wasn't required in silverlight but is now
TextBlock t = new TextBlock()
{
FontSize = fontSize,
Text = s
};
t.Measure(new Size(double.MaxValue, double.MaxValue)); //this line wasn't required in silverlight but is now
return t.ActualWidth;
}
Is there a best way to do this in Windows App Xaml?

Related

iText Vertical Alignment in Text inside a Canvas isn't working

I'm trying to set my text which is inside a canvas to get vertically aligned with VerticalAlignment.BOTTOM property value, but whatever I put doesn't change the visual result.
retangulo = New iText.Kernel.Geom.Rectangle(122, AlturaPag - 208, 235, 27)
PdfCanvas = New iText.Kernel.Pdf.Canvas.PdfCanvas(page).SetLineWidth(1).Rectangle(retangulo).Stroke()
canvas = New iText.Layout.Canvas(PdfCanvas, retangulo)
texto = (New iText.Layout.Element.Text(Npagador).SetFontSize(11).SetBold)
' VerticalAlingment = BOTTOM \/
paragrafo = (New iText.Layout.Element.Paragraph().Add(texto).SetTextAlignment(TextAlignment.LEFT).SetVerticalAlignment(VerticalAlignment.BOTTOM))
canvas.Add(paragrafo)
You are trying to align the contents of the paragraph to the bottom of the paragraph itself, and the paragraph when laying itself out simply uses the minimal necessary height, so whatever alignment (bottom or top) you set, the result it just the same simply because paragraph packs itself to the minimal height.
To make sure setVerticalAlignment has an effect, you need to give the paragraph more vertical space by setting its height. Here is an example where I set paragraph height to match the height of the canvas you add it to, since it's the only element in the canvas. I also set the margins of the paragraph to zero so that you don't get additional spacing around the text.
The code is in Java but you will be able to convert it back to VB.NET as easily as I converted your code to Java:
Paragraph p = new Paragraph().add("Test").setTextAlignment(TextAlignment.LEFT)
.setVerticalAlignment(VerticalAlignment.BOTTOM).setHeight(retangulo.getHeight());
p.setMargin(0);

iText - PDFAppearence issue

We're using iText to put a text inside a signature placeholder in a PDF. We use a code snippet similar to this to define the Signature Appearence
PdfStamper stp = PdfStamper.createSignature(inputReader, os, '\0', tempFile2, true);
sap = stp.getSignatureAppearance();
sap.setVisibleSignature(placeholder);
sap.setRenderingMode(PdfSignatureAppearance.RenderingMode.DESCRIPTION);
sap.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
Calendar cal = Calendar.getInstance();
sap.setSignDate(cal);
sap.setLayer2Text(text+"\n"+cal.getTime().toString());
sap.setReason(text+"\n"+cal.getTime().toString()); `
Everything works fine, but the signature text does not fill all the signature placeholder area as expected by us, but the area filled seems to have an height that is approximately the 70% of the available space.
As a result, sometimes especially if the length of the signature text is quite big, the signature text does not fit in the placeholder and the text is striped away.
Example of filled Signature:
I looked into the PdfSignatureAppearence class and I found this code snippet in the getApperance() method that is responsible of this behaviour and is invoked when
sap.setRenderingMode(PdfSignatureAppearance.RenderingMode.DESCRIPTION);
is being called
else {
dataRect = new Rectangle(
MARGIN,
MARGIN,
rect.getWidth() - MARGIN,
rect.getHeight() * (1 - TOP_SECTION) - MARGIN);
}
I don't get the reason for that, because I expect that the text could use all the available placeholder height, with the proper margin.
Is there any way to bypass this behaviour?
We are using iText 5.4.2, but also newer version contains same code snippet so I expect that the behaviour will be same.
As #JJ. already commented,
TOP_SECTION is connected with acro6layers rendering and the code [determining the datarect in pure DESCRIPTION mode] does not take into account the value of the acro6layer flag.
Unless one wants to fix this in the iText 5 code itself, the easiest way to make one's description use the whole signature space is to construct the layer 2 appearance oneself.
To do so one merely has to retrieve a PdfTemplate from PdfSignatureAppearance.getLayer(2) and fill it as desired after one has called PdfSignatureAppearance.setVisibleSignature. The PdfSignatureAppearance remembers that you already have retrieved the layer 2 and doesn't change it anymore.
For the case at hand we essentially copy the PdfSignatureAppearance.getAppearance code for generating layer 2 in pure DESCRIPTION mode, merely correcting the code determining the datarect:
PdfSignatureAppearance appearance = ...;
[...]
appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
PdfTemplate layer2 = appearance.getLayer(2);
String text = "We're using iText to put a text inside a signature placeholder in a PDF. "
+ "We use a code snippet similar to this to define the Signature Appearence.\n"
+ "Everything works fine, but the signature text does not fill all the signature "
+ "placeholder area as expected by us, but the area filled seems to have an height "
+ "that is approximately the 70% of the available space.\n"
+ "As a result, sometimes especially if the length of the signature text is quite "
+ "big, the signature text does not fit in the placeholder and the text is striped "
+ "away.";
Font font = new Font();
float size = font.getSize();
final float MARGIN = 2;
Rectangle dataRect = new Rectangle(
MARGIN,
MARGIN,
appearance.getRect().getWidth() - MARGIN,
appearance.getRect().getHeight() - MARGIN);
if (size <= 0) {
Rectangle sr = new Rectangle(dataRect.getWidth(), dataRect.getHeight());
size = ColumnText.fitText(font, text, sr, 12, appearance.getRunDirection());
}
ColumnText ct = new ColumnText(layer2);
ct.setRunDirection(appearance.getRunDirection());
ct.setSimpleColumn(new Phrase(text, font), dataRect.getLeft(), dataRect.getBottom(), dataRect.getRight(), dataRect.getTop(), size, Element.ALIGN_LEFT);
ct.go();
(CreateSignature.java test signWithCustomLayer2)
(As description text I used some paragraphs from the question body.)
The result:
By adapting the MARGIN value in the code above, one can even use more are. As that can result in the text touching the border, though, that might not be really beautiful.
As an aside:
if the length of the signature text is quite big, the signature text does not fit in the placeholder and the text is striped away.
If you initialize the size variable above with a non-positive value, the code in the if (size <= 0) block will calculate a font size which allows all of the text to fit into the signature rectangle. This does happen in the code above as new Font() returns a font with a size of UNDEFINED which is a constant -1.

Is there a way to resize an MdiTab to fit your newly-updated text? (Infragistics)

I am resetting the text for an MdiTab in an UltraWinTabbedMdi. I reset it to be bold and longer, but the tab does not resize so the text is truncated. Right now, I'm just resetting the size of the tab to some magic number that I've found looks decent on my computer, but I don't know if it will work elsewhere. I would like to be able to get the dimensions of the new text and add the same size to that every time or call some auto-resize method.
Is there a way to do this?
You could use the MeasureString of the Graphics class.
// Set up string.
string measureString = "YourText";
// The font name and size used to draw the string (from your MdiTab)
Font stringFont = new Font("Arial", 16);
// Measure string.
SizeF stringSize = new SizeF();
stringSize = this.Graphics.MeasureString(measureString, stringFont);
// now you have a stringSize.Width and stringSize.Height to use

Ready An Existing PDF Page Size (ex. 8.5 x 11, 11 x 17) VB.Net

Like the title says i'd like to read an existing pdf page size with VB.Net. I've been working with Itext.Sharp, and the Acrobat.dll. Is this possible??
There are a number of different "Boxes" a given page can have:
Media Box (required): The initial page size when printing viewing.
Crop Box (optional): Supersedes the media box. Defaults to match the media box. Must be a subset or match the media box.
There's also art/trim/bleed boxes, but they don't matter as much and are much less common.
So, the page size:
PdfReader reader = new PdfReader(myPath);
// gets the MEDIA BOX
Rectangle pageRect = reader.getPageSize(1); // 1 -> first page
// gets the crop box if present, or the media box if not.
Rectangle cropRect = reader.getCropBox(1);
// and finally
Rectangle artBox = reader.getBoxSize( 1, "art");
// could be "art", "bleed", "crop", "media", or "trim"
I'd go with getCropBox().
I also recommend checking out the JavaDoc for things like this. At the very least you would have come up with getPageSize() on your own. No, it's not C#. Yes, it's very useful.
http://api.itextpdf.com/
Also note that these Rectangles need not be based on 0,0 (which would be the lower left corner on an unrotated page).
Further, you should check the page's rotation, getPageRotation(int), and swap height and width if the rotation is 90 or 270. There is getPageSizeWithRotation(int), but it only works with the media box, so I'd do it yourself if I were you. It's only a few extra lines of code:
// rotation has to be 0, 90, 180, or 270. "360" isn't kosher IIRC.
if (reader.getPageRotation(pageNum) % 180 != 0) {
float tmp = width;
width = height;
height = tmp;
}

dojox.drawing.Drawing - custom tool to create rectangle with rounded corners

I'm working with dojox.drawing.Drawing to create a simple diagramming tool. I have created a custom tool to draw rounded rectangle by extending dojox.drawing.tools.Rect as shown below -
dojo.provide("dojox.drawing.tools.custom.RoundedRect");
dojo.require("dojox.drawing.tools.Rect");
dojox.drawing.tools.custom.RoundedRect = dojox.drawing.util.oo.declare(
dojox.drawing.tools.Rect,
function(options){
},
{
customType:"roundedrect"
}
);
dojox.drawing.tools.custom.RoundedRect.setup = {
name:"dojox.drawing.tools.custom.RoundedRect",
tooltip:"Rounded Rect",
iconClass:"iconRounded"
};
dojox.drawing.register(dojox.drawing.tools.custom.RoundedRect.setup, "tool");
I was able to add my tool to the toolbar and use it to draw a rectagle on canvas. Now, I would like to customize the rectangle created by my custom tool to have rounded corners, but I'm not able to figure out how.
I have checked the source of dojox.drawing.tools.Rect class as well as it's parent dojox.drawing.stencil.Rect class and I can see the actual rectangle being created in dojox.drawing.stencil.Rect as follows -
_create: function(/*String*/shp, /*StencilData*/d, /*Object*/sty){
// summary:
// Creates a dojox.gfx.shape based on passed arguments.
// Can be called many times by implementation to create
// multiple shapes in one stencil.
//
//console.log("render rect", d)
//console.log("rect sty:", sty)
this.remove(this[shp]);
this[shp] = this.container.createRect(d)
.setStroke(sty)
.setFill(sty.fill);
this._setNodeAtts(this[shp]);
}
In dojox.gfx, rounded corners can be added to a a rectangle by setting r property.
With this context, could anybody please provide answers to my following questions?
What's the mechanism in dojox.drawing to customize the appearance of rectangle to have
rounded corners?
In the code snippet above, StencilData is passed to createRect call. What's the mechanism to customize this data? Can the r property of a rectangle that governs rounded corners be set in this data?
Adding rounded rectangles programmatically is easy. In the tests folder you'll find test_shadows.html which has a line that adds a rectangle with rounded corners:
myDrawing.addStencil("rect", {data:{x:50, y:175, width:100, height:50, r:10}});
You create a data object with x,y,width,height, and a value for r (otherwise it defaults to 0).
If you wanted to do it by extending rect, the easiest way to do it would just be to set the value in the constructor function (data.r=10, for example), or you could create a pointsToData function to override Rect's version. Either you would have set the value for this.data.r, or the default:
pointsToData: function(/*Array*/p){
// summary:
// Converts points to data
p = p || this.points;
var s = p[0];
var e = p[2];
this.data = {
x: s.x,
y: s.y,
width: e.x-s.x,
height: e.y-s.y,
r:this.data.r || 10
};
return this.data;
},
In that example I give r the value 10 as the default, instead of 0 as it was before. This works because every time stencil goes to draw your rect, it converts canvas x,y points (all stencils remember their points) to data (which gfx uses to draw). In other words this function will always be called before rect renders.