I am hopping somebody can help me... it seems like what I am trying to do should be fairly simple but I have been fighting this thing for over a day now and am out of ideas. I have found lots of information on StackOverflow and the Internet at large but nothing has helped me resolve this issue.
I am trying to use itext-2.0.8 along with core-renderer-R8 to create a PDF with an embedded font. I am trying to generate the PDF from valid XHTML and am embedding the font using the #font-face style tag. I have confirmed that the #font-face tag is including the font by opening the file in a browser. And I am always careful to keep the TTF fiel relative to teh XHTML/CSS doc.
In order to try and work my way through this I have created a small 'Hello World' type program to try and embed a font. I have taken two separate approaches and both of them fail to produce the desired result. I have place a copy of this little Eclipse program at http://christopherluft.com/FlyingSaucer.zip
The program produces a PDF in both instances but neither has the PDF embedded as expected. The first method using a file with setDocument produces no errors but also no fonts. And the second method produces a PDF but shows a java.net.MalformedURLException in the debug output.
I have tried numerous permutations of the various paths and URLs; however, none fail to produce the desired result. My suspicion is that I am failing to understand something about ITextRenderer.setDocument; however, I have had a really hard time finding any proper documentation specific to my use case.
The first method I am trying is:
public static void main(String[] args) throws IOException, DocumentException {
System.getProperties().setProperty("xr.util-logging.loggingEnabled",
"true");
XRLog.setLoggingEnabled(true);
String inputFile = "sample.xhtml";
String url = new File(inputFile).toURI().toURL().toString();
String outputFile = "firstdoc.pdf";
OutputStream os = new FileOutputStream(outputFile);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(url);
renderer.layout();
renderer.createPDF(os);
os.close();
}
And the second method I am using (which is closer to the actual way we use it in our app) is:
public static void main(String[] args) throws IOException, DocumentException {
System.getProperties().setProperty("xr.util-logging.loggingEnabled", "true");
XRLog.setLoggingEnabled(true);
String inputFile = "sample.xhtml";
String url = new File(inputFile).toURI().toURL().toString();
DocumentBuilder documentBuilder;
org.w3c.dom.Document xhtmlContent;
try
{
documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
documentBuilder.setEntityResolver(new XhtmlEntityResolver(new SuppressingEntityResolver()));
xhtmlContent = documentBuilder.parse(url);
System.out.println(url);
String outputFile = "firstdoc.pdf";
OutputStream os = new FileOutputStream(outputFile);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(xhtmlContent,".");
renderer.layout();
renderer.createPDF(os);
System.out.println("Finishing up....");
os.close();
}
catch (SAXException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (ParserConfigurationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And the #font-face inclusion in the XHTML looks like this:
#font-face {
font-family: 'MisoRegular';
src: url("miso-regular-webfont.ttf");
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
Now I feel like this is a really common use case and I imagine that I am just failing to perform one simple step in order to get this to work... the problem is that I have been at this for a while and think I am unable to see the forest through the trees. Any help anybody could offer me would be greatly appreciated. Thank you for your time.
I've experienced problems with Flying Saucer where it seemed the fonts were not embedded properly and it ended up being that the font I was trying to embed was corrupted or at least not complete. Attributes regarding the Font Family and description were missing. When I tried validating my font using the Validate File option in FontBook on OS X I was promptly presented with warnings saying:
'name' table usability
'name' table structure
However FlyingSaucer failed silently and just proceeded with embedding Times-Roman and Times-Bold as default fonts. When I tried using a font that passed the FontBook validation I found the font was embedded properly.
I spent hours trying to increase the verbosity in logging from FlyingSaucer to get more information and didn't discover this was the case until I stepped through the entire rendering process and just happened to note that FontFamily was set to "" in the debugger after loading the font and that it didn't include the name I expected it to be registered under.
Bottom line: If you're having an issue with FlyingSaucer and fonts and are banging your head against the wall make sure your font is valid.
I struggled with the same problem like tekgrunt, but finally I got a PDF with a custom font (Computer Modern) embedded. My experiences:
OTF format for the font didn't work (crash in an iText function)
TTF format DID work, after I made the following change: In the CSS, use the same font-family name like the one that is encoded in the font. Set a breakpoint in org.xhtmlrenderer.pdf.ITextFontResolver.addFontFaceFont() and find out which value the variable "fontFamily" gets. If this isn't the same like the CSS font-family, I guess it won't work.
Of course these problems should be reported by the library to the user.
I was facing a similar issue, font not getting applied to the final pdf, and m4t's suggestion about debugging really helped me in identifying the issue. So thanks for that!
In my case actually there were two issues:
The src attribute specified as part of #font-face rule had 2 values, the url and the format. It looked something like
#font-face {
src: url("../../static/fonts/OpenSans-Regular.ttf") format("ttf");
}
Because of the second value format, the CSSParser broke causing the src attribute to be completely skipped silently. As a result in further processing the render did not know where to pick the fonts from. The issue got sorted once I removed the format part from the value.
Once the url was parsed successfully by the CSSParser, it could not be resolved correctly, as the url specified in the css was a relative one and there was no baseUrl specified explicitly (optional 2nd parameter) when calling the setDocumentAsString on the renderer. I fixed the issue by loading uri of static resources explicitly in my code using the classloader, and then setting that as the base url. After that change the path for the font file was resolved successfully and applied to my pdf as well.
Critical thing to note here was, that the base url supplied to
setDocumentAsString must be a URI (file:/folder/structure/static/),
and must end with a trailing slash ('/'). Otherwise the file and url
doesn't get resolved correctly.
Hope this helps someone facing a similar problem.
Related
In a current Project of mine I am using Entity Framework Core together with SQLite in an ASP.Net-Project.
My Problem is, that the Database in the project-files is used, instead of the one in the ./bin-Directory
I followed the instructions of the docs.microsoft-page to create the database:
https://learn.microsoft.com/de-de/ef/core/get-started/overview/first-app?tabs=visual-studio
This is the Connectionstring I am using.
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite("Data Source=MySqliteDatabase.db");
I let the created Database be copyied over, when newer.
I browsed through a number of pages, looking for ways to provide a relative Database path, but I couldnt find a solution to this. It either still uses the project-DB-File, or it wont create the new Database, because it cant be opened, or so.
Does anyone have a solution to this? I noticed that Entity-Framework-Core-5 is kind of a new release, could this be a bug or similar of this particular version?
Thanks #Sergey and #ErikEJ.
So to solve this, I really needed to provide the full path of the directory.
Since Directory.GetCurrentDirectory returned the wrong path, that is, the path to the project-directory instead of the /bin/Debug/... , I looked at the path that is named in the Config-File, as #Sergey suggessted, using the following Code:
AppDomain.CurrentDomain.SetupInformation.ApplicationBase
I got this from the following Stackoverflow page:
How to find path of active app.config file?
It said there, to access the ConfigurationFile-Property, but for ASP.Net it is ApplicationBase I guess.
In there was the correct path, the one of the /bin/Debug/... .
Put together, my new Method looked like this:
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
string databasePath = $"{AppDomain.CurrentDomain.SetupInformation.ApplicationBase}MySqliteDatabase.db";
options.UseSqlite($"Data Source={databasePath}");
}
This works for me as intended, thanks alot for the support, maybe this will help someone else as well.
Problem:
My project... printing a sequence of pages... created based on certain templates and database info...
The sequence of pages to be printed can be, in certain situations, of different sizes.
I have been trying to print to real printer, producing multiple pages
if (m_printer->newPage()) { ... }
and on a physical printer, if I try to change the page size, it either doesn't work or puts the printer in an error state.
So there is not much choice, it seems, but to make each page a separate job. Minor disadvantages - possibly on a network. Oh well.
On pdf or any type of file printing, though, it makes a huge difference, whether the sequence is contained in a single document on multiple pages, or if it creates hundreds of different documents of one page each.
So, I found this Is it possible to make a pdf with different page size in Qt?
it seems to be exactly what I need, if I print to a pdf - while for real printer I will make each page a separate job.
The only problem:
How can I tell if I am creating a pdf file, or if I am sending a job to a real printer ?
I looked in QPrinter and QPrinterInfo, I did not see anything that can help.
Pdf printing is probably enabled because of Adobe Acrobat.
I am implementing this currently in Windows.
Edit: why getting the outputFormat (Naidu's answer below) doesn't work:
qprinter.cpp:
void QPrinterPrivate::initEngines(QPrinter::OutputFormat format, const QPrinterInfo &printer)
{
..
// Only set NativeFormat if we have a valid plugin and printer to use
if (format == QPrinter::NativeFormat) { //////// which of course has to be, we have to support any printer
ps = QPlatformPrinterSupportPlugin::get();
QPrinterInfo printerToUse = findValidPrinter(printer);
if (ps && !printerToUse.isNull()) { //////// both valid since the PDF writer is valid
outputFormat = QPrinter::NativeFormat;
printerName = printerToUse.printerName();
}
}
...
}
I would like to have something to check, other than the fact that "pdf" may be contained in the name. If needed, I am willing to use the awful DEVMODE, I just don't know what to look for.
Use the public function
QPrinter::outputFormat()
it returns an enum type enum QPrinter::OutputFormat.
And check if it is QPrinter::PdfFormat
http://doc.qt.io/qt-5/qprinter.html#OutputFormat-enum
I wanted to place a google static map in a pdffile generated by using the fpdf extension.
and used code to make a tempfile first. Using this code. However I run into an error ('can't open image file').
// define the mapurl
$fullURL = 'http://maps.googleapis.com/maps/api/staticmap?center=Amsterdam&z=14&size=100x100&sensor=false';
// create a tempfile
$tempF = tmpfile();
fwrite($tempF, file_get_contents($fullURL));
//Rewind to the start of file
rewind($tempF);
// place the image in the pdf.
if (!empty($tempF)) {
$this->Image($tempF,$start_x, $this->GetY(),0,100);
}
fclose($tempF); // remove the tempfile
Note: OP's own answer extracted from the question.
Then I found out it can be done much easier... I don't need to use a tempfile. If I put the url in the image variable and give a format the thing works in two lines.. I don't use the height and width parameters in fpdf because they stretch the image into a unreadable form.
$fullURL = "http://maps.googleapis.com/maps/api/staticmap?center=". \
$row-Google_coor."&zoom=10&size=2200x200\
&markers=color:blue%7Clabel:D%7C".$row->Google_coor;
$this->Image($fullURL,$start_x, $this->GetY(),0,0,"PNG");
Saddly when using this function sometimes the program returns an error. The image could not be found. But when I put the url string in the browser the image shows up fine. Hopefully this is also a minor fallback.
Lets see if I find a solution on the google apis site https://developers.google.com/maps/documentation/staticmaps/?csw=1
For what it is worth I had this problem as well, I found that my server had an outgoing connections manager, this would automatically block the request, I had to add the ip, once this was done it worked fine.
I had a problem similiar to the OP's. I was getting an error when using FPDF and trying to get the static map image from Google Maps and into my PDF. I was getting "FPDF error: Missing or incorrect image file". What I did is to register in the Google Developer Console and get an API Key, just like they say in the documentation
Hope this helps.
You can download the image and use it with fpdf
$url ="https://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=600x300&maptype=roadmap&markers=color:blue%7Clabel:S%7C40.702147,-74.015794&markers=color:green%7Clabel:G%7C40.711614,-74.012318&markers=color:red%7Clabel:C%7C40.718217,-73.998284&key=".$googleApiKey;
$img = __DIR__.'/img/map.png';
file_put_contents($img, file_get_contents($url));
$pdf->Image($img,null,null,170);
Hope that this will be helpful
I am trying to work with browseForOpenMultiple function inside Flex, sdk 3.5, I am trying to figure out a bug. The browseForOpenMultiple does not crash everytime, but it seems as though I can upload a file once, but when I go to upload a second file, it crashes when the browseForOpenMultiple function is called. Anyone have any ideas about possible causes?
Update:
private function browseForFiles():void
{
fileBrowser = new File();
fileBrowser.addEventListener(FileListEvent.SELECT_MULTIPLE, filesSelected);
fileBrowser.addEventListener(Event.CANCEL, fileSelectionCancelled);
fileBrowser.browseForOpenMultiple("Select Desired Media File(s)", [(mode == "Media")? MediaTypes.getFileFilter() : MediaTypes.getVideoFilter()]);
}
So the code in our array of file extensions was crashing when there were over 60 items listed in an array that gets converted into a string for the FileFilter. This may not be an Adobe limit, but I wanted to make mention that the crash is fixed, so that others who may be encountering issues with browseForOpenMultiple will know what the issue was for this problem. This is not code that I originally wrote, so I will check into it for more clues, but for the time being, too many array items being joined together into a string for FileFilter object caused the crash.
It could be how it's construct the File, without a real file reference.
Try something like this :
var fileBrowser = File.desktopDirectory
I used something like
Dim i As String
i = Server.MapPath("~/photos/") + fileName
Only once in a project that was working and online, on the offline version, when I run it on my machine, its working, no errors, I uploaded it, it gave me an error like:
'~/photos/http://www.MyURL.com/photos/4411568359267Pic003.jpg' is not a valid virtual path.
Indicating a line in my code:
var marker = new GMarker(new GLatLng(<%=coordinates%>));
This have never happened before, and I don't know where to start troubleshooting as this script -Google Maps- doesn't even need images, i tried to comment it out, it gave me the same error but on a different script this time, the one that show formatting toolbar for the text areas
Line 8: new nicEditor({buttonList : ['fontSize','fontFamily','fontFormat','bold','italic','underline','strikethrough','forecolor','bgcolor','removeformat'], iconsPath : '../nicEdit/nicEditorIcons.gif'}).panelInstance('<%= txtDescription.ClientID %>');
..please HELP :'(
can you post your fileupload aspx page and your function so we can troubleshoot it.
"'~/photos/http://www.MyURL.com/photos/4411568359267Pic003.jpg'"
look closely at the url, it is tacking the full url on to "i". what type of control or you using, a generic or a server side control
solved, turns out the error is due to old database records when i was storing the whole path in the fileName...Thanks Joshua and Keltex