[SOLVED] QML Text position versus Adobe Photoshop text position



  • Hello,

    I'm trying to figure out the formula to convert PSD text position into Qml text position.

    My input data from Photoshop is the text geometry which is the rectangle covering the painted text (different from the layer size by the way => no white pixel).

    I first tried to use the PSD position as this and I got this:

    !http://i61.tinypic.com/2cnimgm.jpg!

    In black you see the qml text elements and in red the corresponding psd text rasterized (since image layer postions are good it gives the correct expected rendering geometry).

    As you can see there are big vertical offsets and small horizontal offsets.

    So I would like to know which value I need to add/substract to the qml text elements positions in order to get the exact same PSD rendering (black text should overlap red text images).

    Here another where I drew the bounding rect of the elements:

    !http://i61.tinypic.com/qn2ukj.png!

    Note that the offset is not linear (17px for the "Test" label and 14px for the "Toto" label)

    I tried the qml exporter photoshop plugin and the positions are wrong too. I looked into the source code of the script and found some hack in the script for the vertical offset ( subtract 1/4 of the font size to y) but result is still innacurate :

    @
    // ### Temporary hack to set font positioning
    // Using pointsize doesnt work for some reason and we need to
    // figure out which metric we need to use ascending, perhaps?
    yoffset -= textItem.size.as("px") / 4;
    @

    As the comment says it is a temporary hack so I guess the developper never find the right formula.

    Any idea ?

    Thanks in advance

    X-Krys



  • Hi X-Krys

    this is only a guess but I think the Unit is in Points and Points
    1 Pixel is equal to 0.75 points.

    Maybe that can be the problem.

    Best regards

    Juergen



  • Thanks juergen but as you can see in the preview picture the offset is not linear. Moreover if it was a unit issue with the conversion you gave the offset will be even worst (4/3 bigger than the actual i've got).

    The real problem is that Photoshop give me the bounding box of the Text, but Qt top-left position does not correponds to the bonding box, there is internal margin within the Text geometry and the effective painted text inside. I just need to know how to compute it in order to apply the right offset.



  • Please can you verify the following points:

    1.) Is set font.fontSizeMode : Text.FixedSize (default)
    2.) Which value has font.renderType ? Two possibilities: Text.QtRendering (default) or Text.NativeRendering
    3.) Which value has font.textFormat

    Can you make the test with QWidget/QLabel and QFontMetrics?
    Because QFontMetrics has a boundingRect() function.

    With this function you can verify that the QFontMetrics::boundingRect() gives you the same values as PhotoShop does.

    As far as I know there is no fontmetrics in Qml.

    The other way to find a solution would be to check the Qml source code about the Text item.

    Maybe that will help you.

    Best regards

    Juergen



  • 1/2/3 : I use default values

    For the "Test" text I got those results:

    Photoshop bounding rect: 111x42
    QML Text painted size : 113x74
    QLabel size: 113x74
    QfontMetrics bounding rect : 111x74

    For the "Toto" text I got those results:

    Photoshop bounding box : 80x27
    QML Text painted size: 84.484375x55
    QLabel size: 80x55
    QfontMetrics bounding rect: 80x55



  • Ah, now it seems that Photoshop is the highest and the lowest pixel of the font to determine the height of the bounding rect.

    The is not correct for a real bounding rect.

    The upper and lower distance from font pixel to the bounding rect can be different when you are using different fonts. That's why it is not linear.

    To get the photoshop height you have to calculate the height like:

    int height = fontM.boundingRect() - fontM.ascent() -fontM.descent();

    I hope that this will solve partially your problem.

    Cheers
    Juergen



  • I just found the way to do it thanks to a new feature of Qt 5.4 : QtQuick.TextMetrics element

    With TextMetrics::tightBoundingRect property we can get the same bounding box that Photoshop is based on and
    with TextMetrics::boundingRect property we get the bounding box that Qt use to position the Text element.

    With these two informations we can now compute the right horizontal & vertical offset we need to match exactly the position on Photoshop.

    To encapsulate the conversion we can create a custom Qml Component based on QtQuick.Text for instance:

    @<PhotoshopText.qml>

    import QtQuick 2.4

    Text {
    id: root

    property real xPS: 0
    property real yPS: 0
    
    // convert from Photoshop coordinates to Qt coordinates
    x: xPS - textMetrics.tightBoundingRect.x
    y: yPS - (textMetrics.tightBoundingRect.y - textMetrics.boundingRect.y)
    
    TextMetrics {
        id: textMetrics
        font: root.font
        text: root.text
    }
    

    }
    @

    Now we can use this new component to position any text with Photoshop coordinates:

    @<main.qml>

    import QtQuick 2.4

    Item {

    PhotoshopText {
        text: "Hello world!"
        xPS : <x value extracted from Photoshop>
        yPS : <y value extracted from Photoshop>
    }
    

    }
    @

    Thanks @Juergen for your help on this issue, you put me into the right direction ;)

    I can now finalize my PSD => QML converter :D

    Best regards

    Krys



  • I just found the way to do it thanks to a new feature of Qt 5.4 : QtQuick.TextMetrics element

    With TextMetrics::tightBoundingRect property we can get the same bounding box that Photoshop is based on and
    with TextMetrics::boundingRect property we get the bounding box that Qt use to position the Text element.

    With these two informations we can now compute the right horizontal & vertical offset we need to match exactly the position on Photoshop.

    To encapsulate the conversion we can create a custom Qml Component based on QtQuick.Text for instance:

    @<PhotoshopText.qml>

    import QtQuick 2.4

    Text {
    id: root

    property real xPS: 0
    property real yPS: 0
    
    // convert from Photoshop coordinates to Qt coordinates
    x: xPS - textMetrics.tightBoundingRect.x
    y: yPS - (textMetrics.tightBoundingRect.y - textMetrics.boundingRect.y)
    
    TextMetrics {
        id: textMetrics
        font: root.font
        text: root.text
    }
    

    }
    @

    Now we can use this new component to position any text with Photoshop coordinates:

    @<main.qml>

    import QtQuick 2.4

    Item {

    PhotoshopText {
        text: "Hello world!"
        xPS : <x value extracted from Photoshop>
        yPS : <y value extracted from Photoshop>
    }
    

    }
    @

    Thanks @Juergen for your help on this issue, you put me into the right direction ;)

    I can now finalize my PSD => QML converter :D

    Best regards

    Krys


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.