How do I change the font size of JFace table data - jface

I am using a Jface table viewer with OwnerDrawLabelProvider for multiline rows, how do I change the font style/size?

Basically you just need to get the font you want to use and set in the event GC in the measure and paint methods.
This might be something like:
private static final int TEXT_MARGIN = 3;
#Override
protected void measure(Event event, Object element)
{
String text = ... get the text
Font font = JFaceResources.getFont(JFaceResources.HEADER_FONT);
event.gc.setFont(font);
Point size = event.gc.textExtent(text);
event.width = size.x + 2 * TEXT_MARGIN;
event.height = Math.max(event.height, size.y + 2 * TEXT_MARGIN);
}
#Override
protected void paint(Event event, Object element)
{
String text = ... get the text
Font font = JFaceResources.getFont(JFaceResources.HEADER_FONT);
event.gc.setFont(font);
event.gc.drawText(text, event.x + TEXT_MARGIN, event.y + TEXT_MARGIN, true);
}
Here I am using JFaceResources.getFont to get one of the existing JFace fonts. You can also create your own font - but be sure to do this only once do not create it every time measure or paint is called.

Related

Adding page number text to pdf copy gets flipped/mirrored with itext 7

So... I've been trying to use the example provided in the documentation of itext for merging documents and creating a TOC for the merged result. But the part that adds page number text to every page isn't working as I would expect. What happens is that the text added gets flipped over some horizontal axis as shown in the next picture:
Also, the java doc for the method used to set a fixed position to the added text (public T setFixedPosition(int pageNumber, float left, float bottom, float width)) doesn't make sense to me:
Sets values for a absolute repositioning of the Element. The coordinates specified correspond to the bottom-left corner of the element and it grows upwards.
But when I run setFixedPosition(pageNumber, 0, 0, 50) the text ends up in the upper left corner, again also flipped. And if I use the width and height from the page size of the source PdfDocument as parameters for left and bottom positions respectively it doesn't even reach bottom right corner.
I might be doing something wrong or misunderstanding something. Either way, here is the code I'm using:
private static int copyPdfPages(PdfDocument source, Document document, Integer start, Integer pages, Integer number) {
int oldC;
int max = start + pages - 1;
Text text;
for (oldC = start; oldC <= max; oldC++) {
text = new Text(String.format("Page %d", number));
PageSize pageSize = source.getDefaultPageSize();
source.copyPagesTo(oldC, oldC, document.getPdfDocument());
document.add(new Paragraph(text).setBorder(new SolidBorder(ColorConstants.RED, 1))
.setFixedPosition(number++, pageSize.getWidth() - 55, pageSize.getHeight() - 30, 50));
}
return oldC - start;
}
public static void main(String[] args) throws IOException {
String path = "/path/to/target";
FileOutputStream fos = new FileOutputStream(path);
PdfDocument pdfDocTgt = new PdfDocument(new PdfWriter(fos));
Document document = new Document(pdfDocTgt);
PdfDocument pdfDocSrc = new PdfDocument(new PdfReader(new FileInputStream("path/to/source")));
copyPdfPages(pdfDocSrc, document, 1, pdfDocSrc.getNumberOfPages(), 1);
pdfDocTgt.close();
pdfDocSrc.close();
document.flush();
document.flush();
fos.flush();
fos.close();
}
And here is the pdf source: https://drive.google.com/open?id=11_9ptuoRqS91hI3fDcs2FRsIUEiX0a84
Help please (and sorry about my english).
The problem
The problem is that Document.add assumes that the instructions in the current content of the current page at its end have the graphics state essentially restored to its initial state (or else that the effects of the differences on the output are desired).
In your sample PDF this assumption is not satisfied, in particular the page content instructions start with
0.750000 0.000000 0.000000 -0.750000 0.000000 841.920044 cm
which changes the current transformation matrix to
scale everything down to 75% and
flip the coordinate system vertically.
The former change causes your addition to not be in a page corner but instead instead somewhere more to the center; the latter causes it to be vertically mirrored and more to the bottom instead of to the top of the page.
The fix
If one does not know whether the current contents of the page have an essentially restored graphics state at the end (usually the case if one processes page contents one has not generated oneself), one should refrain from adding content via a Document instance but instead use a PdfCanvas generated with a constructor that wraps the current page content in a save-graphics-state ... restore-graphics-state envelop.
E.g. for your task:
private static int copyPdfPagesFixed(PdfDocument source, PdfDocument target, int start, int pages, int number) {
int oldC;
int max = start + pages - 1;
Text text;
for (oldC = start; oldC <= max; oldC++) {
text = new Text(String.format("Page %d", number));
source.copyPagesTo(oldC, oldC, target);
PdfPage newPage = target.getLastPage();
Rectangle pageSize = newPage.getCropBox();
try ( Canvas canvas = new Canvas(new PdfCanvas(newPage, true), target, pageSize) ) {
canvas.add(new Paragraph(text).setBorder(new SolidBorder(ColorConstants.RED, 1))
.setFixedPosition(number++, pageSize.getWidth() - 55, pageSize.getHeight() - 30, 50));
}
}
return oldC - start;
}
(AddPagenumberToCopy method)
The PdfCanvas constructor used above is documented as
/**
* Convenience method for fast PdfCanvas creation by a certain page.
*
* #param page page to create canvas from.
* #param wrapOldContent true to wrap all old content streams into q/Q operators so that the state of old
* content streams would not affect the new one
*/
public PdfCanvas(PdfPage page, boolean wrapOldContent)
Used like this
try ( PdfDocument pdfDocSrc = new PdfDocument(new PdfReader(SOURCE));
PdfDocument pdfDocTgt = new PdfDocument(new PdfWriter(TARGET)) ) {
copyPdfPagesFixed(pdfDocSrc, pdfDocTgt, 1, pdfDocSrc.getNumberOfPages(), 1);
}
(AddPagenumberToCopy test testLikeAibanezFixed)
the top of the first result page looks like this:

Winforms Itext Ghost Script Rectangular coordinates selection

Using C# and Winforms, I want to display a PDF, select a rectangular region, and then extract that area of text from a number of PDFs. For displaying the PDF, I have a number of options...
Use an "Adobe PDF Reader" control to display the PDF - However, I cant use mouseover events and according to https://forums.adobe.com/thread/1640606 its just not possible to select a region.
Use a "WebBrowser" control to display the PDF, but it appears I have the same issue with mouseover events and cannot select a region.
Convert the PDF to an image (using ghostscript in my case) and displaying it in a picturebox. I'm finding the most success here, as I can now generate and record the coordinates of a rectangular region. When I take these coordinates and apply them to the PDF using Itext, I don't think my rectangular region translates correctly.
My question is, How do I render the GhostScripted image in a picture box maintaining the same ratios so that my coordinates will line up with the PDF?
Thank you in advance for the down votes!!
Here is the current state of my code... Everything works with the exception that my units are off in space somewhere. The action DOES return text, but it's never the text I selected. Im sure its a combination of the coordinate system / units and I will continue to try to understand this.
---- update
With a PDF at 0 deg rotation (portrait), I think the following holds true, or is at least working for me right now... User Units having not been changed, the coordinates taken from selecting in the picturebox need adjusting. The Y coordinates need to be subtracted from the overall height while the X coordinate remains the same.
iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(first.X, 3024-first.Y, last.X, 3024-last.Y);
This is picking text up exactly as expected on 0 deg rotated PDFs. On 90 deg rotated PDFs, the X and Y coordinates just need to be swapped.I am updating the code snippet below to show my working example.
using System;
using System.Drawing;
using System.Windows.Forms;
using Ghostscript.NET.Rasterizer;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
namespace formPdf
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string fileName; // The filename of the pdf
float width; // The width of the PDF in pixels
float hight; // the Height of the PDF in pixels
float rotation; // the Rotation of the PDF 0 or 90
float llx = 0; // The Lower Left X value for applying to the PDF
float lly = 0; // the Lower Left Y value for applying to the PDF
float urx = 0; // the Upper Right X value for applying to the PDF
float ury = 0; // the Upper Right Y value for applying to the PDF
// OnCLick event to open the file browser and select a file... The Width, Height and rotation values are set and the program
// is directed to render the First page of the pdf by calling the setPicture function
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
fileName = openFileDialog1.FileName;
PdfReader reader = new PdfReader(fileName);
iTextSharp.text.Rectangle dim = reader.GetPageSizeWithRotation(1);
width = dim.Width;
hight = dim.Height;
rotation = dim.Rotation;
setPicture(openFileDialog1.FileName);
} catch
{
// do nothing for now
}
}
}
// Using Ghostscript, the image is rendered to a picturebox. DPIs are set assuming the PDF default value is used
private void setPicture(string fileName)
{
GhostscriptRasterizer rasterizer = new GhostscriptRasterizer();
rasterizer.Open(fileName);
Image img = rasterizer.GetPage(72, 72, 1);
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBox1.Image = img;
}
// Declare point variables for the user defined rectangle indicating the locatoin of the PDF to be searched...
Point first = new Point();
Point last = new Point();
// The first point is collected on the MouseDown event
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
first = e.Location;
}
// The second point is collected on the mouse down event. Points to be applied to the PDF are adjusted based on the rotation of the PDF.
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
last = e.Location;
if (rotation == 0)
{
llx = first.X;
lly = hight - first.Y;
urx = last.X;
ury = hight - last.Y;
} else if(rotation == 90) {
llx = first.Y;
lly = first.X;
urx = last.Y;
ury = last.X;
}
gettext();
}
// the original PDF is opened with Itext and the text is extracted from t he defined location...
private void gettext()
{
PdfReader reader = new PdfReader(fileName);
iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(llx, lly, urx, ury);
RenderFilter[] renderfilter = new RenderFilter[1];
renderfilter[0] = new RegionTextRenderFilter(rect);
ITextExtractionStrategy textExtractionStrategy = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), renderfilter);
string text = PdfTextExtractor.GetTextFromPage(reader, 1, textExtractionStrategy);
iTextSharp.text.Rectangle mediabox = reader.GetPageSizeWithRotation(1);
MessageBox.Show("", text+" "+mediabox+" "+first+" "+last);
}
// Image Controls....
}
}

iTextsharp font color different in PDF

I'm creating a PDF with images and text. Text can be of varying color. I convert the color from the HTML color code to get me a System.Drawing.Color object but the color turns out differently in the generated PDF. In one particular instance, the html code is 3C3C3C and it comes out as 3C403E. I check the color by using a color picker to get the color in the PDF.
var color = System.Drawing.ColorTranslator.FromHtml("#3C3C3C);
iTextSharp.text.Font font = font = FontFactory.GetFont(FontFactory.HELVETICA);
font.Color = new BaseColor(color);
// boxValue is a string
Phrase phrase = new Phrase(boxValue, font);
ColumnText columnText = new ColumnText(canvas);
columnText.SetSimpleColumn(boxRectangle);
columnText.Leading = lineHeight;
columnText.SetLeading(lineHeight, 0);
columnText.SetText(phrase);
columnText.Alignment = alignment;
columnText.Go();
It turns out that it does save the actual color in the PDF. I discovered this by using a PDF inspector and do see the correct values used.
public static BaseColor stringToBaseColor(string code)
{
Color color = ColorFromString(code);
BaseColor b = new BaseColor(color);
return ColorToBaseColor(color);
}
public static BaseColor ColorToBaseColor(Color color)
{
return new BaseColor(color);
}
public static Color ColorFromString(string code)
{
string[] colors = code.Split(',');
List<int> myInts = Array.ConvertAll(colors, s => int.Parse(s)).ToList();
return Color.FromArgb(myInts[0], myInts[1], myInts[2]);
}

Set image to RepositoryItemPictureEdit in XtraGrid

I have XtraGrid, I've added a new column and set its ColumnEdit property to RepositoryItemPictureEdit.
I have tried to set an image to it using RepositoryItemPictureEdit1.Appearance.Image but it does not populate after the form's load, any thoughts why?
I have 2011 version
As i guess you are not assigning image to control in correct way. You can go through this DevExpress KB thread - Why do I get the "No image data" text in the GridColumn with the PictureEdit in-place editor?
Source : Assigning an image to a RepositoryItemPictureEdit
you can use this approach also:
1) Set the column's FieldName property to the "Image" ,as your DataTable contains this Field
2) Set the Image DataColumn type to the Image value
3) Change the code and do not convert an image to a byte array.
Just set it as below:
RepositoryItemPictureEdit pictureEdit = gridControl1.RepositoryItems.Add("PictureEdit") as RepositoryItemPictureEdit;
pictureEdit.SizeMode = PictureSizeMode.Zoom;
pictureEdit.NullText = " ";
gridView1.Columns["Picture"].ColumnEdit = pictureEdit;
To make the editor load images, the underlying data type should correspond to the RepositoryItemPictureEdit.PictureStoreMode property value
If you want to display image in cell then you can use CustomDrawCell Event
Here ImageStream is a property that store image.
public Stream ImageStream { get; set; }
you can use it as below:
if (profile != null)
{
imageStream = MyObj.ImageStream; // this image saved as stream
}
}
if (imageStream != null)
{
e.Graphics.DrawImage(System.Drawing.Image.FromStream(imageStream), e.Bounds);
if (cellValue.Condition== "XXXX")
{
e.Graphics.DrawRectangle(e.Cache.GetPen(Color.Red), e.Bounds);
}
e.DisplayText = text;
Rectangle r = e.Bounds;
Rectangle w = new Rectangle(r.X, r.Y - 5, r.Width, r.Height);
//Draw the cell value
e.Appearance.DrawString(e.Cache, e.DisplayText, w);
e.Bounds.Inflate(-2, -2);
}
More References:
How to put icons in grid cells
How to display external images in grid columns if the data source only contains links to the images
RepositoryItemPictureEdit Load Image
How to load a picture into the repositoryitemPictureEdit
RepositoryItemPictureEdit default empty image

Creating a closeable tab in Mono/GTK

I'm trying to create new GTK Notebook tabs that contain both a name (as a Label) and a close button (as a Button with an Image) with the following code:
Label headerLabel = new Label();
headerLabel.Text = "Header";
HBox headerBox = new HBox();
Button closeBtn = new Button();
Image closeImg = new Image(Stock.Close, IconSize.Menu);
closeBtn.Image = closeImg;
closeBtn.Relief = ReliefStyle.None;
headerBox.Add(headerLabel);
headerBox.Add(closeBtn);
headerBox.ShowAll();
MyNotebook.AppendPage(childWidget, headerBox);
This seems to work just fine; however, the button is about 1.5 - 2 times the size is needs to be, so there is a lot of extra space around the image inside the button. Having looked at remove inner border on gtk.Button I now see that the culprit is the "inner-border" style property of the GtkButton, but (being new to GTK) I can't seem to figure out how to override its value.
Is there some method of doing this that I'm missing? I don't have any reservations about not using a Button/Image combination, so any more obvious suggestions are welcome.
Note: I have seen the suggestion in the linked question to use an EventBox, but I was not able to add the Relief and mouseover effects to that Widget.
You are in luck. I just made the exact same thing yesterday, and can fortunately give you some code. The trick is to create a Custom Tab Widget.
public class MultiTab : Gtk.Box
{
public Gtk.Label Caption;
Gtk.Image img = new Gtk.Image(Platform.IMG + "tab_close.ico");
public Gtk.ToolButton Close;
public Gtk.Notebook _parent;
public MultiTab ( string name )
{
CreateUI(name);
}
public MultiTab(string name, Gtk.Notebook parent)
{
_parent = parent;
CreateUI(name);
CreateHandlers();
}
void CreateUI(string name)
{
Caption = new Gtk.Label(name);
Close = new Gtk.ToolButton(img,"");
PackStart( Caption );
PackStart( Close );
ShowAll();
Close.Hide();
}
void CreateHandlers()
{
Close.Clicked += delegate {
_parent.RemovePage(_parent.CurrentPage);
};
}
public bool Active;
}
Next all you have to do is use this widget(or a similar one created by you) in Gtk.Notebook like this:
MyNoteBook.AppendPage(new <YourPage>(), new MultiTab("<your caption>",this));
And You're done.
Here is a screenshot:
Add this:
RcStyle rcStyle = new RcStyle ();
rcStyle.Xthickness = 0;
rcStyle.Ythickness = 0;
closeBtn.ModifyStyle (rcStyle);
Add items to box using Gtk.Box.PackStart/PackEnd methods rather than generic Gtk.Container.Add method. PackStart/PackEnd will allow you control how child widgets will be allocated space:
headerBox.PackStart (headerLabel, true, true, 0);
headerBox.PackEnd (closeBtn, false, false, 0);