You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-users@xmlgraphics.apache.org by cdellasanta <cd...@detailag.ch> on 2012/11/16 19:23:40 UTC

Extract font width using FOP

Hi all,

I'm trying to auto size a font to not exceed the block dimensions, giving a
default max size and downgrading to predefined steps until it fits or a
minimum size is reached.

I can't use the SVG "trick" because I want to fit to a max defined width,
and and as the size is reduced more text will fit in a single line.

My idea is to build an external processor step that calculates the optimum
font size to be used for the block. But to do this I need the exact font
width (in millipoints) of each character (or word) of the selected font
triplet on each font size I intend to use.

Browsing the fop project  source I've found the
org.apache.fop.fonts.Font.getCharWidth(), but It's for me a bit tricky to
instantiate correctly this Class.

I assume the the best way to get this is to start from the
org.apache.fop.tools.fontlist.FontListMain that does already the fop
configuration and loading of the font. But as a xsl-fo end-user, I've no
knowledge on the fop internals (structure/architecture) to go from A to B.

Can you please give me some hints or practical examples?
Wold it make sense to extend the org.apache.fop.tools to provide this
functionality?
Or am I on the wrong way?

Thanks in advance for any hint or feedback you can provide.

Regards.

p.s. I'm generating documents using a custom font, that I've imported using
org.apache.fop.fonts.apps.TTFReader and imported using the specific
configuration file.




--
View this message in context: http://apache-fop.1065347.n5.nabble.com/Extract-font-width-using-FOP-tp37360.html
Sent from the FOP - Users mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Re: Extract font width using FOP

Posted by atalante <ah...@ch-wissembourg.fr>.
Maybe late, but this post was helpful for me.
As cdellasanta i wanted to get the font object using a custom font.


cdellasanta wrote
> And now I need an additional support; As I mentioned in my first post I'm
> using a custom font, loaded through the custom fop.xconf.
> 
> But the 

>  loads only the predefined fonts metrics (F1 to F14).
> 
> How do I load the metrics of my custom font?
> 
> Best regards,
> Curzio


I explore the fop classes and find my happiness on the FontListGenerator
class.

And then this is a function i wrote for me for retrieving a Font object.
Works with all fonts specified in the fop file configuration.





--
View this message in context: http://apache-fop.1065347.n5.nabble.com/Extract-font-width-using-FOP-tp37360p43763.html
Sent from the FOP - Users mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Re: Extract font width using FOP

Posted by cdellasanta <cd...@detailag.ch>.
Hi all,

First of all I'd like to thank all who answered.

I'd like to share code, results, toughts and ask some more support .

Let's start from the code (many thanks to Matthias):


Here the result:


The Font:getWordWidth is very inaccurate for a long string, becuase for each
character the size is floored to integer [point], means that in worst case
you miss 1 point per char.

I've generated a big document to mesure the real width of the string, and I
got results near the FontMetrics:getWidth ... 3 to 5 points miss, thise are
probably due to my imperfection doing the mesurement manually.

My toughts:
I agree with Glenn when he says

Glenn Adams-2 wrote
> However, calling getCharWidth() on a given character will not necessarily
> produce the same results as FOP regarding line fitting due to the affects
> of:
> 
>    - kerning
>    - letter/word spacing
>    - complex script features (GSUB/GPOS) which apply to all scripts
> 
> In general, I would expect summing getCharWidth() over some substring of
> text to be line fitted will produce a larger width than FOP may end up
> using. So such estimates could be used for upper bounds of required
> measure, but not lower bounds.

The best way to get those points into account is to do the calculation with
the exact code that fop uses in placing the characters into a block. 
For my objective is not needed because:
 - the font I'm using does not uses kernering
 - I'm placing the text left aligned into the block (no justified)
 - (I don't know anything about "complex script features", first time I hear
about this)  

I indeed use a custom letter-spacing, but I assume I can add to my result
"mySpacing * (text.lenght()-1)" .. (right?)
About the word-spacing, are there specific cases where the length of a
"normal white space" diffears ftom the one defined into the font?


And now I need an additional support; As I mentioned in my first post I'm
using a custom font, loaded through the custom fop.xconf.

But the  loads only the predefined fonts metrics (F1 to F14).

How do I load the metrics of my custom font?

Best regards,
Curzio



--
View this message in context: http://apache-fop.1065347.n5.nabble.com/Extract-font-width-using-FOP-tp37360p37383.html
Sent from the FOP - Users mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Re: Extract font width using FOP

Posted by Glenn Adams <gl...@skynav.com>.
However, calling getCharWidth() on a given character will not necessarily
produce the same results as FOP regarding line fitting due to the affects
of:

   - kerning
   - letter/word spacing
   - complex script features (GSUB/GPOS) which apply to all scripts

In general, I would expect summing getCharWidth() over some substring of
text to be line fitted will produce a larger width than FOP may end up
using. So such estimates could be used for upper bounds of required
measure, but not lower bounds.

On Sun, Nov 18, 2012 at 11:48 AM, Matthias Reischenbacher <
matthias8283@gmx.at> wrote:

> Hi,
>
> what you need is an instance of FontInfo, from there you can retrieve the
> "Font" you need and call getCharWidth().
>
> If you are using FOP version 1.1 or older use the following code snippet:
>
> import org.apache.fop.apps.**FOPException;
> import org.apache.fop.fonts.**EmbedFontInfo;
> import org.apache.fop.fonts.**FontCollection;
> import org.apache.fop.fonts.**FontEventListener;
> import org.apache.fop.fonts.FontInfo;
> import org.apache.fop.fonts.**FontInfoConfigurator;
> import org.apache.fop.fonts.**FontManager;
> import org.apache.fop.fonts.**FontManagerConfigurator;
> import org.apache.fop.fonts.**FontResolver;
> import org.apache.fop.fonts.**FontSetup;
>
> FontInfo fontInfo = new FontInfo();
>
> FontResolver fontResolver = FontManager.**createMinimalFontResolver();
>
> FontManager fontManager = new FontManager();
>
> final FontEventListener listener = null;
> final boolean strict = false;
>
> FontManagerConfigurator fm = new FontManagerConfigurator(this.**
> getConfiguration());
>
> fm.configure(fontManager, true);
>
> FontInfoConfigurator fontInfoConfigurator
>     = new FontInfoConfigurator(this.**getConfiguration(), fontManager,
> fontResolver, listener, strict);
> List<EmbedFontInfo> fontInfoList = new ArrayList<EmbedFontInfo>();
> fontInfoConfigurator.**configure(fontInfoList);
>
> if (fontManager.useCache()) {
>     fontManager.getFontCache().**save();
> }
>
> FontSetup.setup(fontInfo, fontInfoList, fontResolver);
>
> fontManager.setup(fontInfo, new FontCollection[]{});
>
> For the FOP trunk version the following code snippet has to be used:
>
> import org.apache.fop.apps.**FOPException;
> import org.apache.fop.apps.**FOUserAgent;
> import org.apache.fop.apps.Fop;
> import org.apache.fop.apps.**FopConfParser;
> import org.apache.fop.apps.**FopFactory;
> import org.apache.fop.apps.**FopFactoryBuilder;
> import org.apache.fop.apps.io.**InternalResourceResolver;
> import org.apache.fop.apps.io.**Resource;
> import org.apache.fop.apps.io.**ResourceResolver;
> import org.apache.fop.apps.io.**ResourceResolverFactory;
>
> import org.apache.fop.fonts.**DefaultFontConfig;
> import org.apache.fop.fonts.**DefaultFontConfigurator;
> import org.apache.fop.fonts.**EmbedFontInfo;
> import org.apache.fop.fonts.**FontCacheManagerFactory;
> import org.apache.fop.fonts.**FontCollection;
> import org.apache.fop.fonts.**FontDetectorFactory;
> import org.apache.fop.fonts.**FontEventListener;
> import org.apache.fop.fonts.FontInfo;
> import org.apache.fop.fonts.**FontManager;
> import org.apache.fop.fonts.**FontManagerConfigurator;
> import org.apache.fop.fonts.**FontSetup;
>
> FontInfo fontInfo = new FontInfo();
>
> final FontEventListener listener = null;
> final boolean strict = false;
>
> Configuration cfg = this.getConfiguration();
>
> ResourceResolver resResolver = ResourceResolverFactory.**
> createDefaultResourceResolver(**);
>
> InternalResourceResolver resourceResolver
>         = ResourceResolverFactory.**createDefaultInternalResourceR**
> esolver(this.getBaseURI());
>
> FontManager fontManager = new FontManager(resourceResolver,
> FontDetectorFactory.**createDefault(),
>         FontCacheManagerFactory.**createDefault());
>
> FontManagerConfigurator fm = new FontManagerConfigurator(cfg,
> this.getBaseURI(), resResolver);
>
> fm.configure(fontManager, true);
>
> DefaultFontConfig.**DefaultFontConfigParser parser
>         = new DefaultFontConfig.**DefaultFontConfigParser();
> DefaultFontConfig fontInfoConfig = parser.parse(cfg, strict);
> DefaultFontConfigurator fontInfoConfigurator
>         = new DefaultFontConfigurator(**fontManager, listener, strict);
> List<EmbedFontInfo> fontInfoList = fontInfoConfigurator.**
> configure(fontInfoConfig);
> fontManager.saveCache();
>
> FontSetup.setup(fontInfo, fontInfoList, resourceResolver, false);
>
> fontManager.setup(fontInfo, new FontCollection[]{});
>
> return fontInfo;
>
> Best regards,
> Matthias
>
> On 16.11.2012 15:23, cdellasanta wrote:
>
>> Hi all,
>>
>> I'm trying to auto size a font to not exceed the block dimensions, giving
>> a
>> default max size and downgrading to predefined steps until it fits or a
>> minimum size is reached.
>>
>> I can't use the SVG "trick" because I want to fit to a max defined width,
>> and and as the size is reduced more text will fit in a single line.
>>
>> My idea is to build an external processor step that calculates the optimum
>> font size to be used for the block. But to do this I need the exact font
>> width (in millipoints) of each character (or word) of the selected font
>> triplet on each font size I intend to use.
>>
>> Browsing the fop project  source I've found the
>> org.apache.fop.fonts.Font.**getCharWidth(), but It's for me a bit tricky
>> to
>> instantiate correctly this Class.
>>
>> I assume the the best way to get this is to start from the
>> org.apache.fop.tools.fontlist.**FontListMain that does already the fop
>> configuration and loading of the font. But as a xsl-fo end-user, I've no
>> knowledge on the fop internals (structure/architecture) to go from A to B.
>>
>> Can you please give me some hints or practical examples?
>> Wold it make sense to extend the org.apache.fop.tools to provide this
>> functionality?
>> Or am I on the wrong way?
>>
>> Thanks in advance for any hint or feedback you can provide.
>>
>> Regards.
>>
>> p.s. I'm generating documents using a custom font, that I've imported
>> using
>> org.apache.fop.fonts.apps.**TTFReader and imported using the specific
>> configuration file.
>>
>>
>>
>>
>> --
>> View this message in context: http://apache-fop.1065347.n5.**
>> nabble.com/Extract-font-width-**using-FOP-tp37360.html<http://apache-fop.1065347.n5.nabble.com/Extract-font-width-using-FOP-tp37360.html>
>>
>> Sent from the FOP - Users mailing list archive at Nabble.com.
>>
>> ------------------------------**------------------------------**---------
>> To unsubscribe, e-mail: fop-users-unsubscribe@**xmlgraphics.apache.org<fo...@xmlgraphics.apache.org>
>> For additional commands, e-mail: fop-users-help@xmlgraphics.**apache.org<fo...@xmlgraphics.apache.org>
>>
>>
>
> ------------------------------**------------------------------**---------
> To unsubscribe, e-mail: fop-users-unsubscribe@**xmlgraphics.apache.org<fo...@xmlgraphics.apache.org>
> For additional commands, e-mail: fop-users-help@xmlgraphics.**apache.org<fo...@xmlgraphics.apache.org>
>
>

Re: Extract font width using FOP

Posted by Matthias Reischenbacher <ma...@gmx.at>.
Hi,

what you need is an instance of FontInfo, from there you can retrieve 
the "Font" you need and call getCharWidth().

If you are using FOP version 1.1 or older use the following code snippet:

import org.apache.fop.apps.FOPException;
import org.apache.fop.fonts.EmbedFontInfo;
import org.apache.fop.fonts.FontCollection;
import org.apache.fop.fonts.FontEventListener;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontInfoConfigurator;
import org.apache.fop.fonts.FontManager;
import org.apache.fop.fonts.FontManagerConfigurator;
import org.apache.fop.fonts.FontResolver;
import org.apache.fop.fonts.FontSetup;

FontInfo fontInfo = new FontInfo();

FontResolver fontResolver = FontManager.createMinimalFontResolver();

FontManager fontManager = new FontManager();

final FontEventListener listener = null;
final boolean strict = false;

FontManagerConfigurator fm = new 
FontManagerConfigurator(this.getConfiguration());

fm.configure(fontManager, true);

FontInfoConfigurator fontInfoConfigurator
     = new FontInfoConfigurator(this.getConfiguration(), fontManager, 
fontResolver, listener, strict);
List<EmbedFontInfo> fontInfoList = new ArrayList<EmbedFontInfo>();
fontInfoConfigurator.configure(fontInfoList);

if (fontManager.useCache()) {
     fontManager.getFontCache().save();
}

FontSetup.setup(fontInfo, fontInfoList, fontResolver);

fontManager.setup(fontInfo, new FontCollection[]{});

For the FOP trunk version the following code snippet has to be used:

import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopConfParser;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.FopFactoryBuilder;
import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.apps.io.Resource;
import org.apache.fop.apps.io.ResourceResolver;
import org.apache.fop.apps.io.ResourceResolverFactory;

import org.apache.fop.fonts.DefaultFontConfig;
import org.apache.fop.fonts.DefaultFontConfigurator;
import org.apache.fop.fonts.EmbedFontInfo;
import org.apache.fop.fonts.FontCacheManagerFactory;
import org.apache.fop.fonts.FontCollection;
import org.apache.fop.fonts.FontDetectorFactory;
import org.apache.fop.fonts.FontEventListener;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontManager;
import org.apache.fop.fonts.FontManagerConfigurator;
import org.apache.fop.fonts.FontSetup;

FontInfo fontInfo = new FontInfo();

final FontEventListener listener = null;
final boolean strict = false;

Configuration cfg = this.getConfiguration();

ResourceResolver resResolver = 
ResourceResolverFactory.createDefaultResourceResolver();

InternalResourceResolver resourceResolver
	= 
ResourceResolverFactory.createDefaultInternalResourceResolver(this.getBaseURI());

FontManager fontManager = new FontManager(resourceResolver, 
FontDetectorFactory.createDefault(),
         FontCacheManagerFactory.createDefault());

FontManagerConfigurator fm = new FontManagerConfigurator(cfg, 
this.getBaseURI(), resResolver);

fm.configure(fontManager, true);

DefaultFontConfig.DefaultFontConfigParser parser
         = new DefaultFontConfig.DefaultFontConfigParser();
DefaultFontConfig fontInfoConfig = parser.parse(cfg, strict);
DefaultFontConfigurator fontInfoConfigurator
         = new DefaultFontConfigurator(fontManager, listener, strict);
List<EmbedFontInfo> fontInfoList = 
fontInfoConfigurator.configure(fontInfoConfig);
fontManager.saveCache();

FontSetup.setup(fontInfo, fontInfoList, resourceResolver, false);

fontManager.setup(fontInfo, new FontCollection[]{});

return fontInfo;

Best regards,
Matthias

On 16.11.2012 15:23, cdellasanta wrote:
> Hi all,
>
> I'm trying to auto size a font to not exceed the block dimensions, giving a
> default max size and downgrading to predefined steps until it fits or a
> minimum size is reached.
>
> I can't use the SVG "trick" because I want to fit to a max defined width,
> and and as the size is reduced more text will fit in a single line.
>
> My idea is to build an external processor step that calculates the optimum
> font size to be used for the block. But to do this I need the exact font
> width (in millipoints) of each character (or word) of the selected font
> triplet on each font size I intend to use.
>
> Browsing the fop project  source I've found the
> org.apache.fop.fonts.Font.getCharWidth(), but It's for me a bit tricky to
> instantiate correctly this Class.
>
> I assume the the best way to get this is to start from the
> org.apache.fop.tools.fontlist.FontListMain that does already the fop
> configuration and loading of the font. But as a xsl-fo end-user, I've no
> knowledge on the fop internals (structure/architecture) to go from A to B.
>
> Can you please give me some hints or practical examples?
> Wold it make sense to extend the org.apache.fop.tools to provide this
> functionality?
> Or am I on the wrong way?
>
> Thanks in advance for any hint or feedback you can provide.
>
> Regards.
>
> p.s. I'm generating documents using a custom font, that I've imported using
> org.apache.fop.fonts.apps.TTFReader and imported using the specific
> configuration file.
>
>
>
>
> --
> View this message in context: http://apache-fop.1065347.n5.nabble.com/Extract-font-width-using-FOP-tp37360.html
> Sent from the FOP - Users mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
> For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Re: Extract font width using FOP

Posted by Glenn Adams <gl...@skynav.com>.
On Sat, Nov 17, 2012 at 5:38 AM, Bonekrusher <dj...@yahoo.com> wrote:

> Would this measurement be considered "relative"? If I pass my java
> extension
> (per example), a string with a Font that is Arial 9, Font Metrics will
> return a length. This is outside of FOP. Are you saying that Font 9 width
> can be different if FOP is not using AWT?
>

Yes. FOP does not use AWT for determining font metrics or for making glyph
placement or line breaking decisions. FOP reads font metrics directly from
font files, including kerning and other glyph position adjustment
information.

So what you may learn from AWT's FontMetrics may or may not be what FOP
uses. If it happens to be the same is some special case, then that is
merely a coincidence.

Re: Extract font width using FOP

Posted by Bonekrusher <dj...@yahoo.com>.
Hi Glenn,

Would this measurement be considered "relative"? If I pass my java extension
(per example), a string with a Font that is Arial 9, Font Metrics will
return a length. This is outside of FOP. Are you saying that Font 9 width
can be different if FOP is not using AWT?

Thx 

Phil  



--
View this message in context: http://apache-fop.1065347.n5.nabble.com/Extract-font-width-using-FOP-tp37360p37366.html
Sent from the FOP - Users mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Re: Extract font width using FOP

Posted by Glenn Adams <gl...@skynav.com>.
except that (in general) FOP does not use AWT to obtain font metrics

On Fri, Nov 16, 2012 at 4:29 PM, Bonekrusher <dj...@yahoo.com> wrote:

> You can right an extension in Java and use Font Metrics... I wrote this a
> while back, so it might need to be updated. This example will return the
> width of a String.
>
>
> import java.awt.Font;
> import java.awt.FontMetrics;
> import java.awt.Toolkit;
>
> public class StringLength {
>
>
>         public static void main(String[] args) throws
> NumberFormatException {
>
>                 if(args.length < 2){
>                         System.out.println("StringLength <string> <int
> font size>");
>                         System.exit(0);
>                 }else{
>                         getStringLength(args[0],
> Integer.parseInt(args[1]));
>                 }
>
>         }
>
>         @SuppressWarnings("deprecation")
>         public static int getStringLength(String str, int size){
>
>                 Toolkit toolkit =  Toolkit.getDefaultToolkit();
>                 int stringlen = 0;
>                 Font font = new Font("Arial", Font.PLAIN, 9);
>                 FontMetrics fontMetrics = toolkit.getFontMetrics(font);
>                 System.out.println ("[Stylesheet Info] Calculating width
> for: " + str + ":
> "  + fontMetrics.stringWidth(str));
>                 stringlen = fontMetrics.stringWidth(str);
>                 return stringlen;
>         }
>
>
> }
>
>
>
>
> --
> View this message in context:
> http://apache-fop.1065347.n5.nabble.com/Extract-font-width-using-FOP-tp37360p37361.html
> Sent from the FOP - Users mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
> For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org
>
>

Re: Extract font width using FOP

Posted by Bonekrusher <dj...@yahoo.com>.
You can right an extension in Java and use Font Metrics... I wrote this a
while back, so it might need to be updated. This example will return the
width of a String.


import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Toolkit;

public class StringLength {


	public static void main(String[] args) throws NumberFormatException {

		if(args.length < 2){
			System.out.println("StringLength <string> <int font size>");
			System.exit(0);
		}else{
			getStringLength(args[0], Integer.parseInt(args[1]));							
		}          
		  		
	}

	@SuppressWarnings("deprecation")
	public static int getStringLength(String str, int size){
				
		Toolkit toolkit =  Toolkit.getDefaultToolkit();
		int stringlen = 0;				
		Font font = new Font("Arial", Font.PLAIN, 9);		
		FontMetrics fontMetrics = toolkit.getFontMetrics(font);
		System.out.println ("[Stylesheet Info] Calculating width for: " + str + ":
"  + fontMetrics.stringWidth(str));
		stringlen = fontMetrics.stringWidth(str);	
		return stringlen;
	}
	
	
}




--
View this message in context: http://apache-fop.1065347.n5.nabble.com/Extract-font-width-using-FOP-tp37360p37361.html
Sent from the FOP - Users mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org