Three.js: Font: Add support for textDirection.

Created on 12 Dec 2019  路  4Comments  路  Source: mrdoob/three.js

Enhancement

Most helpful comment

Workaround:

var text = 't\nh\nr\ne\ne\n.\nj\ns';

I suppose we could consider this issue to be a feature request to add .textDirection.

All 4 comments

Workaround:

var text = 't\nh\nr\ne\ne\n.\nj\ns';

I suppose we could consider this issue to be a feature request to add .textDirection.

Remembers me at #11680

I worked on this with results :
Screen Shot 2020-01-20 at 6 20 46

but also many problems like misplaced accents and dots :
Screen Shot 2020-01-20 at 7 18 04

or huge white spaces between letters even if latin character aren't design to be displayed vertically.

I don't really know if I'm taking the problem in the right direction. My idea was to create the character geometries separately for each shape then use then using those geometry's bounding boxes to translate character's vertices.

`
if ( parameters.textDirection === undefined || parameters.textDirection.equals( new Vector2( 1, 0 ) ) ) {
ExtrudeBufferGeometry.call( this, shapes, parameters );
} else {
BufferGeometry.call ( this );

    var verticesArray = [],
        uvArray = [];

    var xOffset = 0,
        yOffset = 0,
        prevXOffset = 0,
        lineXOffset = 0,
        lineYOffset = 0;

    var textDirectionNormal = parameters.textDirection.clone().normalize();
        textDirectionNormal.set ( -textDirectionNormal.y, textDirectionNormal.x ).normalize();

    var lineHeight = ( font.data.boundingBox.yMax - font.data.boundingBox.yMin + font.data.underlineThickness ) * (parameters.size / font.data.resolution);

    shapes.forEach(shape => {
        var geo = new ExtrudeBufferGeometry( shape, parameters );
        geo.computeBoundingBox();

        xOffset = lineXOffset + geo.boundingBox.min.x;
        if( prevXOffset > xOffset ){
            //new line
            lineXOffset -= lineHeight * textDirectionNormal.x;
            lineYOffset -= lineHeight * textDirectionNormal.y;

            xOffset = lineXOffset + geo.boundingBox.min.x;
            yOffset = lineYOffset;
        } else {
            yOffset += geo.boundingBox.max.y - geo.boundingBox.min.y;
        }

        var scaledDirection = parameters.textDirection.clone().multiply( new Vector2( xOffset, yOffset ) );

        var vertices = geo.getAttribute( 'position' ).array;
        for (var i = 0; i < vertices.length; i += 3){
            vertices[i] += scaledDirection.x - xOffset;
            vertices[i + 1] += scaledDirection.y - yOffset;
        }

        verticesArray.push( ...vertices );
        uvArray.push( ...geo.getAttribute( 'uv' ).array );
        prevXOffset = xOffset;
    });

    this.setAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) );
    this.setAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) );

    this.computeVertexNormals();
}

`
I wonder if it would be better to use the textDirection parameters directly in the Font class ?

I wonder if it would be better to use the textDirection parameters directly in the Font class ?

Yes, I think so. For rtl support, I have read that you need a compatible font anyway because of problematic letter spacings. In other words, you can't just generate the text along arbitrary directions because it will look like in your screenshot.

Was this page helpful?
0 / 5 - 0 ratings