FontMetrics for Marvin TextBoxes

User c23c5e9da4

10-02-2007 18:59:29

Is there an equivalent of FontMetrics for strings in text boxes in an MDocument? I need to calculate the length of a string so I know where to place the text box so it is centered above the reaction arrow.





Thanks,





Trevor

User f359e526a1

12-02-2007 12:23:44

Hello, you can get the FontMetrics by:


Code:



MTextDocument text = textbox.getTextDocument();


fm = text.getSection(i).getFontMetrics(g, text.getDefaultFont());


User c23c5e9da4

12-02-2007 16:00:43

Thanks - where is the Graphics object you are passing to getFontMetrics coming from?

ChemAxon 7c2d26e5cf

13-02-2007 15:17:01

There is no reference in MTextDocument to Graphics. The graphics of Marvin components are not accessible from the Marvin Beans API. But if you draw text box on your own graphics, you call MTextDocument.Section.getFontMetrics(Graphics,MFont) with this graphics.


We are considering that implement alignment property in TextDocument. Probably it would solve also your problem to position text box to the middle of the reaction arrow.

User ef5e605ae6

14-02-2007 10:31:26

tkram01 wrote:
I need to calculate the length of a string so I know where to place the text box so it is centered above the reaction arrow.
In Marvin 4.2, you will be able to center the text in the box using


textBox.setHorizontalAlignment(MTextBox.ALIGN_CENTER);


textBox.setVerticalAlignment(MTextBox.ALIGN_CENTER);


It will also work in the next test release.

User c23c5e9da4

16-03-2007 22:07:11

What is the relationship between what is returned from textbox.getTextDocument().getSection(0).getFontMetrics(g, textbox.getTextDocument().getDefaultFont()).stringWidth(s) and the coordinates of the MDocument? How do I use the result of a stringWidth call to FontMetrics to determine the appropriate size of a MTextBox?





Thanks,





Trevor

User ef5e605ae6

19-03-2007 10:37:52

There is no direct relationship; it depends on the scale factor and the Graphics context you use for drawing. As far as I know, Java does not guarantee that a font will have the same size in different contexts.





I don't really understand your problem. It seems that you are creating a document and not drawing it. If you are not drawing then you don't have a Graphics, thus you cannot use getFontMetrics.

User c23c5e9da4

19-03-2007 15:29:11

I have a graphics context I'm using for drawing and I am using that to get the FontMetrics but I'm not sure how to use a result from stringWidth to determine where to place a textbox in an MDocument so it is centered in relation to a chemical entity.

User ef5e605ae6

19-03-2007 19:01:02

stringWidth returns the width in pixels, you should divide it by the scale factor (det(transformation matrix)^(1/3)) to get molecular coordinates. For centering, you should use textBox.setHorizontalAlignment(MTextBox.ALIGN_CENTER) (see Marvin 4.2.0alpha5); it works well even if the box size is larger than the actual text width.

User c23c5e9da4

20-03-2007 02:23:19

Thanks but I am not seeing where I can get the transformation matrix to calculate the scale factor.

User ef5e605ae6

20-03-2007 22:40:31

It's hard to answer because I have no idea how do you draw at all using the public API. It does not really support drawing, only Image conversion is supported (see MDocument.exportToObject("image")). Although there is a new utility method MPainterUtil.draw, it does not really seem to be practically useful, because it does not have x, y and scale arguments. I try to get its author to answer your questions.

User c23c5e9da4

20-03-2007 22:42:30

Yes - I am using the MPainter class to do the drawing.

ChemAxon 7c2d26e5cf

21-03-2007 12:06:01

Hi Trevor,


We are considering to add new methods to the MPainterUtil API:


Code:
public static void draw(MDocument doc,Graphics g,Rectangle rect,String opts)



Code:
public static double calcScale(MDocument doc,Graphics g,Rectangle rect,String opts)



The rectangle would specify an area on the graphics (clip) where the molecule will be painted. By calling calcScale(...) (before the draw method), you would be able to calculate the scaling factor that the draw method will use.


Is it a suitable solution for you? If yes, we are going to implement these methods.

User c23c5e9da4

21-03-2007 16:10:37

Yes - This sounds like a good solution. Thanks.

ChemAxon 7c2d26e5cf

21-03-2007 18:05:29

OK, we are going to do it.

ChemAxon 7c2d26e5cf

03-05-2007 13:39:45

We have implemented required features. Instead of MPainterUtil, we have placed required methods into the chemaxon.marvin.MolPrinter. Extended MolPrinter API will be available in Marvin 4.1.8.

User c23c5e9da4

18-05-2007 18:31:24

Was this implemented in 4.1.8?

ChemAxon 7c2d26e5cf

21-05-2007 10:19:04

Yes, it is implemented. Please, see the MolPrinter API.

User c23c5e9da4

21-05-2007 14:55:47

thanks - sorry I was looking for calcScale - I see how to do it now. One more question - I see a method for setSetColoringEnabled but I don't see where to set the colors - like the "setcolors:a1:#00ff00:b1:#00ff00" option when using MPainterUtil.





Thanks,





Trevor

ChemAxon 7c2d26e5cf

23-05-2007 09:55:25

You should specify atom sets and theirs colors in the Molecule and in the MDocument. After then, add this MDocument to the MolPrinter.


Code:
MDocument mdoc = new MDocument(mol);


Color green = new Color(0, 255, 0);


//set the color of the 1. atom set


mdoc.setAtomSetColorMode(1, MDocument.SETCOLOR_SPECIFIED);


mdoc.setAtomSetRGB(1, green.getRGB());


//set the color of the 2. and 8. atoms in the molecule


mol.getAtom(2).setSetSeq(1);


mol.getAtom(8).setSetSeq(1);


...


MolPrinter p = new MolPrinter(mdoc);



The attached file includes the full (runnable) example.

User c23c5e9da4

25-05-2007 21:33:30

I'm still confused about how to get the string length in molecular coordinates - if I call





double stringWidth = textBox.getTextDocument().getSection(0).getFontMetrics(g, textBox.getTextDocument().getDefaultFont()).stringWidth(s) / scaleFactor;





the stringWidth gets larger as the scale factor decreases - so as the document gets smaller (and the text gets smaller) the stringWidth gets larger which makes no sense.

ChemAxon 7c2d26e5cf

29-05-2007 11:27:18

We will check it.

User c23c5e9da4

29-05-2007 18:45:19

I am also seeing cases where when using setAutoSize(true) it makes the box too short and the text is cutoff.

User f359e526a1

29-05-2007 19:36:05

Could you please send a code snippet that ultimately leands to this text cutoff behaviour?

User c23c5e9da4

29-05-2007 19:55:35

maybe I don't understand what setAutoSize does. I thought it would adjust the horizontal size of the text box to make the text fit in one line. Is this correct?

User c23c5e9da4

29-05-2007 21:25:17

Here is an example showing the scaleFactor issue





import chemaxon.formats.MolImporter;


import chemaxon.marvin.MolPrinter;


import chemaxon.struc.MDocument;


import chemaxon.struc.MPoint;


import chemaxon.struc.graphics.MTextBox;





import java.awt.*;





public class ScaleFactorBugExample {


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


MDocument doc = new MDocument(MolImporter.importMol("c1ccccc1>>c1ccccccc1"));


MTextBox textBox = new MTextBox();


textBox.setCorners(new MPoint(0, -3), new MPoint(4, -3));


textBox.setText("Test Text");


doc.addObject(textBox);





MolPrinter printer = new MolPrinter(doc);


double scaleFactor = printer.maxScale(new Rectangle(733, 143));


System.err.println("scaleFactor = " + scaleFactor);


scaleFactor = printer.maxScale(new Rectangle(1108, 166));


System.err.println("scaleFactor = " + scaleFactor);


}


}








The second println shows a larger scale factor for the larger rectangle - so when applied to stringWidth/scaleFactor it will result in a string width in molecule coordinates that gets smaller as the zoom increases which shouldn't happen.

User f359e526a1

31-05-2007 20:17:12

I am still confused; do not you have some code with this cutoff problem? We had some scaling/cutoff problems before but I hoped we fixed that.

User c23c5e9da4

01-06-2007 02:28:22

There are 2 issues - the first and most critical is the FontMetrics issue where I am not able to get the correct length of a string using the supplied methods. The second issue is with cutoff of text when using autosizing but that is a secondary issue that becomes mute if the first issue it fixed.





Trevor

User c23c5e9da4

12-06-2007 15:54:36

Attached is an example showing the FontMetrics problem. Run the example and resize the window and you will see that the string width calculations are off.

User f359e526a1

13-06-2007 15:59:13

Thanks, clearly have some problem with the scaling, we already find it out with a similar program. Unfortunately it is buried a bit in the depth of image transformation, but please bear with us, we are on the problem.

ChemAxon fb166edcbd

17-07-2007 14:27:48

There is an 'autoSize' property in MTextBox which is designed to set the textbox width and height automatically to fit the enclosed text:


MTextBox.setAutoSize(boolean)


If this property is true, then the second parameter in


MTextBox.setCorners(MPoint, MPoint) is ignored.





However, this is not working in the current Marvin releases due to a simple property - copy bug. I have fixed this and the attached form of your ScaleFactorBugExample will work with the next Marvin patch / main releases. There is some smaller problems with the text width computing in this autoSize case, therefore I added some spaces to the text string. I hope this calculation problem will also be fixed soon.





In the meanwhile, I have improved your workaround to manually set the corners. You should not use the printScale but FontMetrics.getStringBounds(String, Graphics) and the fontScale of the textbox. You find my code in ScaleFactorBugExampleWorkaround and this is working with the current releases.

User c23c5e9da4

26-07-2007 18:25:54

are the text width computing bugs mentioned fixed in the current release?

ChemAxon fb166edcbd

27-08-2007 20:42:26

Yes, in the sense mentioned in my post on Tue Jul 17, 2007. (The 'autoSize' property is now working but there are some smaller problems in text width computing, therefore it may be better to ad some spaces to the text string.)

User c23c5e9da4

17-12-2007 19:31:40

Is there a way to compute the bounds of the drawing when using MolPrinter when you know the scale?

ChemAxon 7c2d26e5cf

20-12-2007 17:41:08

You can store molecule rect in chemaxon.marvin.util.MolImageSize.


To calculate the rect, try this code:


Code:
MolPrinter printer = ...


Molecule m = ...


Double sc = new Double(printer.getScale());


String opts = "image:scale"+sc.toString();


chemaxon.marvin.util.MolImageSize isize = m.getImageSize(opts);



See

User c23c5e9da4

21-12-2007 22:57:41

Perfect - Thanks