Not finding font Arial.ttf with apache fop 1.0 - apache-fop

I use:
Apache fop 1.0
Java
I need to handle with special characters which unicode is higher than u0100. The target font I should use is Arial. As I cannot expect Arial is present on the target platform (eg. Linux), I embedded an Arial.ttf in my jar.
My actual config-file looks like this:
<fop ...>
<!-- Base URL for resolving relative URLs -->
<base>./</base>
<!-- Font Base URL for resolving relative font URLs -->
<font-base>./</font-base>
<renderers>
<renderer mime="application/pdf">
<fonts>
<font kerning="yes" embed-url="arial.ttf" encoding-mode="auto">
<font-triplet name="Arial" style="normal" weight="normal"/>
<font-triplet name="ArialMT" style="normal" weight="normal"/>
</font>
<!--<directory>C:/Windows/Fonts</directory>-->
</fonts>
<auto-detect/>
</renderer>
...
</fop>
Doing it this way I get an error loading my config-file to fop:
org.apache.fop.apps.FOPException: Failed to resolve font with embed-url 'arial.ttf'
The only way I managed to get it work until now was to hardcode the folder path into the config file:
<font kerning="yes" embed-url="C:/myapp/arial.ttf" encoding-mode="auto">
<font-triplet name="Arial" style="normal" weight="normal"/>
<font-triplet name="ArialMT" style="normal" weight="normal"/>
</font>
But obviously this cannot be the solution!
Using the "directory" tag whould work on Windows, just because you have Arial there. But as mentioned above it must also run on Linux, Macs, etc.
The "auto-detect" tag didn't work either (even not on Windows) - and isn't a solution as I cannot expect the target platform having Arial installed.
Any suggestions to solve this?

I finally found the answer. See:
https://web.archive.org/web/20120831233158/http://www.publicstaticfinal.de/2011/01/26/fop-embedding-fonts-from-classpath
The solution is to add an own URIResolver to the fopFactory.

This solution doesn't work for me. It is because ClassLoader.getSystemResourceAsStream(href); returns null.
I have found another solution but it has a different problem - if you have some other resources which you add to the FOP with the absolute system path (e.g. images selected by user), than your custom URIResolver is used either for them so they are resolved incorrectly.
If you want to correct these examples just mix them and you are getting working solution like this:
import java.io.InputStream;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;
public class ClasspathUriResolver implements URIResolver {
#Override
public Source resolve(String href, String base) throws TransformerException {
Source source = null;
InputStream inputStream = getClass().getResourceAsStream(href);
if (inputStream != null) {
source = new StreamSource(inputStream);
}
return source;
}
}
Usage
[...]
FopFactory fopFactory = FopFactory.newInstance();
FOURIResolver uriResolver = (FOURIResolver) fopFactory.getURIResolver();
uriResolver.setCustomURIResolver(new ClasspathUriResolver());
[...]

You have <auto-detect/> outside the <fonts> tag. To solve our font problem we put <auto-detect/> inside the <fonts> tag.
We don't use additional <font> configurations, but just use the system fonts detected with <auto-detect/>

Not sure if it's your problem but I found out that since some version relative paths don't work for in the Fop config file. For me, it worked if I either supplied an absolute path (starting with '/') or prefixed the path with 'file:' like 'file:.'.

Related

Vala Gtk css provider load_from_path

I don't know why load_from_path does not work during sudo ninja install. It returns:
warning: unhandled error `GLib.Error'
css_provider.load_from_path ("com.github.saidbakr.quick-shutdown.css");
I tried to catch the exception, but the same Warning:
Gtk.CssProvider css_provider = new Gtk.CssProvider ();
try {
css_provider.load_from_path ("com.github.saidbakr.quick-shutdown.css");
}
catch (IOError e){
GLib.error("", e.message);
}
I checkedout the meson.build:
...
install_data(
join_paths('data', meson.project_name()+ '.css'),
install_dir: join_paths(get_option('datadir'))
)
The path of the file is added and it is installed to /usr/local/share
I don't know how to solve this issue.
The docs for Gtk.CssProvider.load_from_path() make no mention of searching in /usr/local/share/<app-data-dir> or any other standard directory. It's expecting an absolute path.
The standard way to solve this is to use GResource. If you're using a tutorial or template, it probably has something on GResource that you can use.
If not:
Create a file, quick-shutdown.gresource.xml, with the following:
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/com/github/saidbakr/quick-shutdown">
<file>com.github.saidbakr.quick-shutdown.css</file>
</gresource>
</gresources>
Add this to your meson.build:
gnome = import('gnome')
resources = gnome.compile_resources('com.github.saidbakr.quick-shutdown',
files('quick-shutdown.gresource.xml'),
)
Add resources to the list of sources in your executable() call in meson.build
Use Gtk.CssProvider.load_from_resource() instead: css_provider.load_from_resource ("/com/github/saidbakr/quick-shutdown/com.github.saidbakr.quick-shutdown.css")
Remove the meson code where you install the CSS file. It is now built directly into your executable.
For a real-world example of how to do this, check out the GNOME Clocks source code.
This may sound like a lot of steps, but it's the same steps as adding GtkBuilder UI files (or really any other kind of static file you need in your program). If you need to do that later, all you'll have to do is add <file> entries to the .gresource.xml file.

Automatically create i18n directory for VSCode extension

I am trying to understand the workflow presented in https://github.com/microsoft/vscode-extension-samples/tree/master/i18n-sample for localizing Visual Studio Code extensions.
I cannot figure out how the i18n directory gets created to begin with, as well as how the set of string keys in that directory get maintained over time.
There is one line in the README.md which says "You could have created this folder by hand, or you could have used the vscode-nls-dev tool to extract it."...how would one use vscode-nls-dev tool to extract it?
What I Understand
I understand that you can use vscode-nls, and wrap strings like this: localize("some.key", "My String") to pick up the localized version of that string at runtime.
I am pretty sure I understand that vscode-nls-dev is used at build time to substitute the content of files in the i18n directory into the transpiled JavaScript code, as well as creating files like out/extension.nls.ja.json
What is missing
Surely it is not expected that: for every file.ts file in your project you create an i18n/lang/out/file.i18n.json for every lang you support...and then keep the set of keys in that file up to date manually with every string change.
I am assuming that there is some process which automatically goes "are there any localize("key", "String") calls in file.ts for new keys not yet in file.i18n.json? If so, add those keys with some untranslated values". What is that process?
I have figured this out, referencing https://github.com/Microsoft/vscode-extension-samples/issues/74
This is built to work if you use Transifex for your translator. At the bare minimum you need to use .xlf files as your translation file format.
I think that this is best illustrated with an example, so lets say you wanted to get the sample project working after you had deleted the i18n folder
Step 1: Clone that project, and delete the i18n directory
Step 2: Modify the gulp file so that the compile function also generates nls metadata files in the out directory. Something like:
function compile(buildNls) {
var r = tsProject.src()
.pipe(sourcemaps.init())
.pipe(tsProject()).js
.pipe(buildNls ? nls.rewriteLocalizeCalls() : es.through())
.pipe(buildNls ? nls.createAdditionalLanguageFiles(languages, 'i18n', 'out') : es.through())
.pipe(buildNls ? nls.bundleMetaDataFiles('ms-vscode.node-debug2', 'out') : es.through())
.pipe(buildNls ? nls.bundleLanguageFiles() : es.through())
Step 3: Run the gulp build command. This will generate several necessary metadata files in the out/ directory
Step 4: Create and run a new gulp function to export the necessarry translations to the xlf file. Something like:
gulp.task('export-i18n', function() {
return gulp.src(['package.nls.json', 'out/nls.metadata.header.json', 'out/nls.metadata.json'])
.pipe(nls.createXlfFiles("vscode-extensions", "node-js-debug2"))
.pipe(gulp.dest(path.join('vscode-translations-export')));
}
Step 5: Get the resulting xlf file translated. Or, add some dummy values. I cant find if/where there is documentation for the file format needed, but this worked for me (for the extension):
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file original="package" source-language="en" target-language="ja" datatype="plaintext"><body>
<trans-unit id="extension.sayHello.title">
<source xml:lang="en">Hello</source>
<target>JA_Hello</target>
</trans-unit>
<trans-unit id="extension.sayBye.title">
<source xml:lang="en">Bye</source>
<target>JA_Bye</target>
</trans-unit>
</body></file>
<file original="out/extension" source-language="en" target-language="ja" datatype="plaintext"><body>
<trans-unit id="sayHello.text">
<source xml:lang="en">Hello</source>
<target>JA_Hello</target>
</trans-unit>
</body></file>
<file original="out/command/sayBye" source-language="en" target-language="ja" datatype="plaintext"><body>
<trans-unit id="sayBye.text">
<source xml:lang="en">Bye</source>
<target>JA_Bye</target>
</trans-unit>>
</body></file>
</xliff>
Step 6: Stick that file in some known location, let's say /path/to/translation.xlf. Then add/run another new gulp task to import the translation. Something like:
gulp.task('i18n-import', () => {
return es.merge(languages.map(language => {
console.log(language.folderName)
return gulp.src(["/path/to/translation.xlf"])
.pipe(nls.prepareJsonFiles())
.pipe(gulp.dest(path.join('./i18n', language.folderName)));
}));
});
Step 7: Run the gulp build again.
The i18n/ directory should now be recreated correctly! Running the same build/export/translate/import/build steps will pick up any new changes to the localize() calls in your TypeScript code
Obviously this is not perfect, there are a lot of hardcoded paths and such, but hopefully it helps out anyone else who hits this issue.

How to use TrueType Fonts in AFP with Apache FOP?

I'm trying to use a TrueType font in AFP with Apache FOP 2.2.
I believe I configured things correctly, but I'm getting the following exception:
java.lang.ClassCastException: org.apache.fop.afp.modca.MapDataResource cannot be cast to org.apache.fop.afp.modca.MapCodedFont
at org.apache.fop.afp.modca.ActiveEnvironmentGroup.getCurrentMapCodedFont(ActiveEnvironmentGroup.java:286)
at org.apache.fop.afp.modca.ActiveEnvironmentGroup.createFont(ActiveEnvironmentGroup.java:201)
at org.apache.fop.afp.modca.AbstractPageObject.createFont(AbstractPageObject.java:149)
at org.apache.fop.afp.DataStream.createFont(DataStream.java:331)
at org.apache.fop.afp.DataStream.addFontsToCurrentPage(DataStream.java:313)
at org.apache.fop.render.afp.AFPDocumentHandler.endPage(AFPDocumentHandler.java:310)
at org.apache.fop.render.intermediate.util.IFDocumentHandlerProxy.endPage(IFDocumentHandlerProxy.java:167)
at org.apache.fop.render.intermediate.EventProducingFilter.endPage(EventProducingFilter.java:48)
at org.apache.fop.render.intermediate.IFRenderer.renderPage(IFRenderer.java:603)
at org.apache.fop.area.RenderPagesModel.renderPage(RenderPagesModel.java:193)
at org.apache.fop.area.RenderPagesModel.checkPreparedPages(RenderPagesModel.java:174)
at org.apache.fop.area.RenderPagesModel.addPage(RenderPagesModel.java:146)
at org.apache.fop.layoutmgr.AbstractPageSequenceLayoutManager.finishPage(AbstractPageSequenceLayoutManager.java:316)
at org.apache.fop.layoutmgr.PageSequenceLayoutManager.finishPage(PageSequenceLayoutManager.java:226)
at org.apache.fop.layoutmgr.PageSequenceLayoutManager.activateLayout(PageSequenceLayoutManager.java:145)
at org.apache.fop.area.AreaTreeHandler.endPageSequence(AreaTreeHandler.java:267)
at org.apache.fop.fo.pagination.PageSequence.endOfNode(PageSequence.java:130)
at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
Below is a snippet of my conf.xml configuration:
<renderer mime="application/x-afp">
<fonts>
<font name="Script MT Bold" kerning="yes" embed-url="/fonts/SCRIPTBL.TTF">
<font-triplet name="Script MT Bold" style="normal" weight="normal"/>
</font>
</fonts>
</renderer>
Do I require additional configurations?
Additionally, must I embed the TrueType font in AFP or can I simply include a reference and rely on the mainframe printer to resolve it?
I also faced the same exception. It seems like while creating the fonts for rendering the current page FOP populates a list of AbstractStructuredObject.
While loading the True Type font FOP creates a MapDataResource for it and populates the same in the list of AbstractStructuredObject.
However if the page has some other font such as a raster font then before loading this raster font it gets the most recent AbstractStructuredObject from the list and typecasts it to MapCodedFont. Since, the recent most object was of of type MapDataResource we get ClassCastException.
As a workaround I am currently using only True Type fonts in my AFP document and have added the default font-triplet to one of the font configuration.
<font name="Script MT Bold" kerning="yes" embed-url="/fonts/SCRIPTBL.TTF">
<font-triplet name="Script MT Bold" style="normal" weight="normal"/>
<font-triplet name="any" style="normal" weight="normal"/>
</font>

Apache FOP | custom fonts | relative URL not working

I have got configuration file to load custom fonts for Apache FOP. I am struggling to configure embed-url on server so that font url changes as per server domain.
I have tried embed-url property value as:
Non working embed-urls:
embed-url="context:/etc/designs/projectName/clientlibs/pdffonts/Batang.ttf"
embed-url="file:/etc/designs/projectName/clientlibs/pdffonts/Batang.ttf"
Working embed-url:
embed-url="http://localhost:4503/etc/designs/projectName/clientlibs/pdffonts/Batang.ttf"
Somehow I can't seems to find proper syntax here. I am using FOP with AEM 6.0.
<?xml version="1.0"?>
<fop version="1.0">
<renderers>
<renderer mime="application/pdf">
<fonts>
<font kerning="yes"
embed-url="context:/etc/designs/projectName/clientlibs/pdffonts/Batang.ttf" -- this doesn't
embedding-mode="subset">
<font-triplet name="SimSun" style="normal" weight="normal" />
</font>
<font kerning="yes"
embed-url="file:/etc/designs/projectName/clientlibs/pdffonts/Batang.ttf" -- this doesn't
embedding-mode="subset">
<font-triplet name="Batang" style="normal" weight="normal" />
</font>
<font kerning="yes"
embed-url="http://localhost:4503/etc/designs/projectName/clientlibs/pdffonts/Batang.ttf" -- this works
embedding-mode="subset">
<font-triplet name="Batang" style="normal" weight="normal" />
</font>
</fonts>
</renderer>
</renderers>
</fop>
"Starting point" for relative paths:
if the configuration file has a font-base element (as a direct child of the document root element), its value is used to resolve relative font paths
otherwise, the value of the base element is used instead
the default configuration file included in the distribution has the element <base>.</base>, meaning that relative paths must be interpreted as relative to the position of the configuration file
Note that the values of font-base and base can be relative too, in which case they refer to the configuration file path.
<?xml version="1.0"?>
<fop version="1.0">
<base>.</base>
<font-base>/Users/lfurini/Library/Fonts</font-base>
<!-- other possible examples:
<font-base>.</font-base>
<font-base>../fonts</font-base>
-->
<!-- ... -->
</fop>
Relative paths syntax:
you don't need context: or file:
if the embed-url starts with / it's an absolute path, otherwise it's a relative one referring to the "starting point" defined before
relative paths can contain ../ to go back up in the folder hierarchy, if needed
<!-- directly in the base folder -->
<font kerning="yes" embed-url="font1.ttf">
<font-triplet name="font1" style="normal" weight="normal"/>
</font>
<!-- in a "sister" folder -->
<font kerning="yes" embed-url="../otherFonts/font2.ttf">
<font-triplet name="font2" style="normal" weight="normal"/>
</font>
<!-- in a sub-folder -->
<font kerning="yes" embed-url="specialFonts/font3.ttf">
<font-triplet name="font3" style="normal" weight="normal"/>
</font>
<!-- absolute path -->
<font kerning="yes" embed-url="/Users/lfurini/Library/Fonts/font4.ttf" embedding-mode="subset">
<font-triplet name="font4" style="normal" weight="normal"/>
</font>
(tested with FOP 1.1, 2.0 and 2.1)
(disclosure: I'm a FOP developer, though not very active nowadays)
I solved it by adding full path upto application from code. and added later patr from config file.
fopFactory.setBaseURL(this.getServletContext().getInitParameter("my_path"));
In config
embed-url="fonts/newfont.ttf"
For FOP-2.1 there is a patch for "Allow relative paths to font files/directories" at https://issues.apache.org/jira/browse/FOP-2627.

Simple WoW Interface Addon doesn't work (Lua)

I'm trying to build a simple Hello World interface addon for World of Warcraft. But it won't work :/ Can anybody tell me what I'm doing wrong?
Here is the HelloWorld.toc file:
## Interface: 60000
## Title: HelloWorld
## Notes: HelloWorld Addon
## Version: 1.0
HelloWorld.xml
Here is the HelloWorld.xml file:
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
<Script file= “HelloWorld.lua”/> <!-- wrong quotation here -->
<Frame name= “HelloWorldFrame”> <!-- and here (see answer)-->
<Scripts>
<OnLoad>
HelloWorld_OnLoad();
</OnLoad>
</Scripts>
</Frame>
</Ui>
And here is the HelloWorld.lua file:
function HelloWorld_OnLoad()
print("Hello World!");
end
If I start the game then I can see the "HelloWorld" addon in the list. But after I login with a character nothing happens.
Make sure you check all scripts for "wrong" quotation marks. Compilers or interpreters expect either " or ' (" in the case of Lua and files).
Many word processors or internet sites use different quotation marks because they "look better". But compilers aren't in it for the looks, they will not understand those better looking characters.